gif_cond_exp#

class brainpy.state.gif_cond_exp(in_size, g_L=Quantity(4., "nS"), E_L=Quantity(-70., "mV"), C_m=Quantity(80., "pF"), V_reset=Quantity(-55., "mV"), Delta_V=Quantity(0.5, "mV"), V_T_star=Quantity(-35., "mV"), lambda_0=1.0, t_ref=Quantity(4., "ms"), E_ex=Quantity(0., "mV"), E_in=Quantity(-85., "mV"), tau_syn_ex=Quantity(2., "ms"), tau_syn_in=Quantity(2., "ms"), I_e=Quantity(0., "pA"), tau_sfa=(), q_sfa=(), tau_stc=(), q_stc=(), gsl_error_tol=1e-06, rng_key=None, V_initializer=Constant(value=-70. mV), g_ex_initializer=Constant(value=0. nS), g_in_initializer=Constant(value=0. nS), spk_fun=ReluGrad(alpha=0.3, width=1.0), spk_reset='hard', ref_var=False, name=None)#

Conductance-based generalized integrate-and-fire neuron (GIF) model.

gif_cond_exp is the generalized integrate-and-fire neuron according to Mensi et al. (2012) [1] and Pozzorini et al. (2015) [2], with postsynaptic conductances in the form of truncated exponentials.

This is a brainpy.state re-implementation of the NEST simulator model of the same name, using NEST-standard parameterization.

This model features both an adaptation current and a dynamic threshold for spike-frequency adaptation. The membrane potential \(V\) is described by the differential equation:

\[C_\mathrm{m} \frac{dV(t)}{dt} = -g_\mathrm{L}(V(t) - E_\mathrm{L}) - g_\mathrm{ex}(t)(V(t) - E_\mathrm{ex}) - g_\mathrm{in}(t)(V(t) - E_\mathrm{in}) - \eta_1(t) - \eta_2(t) - \ldots - \eta_n(t) + I_\mathrm{e} + I_\mathrm{stim}(t)\]

where each \(\eta_i\) is a spike-triggered current (stc), and the neuron model can have an arbitrary number of them.

Synaptic conductances decay exponentially:

\[\frac{dg_\mathrm{ex}}{dt} = -\frac{g_\mathrm{ex}}{\tau_{\mathrm{syn,ex}}}, \qquad \frac{dg_\mathrm{in}}{dt} = -\frac{g_\mathrm{in}}{\tau_{\mathrm{syn,in}}}.\]

1. Spike-triggered currents

Dynamic of each \(\eta_i\) is described by:

\[\tau_{\eta_i} \cdot \frac{d\eta_i}{dt} = -\eta_i\]

and in case of spike emission, its value is increased by a constant:

\[\eta_i = \eta_i + q_{\eta_i} \quad \text{(on spike emission)}\]

2. Spike-frequency adaptation

The neuron produces spikes stochastically according to a point process with the firing intensity:

\[\lambda(t) = \lambda_0 \cdot \exp\left(\frac{V(t) - V_T(t)}{\Delta_V}\right)\]

where \(V_T(t)\) is a time-dependent firing threshold:

\[V_T(t) = V_{T^*} + \gamma_1(t) + \gamma_2(t) + \ldots + \gamma_m(t)\]

where \(\gamma_i\) is a kernel of spike-frequency adaptation (sfa). Dynamic of each \(\gamma_i\) is described by:

\[\tau_{\gamma_i} \cdot \frac{d\gamma_i}{dt} = -\gamma_i\]

and in case of spike emission, its value is increased by a constant:

\[\gamma_i = \gamma_i + q_{\gamma_i} \quad \text{(on spike emission)}\]

3. Stochastic spiking

The probability of firing within a time step \(dt\) is computed using the hazard function:

\[P(\text{spike}) = 1 - \exp(-\lambda(t) \cdot dt)\]

A random number is drawn each (non-refractory) time step and compared to this probability to determine whether a spike occurs.

4. Refractory mechanism

After a spike, the neuron enters an absolute refractory period of duration \(t_\mathrm{ref}\). During this period:

  • \(V_\mathrm{m}\) is clamped to \(V_\mathrm{reset}\),

  • \(dV_\mathrm{m}/dt = 0\),

  • conductances continue to decay,

  • refractory counter decrements each step.

5. Numerical integration and update order

