Пример #1
0
def _numba_dfun(S, c, ae, be, de, ge, te, wp, we, jn, ai, bi, di, gi, ti, wi,
                ji, g, l, io, dx):
    "Gufunc for reduced Wong-Wang model equations."

    cc = g[0] * jn[0] * c[0]

    if S[0] < 0.0:
        S_e = 0.0  # - S[0] # TODO: clarify the boundary to be reflective or saturated!!!
    elif S[0] > 1.0:
        S_e = 1.0  # - S[0] # TODO: clarify the boundary to be reflective or saturated!!!
    else:
        S_e = S[0]

    if S[1] < 0.0:
        S_i = 0.0  # - S[1]  TODO: clarify the boundary to be reflective or saturated!!!
    elif S[1] > 1.0:
        S_i = 1.0  #  - S[1] TODO: clarify the boundary to be reflective or saturated!!!
    else:
        S_i = S[1]

    jnSe = jn[0] * S_e
    x = wp[0] * jnSe - ji[0] * S_i + we[0] * io[0] + cc
    x = ae[0] * x - be[0]
    h = x / (1 - numpy.exp(-de[0] * x))
    dx[0] = -(S_e / te[0]) + (1.0 - S_e) * h * ge[0]

    x = jnSe - S_i + wi[0] * io[0] + l[0] * cc
    x = ai[0] * x - bi[0]
    h = x / (1 - numpy.exp(-di[0] * x))
    dx[1] = -(S_i / ti[0]) + h * gi[0]
def _numba_update_non_state_variables_before_integration(
        S, c, ae, be, de, wp, we, jn, re, ai, bi, di, wi, ji, ri, g, l, io, ie,
        newS):
    "Gufunc for reduced Wong-Wang model equations."

    newS[0] = S[0]  # S_e
    newS[1] = S[1]  # S_i

    cc = g[0] * jn[0] * c[0]

    jnSe = jn[0] * S[0]
    # S_i
    newS[6] = wp[0] * jnSe - ji[0] * S[1] + we[0] * io[0] + cc + ie[0]  # I_e
    if re[0] <= 0.0:
        # TVB computation
        x = ae[0] * newS[6] - be[0]
        h = x / (1 - numpy.exp(-de[0] * x))
        newS[2] = h  # R_e
        newS[4] = 0.0  # Rin_e
    else:
        # Updating from spiking network
        newS[2] = S[2]  # R_e
        newS[4] = S[4]  # Rin_e

        # S_i
    newS[7] = jnSe - S[1] + wi[0] * io[0] + l[0] * cc  # I_i
    if ri[0] <= 0.0:
        # TVB computation
        x = ai[0] * newS[7] - bi[0]
        h = x / (1 - numpy.exp(-di[0] * x))
        newS[3] = h  # R_i
        newS[5] = 0.0  # Rin_i
    else:
        newS[3] = S[3]  # R_i
        newS[5] = S[5]  # Rin_i
    def update_non_state_variables(self,
                                   state_variables,
                                   coupling,
                                   local_coupling=0.0,
                                   use_numba=True):
        if use_numba:
            _numba_update_non_state_variables(
                state_variables.reshape(state_variables.shape[:-1]).T,
                coupling.reshape(coupling.shape[:-1]).T +
                local_coupling * state_variables[0], self.a_e, self.b_e,
                self.d_e, self.w_p, self.W_e, self.J_N, self.R_e, self.a_i,
                self.b_i, self.d_i, self.W_i, self.J_i, self.R_i, self.G,
                self.lamda, self.I_o)
            return state_variables

        # In this case, rates (H_e, H_i) are non-state variables,
        # i.e., they form part of state_variables but have no dynamics assigned on them
        # Most of the computations of this dfun aim at computing rates, including coupling considerations.
        # Therefore, we compute and update them only once a new state is computed,
        # and we consider them constant for any subsequent possible call to this function,
        # by any integration scheme

        S = state_variables[:2, :]  # synaptic gating dynamics
        R = state_variables[2:, :]  # rates

        c_0 = coupling[0, :]

        # if applicable
        lc_0 = local_coupling * S[0]

        coupling = self.G * self.J_N * (c_0 + lc_0)

        J_N_S_e = self.J_N * S[0]

        # TODO: Confirm that this computation is correct for this model depending on the r_e and r_i values!
        x_e = self.w_p * J_N_S_e - self.J_i * S[
            1] + self.W_e * self.I_o + coupling

        x_e = self.a_e * x_e - self.b_e
        # Only rates with r_e < 0 will be updated by TVB.
        H_e = numpy.where(self.R_e >= 0, R[0],
                          x_e / (1 - numpy.exp(-self.d_e * x_e)))

        x_i = J_N_S_e - S[1] + self.W_i * self.I_o + self.lamda * coupling

        x_i = self.a_i * x_i - self.b_i
        # Only rates with r_i < 0 will be updated by TVB.
        H_i = numpy.where(self.R_i >= 0, R[1],
                          x_i / (1 - numpy.exp(-self.d_i * x_i)))

        # We now update the state_variable vector with the new rates:
        state_variables[2, :] = H_e
        state_variables[3, :] = H_i

        return state_variables
    def _numpy_dfun(self, state_variables, coupling, local_coupling=0.0):
        r"""
        Equations taken from [DPA_2013]_ , page 11242

        .. math::
                 x_{ek}       &=   w_p\,J_N \, S_{ek} - J_iS_{ik} + W_eI_o + GJ_N \mathbf\Gamma(S_{ek}, S_{ej}, u_{kj}),\\
                 H(x_{ek})    &=  \dfrac{a_ex_{ek}- b_e}{1 - \exp(-d_e(a_ex_{ek} -b_e))},\\
                 \dot{S}_{ek} &= -\dfrac{S_{ek}}{\tau_e} + (1 - S_{ek}) \, \gammaH(x_{ek}) \,

                 x_{ik}       &=   J_N \, S_{ek} - S_{ik} + W_iI_o + \lambdaGJ_N \mathbf\Gamma(S_{ik}, S_{ej}, u_{kj}),\\
                 H(x_{ik})    &=  \dfrac{a_ix_{ik} - b_i}{1 - \exp(-d_i(a_ix_{ik} -b_i))},\\
                 \dot{S}_{ik} &= -\dfrac{S_{ik}}{\tau_i} + \gamma_iH(x_{ik}) \,

        """
        S = state_variables[:, :]

        S[S < 0] = 0.0
        S[S > 1] = 1.0

        c_0 = coupling[0, :]

        # if applicable
        lc_0 = local_coupling * S[0]

        coupling = self.G * self.J_N * (c_0 + lc_0)

        J_N_S_e = self.J_N * S[0]

        # TODO: Confirm that this combutation is correct for this model depending on the r_e and r_i values!
        x_e = self.w_p * J_N_S_e - self.J_i * S[
            1] + self.W_e * self.I_o + coupling

        x_e = self.a_e * x_e - self.b_e
        H_e = numpy.where(self.r_e >= 0, self.r_e,
                          x_e / (1 - numpy.exp(-self.d_e * x_e)))

        dS_e = -(S[0] / self.tau_e) + (1 - S[0]) * H_e * self.gamma_e

        x_i = J_N_S_e - S[1] + self.W_i * self.I_o + self.lamda * coupling

        x_i = self.a_i * x_i - self.b_i
        H_i = numpy.where(self.r_i >= 0, self.r_i,
                          x_i / (1 - numpy.exp(-self.d_i * x_i)))

        dS_i = -(S[1] / self.tau_i) + H_i * self.gamma_i

        derivative = numpy.array([dS_e, dS_i])

        return derivative
