Beispiel #1
0
    def __init__(self,
                 size,
                 ENa=50.,
                 EK=-77.,
                 EL=-54.387,
                 C=1.0,
                 gNa=120.,
                 gK=36.,
                 gL=0.03,
                 V_th=20.,
                 **kwargs):
        # parameters
        self.ENa = ENa
        self.EK = EK
        self.EL = EL
        self.C = C
        self.gNa = gNa
        self.gK = gK
        self.gL = gL
        self.V_th = V_th

        # variables
        self.V = bp.ops.ones(size) * -65.
        self.m = bp.ops.ones(size) * 0.5
        self.h = bp.ops.ones(size) * 0.6
        self.n = bp.ops.ones(size) * 0.32
        self.spike = bp.ops.zeros(size)
        self.input = bp.ops.zeros(size)

        self.int_V = bp.odeint(f=self.dev_V)
        self.int_m = bp.odeint(f=self.dev_m)
        self.int_h = bp.odeint(f=self.dev_h)
        self.int_n = bp.odeint(f=self.dev_n)

        super(HH, self).__init__(size=size, **kwargs)
    def __init__(self, method='exp_auto'):
        super(HindmarshRose, self).__init__()

        # parameters
        self.a = 1.
        self.b = 2.5
        self.c = 1.
        self.d = 5.
        self.s = 4.
        self.x_r = -1.6
        self.r = 0.001

        # variables
        self.x = bp.math.Variable(bp.math.ones(1))
        self.y = bp.math.Variable(bp.math.ones(1))
        self.z = bp.math.Variable(bp.math.ones(1))
        self.I = bp.math.Variable(bp.math.zeros(1))

        # integral functions
        def dx(x, t, y, z, Isyn):
            return y - self.a * x**3 + self.b * x * x - z + Isyn

        def dy(y, t, x):
            return self.c - self.d * x * x - y

        def dz(z, t, x):
            return self.r * (self.s * (x - self.x_r) - z)

        self.int_x = bp.odeint(f=dx, method=method)
        self.int_y = bp.odeint(f=dy, method=method)
        self.int_z = bp.odeint(f=dz, method=method)
Beispiel #3
0
    def __init__(self, size):
        super().__init__(size)

        self.V = bm.Variable(bm.zeros(self.num) - 70.)
        self.u = bm.Variable(bm.zeros(self.num))
        self.input = bm.Variable(bm.zeros(self.num))

        self.int_V = bp.odeint(self.dV, method='rk2')
        self.int_u = bp.odeint(self.du, method='rk2')
Beispiel #4
0
    def __init__(self, size, **kwargs):
        # variables
        self.V = bp.ops.zeros(size)
        self.spike = bp.ops.zeros(size)
        self.ge = bp.ops.zeros(size)
        self.gi = bp.ops.zeros(size)
        self.input = bp.ops.zeros(size)
        self.t_last_spike = bp.ops.ones(size) * -1e7

        self.int_V = bp.odeint(self.dev_V)
        self.int_ge = bp.odeint(self.dev_ge)
        self.int_gi = bp.odeint(self.dev_gi)

        super(LIF, self).__init__(size=size, **kwargs)
