(Brette, et, al., 2007) CUBA
Implementation of the paper:
Brette, R., Rudolph, M., Carnevale, T., Hines, M., Beeman, D., Bower, J. M., et al. (2007), Simulation of networks of spiking neurons: a review of tools and strategies., J. Comput. Neurosci., 23, 3, 349–98
which is based on the balanced network proposed by:
Vogels, T. P. and Abbott, L. F. (2005), Signal propagation and logic gating in networks of integrate-and-fire neurons., J. Neurosci., 25, 46, 10786–95
Authors:
Chaoming Wang (chao.brain@qq.com)
[1]:
import brainmodels
import brainpy as bp
Parameters
[2]:
num_exc = 3200
num_inh = 800
taum = 20
taue = 5
taui = 10
Vt = -50
Vr = -60
El = -49
we = 60 * 0.27 / 10 # excitatory synaptic weight (voltage)
wi = -20 * 4.5 / 10 # inhibitory synaptic weight
ref = 5.0
Implementation 1
[3]:
# neuron groups
E = brainmodels.LIF(num_exc, tau_ref=ref, V_rest=El, V_th=Vt, V_reset=Vr, tau=taum, monitors=['spike'])
I = brainmodels.LIF(num_inh, tau_ref=ref, V_rest=El, V_th=Vt, V_reset=Vr, tau=taum)
E.V[:] = Vr + bp.math.random.rand(num_exc) * (Vt - Vr)
I.V[:] = Vr + bp.math.random.rand(num_inh) * (Vt - Vr)
[4]:
# synapses
E2E = brainmodels.ExpCUBA(E, E, bp.connect.FixedProb(prob=0.02), g_max=we, tau=taue)
E2I = brainmodels.ExpCUBA(E, I, bp.connect.FixedProb(prob=0.02), g_max=we, tau=taue)
I2E = brainmodels.ExpCUBA(I, E, bp.connect.FixedProb(prob=0.02), g_max=wi, tau=taui)
I2I = brainmodels.ExpCUBA(I, I, bp.connect.FixedProb(prob=0.02), g_max=wi, tau=taui)
[5]:
# network
net = bp.math.jit(bp.Network(E2E, E2I, I2I, I2E, E=E, I=I))
[6]:
# simulation and visualization
net.run(400., report=0.1)
bp.visualize.raster_plot(E.mon.ts, E.mon.spike, show=True)
Compilation used 9.7329 s.
Start running ...
Run 10.0% used 0.031 s.
Run 20.0% used 0.065 s.
Run 30.0% used 0.098 s.
Run 40.0% used 0.130 s.
Run 50.0% used 0.164 s.
Run 60.0% used 0.197 s.
Run 70.0% used 0.232 s.
Run 80.0% used 0.265 s.
Run 90.0% used 0.297 s.
Run 100.0% used 0.329 s.
Simulation is done in 0.329 s.

Implementation 2
[7]:
class LIF(bp.NeuGroup):
target_backend = 'numpy'
def __init__(self, size, **kwargs):
super(LIF, self).__init__(size=size, **kwargs)
self.V = bp.math.Variable(bp.math.ones(size) * Vr)
self.Isyn = bp.math.Variable(bp.math.zeros(size))
self.t_spike = bp.math.Variable(-1e7 * bp.math.ones(size))
self.spike = bp.math.Variable(bp.math.zeros(size, dtype=bool))
self.integral = bp.odeint(self.derivative)
def derivative(self, V, t, Isyn):
return (Isyn + (El - V)) / taum
def update(self, _t, _dt):
for i in range(self.num):
self.spike[i] = 0.
if (_t - self.t_spike[i]) > ref:
V = self.integral(self.V[i], _t, self.Isyn[i])
self.spike[i] = 0.
if V >= Vt:
self.V[i] = Vr
self.spike[i] = 1.
self.t_spike[i] = _t
else:
self.V[i] = V
self.Isyn[:] = 0.
[8]:
class Syn(bp.TwoEndConn):
target_backend = 'numpy'
def __init__(self, pre, post, conn, w, tau, **kwargs):
super(Syn, self).__init__(pre, post, conn=conn, **kwargs)
# parameters
self.w = w
self.tau = tau
self.pre2post = self.conn.requires('pre2post') # connections
self.g = bp.math.Variable(bp.math.zeros(post.num)) # variables
self.integral = bp.odeint(self.derivative)
def derivative(self, g, t):
dg = - g / self.tau
return dg
def update(self, _t, _dt):
self.g[:] = self.integral(self.g, _t)
for pre_id in range(self.pre.num):
if self.pre.spike[pre_id] > 0.:
post_ids = self.pre2post[pre_id]
for i in post_ids:
self.g[i] += self.w
self.post.Isyn += self.g
[9]:
E = LIF(num_exc, monitors=['spike'])
I = LIF(num_inh)
E.V[:] = Vr + bp.math.random.rand(num_exc) * (Vt - Vr)
I.V[:] = Vr + bp.math.random.rand(num_inh) * (Vt - Vr)
[10]:
E2E = Syn(pre=E, post=E, conn=bp.connect.FixedProb(prob=0.02), w=we, tau=taue)
E2I = Syn(pre=E, post=I, conn=bp.connect.FixedProb(prob=0.02), w=we, tau=taue)
I2E = Syn(pre=I, post=E, conn=bp.connect.FixedProb(prob=0.02), w=wi, tau=taui)
I2I = Syn(pre=I, post=I, conn=bp.connect.FixedProb(prob=0.02), w=wi, tau=taui)
net = bp.Network(E, I, E2E, E2I, I2I, I2E)
net = bp.math.jit(net)
[11]:
net.run(400., report=0.1)
bp.visualize.raster_plot(E.mon.ts, E.mon.spike, show=True)
Compilation used 3.7684 s.
Start running ...
Run 10.0% used 0.018 s.
Run 20.0% used 0.037 s.
Run 30.0% used 0.055 s.
Run 40.0% used 0.074 s.
Run 50.0% used 0.093 s.
Run 60.0% used 0.113 s.
Run 70.0% used 0.131 s.
Run 80.0% used 0.149 s.
Run 90.0% used 0.167 s.
Run 100.0% used 0.186 s.
Simulation is done in 0.186 s.