Пример #5
0
def _numba_update_non_state_variables_before_integration(
        S, c, a, b, d, w, jn, r, g, io, newS):
    "Gufunc for reduced Wong-Wang model equations."

    newS[0] = S[0]  # S
    newS[1] = S[1]  # Rint

    cc = g[0] * jn[0] * c[0]
    newS[4] = w[0] * jn[0] * S[0] + io[0] + cc  # I
    if r[0] <= 0.0:
        # R computed in TVB
        x = a[0] * newS[4] - b[0]
        h = x / (1 - numpy.exp(-d[0] * x))
        newS[2] = h  # R
        newS[3] = 0.0  # Rin
    else:
        # R updated from Spiking Network model
        # Rate has to be scaled down from the Spiking neural model rate range to the TVB one
        if S[1] < 40.0:  # Rint
            # For low activity
            R = numpy.sqrt(S[1])
        else:
            # For high activity
            R = 0.0000050 * g[0] * S[1]**2
        newS[2] = R
        newS[3] = S[3]  # Rin
Пример #6
0
    def update_state_variables_before_integration(self,
                                                  state_variables,
                                                  coupling,
                                                  local_coupling=0.0,
                                                  stimulus=0.0):
        if self.use_numba:
            state_variables = \
                _numba_update_non_state_variables(state_variables.reshape(state_variables.shape[:-1]).T,
                                                  coupling.reshape(coupling.shape[:-1]).T +
                                                  local_coupling * state_variables[0],
                                                  self.a, self.b, self.d,
                                                  self.w, self.J_N, self.Rin,
                                                  self.G, self.I_o)
            return state_variables.T[..., numpy.newaxis]

        # In this case, rates (H_e, H_i) are non-state variables,
        # i.e., they form part of state_variables but have no dynamics assigned on them
        # Most of the computations of this dfun aim at computing rates, including coupling considerations.
        # Therefore, we compute and update them only once a new state is computed,
        # and we consider them constant for any subsequent possible call to this function,
        # by any integration scheme

        S = state_variables[0, :]  # synaptic gating dynamics
        Rint = state_variables[1, :]  # Rates from Spiking Network, integrated
        Rin = state_variables[3, :]  # Input rates from Spiking Network

        c_0 = coupling[0, :]

        # if applicable
        lc_0 = local_coupling * S[0]

        coupling = self.G * self.J_N * (c_0 + lc_0)

        # Currents
        I = self.w * self.J_N * S + self.I_o + coupling
        x = self.a * I - self.b

        # Rates
        # Only rates with _Rin <= 0 0 will be updated by TVB.
        # The rest, are updated from the Spiking Network
        R = numpy.where(self._Rin, Rint, x / (1 - numpy.exp(-self.d * x)))

        Rin = numpy.where(
            self._Rin, Rin,
            0.0)  # Reset to 0 the Rin for nodes not updated by Spiking Network

        # We now update the state_variable vector with the new rates and currents:
        state_variables[2, :] = R
        state_variables[3, :] = Rin
        state_variables[4, :] = I

        # Keep them here so that they are not recomputed in the dfun
        self._R = numpy.copy(R)
        self._Rin = numpy.copy(Rin)

        return state_variables