Beispiel #5
0
def quadratic_system1():
  int_x = bp.odeint(lambda x, t: -x ** 2)
  analyzer = bp.analysis.PhasePlane1D(model=int_x,
                                      target_vars={'x': [-2, 2]},
                                      resolutions=0.001)
  analyzer.plot_vector_field()
  analyzer.plot_fixed_point(show=True)

  int_x = bp.odeint(lambda x, t: x ** 2)
  analyzer = bp.analysis.PhasePlane1D(model=int_x,
                                      target_vars={'x': [-2, 2]},
                                      resolutions=0.001)
  analyzer.plot_vector_field()
  analyzer.plot_fixed_point(show=True)
    def __init__(self, size, name=None, T=36., method='rk4'):
        super(ReducedTRNModel, self).__init__(size=size, name=name)

        self.IT_th = -3.
        self.b = 0.5
        self.g_T = 2.0
        self.g_L = 0.02
        self.E_L = -70.
        self.g_KL = 0.005
        self.E_KL = -95.
        self.NaK_th = -55.

        # temperature
        self.T = T

        # parameters of INa, IK
        self.g_Na = 100.
        self.E_Na = 50.
        self.g_K = 10.
        self.phi_m = self.phi_h = self.phi_n = 3**((self.T - 36) / 10)

        # parameters of IT
        self.E_T = 120.
        self.phi_p = 5**((self.T - 24) / 10)
        self.phi_q = 3**((self.T - 24) / 10)
        self.p_half, self.p_k = -52., 7.4
        self.q_half, self.q_k = -80., -5.

        # parameters of V
        self.C, self.Vth, self.area = 1., 20., 1.43e-4
        self.V_factor = 1e-3 / self.area

        # parameters
        self.b = 0.14
        self.rho_p = 0.

        # variables
        self.V = bm.Variable(bm.zeros(self.num))
        self.y = bm.Variable(bm.zeros(self.num))
        self.z = bm.Variable(bm.zeros(self.num))
        self.spike = bm.Variable(bm.zeros(self.num, dtype=bool))
        self.input = bm.Variable(bm.zeros(self.num))

        # functions
        self.int_V = bp.odeint(self.fV, method=method)
        self.int_y = bp.odeint(self.fy, method=method)
        self.int_z = bp.odeint(self.fz, method=method)
        if not isinstance(self.int_V, bp.ode.ExpEulerAuto):
            self.integral = bp.odeint(self.derivative, method=method)
Beispiel #7
0
    def __init__(self,
                 pre,
                 post,
                 conn,
                 g_max=1.,
                 delay=0.,
                 tau=8.0,
                 E=0.,
                 method='exp_auto'):
        super(ExpCOBA, self).__init__(pre=pre, post=post, conn=conn)
        self.check_pre_attrs('spike')
        self.check_post_attrs('input', 'V')

        # parameters
        self.E = E
        self.tau = tau
        self.delay = delay
        self.g_max = g_max
        self.pre2post = self.conn.require('pre2post')

        # variables
        self.g = bm.Variable(bm.zeros(self.post.num))

        # function
        self.integral = bp.odeint(lambda g, t: -g / self.tau, method=method)
Beispiel #8
0
    def __init__(self,
                 pre,
                 post,
                 conn,
                 delay=0.,
                 g_max=0.10,
                 E=0.,
                 tau=2.0,
                 **kwargs):
        # parameters
        self.g_max = g_max
        self.E = E
        self.tau = tau
        self.delay = delay

        # connections
        self.conn = conn(pre.size, post.size)
        self.pre_ids, self.post_ids = conn.requires('pre_ids', 'post_ids')
        self.num = len(self.pre_ids)

        # data
        self.s = bp.ops.zeros(self.num)
        self.s0 = bp.ops.zeros(1)
        self.g = self.register_constant_delay('g',
                                              size=self.num,
                                              delay_time=delay)

        self.int_s = bp.odeint(f=self.dev_s)

        super(AMPA1, self).__init__(pre=pre, post=post, **kwargs)
    def __init__(
        self,
        size,
        tau_neu=10.,
        tau_syn=0.5,
        tau_ref=2.,
        V_reset=-65.,
        V_th=-50.,
        Cm=0.25,
    ):
        super(LIF, self).__init__(size=size)

        # parameters
        self.tau_neu = tau_neu  # membrane time constant [ms]
        self.tau_syn = tau_syn  # Post-synaptic current time constant [ms]
        self.tau_ref = tau_ref  # absolute refractory period [ms]
        self.Cm = Cm  # membrane capacity [nF]
        self.V_reset = V_reset  # reset potential [mV]
        self.V_th = V_th  # fixed firing threshold [mV]
        self.Iext = 0.  # constant external current [nA]

        # variables
        self.V = bm.Variable(-65. + 5.0 * bm.random.randn(self.num))  # [mV]
        self.I = bm.Variable(bm.zeros(self.num))  # synaptic currents [nA]
        self.spike = bm.Variable(bm.zeros(self.num, dtype=bool))
        self.t_last_spike = bm.Variable(bm.ones(self.num) * -1e7)

        # function
        self.integral = bp.odeint(bp.JointEq([self.dV, self.dI]),
                                  method='exp_auto')
