时间类的创建

我们重写理一下SNN的更新过程,如下图

时间类的创建_第1张图片按照类比时间的话,在这个更新的过程中,dt相当于现实生活中的秒,而min_delay就相当于现实生活的分。然后我就在思考应该如何描述一个脉冲的发放时间呢?比如仿真时间为10ms,dt=0.1ms,min_delay=1ms。那么一个脉冲发放的时间可以记录为在2.3ms时刻,发射了一个脉冲。

为了方便管理Time类应该满足:1,在每个时间片后完成更新(全局),2,可以获取任意时刻的对应的时间。这是对于每一个神经元来说的,比如,我想知道在三个时间片的第五步时刻对应的时间。

#ifndef TIME_H
#define TIME_H

class Time
{
public:
	Time();
	~Time();
	double get_ms(int step_);

	int get_step();

	void update(int min_delay);
private:
	double ms;
	double dt;
	int step;
};

Time::Time():ms(0),dt(0.1),step(0)
{
}

Time::~Time()
{
}

double Time::get_ms(int step_)
{
	return step_ * dt;
}

int Time::get_step()
{
	return step;
}

void Time::update(int min_delay)
{
	step += min_delay;
}




#endif // !TIME_H

然后是打印出结果的话如图

时间类的创建_第2张图片

我们可以看到0和1之间的延迟是1ms,且能够正常显示。所以0和2之间的连接是有问题的。这证明之前的双循环机制还是有问题的,应该是理解有问题,导致按照之前的思路写代码会出现问题,我们必须重新理清他的循环机制

时间类的创建_第3张图片

如上图所示,我们的更新步骤其实就是计算下一次更新ringbuffer的内容。红色的线代表的是我们要计算的。我们要计算的关系其实是这一步lag,muduli,下一步的lag之间的关系。因为程序每个时间片就是最小延迟。

在这个表中  neuron第一次发射脉冲的时间为 2   那么对neuron1来说他会在2+2时刻接受到neron的脉冲,但是因为是从零开始的,所以要减一,2+2-1=3,也就是说moduli[3]=1的,但是buffer最大的长度是3怎么办呢,buffer[3%3=0]=1;这样就完成了循环。

那么我么验证在第二个时间片中,当lag=0时,moduli[0]=2, 而buffer[moduli[0]] = 0,说明neuron1是没有接收到脉冲的,当lag=1时moduli[1] = 3。他又超过了buffer的最大值,因此需要取余max_delay,也就是0 此时读取的buffer[0] = 1 正好时上一步修改的。

同样,我们再次测试neuron第二个脉冲4,加上延迟减一,再减去上次执行的长度2,4+2-1-2=3。

此时呢,moduli[3]=0。buffer[0] = 1;在三个时间片验证:当lag=0时,moduli[0]=4, 而buffer[moduli[0]%3] = buffer[1] 的,此时buffer[1] = 0。,当lag=1时moduli[1] = 0,buffer[0]正好时第二个时间片传过来的脉冲。综上,理论成立。

同样的理论也可以放到neuron2里面。neuron第一次发射脉冲的时间为 2 ,那么就是2+3-1=4。此时moduli[4]=1,同样大于max_delay。怎么办呢?再次取余可以得到buffer[1] = 1。

在第二个时间片中,当lag=0时,moduli[0]=2, 而buffer[moduli[0]] = 0,说明neuron2是没有接收到脉冲的,当lag=1时moduli[1] = 3。他又超过了buffer的最大值,因此需要取余max_delay,也就是0 此时读取的buffer[0] = 0 。说明这个时间片中,neuron2根本没有接收到脉冲。

那么我们看,在第三个时间片中,当lag=0时,moduli[0]=4, 而buffer[moduli[0]%3=1] = buffer[1]=1。这正是一号神经元在2时刻发送的脉冲。

好了,双循环机制基本上就是这样的。那我们重新梳理一下代码。

你可能感兴趣的:(分布式模拟脉冲神经网络,算法)