I have a questions with regards to the implementation of the leaky integrate and fire model in Python using ODE solvers.
I have an implementation using the Euler method with a for loop:
import numpy as np
import matplotlib.pyplot as plt
# Define parameters
tau_m = 10 # membrane time constant (ms)
v_rest = -70 # resting membrane potential (mV)
v_thresh = -55 # spike threshold (mV)
v_reset = -80 # reset potential (mV)
i_e = 3 # input current (nA)
dt = 0.1 # time step (ms)
t_max = 100 # simulation time (ms)
# Initialize variables
v = v_rest # membrane potential (mV)
# Simulate LIF model
for t in np.arange(0, t_max, dt):
dv_dt = (-(v - v_rest) + i_e) / tau_m # membrane potential differential equation
v += dv_dt * dt # update membrane potential
if v >= v_thresh: # spike condition
v = v_reset # reset membrane potential
Now, the issue is that I have a much larger model implemented using solve_ivp() and I need to integrate the LIF model into it.
Defining the differential term of the membrane potential (dv_dt) is doable and I can do it as follows:
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
# Define LIF model
def lif(t, y, tau_m, v_rest, v_thresh, v_reset, i_e):
dv_dt = (-(y - v_rest) + i_e) / tau_m # membrane potential differential equation
return dv_dt
# Define parameters
tau_m = 10 # membrane time constant (ms)
v_rest = -70 # resting membrane potential (mV)
v_thresh = -55 # spike threshold (mV)
v_reset = -80 # reset potential (mV)
i_e = 3 # input current (nA)
t_span = (0, 100) # simulation time span (ms)
y0 = v_rest # initial membrane potential (mV)
# Simulate LIF model
sol = solve_ivp(lambda t, y: lif(t, y, tau_m, v_rest, v_thresh, v_reset, i_e), t_span, [y0])
# Extract results
t = sol.t
v = sol.y[0]
But I was not sure how to implement the hard change in membrane potential after depolarization.
v = v_reset if v >= v_thresh # spike condition
since when you call the solver solve_ivp(), the only output of the function is the differential term dv_dt. I have thought about doing:
dv_dt = (v_reset - y) if y >= v_thresh else (-(y - v_rest) + i_e) / tau_m
So that I implement the change to y in the next iteration through dv_dt, but although this decreases the membrane potential, it does not reset it to v_reset.
Any ideas would be appreciated!