NEST integrates this model with adaptive RKF45. This implementation mirrors that behavior with an RKF45(4,5) integrator and persistent internal step size. The discrete-time update order per simulation step is:

  1. Compute total stc (sum of stc elements) and sfa threshold (V_T_star + sum of sfa elements). Then decay all stc and sfa elements by their respective exponential factors.

  2. Integrate continuous dynamics \([V_\mathrm{m}, g_\mathrm{ex}, g_\mathrm{in}]\) over \((t, t+dt]\) using RKF45.

  3. Add synaptic conductance jumps from spike inputs arriving this step.

  4. If not refractory: compute firing intensity, draw random number, potentially emit spike (update stc/sfa elements, set refractory counter). If refractory: decrement counter, clamp V to V_reset.

  5. Store external current input as \(I_\mathrm{stim}\) for the next step.

Note

In the NEST implementation, the stc and sfa element jumps occur immediately after spike emission. The GIF toolbox uses a different convention where jumps occur after the refractory period. Conversion:

\[q_{\eta,\text{toolbox}} = q_{\eta,\text{NEST}} \cdot (1 - \exp(-t_\mathrm{ref} / \tau_\eta))\]

Note

Because spiking is stochastic (random number drawn each step), exact spike-time reproducibility requires matching the random number generator state. For deterministic testing, set rng_key explicitly.

Parameters:
  • in_size (int, sequence of int) – Population shape (e.g., 100 or (10, 10)). Required.

  • g_L (ArrayLike, default: 4.0 nS) – Leak conductance. Must be strictly positive. Shape: scalar or broadcastable to in_size.

  • E_L (ArrayLike, default: -70.0 mV) – Leak reversal potential (resting potential). Shape: scalar or broadcastable to in_size.

  • C_m (ArrayLike, default: 80.0 pF) – Membrane capacitance. Must be strictly positive. Shape: scalar or broadcastable to in_size.

  • V_reset (ArrayLike, default: -55.0 mV) – Reset potential after spike. Shape: scalar or broadcastable to in_size.

  • Delta_V (ArrayLike, default: 0.5 mV) – Stochasticity level for exponential firing intensity. Must be strictly positive. Shape: scalar or broadcastable to in_size.

  • V_T_star (ArrayLike, default: -35.0 mV) – Base (non-adapting) firing threshold. Shape: scalar or broadcastable to in_size.

  • lambda_0 (float, default: 1.0) – Stochastic intensity at threshold (in 1/s). Must be non-negative. Internally converted to 1/ms.

  • t_ref (ArrayLike, default: 4.0 ms) – Absolute refractory period duration. Must be non-negative. Shape: scalar or broadcastable to in_size.

  • E_ex (ArrayLike, default: 0.0 mV) – Excitatory reversal potential. Shape: scalar or broadcastable to in_size.

  • E_in (ArrayLike, default: -85.0 mV) – Inhibitory reversal potential. Shape: scalar or broadcastable to in_size.

  • tau_syn_ex (ArrayLike, default: 2.0 ms) – Excitatory conductance decay time constant. Must be strictly positive. Shape: scalar or broadcastable to in_size.

  • tau_syn_in (ArrayLike, default: 2.0 ms) – Inhibitory conductance decay time constant. Must be strictly positive. Shape: scalar or broadcastable to in_size.

  • I_e (ArrayLike, default: 0.0 pA) – Constant external current. Shape: scalar or broadcastable to in_size.

  • tau_sfa (Sequence[float], default: ()) – Time constants for spike-frequency adaptation (SFA) threshold elements (in ms). Each element must be strictly positive. Must have same length as q_sfa.

  • q_sfa (Sequence[float], default: ()) – Jump values for SFA threshold elements (in mV). Must have same length as tau_sfa.

  • tau_stc (Sequence[float], default: ()) – Time constants for spike-triggered current (STC) elements (in ms). Each element must be strictly positive. Must have same length as q_stc.

  • q_stc (Sequence[float], default: ()) – Jump values for STC elements (in nA). Must have same length as tau_stc.

  • gsl_error_tol (ArrayLike, default: 1e-6) – Unitless local RKF45 error tolerance, broadcastable and strictly positive.

  • rng_key (jax.Array, optional) – JAX PRNG key for stochastic spiking. If None, defaults to jax.random.PRNGKey(0).

  • V_initializer (Callable, default: Constant(-70.0 mV)) – Initializer for membrane potential. Must return values compatible with in_size.

  • g_ex_initializer (Callable, default: Constant(0.0 nS)) – Initializer for excitatory conductance. Must return values compatible with in_size.

  • g_in_initializer (Callable, default: Constant(0.0 nS)) – Initializer for inhibitory conductance. Must return values compatible with in_size.

  • spk_fun (Callable, default: ReluGrad()) – Surrogate gradient function for spike generation. Used in gradient-based learning.

  • spk_reset (str, default: 'hard') – Spike reset mode. ‘hard’ (stop gradient, matches NEST) or ‘soft’ (subtract threshold).

  • ref_var (bool, default: False) – If True, allocate and expose self.refractory state.

  • name (str, optional) – Module name. If None, auto-generated.