def _numba_dfun(S, c, ae, be, de, ge, te, wp, we, jn, re, ai, bi, di, gi, ti,
                wi, ji, ri, g, l, io, dx):
    "Gufunc for reduced Wong-Wang model equations."

    cc = g[0] * jn[0] * c[0]

    if S[0] < 0.0:
        S_e = 0.0
    elif S[0] > 1.0:
        S_e = 1.0
    else:
        S_e = S[0]

    jnSe = jn[0] * S_e

    if S[1] < 0.0:
        S_i = 0.0
    elif S[1] > 1.0:
        S_i = 1.0
    else:
        S_i = S[1]

    if re[0] < 0.0:
        x = wp[0] * jnSe - ji[0] * S_i + we[0] * io[0] + cc
        x = ae[0] * x - be[0]
        h = x / (1 - numpy.exp(-de[0] * x))
    else:
        h = re[0]
    dx[0] = -(S_e / te[0]) + (1.0 - S_e) * h * ge[0]

    if ri[0] < 0.0:
        x = jnSe - S_i + wi[0] * io[0] + l[0] * cc
        x = ai[0] * x - bi[0]
        h = x / (1 - numpy.exp(-di[0] * x))
    else:
        h = ri[0]
    dx[1] = -(S_i / ti[0]) + h * gi[0]