Beispiel #10
0
        def __init__(self,
                     size,
                     ENa=50.,
                     EK=-77.,
                     EL=-54.387,
                     C=1.0,
                     gNa=120.,
                     gK=36.,
                     gL=0.03,
                     V_th=20.,
                     **kwargs):
            super(HH, self).__init__(size=size, **kwargs)

            # parameters
            self.ENa = ENa
            self.EK = EK
            self.EL = EL
            self.C = C
            self.gNa = gNa
            self.gK = gK
            self.gL = gL
            self.V_th = V_th

            # variables
            self.V = bp.math.numpy.Variable(np.ones(size) * -65.)
            self.m = bp.math.numpy.Variable(np.ones(size) * 0.5)
            self.h = bp.math.numpy.Variable(np.ones(size) * 0.6)
            self.n = bp.math.numpy.Variable(np.ones(size) * 0.32)
            self.spike = bp.math.numpy.Variable(np.zeros(size, dtype=bool))
            self.input = bp.math.numpy.Variable(np.zeros(size))

            # integral
            self.integral = bp.odeint(method='rk4', f=self.derivaitve)
Beispiel #11
0
        def __init__(self,
                     size,
                     ENa=50.,
                     EK=-77.,
                     EL=-54.387,
                     C=1.0,
                     gNa=120.,
                     gK=36.,
                     gL=0.03,
                     V_th=20.,
                     **kwargs):
            super(HH, self).__init__(size=size, **kwargs)

            # parameters
            self.ENa = ENa
            self.EK = EK
            self.EL = EL
            self.C = C
            self.gNa = gNa
            self.gK = gK
            self.gL = gL
            self.V_th = V_th

            # integral
            self.integral = bp.odeint(method='rk4', f=self.derivaitve)
Beispiel #12
0
    def __init__(self,
                 size,
                 t_refractory=1.,
                 V_rest=0.,
                 V_reset=-5.,
                 V_th=20.,
                 R=1.,
                 tau=10.,
                 has_noise=True,
                 **kwargs):
        # parameters
        self.V_rest = V_rest
        self.V_reset = V_reset
        self.V_th = V_th
        self.R = R
        self.tau = tau
        self.t_refractory = t_refractory

        # variables
        self.t_last_spike = bp.ops.ones(size) * -1e7
        self.refractory = bp.ops.zeros(size)
        self.input = bp.ops.zeros(size)
        self.spike = bp.ops.zeros(size)
        self.V = bp.ops.ones(size) * V_reset

        if has_noise:
            self.int_V = bp.sdeint(f=self.f_v, g=self.g_v)
        else:
            self.int_V = bp.odeint(f=self.f_v)

        super(StochasticLIF, self).__init__(size=size, **kwargs)
Beispiel #13
0
    def __init__(self, size):
        super().__init__(size)

        self.V = bm.Variable(bm.zeros(self.num) - 70.)
        self.u = bm.Variable(bm.zeros(self.num))
        self.input = bm.Variable(bm.zeros(self.num))

        self.integral = bp.odeint(self.derivative, method='rk2')
Beispiel #14
0
  def __init__(self, size, method, name=None):
    super(Channel, self).__init__(name=name)

    self.size = size
    self.method = method
    self.num = bp.tools.size2num(size)

    self.integral = bp.odeint(self.derivative, method=method)
