Izhikevich neuron model in Brian : spike emitted before reseting?

Description of problem

Hi,
From my understanding of some neuron models like the Izhikevich model, the spike is supposed to be emitted when the potential threshold “v_th” is reached, causing at the same time the reset of its variables.

But I just realized recently that when simulating the Izhikevich neuron model in Brian, the spike is emitted 1 timestep before the reset of its variables (i.e before the threshold is reached). I might be wrong, but I don’t see where … :confused:

Minimal code to reproduce problem

Here is my Brian codes to simulate the Izhikevich model (without units). I’m printing on the terminal the variables “v”, “u” and the eventual emitted “spike” each time step.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from brian2 import *

start_scope()

duration = 0.03*second          # simulation time to observe the first spike 
defaultclock.dt = 1*ms           # time step dt 

# IZH parameters
I_exc = 7.0
a = 0.02
b = 0.2 
c = -65.0
d = 8.0
v_th = 30.0

v_init = c
u_init = b*c

time_refractory = 0.0*ms

# IZH equations 
eqs_IZH = '''
        	dv/dt = (0.04*v**2 + 5*v + 140 - u + I_exc)/ms : 1
       	 	du/dt = a*(b*v - u)/ms : 1
      	  '''
      	 
reset = '''
          v = c
          u += d
        '''    

# 
NG = NeuronGroup(1, eqs_IZH, threshold='v>v_th', reset=reset, refractory=time_refractory, method="euler")
NG.v = v_init
NG.u = u_init

# MONITORS
s_mon = SpikeMonitor(NG)
v_mon = StateMonitor(NG, variables = True, record = True)


# RUN SIMULATION
run(duration)



# DEBUG : printing variables "v", "u" and emitted "spike" for each timestep  
time_spike = 0
print ('////////////////////////////////////////////////////')
print("t \t\t  v \t\t   u \t\t spike")
for i in range(0,int(s_mon.t[0]/defaultclock.dt)+3):   # print until the 1st spike + 2 timesteps after
	if (i == int(s_mon.t[time_spike]/defaultclock.dt)):	
		print("%2.6f \t %2.6f \t %2.6f \t 1 <-----" % (v_mon.t[i], v_mon.v[0][i], v_mon.u[0][i]))
		if (time_spike != size(s_mon.t)-1):
			time_spike = time_spike + 1
	else :
		print("%2.6f \t %2.6f \t %2.6f \t 0" % (v_mon.t[i], v_mon.v[0][i], v_mon.u[0][i]))
print ('///////////////////////////////////////////////////')

Expected output

This is where I expected the emitted spike to be, i.e when the variables reset is done.

////////////////////////////////////////////////////
t 		      v 		      u 		 spike
0.000000 	 -65.000000 	 -13.000000 	 0
0.001000 	 -61.000000 	 -13.000000 	 0
0.002000 	 -57.160000 	 -12.984000 	 0
0.003000 	 -52.285376 	 -12.952960 	 0
0.004000 	 -44.408874 	 -12.903042 	 0
0.005000 	 -27.664279 	 -12.822617 	 0
0.006000 	 24.449437 	     -12.676822 	 0
0.007000 	 -65.000000 	 -4.325488 	     1 <----- when threshold reached and varialbes are reset
0.008000 	 -69.674512 	 -4.498978 	     0
///////////////////////////////////////////////////

Actual output

But I get this instead :

////////////////////////////////////////////////////
t 		     v 		          u 		 spike
0.000000 	 -65.000000 	 -13.000000 	 0
0.001000 	 -61.000000 	 -13.000000 	 0
0.002000 	 -57.160000 	 -12.984000 	 0
0.003000 	 -52.285376 	 -12.952960 	 0
0.004000 	 -44.408874 	 -12.903042 	 0
0.005000 	 -27.664279 	 -12.822617 	 0
0.006000 	 24.449437 	     -12.676822 	 1 <----- threshold not reached here ... right ?
0.007000 	 -65.000000 	 -4.325488 	     0
0.008000 	 -69.674512 	 -4.498978 	     0
///////////////////////////////////////////////////

Am I wrong in my codes or maybe my understanding of the Izhikevich model ?

Thanks for your help,

Best regards,

Marino

Code and your understanding of the model are correct. The confusion comes from the fact that the StateMonitor records the variable values at the beginning of each time step. In the time step where the spike happens, it therefore records the values before the reset is applied. If you add when='end' to the StateMonitor creation, you will instead record values at the end of each time step and get what you expect. I explain this in more detail in this blog post and in the equivalent screencast video.

1 Like

Thanks @mstimberg for the solution and the explanations !! :ok_hand: After adding the “when=‘end’”, I got what I wanted ! :v:

1 Like