def _numba_update_non_state_variables(S, c, ae, be, de, wp, we, jn, re, ai, bi,
                                      di, wi, ji, ri, g, l, io, newS):
    "Gufunc for reduced Wong-Wang model equations."

    cc = g[0] * jn[0] * c[0]

    jnSe = jn[0] * S[0]

    if re[0] < 0.0:
        x = wp[0] * jnSe - ji[0] * S[1] + we[0] * io[0] + cc
        x = ae[0] * x - be[0]
        h = x / (1 - numpy.exp(-de[0] * x))
        S[2] = h

    if ri[0] < 0.0:
        x = jnSe - S[1] + wi[0] * io[0] + l[0] * cc
        x = ai[0] * x - bi[0]
        h = x / (1 - numpy.exp(-di[0] * x))
        S[3] = h

    newS[0] = S[0]
    newS[1] = S[1]
    newS[3] = S[2]
    newS[4] = S[4]
    def update_state_variables_before_integration(self,
                                                  state_variables,
                                                  coupling,
                                                  local_coupling=0.0,
                                                  stimulus=0.0,
                                                  use_numba=False):

        for ii in range(state_variables[0].shape[0]):
            _E = self._E(ii)  # excitatory neurons'/modes' indices
            _I = self._I(ii)  # inhibitory neurons'/modes' indices

            # Make sure that all empty positions are set to 0.0, if any:
            self._zero_empty_positions(state_variables, _E, _I, ii)

            # Set  inhibitory synapses for excitatory neurons & excitatory synapses for inhibitory neurons to 0.0...
            self._zero_cross_synapses(state_variables, _E, _I, ii)

            # compute large scale coupling_ij = sum(C_ij * S_e(t-t_ij))
            large_scale_coupling = numpy.sum(coupling[0, ii, :self._N_E_max])

            if ii in self._spiking_regions_inds:

                # -----------------------------------Updates after previous iteration:----------------------------------

                # Refractory neurons from past spikes if 6. t_ref > 0.0
                self._refractory_neurons_E[ii] = state_variables[6, ii,
                                                                 _E] > 0.0
                self._refractory_neurons_I[ii] = state_variables[6, ii,
                                                                 _I] > 0.0

                # set 5. V_m for refractory neurons to V_reset
                state_variables[5, ii, _E] = numpy.where(
                    self._refractory_neurons_E[ii],
                    self._x_E(self.V_reset, ii), state_variables[5, ii, _E])

                state_variables[5, ii, _I] = numpy.where(
                    self._refractory_neurons_I[ii],
                    self._x_I(self.V_reset, ii), state_variables[5, ii, _I])

                # Compute spikes sent at time t:
                # 8. spikes
                state_variables[8, ii, _E] = numpy.where(
                    state_variables[5, ii, _E] > self._x_E(self.V_thr, ii),
                    1.0, 0.0)
                state_variables[8, ii, _I] = numpy.where(
                    state_variables[5, ii, _I] > self._x_I(self.V_thr, ii),
                    1.0, 0.0)
                self._spikes_E[ii] = state_variables[8, ii, _E] > 0.0
                self._spikes_I[ii] = state_variables[8, ii, _I] > 0.0

                # set 5. V_m for spiking neurons to V_reset
                state_variables[5, ii,
                                _E] = numpy.where(self._spikes_E[ii],
                                                  self._x_E(self.V_reset, ii),
                                                  state_variables[5, ii, _E])

                state_variables[5, ii,
                                _I] = numpy.where(self._spikes_I[ii],
                                                  self._x_I(self.V_reset, ii),
                                                  state_variables[5, ii, _I])

                # set 6. t_ref  to tau_ref for spiking neurons
                state_variables[6, ii, _E] = numpy.where(
                    self._spikes_E[ii], self._x_E(self.tau_ref_E, ii),
                    state_variables[6, ii, _E])

                state_variables[6, ii, _I] = numpy.where(
                    self._spikes_I[ii], self._x_I(self.tau_ref_I, ii),
                    state_variables[6, ii, _I])

                # Refractory neurons including current spikes sent at time t
                self._refractory_neurons_E[ii] = numpy.logical_or(
                    self._refractory_neurons_E[ii], self._spikes_E[ii])
                self._refractory_neurons_I[ii] = numpy.logical_or(
                    self._refractory_neurons_I[ii], self._spikes_I[ii])

                # 9. rate
                # Compute the average population rate sum_of_population_spikes / number_of_population_neurons
                # separately for excitatory and inhibitory populations,
                # and set it at the first position of each population, similarly to the mean-field region nodes
                state_variables[9, ii, _E] = 0.0
                state_variables[9, ii, _I] = 0.0
                state_variables[9, ii, 0] = numpy.sum(
                    state_variables[8, ii, _E]) / self._n_E(ii)
                state_variables[9, ii, self._N_E_max] = numpy.sum(
                    state_variables[8, ii, _I]) / self._n_I(ii)

                # -------------------------------------Updates before next iteration:---------------------------------------

                # ----------------------------------First deal with inputs at time t:---------------------------------------

                # Collect external spikes received at time t, and update the incoming s_AMPA_ext synapse:

                # 7. spikes_ext
                # get external spike stimulus 7. spike_ext, if any:
                state_variables[7, ii, _E] = self._x_E(self.spikes_ext, ii)
                state_variables[7, ii, _I] = self._x_I(self.spikes_ext, ii)

                # 4. s_AMPA_ext
                # ds_AMPA_ext/dt = -1/tau_AMPA * (s_AMPA_exc + spikes_ext)
                # Add the spike at this point to s_AMPA_ext
                state_variables[4, ii, _E] += state_variables[7, ii,
                                                              _E]  # spikes_ext
                state_variables[4, ii, _I] += state_variables[7, ii,
                                                              _I]  # spikes_ext

                # Compute currents based on synaptic gating variables at time t:

                # V_E_E = V_m - V_E
                V_E_E = state_variables[5, ii, _E] - self._x_E(self.V_E, ii)
                V_E_I = state_variables[5, ii, _I] - self._x_I(self.V_E, ii)

                # 10. I_syn = I_L + I_AMPA + I_NMDA + I_GABA + I_AMPA_EXT
                state_variables[10, ii,
                                _E] = numpy.sum(state_variables[10:, ii, _E],
                                                axis=0)
                state_variables[10, ii,
                                _I] = numpy.sum(state_variables[10:, ii, _I],
                                                axis=0)

                # 11. I_L = g_m * (V_m - V_E)
                state_variables[11, ii, _E] = \
                    self._x_E(self.g_m_E, ii) * (state_variables[5, ii, _E] - self._x_E(self.V_L, ii))
                state_variables[11, ii, _I] = \
                    self._x_I(self.g_m_I, ii) * (state_variables[5, ii, _I] - self._x_I(self.V_L, ii))

                w_EE = self._x_E(self.w_EE, ii)
                w_EI = self._x_E(self.w_EI, ii)

                # 12. I_AMPA = g_AMPA * (V_m - V_E) * sum(w * s_AMPA_k)
                coupling_AMPA_E, coupling_AMPA_I = \
                    self._compute_region_exc_population_coupling(state_variables[0, ii, _E], w_EE, w_EI)
                state_variables[12, ii, _E] = self._x_E(
                    self.g_AMPA_E, ii) * V_E_E * coupling_AMPA_E
                # s_AMPA
                state_variables[12, ii, _I] = self._x_I(
                    self.g_AMPA_I, ii) * V_E_I * coupling_AMPA_I

                # 13. I_NMDA = g_NMDA * (V_m - V_E) / (1 + lamda_NMDA * exp(-beta*V_m)) * sum(w * s_NMDA_k)
                coupling_NMDA_E, coupling_NMDA_I = \
                    self._compute_region_exc_population_coupling(state_variables[2, ii, _E], w_EE, w_EI)
                state_variables[13, ii, _E] = \
                    self._x_E(self.g_NMDA_E, ii) * V_E_E \
                    / (self._x_E(self.lamda_NMDA, ii) * numpy.exp(-self._x_E(self.beta, ii) *
                                                                  state_variables[5, ii, _E])) \
                    * coupling_NMDA_E  # s_NMDA
                state_variables[13, ii, _I] = \
                    self._x_I(self.g_NMDA_I, ii) * V_E_I \
                    / (self._x_I(self.lamda_NMDA, ii) * numpy.exp(-self._x_I(self.beta, ii) *
                                                                  state_variables[5, ii, _I])) \
                    * coupling_NMDA_I  # s_NMDA

                # 14. I_GABA = g_GABA * (V_m - V_I) * sum(w_ij * s_GABA_k)
                w_IE = self._x_I(self.w_IE, ii)
                w_II = self._x_I(self.w_II, ii)
                coupling_GABA_E, coupling_GABA_I = \
                    self._compute_region_inh_population_coupling(state_variables[3, ii, _I], w_IE, w_II)
                state_variables[14, ii, _E] = self._x_E(self.g_GABA_E, ii) * \
                                              (state_variables[5, ii, _E] - self._x_E(self.V_I, ii)) * \
                                              coupling_GABA_E  # s_GABA
                state_variables[14, ii, _I] = self._x_I(self.g_GABA_I, ii) * \
                                              (state_variables[5, ii, _I] - self._x_I(self.V_I, ii)) * \
                                              coupling_GABA_I  # s_GABA

                # 15. I_AMPA_ext = g_AMPA_ext * (V_m - V_E) * ( G*sum{c_ij sum{s_AMPA_j(t-delay_ij)}} + s_AMPA_ext)
                # Compute large scale coupling_ij = sum(c_ij * S_e(t-t_ij))
                large_scale_coupling += numpy.sum(local_coupling *
                                                  state_variables[0, ii, _E])
                state_variables[15, ii, _E] = self._x_E(self.g_AMPA_ext_E, ii) * V_E_E * \
                                              (self._x_E(self.G, ii) * large_scale_coupling
                                               + state_variables[4, ii, _E])
                #                                          # feedforward inhibition
                state_variables[15, ii, _I] = self._x_I(self.g_AMPA_ext_I, ii) * V_E_I * \
                                              (self._x_I(self.G, ii) * self._x_I(self.lamda, ii) * large_scale_coupling
                                               + state_variables[4, ii, _I])

            else:

                # For mean field modes:
                # Given that the 3rd dimension corresponds to neurons, not modes,
                # we use only the first element of its population, i.e., 0 and _I[0],
                # and consider all the rest to be identical
                # Similarly, we assume that all parameters are of of these shapes:
                # (1, ), (1, 1), (number_of_regions, ), (number_of_regions, 1)

                # S_e = s_AMPA = s_NMDA
                # S_i = s_GABA

                # 1. s_NMDA
                # = s_AMPA for excitatory mean field models
                state_variables[1, ii, _E] = state_variables[0, ii, 0]

                # 1. x_NMDA, 4. s_AMPA_ext, 5. V_m, 6. t_ref, 7. spikes_ext, 8. spikes, 11. I_L
                # are 0 for mean field models:
                state_variables[[1, 4, 5, 6, 7, 8, 11], ii] = 0.0

                # J_N is indexed by the receiver node
                J_N_E = self._region(self.J_N, ii)
                J_N_I = self._region(self.J_N, ii)

                # 12. I_AMPA
                # = w+ * J_N * S_e
                state_variables[12, ii, _E] = self._region(
                    self.w_p, ii) * J_N_E * state_variables[0, ii, 0]
                # = J_N * S_e
                state_variables[12, ii, _I] = J_N_I * state_variables[0, ii, 0]

                # 13. I_NMDA = I_AMPA for mean field models
                state_variables[13, ii] = state_variables[13, ii]

                # 14. I_GABA                                              # 3. s_GABA
                state_variables[14, ii, _E] = -self._x_E(
                    self.J_i, ii) * state_variables[3, ii, _I[0]]  # = -J_i*S_i
                state_variables[14, ii,
                                _I] = -state_variables[3, ii, _I[0]]  # = - S_i

                # 15. I_AMPA_ext
                large_scale_coupling += local_coupling * state_variables[0, ii,
                                                                         0]
                # = G * J_N * coupling_ij = G * J_N * sum(C_ij * S_e(t-t_ij))
                state_variables[15, ii, _E] = self._x_E(
                    self.G, ii)[0] * J_N_E * large_scale_coupling
                # = lamda * G * J_N * coupling_ij = lamda * G * J_N * sum(C_ij * S_e(t-t_ij))
                state_variables[15, ii, _I] = \
                    self._x_I(self.G, ii)[0] * self._x_I(self.lamda, ii)[0] * J_N_I * large_scale_coupling

                # 8. I_syn = I_E(NMDA) + I_I(GABA) + I_AMPA_ext
                # Note measuring twice I_AMPA and I_NMDA though, as they count as a single excitatory current:
                state_variables[10, ii, _E] = numpy.sum(state_variables[13:,
                                                                        ii, 0],
                                                        axis=0)
                state_variables[10, ii,
                                _I] = numpy.sum(state_variables[13:, ii,
                                                                _I[0]],
                                                axis=0)

                # 6. rate sigmoidal of total current = I_syn + I_o

                total_current = \
                    state_variables[10, ii, 0] + self._region(self.W_e, ii) * self._region(self.I_o, ii)
                # Sigmoidal activation: (a*I_tot_current - b) / ( 1 - exp(-d*(a*I_tot_current - b)))
                total_current = self._region(
                    self.a_e, ii) * total_current - self._region(self.b_e, ii)
                state_variables[9, ii, _E] = \
                    total_current / (1 - numpy.exp(-self._region(self.d_e, ii) * total_current))

                total_current = \
                    state_variables[10, ii, _I[0]] + self._region(self.W_i, ii) * self._region(self.I_o, ii)
                # Sigmoidal activation:
                total_current = self._region(
                    self.a_i, ii) * total_current - self._region(self.b_i, ii)
                state_variables[9, ii, _I] = \
                    total_current / (1 - numpy.exp(-self._region(self.d_i, ii) * total_current))

        return state_variables