Beispiel #15
0
    def __init__(self, num=2, method='exp_auto'):
        super(GJCoupledFHN, self).__init__()

        # parameters
        self.num = num
        self.a = 0.7
        self.b = 0.8
        self.tau = 12.5
        self.gjw = 0.0001

        # variables
        self.V = bm.Variable(bm.random.uniform(-2, 2, num))
        self.w = bm.Variable(bm.random.uniform(-2, 2, num))
        self.Iext = bm.Variable(bm.zeros(num))

        # functions
        self.int_V = bp.odeint(self.dV, method=method)
        self.int_w = bp.odeint(self.dw, method=method)
Beispiel #16
0
  def test_ode2(self):
    a, b, tau=0.7, 0.8, 12.5
    dV = lambda V, t, w, Iext:  V - V * V * V / 3 - w + Iext
    dw = lambda w, t, V: (V + a - b * w) / tau
    fhn = bp.odeint(bp.JointEq([dV, dw]), method='rk4', dt=0.1)

    runner = bp.IntegratorRunner(fhn, monitors=['V', 'w'], inits=[1., 1.], args=dict(Iext=1.5))
    runner.run(100.)
    bp.visualize.line_plot(runner.mon.ts, runner.mon['V'], legend='V')
    bp.visualize.line_plot(runner.mon.ts, runner.mon['w'], legend='w', show=True)
Beispiel #17
0
    def __init__(self, size, method='exp_euler_auto', name=None):
        super(Neuron, self).__init__(size=size, name=name)

        # variables
        self.V = bm.Variable(bm.zeros(self.num))
        self.input = bm.Variable(bm.zeros(self.num))
        self.spike = bm.Variable(bm.zeros(self.num, dtype=bool))
        self.t_last_spike = bm.Variable(bm.ones(self.num) * -1e7)

        # integral
        self.integral = bp.odeint(method=method, f=self.derivative)
Beispiel #18
0
    def __init__(self, num, a=1., b=3., c=1., d=5., s=4., x_r=-1.6, r=0.001, Vth=1.9, **kwargs):

        def dev_hr(x, y, z, t, Isyn):
            dx = y - a * x ** 3 + b * x * x - z + Isyn
            dy = c - d * x * x - y
            dz = r * (s * (x - x_r) - z)
            return dx, dy, dz

        self.int_hr = bp.odeint(f=dev_hr, method='rk4', dt=0.02)

        super(HRNeuron, self).__init__(size=num, **kwargs)
Beispiel #19
0
  def __init__(self, num, method='exp_auto'):
    super(WilsonCowanModel, self).__init__()

    # Connection weights
    self.wEE = 12
    self.wEI = 4
    self.wIE = 13
    self.wII = 11

    # Refractory parameter
    self.r = 1

    # Excitatory parameters
    self.E_tau = 1  # Timescale of excitatory population
    self.E_a = 1.2  # Gain of excitatory population
    self.E_theta = 2.8  # Threshold of excitatory population

    # Inhibitory parameters
    self.I_tau = 1  # Timescale of inhibitory population
    self.I_a = 1  # Gain of inhibitory population
    self.I_theta = 4  # Threshold of inhibitory population

    # variables
    self.i = bm.Variable(bm.ones(num))
    self.e = bm.Variable(bm.ones(num))
    self.Iext = bm.Variable(bm.zeros(num))

    # functions
    def F(x, a, theta):
      return 1 / (1 + bm.exp(-a * (x - theta))) - 1 / (1 + bm.exp(a * theta))

    def de(e, t, i, Iext=0.):
      x = self.wEE * e - self.wEI * i + Iext
      return (-e + (1 - self.r * e) * F(x, self.E_a, self.E_theta)) / self.E_tau

    def di(i, t, e):
      x = self.wIE * e - self.wII * i
      return (-i + (1 - self.r * i) * F(x, self.I_a, self.I_theta)) / self.I_tau

    self.int_e = bp.odeint(de, method=method)
    self.int_i = bp.odeint(di, method=method)