Parameter Mapping

Maps brainpy.state parameter names to NEST equivalents for cross-framework compatibility:

Parameter

Default

Math equivalent

Description

in_size

(required)

Population shape

g_L

4.0 nS

\(g_\mathrm{L}\)

Leak conductance

E_L

-70.0 mV

\(E_\mathrm{L}\)

Leak reversal potential

C_m

80.0 pF

\(C_\mathrm{m}\)

Membrane capacitance

V_reset

-55.0 mV

\(V_\mathrm{reset}\)

Reset potential

Delta_V

0.5 mV

\(\Delta_V\)

Stochasticity level

V_T_star

-35.0 mV

\(V_{T^*}\)

Base firing threshold

lambda_0

1.0 /s

\(\lambda_0\)

Stochastic intensity at threshold

t_ref

4.0 ms

\(t_\mathrm{ref}\)

Absolute refractory period

E_ex

0.0 mV

\(E_\mathrm{ex}\)

Excitatory reversal potential

E_in

-85.0 mV

\(E_\mathrm{in}\)

Inhibitory reversal potential

tau_syn_ex

2.0 ms

\(\tau_{\mathrm{syn,ex}}\)

Excitatory conductance time constant

tau_syn_in

2.0 ms

\(\tau_{\mathrm{syn,in}}\)

Inhibitory conductance time constant

I_e

0.0 pA

\(I_\mathrm{e}\)

Constant external current

tau_sfa

() ms

\(\tau_{\gamma_i}\)

SFA time constants (tuple/list)

q_sfa

() mV

\(q_{\gamma_i}\)

SFA jump values (tuple/list)

tau_stc

() ms

\(\tau_{\eta_i}\)

STC time constants (tuple/list)

q_stc

() nA

\(q_{\eta_i}\)

STC jump values (tuple/list)

gsl_error_tol

1e-6

RKF45 absolute error tolerance

rng_key

None

JAX PRNG key for stochastic spiking

V_initializer

Constant(-70 mV)

Initializer for membrane potential

g_ex_initializer

Constant(0 nS)

Initializer for excitatory conductance

g_in_initializer

Constant(0 nS)

Initializer for inhibitory conductance

spk_fun

ReluGrad()

Surrogate spike function

spk_reset

'hard'

Reset mode; hard reset matches NEST

ref_var

False

If True, expose boolean refractory state

State Variables

After init_state(), the following state variables are available:

State variable

Type

Description

V

HiddenState

Membrane potential \(V_\mathrm{m}\) (mV)

g_ex

HiddenState

Excitatory conductance \(g_\mathrm{ex}\) (nS)

g_in

HiddenState

Inhibitory conductance \(g_\mathrm{in}\) (nS)

refractory_step_count

ShortTermState

Remaining refractory grid steps (int32)

integration_step

ShortTermState

Internal RKF45 step-size state (ms)

I_stim

ShortTermState

Buffered current applied in next step (pA)

last_spike_time

ShortTermState

Last spike time (ms)

refractory

ShortTermState

Optional boolean refractory indicator (ref_var=True)

Additionally, the following NumPy arrays are maintained internally:

  • _stc_elems – shape (len(tau_stc), *in_size) – individual stc elements (nA)

  • _sfa_elems – shape (len(tau_sfa), *in_size) – individual sfa elements (mV)

  • _stc_val – shape in_size – total spike-triggered current (nA)

  • _sfa_val – shape in_size – adaptive threshold \(V_T(t)\) (mV)

Raises:

ValueError – If C_m <= 0, g_L <= 0, Delta_V <= 0, t_ref < 0, lambda_0 < 0, tau_syn_ex <= 0, tau_syn_in <= 0, any tau_sfa <= 0, any tau_stc <= 0, len(tau_sfa) != len(q_sfa), or len(tau_stc) != len(q_stc).

Notes

  • Defaults follow NEST C++ source for gif_cond_exp.

  • lambda_0 is specified in 1/s (as in NEST’s Python interface) and is internally converted to 1/ms for computation.

  • Synaptic spike weights are interpreted in conductance units (nS), with positive/negative sign selecting excitatory/inhibitory channel.

  • RKF45 integration with adaptive step size ensures numerical stability for stiff systems, matching NEST’s GSL-based integrator behavior.

  • The stochastic spiking mechanism uses JAX PRNG, which is split each time step to ensure reproducible randomness under JIT compilation.

