Description of problem
Trying to implement uniform network structure as in "Slow dynamics and high variability in balanced cortical networks with clustered connections " by Litwin-Kumar and Doiron we got zero division error in implementing the differential equations for synapses.
The full code for reproducibility of the problem is below:
Minimal code to reproduce problem
def get_population(name, N, tau_mem, mu):
“”“Get population of neurons
name – name of population
N – number of neurons
tau_mem – time constant of neuron’s membrane
mu – ???
“””
v_thresh = 1 # units?
v_reset = 0
neurons = NeuronGroup(
N,
"""
tau_mem : second
mu : 1
v_reset : 1
v_thresh : 1
I_syn_ee_synapses : 1 / second
I_syn_ei_synapses : 1 / second
I_syn_ie_synapses : 1 / second
I_syn_ii_synapses : 1 / second
dv/dt = (mu - v)/tau_mem + (I_syn_ee_synapses +
I_syn_ei_synapses +
I_syn_ie_synapses +
I_syn_ii_synapses) : 1 (unless refractory)
""",
threshold="v > v_thresh",
reset="v = v_reset",
refractory=5*second,
method="exact",
name=name,
)
neurons.mu = mu
neurons.tau_mem = tau_mem # different for exc and inh neurons 15 and 10 ms
neurons.v_thresh = v_thresh
neurons.v_reset = v_reset
return neurons
def get_synapses(name, source, target, J, tau_1, tau_2, proba):
“”"Construct connections and retrieve synapses
name -- name of synapses
source -- source of connections
target -- target of connections
J -- weight of the synapse
tau_1 -- time constant of source group
tau_2 -- time constant of target group
proba -- probability of connection between groups
"""
# may need to multiply J by 15mV to dimensionise it
# for now dimensionless as I do not have a clue how units
# work in Brian
synapses_eqs = """
J : 1
tau_1 : second
tau_2 : second
dF/dt = -F/tau_2 + x/(tau_1 * tau_2) : 1 / second (clock-driven)
dx/dt = -x/tau_1 : 1 (clock-driven)
I_syn_{}_post = F : 1 / second (summed)
""".format(name)
synapses_action = """x += J"""
synapses = Synapses(
source,
target,
model=synapses_eqs,
on_pre=synapses_action,
method="exact",
name=name,
)
synapses.connect(p = proba)
# N_syn = len(synapses)
# different values depending on types of pre/post synaptic neurons
# TODO: scale J appropriately to its neuron group size!!!!!
synapses.J = J
return synapses
start_scope()
configure neuron populations
exc_neurons = get_population(“exc_neurons”, N=4000, tau_mem=15second, mu=np.random.uniform(1.1, 1.2))
inh_neurons = get_population(“inh_neurons”, N=1000, tau_mem=10second, mu=np.random.uniform(1.0, 1.05))
configure synapses
ee_synapses = get_synapses(
“ee_synapses”,
exc_neurons,
exc_neurons,
J=0.024,
tau_1 = 1second,
tau_2 = 3second,
proba=0.2
)
ei_synapses = get_synapses(
“ei_synapses”,
exc_neurons,
inh_neurons,
J=-0.045,
tau_1 = 1second, # ???
tau_2 = 2second,
proba=0.5
)
ie_synapses = get_synapses(
“ie_synapses”,
inh_neurons,
exc_neurons,
J=0.014,
tau_1 = 1second, # ???
tau_2 = 3second,
proba=0.5
)
ii_synapses = get_synapses(
“ii_synapses”,
inh_neurons,
inh_neurons,
J=-0.057,
tau_1 = 1second, # ???
tau_2 = 2second,
proba=0.5
)
run for burnin time to settle network activity
defaultclock.dt = 0.1 * second
burnin = 500 * second
run(burnin)
record from now on
spike_monitor_exc = SpikeMonitor(exc_neurons)
spike_monitor_inh = SpikeMonitor(inh_neurons)
state_monitor_ee = StateMonitor(ee_synapses, [“x”], record=True)
duration = 4200 * second
run(duration, report=“text”)
What you have aready tried
We tried to switch from cyton execution to numpy one, but there is still a problem with division by 0 somewhere. The equations are implemented the best way possible in our opinion.