Beispiel #20
0
  def test_ode3(self):
    a, b, tau=0.7, 0.8, 12.5
    dV = lambda V, t, w, Iext:  V - V * V * V / 3 - w + Iext
    dw = lambda w, t, V: (V + a - b * w) / tau
    fhn = bp.odeint(bp.JointEq([dV, dw]), method='rk4', dt=0.1)

    Iext, duration = bp.inputs.section_input([0., 1., 0.5], [200, 500, 200], return_length=True)
    runner = bp.IntegratorRunner(fhn, monitors=['V', 'w'], inits=[1., 1.],
                                 dyn_args=dict(Iext=Iext))
    runner.run(duration)
    bp.visualize.line_plot(runner.mon.ts, runner.mon['V'], legend='V')
    bp.visualize.line_plot(runner.mon.ts, runner.mon['w'], legend='w', show=True)
Beispiel #21
0
def test_ode():
    def lorenz_f(x, y, z, t, sigma=10, beta=8 / 3, rho=28):
        dx = sigma * (y - x)
        dy = x * (rho - z) - y
        dz = x * y - beta * z
        return dx, dy, dz

    for method in general_rk_methods.__all__ + exp_euler_method.__all__:
        for var_type in bp.SUPPORTED_VAR_TYPE:
            print(f'"{method}" method, "{var_type}" var type:')
            if method == 'exponential_euler' and var_type == bp.SYSTEM_VAR:
                with pytest.raises(bp.errors.IntegratorError):
                    bp.odeint(f=lorenz_f,
                              show_code=True,
                              method=method,
                              var_type=var_type)
            else:
                bp.odeint(f=lorenz_f,
                          show_code=True,
                          method=method,
                          var_type=var_type)
            print()

    for method in adaptive_rk_methods.__all__:
        for var_type in bp.SUPPORTED_VAR_TYPE:
            for adaptive in [True, False]:
                print(
                    f'"{method}" method, "{var_type}" var type, adaptive = {adaptive}:'
                )
                bp.odeint(f=lorenz_f,
                          show_code=True,
                          method=method,
                          var_type=var_type,
                          adaptive=adaptive)
                print()
Beispiel #22
0
  def __init__(self, pre, post, delay=0.5, g_max=0.10, E=0., tau=2.0, **kwargs):
    super(AMPA, self).__init__(pre=pre, post=post, **kwargs)

    # parameters
    self.g_max = g_max
    self.E = E
    self.tau = tau
    self.delay = delay

    # variables
    self.s = bm.Variable(bm.zeros(self.post.num))
    self.pre_spike = self.register_constant_delay('ps', size=self.pre.num, delay=delay)

    # function
    self.integral = bp.odeint(self.derivative)
    def __init__(self, method='exp_auto'):
        super(FitzHughNagumoModel, self).__init__()

        # parameters
        self.a = 0.7
        self.b = 0.8
        self.tau = 12.5

        # variables
        self.V = bm.Variable(bm.zeros(1))
        self.w = bm.Variable(bm.zeros(1))
        self.Iext = bm.Variable(bm.zeros(1))

        # functions
        def dV(V, t, w, Iext=0.):
            dV = V - V * V * V / 3 - w + Iext
            return dV

        def dw(w, t, V, a=0.7, b=0.8):
            dw = (V + a - b * w) / self.tau
            return dw

        self.int_V = bp.odeint(dV, method=method)
        self.int_w = bp.odeint(dw, method=method)