Пример #10
0
    def update_state_variables_before_integration(self,
                                                  state_variables,
                                                  coupling,
                                                  local_coupling=0.0,
                                                  stimulus=0.0):
        if self._n_regions == 0:
            self._n_regions = state_variables.shape[1]
            self._prepare_indices()
        for ii in range(self._n_regions):  # For every region node....
            _E = self._E(ii)  # excitatory neurons' indices
            _I = self._I(ii)  # inhibitory neurons' indices

            # Make sure that all empty positions are set to 0.0, if any:
            self._zero_empty_positions(state_variables, _E, _I, ii)

            # Set  inhibitory synapses for excitatory neurons & excitatory synapses for inhibitory neurons to 0.0...
            self._zero_cross_synapses(state_variables, _E, _I, ii)

            # -----------------------------------Updates after previous iteration:--------------------------------------

            # Refractory neurons from past spikes if 6. t_ref > 0.0
            self._refractory_neurons_E[ii] = state_variables[6, ii, _E] > 0.0
            self._refractory_neurons_I[ii] = state_variables[6, ii, _I] > 0.0

            # set 5. V_m for refractory neurons to V_reset
            state_variables[5, ii,
                            _E] = numpy.where(self._refractory_neurons_E[ii],
                                              self._x_E(self.V_reset, ii),
                                              state_variables[5, ii, _E])

            state_variables[5, ii,
                            _I] = numpy.where(self._refractory_neurons_I[ii],
                                              self._x_I(self.V_reset, ii),
                                              state_variables[5, ii, _I])

            # Compute spikes sent at time t:
            # 8. spikes
            state_variables[8, ii, _E] = numpy.where(
                state_variables[5, ii, _E] > self._x_E(self.V_thr, ii), 1.0,
                0.0)
            state_variables[8, ii, _I] = numpy.where(
                state_variables[5, ii, _I] > self._x_I(self.V_thr, ii), 1.0,
                0.0)
            exc_spikes = state_variables[8, ii, _E]  # excitatory spikes
            inh_spikes = state_variables[8, ii, _I]  # inhibitory spikes
            self._spikes_E[ii] = exc_spikes > 0.0
            self._spikes_I[ii] = inh_spikes > 0.0

            # set 5. V_m for spiking neurons to V_reset
            state_variables[5, ii,
                            _E] = numpy.where(self._spikes_E[ii],
                                              self._x_E(self.V_reset, ii),
                                              state_variables[5, ii, _E])

            state_variables[5, ii,
                            _I] = numpy.where(self._spikes_I[ii],
                                              self._x_I(self.V_reset, ii),
                                              state_variables[5, ii, _I])

            # set 6. t_ref  to tau_ref for spiking neurons
            state_variables[6, ii,
                            _E] = numpy.where(self._spikes_E[ii],
                                              self._x_E(self.tau_ref_E, ii),
                                              state_variables[6, ii, _E])

            state_variables[6, ii,
                            _I] = numpy.where(self._spikes_I[ii],
                                              self._x_I(self.tau_ref_I, ii),
                                              state_variables[6, ii, _I])

            # Refractory neurons including current spikes sent at time t
            self._refractory_neurons_E[ii] = numpy.logical_or(
                self._refractory_neurons_E[ii], self._spikes_E[ii])
            self._refractory_neurons_I[ii] = numpy.logical_or(
                self._refractory_neurons_I[ii], self._spikes_I[ii])

            # -------------------------------------Updates before next iteration:---------------------------------------

            # ----------------------------------First deal with inputs at time t:---------------------------------------

            # Collect external spikes received at time t, and update the incoming s_AMPA_ext synapse:

            # 7. spikes_ext
            # get external spike stimulus 7. spike_ext, if any:
            state_variables[7, ii, _E] = self._x_E(self.spikes_ext, ii)
            state_variables[7, ii, _I] = self._x_I(self.spikes_ext, ii)

            # 4. s_AMPA_ext
            # ds_AMPA_ext/dt = -1/tau_AMPA * (s_AMPA_exc + spikes_ext)
            # Add the spike at this point to s_AMPA_ext
            state_variables[4, ii, _E] += state_variables[7, ii,
                                                          _E]  # spikes_ext
            state_variables[4, ii, _I] += state_variables[7, ii,
                                                          _I]  # spikes_ext

            # Compute currents based on synaptic gating variables at time t:

            # V_E_E = V_m - V_E
            V_E_E = state_variables[5, ii, _E] - self._x_E(self.V_E, ii)
            V_E_I = state_variables[5, ii, _I] - self._x_I(self.V_E, ii)

            # 9. I_L = g_m * (V_m - V_E)
            state_variables[9, ii, _E] = \
                self._x_E(self.g_m_E, ii) * (state_variables[5, ii, _E] - self._x_E(self.V_L, ii))
            state_variables[9, ii, _I] = \
                self._x_I(self.g_m_I, ii) * (state_variables[5, ii, _I] - self._x_I(self.V_L, ii))

            w_EE = self._x_E(self.w_EE, ii)
            w_EI = self._x_E(self.w_EI, ii)

            # 10. I_AMPA = g_AMPA * (V_m - V_E) * sum(w * s_AMPA_k)
            coupling_AMPA_E, coupling_AMPA_I = \
                self._compute_region_exc_population_coupling(state_variables[0, ii, _E], w_EE, w_EI)
            state_variables[10, ii, _E] = self._x_E(
                self.g_AMPA_E, ii) * V_E_E * coupling_AMPA_E
            # s_AMPA
            state_variables[10, ii, _I] = self._x_I(
                self.g_AMPA_I, ii) * V_E_I * coupling_AMPA_I

            # 11. I_NMDA = g_NMDA * (V_m - V_E) / (1 + lamda_NMDA * exp(-beta*V_m)) * sum(w * s_NMDA_k)
            coupling_NMDA_E, coupling_NMDA_I = \
                self._compute_region_exc_population_coupling(state_variables[2, ii, _E], w_EE, w_EI)
            state_variables[11, ii, _E] = \
                self._x_E(self.g_NMDA_E, ii) * V_E_E \
                / (self._x_E(self.lamda_NMDA, ii) * numpy.exp(-self._x_E(self.beta, ii) *
                                                              state_variables[5, ii, _E])) \
                * coupling_NMDA_E  # s_NMDA
            state_variables[11, ii, _I] = \
                self._x_I(self.g_NMDA_I, ii) * V_E_I \
                / (self._x_I(self.lamda_NMDA, ii) * numpy.exp(-self._x_I(self.beta, ii) *
                                                              state_variables[5, ii, _I])) \
                * coupling_NMDA_I  # s_NMDA

            # 0. s_AMPA
            # s_AMPA += exc_spikes
            state_variables[0, ii, _E] += exc_spikes

            # 1. x_NMDA
            # x_NMDA += exc_spikes
            state_variables[1, ii, _E] += exc_spikes

            # 12. I_GABA = g_GABA * (V_m - V_I) * sum(w_ij * s_GABA_k)
            w_IE = self._x_I(self.w_IE, ii)
            w_II = self._x_I(self.w_II, ii)
            coupling_GABA_E, coupling_GABA_I = \
                self._compute_region_inh_population_coupling(state_variables[3, ii, _I], w_IE, w_II)
            state_variables[12, ii, _E] = self._x_E(self.g_GABA_E, ii) * \
                                          (state_variables[5, ii, _E] - self._x_E(self.V_I, ii)) * \
                                          coupling_GABA_E  # s_GABA
            state_variables[12, ii, _I] = self._x_I(self.g_GABA_I, ii) * \
                                          (state_variables[5, ii, _I] - self._x_I(self.V_I, ii)) * \
                                          coupling_GABA_I  # s_GABA

            # 3. s_GABA += inh_spikes
            state_variables[3, ii, _I] += inh_spikes

            # 13. I_AMPA_ext = g_AMPA_ext * (V_m - V_E) * ( G*sum{c_ij sum{s_AMPA_j(t-delay_ij)}} + s_AMPA_ext)
            # Compute large scale coupling_ij = sum(c_ij * S_e(t-t_ij))
            large_scale_coupling = numpy.sum(coupling[0, ii, :self._N_E_max])
            large_scale_coupling += numpy.sum(local_coupling *
                                              state_variables[0, ii, _E])
            state_variables[13, ii, _E] = self._x_E(self.g_AMPA_ext_E, ii) * V_E_E * \
                                          ( self._x_E(self.G, ii) * large_scale_coupling
                                            + state_variables[4, ii, _E] )
            #                                          # feedforward inhibition
            state_variables[13, ii, _I] = self._x_I(self.g_AMPA_ext_I, ii) * V_E_I * \
                                          ( self._x_I(self.G, ii) * self._x_I(self.lamda, ii) * large_scale_coupling
                                            + state_variables[4, ii, _I] )

        self._non_integrated_variables = state_variables[
            self._non_integrated_variables_inds]

        return state_variables
    def update_state_variables_before_integration(self,
                                                  state_variables,
                                                  coupling,
                                                  local_coupling=0.0,
                                                  stimulus=0.0):
        self._stimulus = stimulus
        if self.use_numba:
            state_variables = \
                _numba_update_non_state_variables_before_integration(
                    state_variables.reshape(state_variables.shape[:-1]).T,
                    coupling.reshape(coupling.shape[:-1]).T +
                    local_coupling * state_variables[0],
                    self.a_e, self.b_e, self.d_e,
                    self.w_p, self.W_e, self.J_N, self.Rin_e,
                    self.a_i, self.b_i, self.d_i,
                    self.W_i, self.J_i, self.Rin_i,
                    self.G, self.lamda, self.I_o, self.I_ext)
            return state_variables.T[..., numpy.newaxis]

        # In this case, rates (H_e, H_i) are non-state variables,
        # i.e., they form part of state_variables but have no dynamics assigned on them
        # Most of the computations of this dfun aim at computing rates, including coupling considerations.
        # Therefore, we compute and update them only once a new state is computed,
        # and we consider them constant for any subsequent possible call to this function,
        # by any integration scheme

        S = state_variables[:2, :]  # synaptic gating dynamics
        R = state_variables[2:4, :]  # Rates
        Rin = state_variables[4:6, :]  # Input rates from spiking network

        c_0 = coupling[0, :]

        # if applicable
        lc_0 = local_coupling * S[0]

        coupling = self.G * self.J_N * (c_0 + lc_0)

        J_N_S_e = self.J_N * S[0]

        # TODO: Confirm that this computation is correct for this model depending on the r_e and r_i values!
        I_e = self.w_p * J_N_S_e - self.J_i * S[
            1] + self.W_e * self.I_o + coupling + self.I_ext

        x_e = self.a_e * I_e - self.b_e
        # Only rates with R_e <= 0 0 will be updated by TVB.
        R_e = numpy.where(self._Rin_e_mask, R[0],
                          x_e / (1 - numpy.exp(-self.d_e * x_e)))
        # ...and their Rin_e should be zero:
        Rin_e = numpy.where(self._Rin_e_mask, Rin[0], 0.0)

        I_i = J_N_S_e - S[1] + self.W_i * self.I_o + self.lamda * coupling

        x_i = self.a_i * I_i - self.b_i
        # Only rates with R_i < 0 will be updated by TVB.
        R_i = numpy.where(self._Rin_i_mask, R[1],
                          x_i / (1 - numpy.exp(-self.d_i * x_i)))
        # ...and their Rin_i should be zero:
        Rin_i = numpy.where(self._Rin_i_mask, Rin[1], 0.0)

        # We now update the state_variable vector with the new rates:
        state_variables[2, :] = R_e
        state_variables[3, :] = R_i
        state_variables[4, :] = Rin_e
        state_variables[5, :] = Rin_i
        state_variables[6, :] = I_e
        state_variables[7, :] = I_i

        # Keep them here so that they are not recomputed in the dfun
        self._Rin = numpy.copy(state_variables[4:6])

        return state_variables