Search code examples
rneural-networkbiological-neural-network

Implementing the Izhikevich neuron model


I'm trying to implement the spiking neuron of the Izhikevich model. The formula for this type of neuron is really simple:

v[n+1] = 0.04*v[n]^2 + 5*v[n] + 140 - u[n] + I

u[n+1] = a*(b*v[n] - u[n])

where v is the membrane potential and u is a recovery variable.

If v gets above 30, it is reset to c and u is reset to u + d.

Given such a simple equation I wouldn't expect any problems. But while the graph should look like what it should look like, all I'm getting is this: what it looks like

I'm completely at loss what I'm doing wrong exactly because there's so little to do wrong. I've looked for other implementations but the code I'm looking for is always hidden in a dll somewhere. However I'm pretty sure I'm doing exactly what the Matlab code of the author (2) is doing. Here is my full R code:

v = -70
u = 0
a = 0.02
b = 0.2
c = -65
d = 6
history <- c()

for (i in 1:100) {
  if (v >= 30) {
    v = c
    u = u + d
  }
  v = 0.04*v^2 + 5*v + 140 - u + 0
  u=a*(b*v-u); 
  history <- c(history, v)
}

plot(history, type = "l")

To anyone who's ever implemented an Izhikevich model, what am I missing?

usefull links: (1) http://www.opensourcebrain.org/projects/izhikevichmodel/wiki (2) http://www.izhikevich.org/publications/spikes.pdf

Answer

So it turns out I read the formula wrong. Apparently v' means new v = v + 0.04*v^2 + 5*v + 140 - u + I. My teachers would have written this as v' = 0.04*v^2 + 6*v + 140 - u + I. I'm very grateful for your help in pointing this out to me.


Solution

  • Take a look at the code that implements the Izhikevich model in R below. It results in the following R plots:

    Regular Spiking Cell:

    Izhikevich Regular Spiking RS Cell Plot

    Chattering Cell: Izhikevich Chattering CH Cell Plot

    And the R code:

    # Simulation parameters
    dt = 0.01 # ms
    simtime = 500 # ms
    t = 0
    
    # Injection current
    I = 15
    delay = 100 # ms
    
    # Model parameters (RS)
    a = 0.02
    b = 0.2
    c = -65
    d = 8
    
    # Params for chattering cell (CH)
    # c = -50
    # d = 2
    
    # Initial conditions
    v = -80 # mv
    u = 0
    
    # Input current equation
    current = function()
    {
      if(t >= delay)
      {
        return(I)
      }
    
      return (0)
    }
    
    # Model state equations
    deltaV = function()
    {
      return (0.04*v*v+5*v+140-u+current())
    }
    
    deltaU = function()
    {
      return (a*(b*v-u))
    }
    
    updateState = function()
    {
      v <<- v + deltaV()*dt
      u <<- u + deltaU()*dt
    
      if(v >= 30) 
      {
        v <<- c
        u <<- u + d
      }
    }
    
    # Simulation code
    runsim = function()
    {
      steps = simtime / dt
      resultT = rep(NA, steps)
      resultV = rep(NA, steps)
    
      for (i in seq(steps))
      {
        updateState()
        t <<- dt*(i-1)
    
        resultT[i] = t
        resultV[i] = v
      }
    
      plot(resultT, resultV, 
           type="l", xlab = "Time (ms)", ylab = "Membrane Potential (mV)")
    }
    
    runsim()
    

    Some notes:

    • I've picked the parameters for the "Regular Spiking (RS)" cell from Izhikevich's site. You can pick other parameters from the two upper-right plots on that page. Uncomment the CH parameters to get a plot for the "Chattering" type cell.
    • As commenters have suggested, the first two equations in the question are incorrectly implemented differential equations. The correct way to implement the first one would be something like: "v[n+1] = v[n] + (0.04*v[n]^2 + 5*v[n] + 140 - u[n] + I) * dt". See the code above for example. dt refers to the user specified time step integration variable and usually dt << 1 ms.
    • In the for loop in the question, the state variables u and v should be updated first, then the condition checked after.
    • As noted by others, a current source is needed for both of these cell types. I've used 15 (I believe these are pico amps) from this page on the author's site (bottom value for I in the screenshot). I've also implemented a delay for the current onset (100 ms parameter).
    • The simulation code should implement some kind of time tracking so it's easier to know when the spikes are occurring in resulting plot. The above code implements this, and runs the simulation for 500 ms.