Beispiel #24
0
            def __init__(self,
                         size,
                         ENa=55.,
                         EK=-90.,
                         EL=-65,
                         C=1.0,
                         gNa=35.,
                         gK=9.,
                         gL=0.1,
                         V_th=20.,
                         phi=5.0,
                         name=None,
                         method='exponential_euler'):
                super(HH, self).__init__(size=size, name=name)

                # parameters
                self.ENa = ENa
                self.EK = EK
                self.EL = EL
                self.C = C
                self.gNa = gNa
                self.gK = gK
                self.gL = gL
                self.V_th = V_th
                self.phi = phi

                # variables
                self.V = bm.Variable(bm.ones(size) * -65.)
                self.h = bm.Variable(bm.ones(size) * 0.6)
                self.n = bm.Variable(bm.ones(size) * 0.32)
                self.spike = bm.Variable(bm.zeros(size, dtype=bool))
                self.input = bm.Variable(bm.zeros(size))

                self.int_h = bp.odeint(self.dh, method=method, show_code=True)
                self.int_n = bp.odeint(self.dn, method=method, show_code=True)
                self.int_V = bp.odeint(self.dV, method=method, show_code=True)
Beispiel #25
0
  def __init__(self, method='exp_auto'):
    super(MeanFieldQIF, self).__init__()

    # parameters
    self.tau = 1.  # the population time constant
    self.eta = -5.0  # the mean of a Lorenzian distribution over the neural excitability in the population
    self.delta = 1.0  # the half-width at half maximum of the Lorenzian distribution over the neural excitability
    self.J = 15.  # the strength of the recurrent coupling inside the population

    # variables
    self.r = bm.Variable(bm.ones(1))
    self.v = bm.Variable(bm.ones(1))
    self.Iext = bm.Variable(bm.zeros(1))

    # functions
    def dr(r, t, v, delta=1.0):
      return (delta / (bm.pi * self.tau) + 2. * r * v) / self.tau

    def dv(v, t, r, Iext=0., eta=-5.0):
      return (v ** 2 + eta + Iext + self.J * r * self.tau -
              (bm.pi * r * self.tau) ** 2) / self.tau

    self.int_r = bp.odeint(dr, method=method)
    self.int_v = bp.odeint(dv, method=method)
Beispiel #26
0
  def __init__(self, size, V_L=-70., V_reset=-55., V_th=-50.,
               Cm=0.5, gL=0.025, t_refractory=2., **kwargs):
    super(LIF, self).__init__(size=size, **kwargs)

    self.V_L = V_L
    self.V_reset = V_reset
    self.V_th = V_th
    self.Cm = Cm
    self.gL = gL
    self.t_refractory = t_refractory

    self.V = bm.Variable(bm.ones(self.num) * V_L)
    self.input = bm.Variable(bm.zeros(self.num))
    self.spike = bm.Variable(bm.zeros(self.num, dtype=bool))
    self.refractory = bm.Variable(bm.zeros(self.num, dtype=bool))
    self.t_last_spike = bm.Variable(bm.ones(self.num) * -1e7)

    self.integral = bp.odeint(self.derivative)
Beispiel #27
0
    def __init__(self, size, method='exp_auto'):
        super(HH, self).__init__(size)

        # variables
        self.V = bm.Variable(El + (bm.random.randn(self.num) * 5 - 5))
        self.m = bm.Variable(bm.zeros(self.num))
        self.n = bm.Variable(bm.zeros(self.num))
        self.h = bm.Variable(bm.zeros(self.num))
        self.spike = bm.Variable(bm.zeros(self.num, dtype=bool))
        self.input = bm.Variable(bm.zeros(size))

        def dV(V, t, m, h, n, Isyn):
            gna = g_Na * (m * m * m) * h
            gkd = g_Kd * (n * n * n * n)
            dVdt = (-gl * (V - El) - gna * (V - ENa) - gkd *
                    (V - EK) + Isyn) / Cm
            return dVdt

        def dm(
            m,
            t,
            V,
        ):
            m_alpha = 0.32 * (13 - V + VT) / (bm.exp((13 - V + VT) / 4) - 1.)
            m_beta = 0.28 * (V - VT - 40) / (bm.exp((V - VT - 40) / 5) - 1)
            dmdt = (m_alpha * (1 - m) - m_beta * m)
            return dmdt

        def dh(h, t, V):
            h_alpha = 0.128 * bm.exp((17 - V + VT) / 18)
            h_beta = 4. / (1 + bm.exp(-(V - VT - 40) / 5))
            dhdt = (h_alpha * (1 - h) - h_beta * h)
            return dhdt

        def dn(n, t, V):
            c = 15 - V + VT
            n_alpha = 0.032 * c / (bm.exp(c / 5) - 1.)
            n_beta = .5 * bm.exp((10 - V + VT) / 40)
            dndt = (n_alpha * (1 - n) - n_beta * n)
            return dndt

        # functions
        self.integral = bp.odeint(bp.JointEq([dV, dm, dh, dn]), method=method)