Examples

Create a GIF neuron with default parameters:

>>> import brainpy.state as bst
>>> import saiunit as u
>>> import brainstate as bs
>>> bs.environ.context(dt=0.1 * u.ms)
>>> neuron = bst.gif_cond_exp(in_size=10)
>>> neuron.init_all_states()
>>> spikes = neuron.update(x=5.0 * u.pA)

Create a GIF neuron with spike-frequency adaptation:

>>> import brainpy.state as bst
>>> import saiunit as u
>>> import brainstate as bs
>>> bs.environ.context(dt=0.1 * u.ms)
>>> neuron = bst.gif_cond_exp(
...     in_size=10,
...     tau_sfa=(100.0, 200.0),  # Two SFA time constants (ms)
...     q_sfa=(5.0, 10.0),       # SFA jumps (mV)
...     tau_stc=(50.0,),         # One STC time constant (ms)
...     q_stc=(100.0,),          # STC jump (nA)
... )
>>> neuron.init_all_states()
>>> spikes = neuron.update(x=50.0 * u.pA)

References

get_spike(V=None)[source]#

Compute differentiable spike signal using surrogate gradient.

Parameters:

V (ArrayLike, optional) – Membrane potential (mV). If None, uses current self.V.value.

Returns:

Differentiable spike signal in [0, 1], computed via surrogate function. Shape matches V or self.V.value.

Return type:

ArrayLike

Notes

  • This method is used for gradient-based learning, not for actual spike generation in forward simulation (which is stochastic via update()).

  • Spike signal is computed as spk_fun((V - V_reset) / Delta_V).

  • Default spk_fun is ReluGrad(), providing a piecewise-linear surrogate.

init_state(**kwargs)[source]#

Initialize all state variables for the GIF neuron.

Initializes membrane potential (V), conductances (g_ex, g_in), adaptation elements (_stc_elems, _sfa_elems), refractory counter, integration step size, buffered current, and RNG state.

Parameters:

**kwargs – Unused compatibility parameters accepted by the base-state API.

Notes

  • Sets V using V_initializer (default: -70 mV).

  • Sets g_ex and g_in using respective initializers (default: 0 nS).

  • Initializes all STC and SFA elements to zero.

  • Sets refractory_step_count to 0 (not refractory).

  • Sets integration_step to simulation timestep (from brainstate.environ.get_dt()).

  • Initializes RNG state from rng_key if provided, else uses jax.random.PRNGKey(0).

update(x=Quantity(0., 'pA'))[source]#

Advance the neuron state by one simulation timestep.

Performs the complete GIF update cycle: decay adaptation elements, integrate membrane dynamics via RKF45, add synaptic inputs, evaluate stochastic spike condition, handle refractory period, and update all state variables.

Parameters:

x (ArrayLike, default: 0.0 pA) – External current input for this timestep (pA). Shape must be broadcastable to in_size.

Returns:

Binary spike indicator (0 or 1) for each neuron. Shape matches in_size. Value is 1.0 if neuron spiked, 0.0 otherwise.

Return type:

ArrayLike

Notes

Update order:

  1. Compute total stc and sfa from element arrays, then decay all elements.

  2. Integrate continuous dynamics [V, g_ex, g_in] using adaptive RKF45.

  3. Add synaptic conductance jumps from delta_inputs.

  4. Evaluate stochastic spike condition (if not refractory): - Compute firing intensity: \(\\lambda = \\lambda_0 \\exp((V - V_T) / \\Delta_V)\) - Draw random number, spike if \(U < 1 - \\exp(-\\lambda \\cdot dt)\) - On spike: increment stc/sfa elements, set refractory counter

  5. If refractory: decrement counter, clamp V to V_reset.

  6. Buffer current input for next step.

Synaptic input handling:

  • Conductance inputs are accumulated from delta_inputs dict.

  • Positive weights -> excitatory (g_ex), negative weights -> inhibitory (g_in).

  • Current inputs are summed via sum_current_inputs() and buffered for next step.

Stochastic spiking:

  • RNG state is advanced each timestep via jax.random.split().

  • Spike times are not exact (unlike *_ps models) – spikes occur on grid.

  • For reproducibility, set rng_key explicitly during initialization.

Failure modes:

  • If RKF45 cannot converge within _MAX_ITERS iterations, integration may be incomplete. This typically occurs only with extreme parameter values or very large dt.