Beispiel #28
0
    def __init__(self,
                 pre,
                 post,
                 conn,
                 method='exp_auto',
                 build_integral=True,
                 **kwargs):
        super(Synapse, self).__init__(pre=pre, post=post, conn=conn, **kwargs)

        if not isinstance(pre, Neuron):
            raise bp.errors.BrainPyError(
                f'"pre" must be an instance of {Neuron}.')
        if not isinstance(post, Neuron):
            raise bp.errors.BrainPyError(
                f'"post" must be an instance of {Neuron}.')
        self.pre = pre
        self.post = post

        # integrals
        if build_integral:
            self.integral = bp.odeint(method=method, f=self.derivative)
Beispiel #29
0
  def __init__(self, pre, post, delay=0.5, tau_decay=100, tau_rise=2.,
               g_max=0.15, E=0., cc_Mg=1., alpha=0.5, **kwargs):
    super(NMDA, self).__init__(pre=pre, post=post, **kwargs)

    # parameters
    self.g_max = g_max
    self.E = E
    self.cc_Mg = cc_Mg
    self.alpha = alpha
    self.tau_decay = tau_decay
    self.tau_rise = tau_rise
    self.delay = delay
    self.size = (self.pre.num, self.post.num)
    self.pre_one = bm.ones(self.pre.num)

    # variables
    self.pre_spike = self.register_constant_delay('ps', size=self.pre.num, delay=delay)
    self.s = bm.Variable(bm.zeros(self.size))
    self.x = bm.Variable(bm.zeros(self.size))

    # function
    self.integral = bp.odeint(self.derivative)
    def __init__(self, num, C=135., method='exp_auto'):
        super(JansenRitModel, self).__init__()

        self.num = num

        # parameters #
        self.v_max = 5.  # maximum firing rate
        self.v0 = 6.  # firing threshold
        self.r = 0.56  # slope of the sigmoid
        # other parameters
        self.A = 3.25
        self.B = 22.
        self.a = 100.
        self.tau_e = 0.01  # second
        self.tau_i = 0.02  # second
        self.b = 50.
        self.e0 = 2.5
        # The connectivity constants
        self.C1 = C
        self.C2 = 0.8 * C
        self.C3 = 0.25 * C
        self.C4 = 0.25 * C

        # variables #
        # y0, y1 and y2 representing the firing rate of
        # pyramidal, excitatory and inhibitory neurones.
        self.y0 = bm.Variable(bm.zeros(self.num))
        self.y1 = bm.Variable(bm.zeros(self.num))
        self.y2 = bm.Variable(bm.zeros(self.num))
        self.y3 = bm.Variable(bm.zeros(self.num))
        self.y4 = bm.Variable(bm.zeros(self.num))
        self.y5 = bm.Variable(bm.zeros(self.num))
        self.p = bm.Variable(bm.ones(self.num) * 220.)

        # integral function
        self.derivative = bp.JointEq(
            [self.dy0, self.dy1, self.dy2, self.dy3, self.dy4, self.dy5])
        self.integral = bp.odeint(self.derivative, method=method)