iaf_cond_exp#

class brainpy.state.iaf_cond_exp(in_size, E_L=Quantity(-70., "mV"), C_m=Quantity(250., "pF"), t_ref=Quantity(2., "ms"), V_th=Quantity(-55., "mV"), V_reset=Quantity(-60., "mV"), E_ex=Quantity(0., "mV"), E_in=Quantity(-85., "mV"), g_L=Quantity(16.6667, "nS"), tau_syn_ex=Quantity(0.2, "ms"), tau_syn_in=Quantity(2., "ms"), I_e=Quantity(0., "pA"), gsl_error_tol=0.001, 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)#

Leaky integrate-and-fire model with exponential conductance synapses.

This is a conductance-based leaky integrate-and-fire neuron with hard threshold, fixed absolute refractory period, exponentially decaying excitatory and inhibitory synaptic conductances, and no adaptation variables.

This implementation follows NEST iaf_cond_exp dynamics and update order, using NEST C++ model behavior as the source of truth.

1. Membrane Potential and Synaptic Conductances

The membrane potential evolves according to

\[\frac{dV_\mathrm{m}}{dt} = \frac{-g_\mathrm{L}(V_\mathrm{m}-E_\mathrm{L}) - I_\mathrm{syn} + I_\mathrm{e} + I_\mathrm{stim}} {C_\mathrm{m}}\]

with the total synaptic current given by

\[I_\mathrm{syn} = I_{\mathrm{syn,ex}} + I_{\mathrm{syn,in}} = g_\mathrm{ex}(V_\mathrm{m}-E_\mathrm{ex}) + g_\mathrm{in}(V_\mathrm{m}-E_\mathrm{in}) .\]

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}}}.\]

A presynaptic spike with weight \(w\) causes an instantaneous jump at the end of the simulation step:

\[w > 0 \Rightarrow g_\mathrm{ex} \leftarrow g_\mathrm{ex} + w, \qquad w < 0 \Rightarrow g_\mathrm{in} \leftarrow g_\mathrm{in} + |w|.\]

2. Spike Emission and Refractory Mechanism

A spike is emitted when \(V_\mathrm{m} \ge V_\mathrm{th}\) at the end of a simulation step. On spike:

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

  • refractory counter is set to \(\lceil t_\mathrm{ref}/dt \rceil\),

  • spike time is recorded as \(t + dt\).

During absolute refractory period:

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

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

  • conductances continue to decay.

3. 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 is:

  1. Integrate continuous dynamics on \((t, t+dt]\).

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

  3. Apply refractory countdown / threshold check / reset and spike emission.

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

The one-step delayed application of current input (I_stim buffer) is intentional and matches NEST’s ring-buffer update semantics.

Parameters:
  • in_size (int, tuple of int) – Shape of the neuron population. Can be an integer for 1D population or tuple for multi-dimensional populations.

  • E_L (float, ArrayLike, optional) – Leak reversal potential. Must have unit of voltage (mV). Default: -70 mV

  • C_m (float, ArrayLike, optional) – Membrane capacitance. Must be strictly positive with unit of capacitance (pF). Default: 250 pF

  • t_ref (float, ArrayLike, optional) – Absolute refractory period duration. Must be non-negative with unit of time (ms). Default: 2 ms

  • V_th (float, ArrayLike, optional) – Spike threshold voltage. Must be greater than V_reset with unit of voltage (mV). Default: -55 mV

  • V_reset (float, ArrayLike, optional) – Reset potential after spike. Must be less than V_th with unit of voltage (mV). Default: -60 mV

  • E_ex (float, ArrayLike, optional) – Excitatory reversal potential. Must have unit of voltage (mV). Default: 0 mV

  • E_in (float, ArrayLike, optional) – Inhibitory reversal potential. Must have unit of voltage (mV). Default: -85 mV

  • g_L (float, ArrayLike, optional) – Leak conductance. Must be strictly positive with unit of conductance (nS). Default: 16.6667 nS

  • tau_syn_ex (float, ArrayLike, optional) – Excitatory synaptic conductance time constant. Must be strictly positive with unit of time (ms). Default: 0.2 ms

  • tau_syn_in (float, ArrayLike, optional) – Inhibitory synaptic conductance time constant. Must be strictly positive with unit of time (ms). Default: 2.0 ms

  • I_e (float, ArrayLike, optional) – Constant external input current. Must have unit of current (pA). Default: 0 pA

  • gsl_error_tol (ArrayLike) – Unitless local RKF45 error tolerance, broadcastable and strictly positive.

  • V_initializer (Callable, optional) – Initializer function for membrane potential state. Must return values with voltage units. Default: braintools.init.Constant(-70 * u.mV)

  • g_ex_initializer (Callable, optional) – Initializer function for excitatory conductance state. Must return values with conductance units. Default: braintools.init.Constant(0 * u.nS)

  • g_in_initializer (Callable, optional) – Initializer function for inhibitory conductance state. Must return values with conductance units. Default: braintools.init.Constant(0 * u.nS)

  • spk_fun (Callable, optional) – Surrogate gradient function for differentiable spike generation. Must be a callable with signature (x: ArrayLike) -> ArrayLike. Default: braintools.surrogate.ReluGrad()

  • spk_reset (str, optional) – Spike reset mode. Options: 'hard' (gradient blocking, matches NEST), 'soft' (gradient-friendly subtraction). Default: 'hard'

  • ref_var (bool, optional) – If True, expose a boolean refractory state variable indicating whether each neuron is currently in the refractory period. Default: False

  • name (str, optional) – Name of the neuron population. If None, an automatic name is generated.

Parameter Mapping

Parameter

Default

Math equivalent

in_size

(required)

E_L

-70 mV

\(E_\mathrm{L}\)

C_m

250 pF

\(C_\mathrm{m}\)

t_ref

2 ms

\(t_\mathrm{ref}\)

V_th

-55 mV

\(V_\mathrm{th}\)

V_reset

-60 mV

\(V_\mathrm{reset}\)

E_ex

0 mV

\(E_\mathrm{ex}\)

E_in

-85 mV

\(E_\mathrm{in}\)

g_L

16.6667 nS

\(g_\mathrm{L}\)

tau_syn_ex

0.2 ms

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

tau_syn_in

2.0 ms

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

I_e

0 pA

\(I_\mathrm{e}\)

gsl_error_tol

1e-3

V_initializer

Constant(-70 mV)

g_ex_initializer

Constant(0 nS)

g_in_initializer

Constant(0 nS)

spk_fun

ReluGrad()

spk_reset

'hard'

ref_var

False

State Variables

Vbrainstate.HiddenState

Membrane potential \(V_\mathrm{m}\) in mV, shape (*in_size).

g_exbrainstate.HiddenState

Excitatory synaptic conductance \(g_\mathrm{ex}\) in nS, shape (*in_size).

g_inbrainstate.HiddenState

Inhibitory synaptic conductance \(g_\mathrm{in}\) in nS, shape (*in_size).

last_spike_timebrainstate.ShortTermState

Last spike emission time in ms, shape (*in_size).

refractory_step_countbrainstate.ShortTermState

Remaining refractory time steps (int32), shape (*in_size).

integration_stepbrainstate.ShortTermState

Internal RKF45 adaptive step size in ms, shape (*in_size).

I_stimbrainstate.ShortTermState

Buffered external current (one-step delayed) in pA, shape (*in_size).

refractorybrainstate.ShortTermState, optional

Boolean refractory state indicator, shape (*in_size). Only present if ref_var=True.

Raises:
  • ValueError – If V_reset >= V_th (reset must be below threshold).

  • ValueError – If C_m <= 0 (capacitance must be strictly positive).

  • ValueError – If t_ref < 0 (refractory time cannot be negative).

  • ValueError – If tau_syn_ex <= 0 or tau_syn_in <= 0 (time constants must be positive).

  • ValueError – If gsl_error_tol <= 0 (error tolerance must be strictly positive).

Notes

  • Defaults follow NEST C++ source for iaf_cond_exp.

  • In NEST docs, some printed default values may differ from the source for specific releases; source code behavior is used here for parity.

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

  • The RKF45 integrator uses absolute error tolerance of 1e-3 with minimum step size of 1e-8 ms and maximum iteration count of 10000 per simulation step.

  • Integration may fall back to minimum step size if adaptive control fails, potentially degrading accuracy for stiff dynamics.

Examples

Create a population of 100 conductance-based LIF neurons:

>>> import brainpy.state as bst
>>> import saiunit as u
>>> neurons = bst.iaf_cond_exp(100, V_th=-50*u.mV, t_ref=5*u.ms)

Simulate with external current input:

>>> with bst.environ.context(dt=0.1*u.ms):
...     neurons.init_all_states()
...     for t in range(1000):
...         spike = neurons.update(x=500*u.pA)

References

See also

iaf_psc_delta

Current-based LIF with delta synapses

iaf_psc_exp

Current-based LIF with exponential synapses

iaf_cond_alpha

Conductance-based LIF with alpha-function synapses

get_spike(V=None)[source]#

Compute differentiable spike output using surrogate gradient.

Transforms membrane potential into a continuous spike signal suitable for gradient-based learning. Uses the configured surrogate gradient function (spk_fun) applied to normalized voltage distance from threshold.

Parameters:

V (ArrayLike, optional) – Membrane potential values to evaluate (with voltage units). If None, uses current self.V.value. Default: None

Returns:

Spike signal with same shape as input V. Values are continuous (not binary) to support gradient flow. Typically near 0 below threshold and near 1 above threshold, with smooth transition determined by spk_fun.

Return type:

ArrayLike

Notes

  • Voltage is normalized as (V - V_th) / (V_th - V_reset) before applying the surrogate function.

  • The normalization ensures consistent surrogate behavior across different threshold/reset voltage configurations.

  • This method is used internally by update but can also be called externally for spike extraction.

init_state(**kwargs)[source]#

Initialize all state variables for the neuron population.

Creates and registers state variables for membrane potential, synaptic conductances, refractory tracking, RKF45 integration, and buffered currents. All states are initialized using the configured initializer functions.

Parameters:

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

Notes

  • State variables are registered as brainstate.HiddenState (continuous dynamics) or brainstate.ShortTermState (discrete/reset behavior).

  • last_spike_time is initialized to -1e7 ms (far past) to indicate no prior spikes.

  • integration_step is initialized to the simulation timestep dt.

  • If ref_var=True, an additional boolean refractory state is created.

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

Advance neuron dynamics by one simulation timestep.

Integrates membrane potential and synaptic conductances using adaptive RKF45, applies synaptic input increments, handles spike emission and reset, and stores external current for the next step. This method implements the complete NEST update cycle.

Parameters:

x (ArrayLike, optional) – External current input for the next timestep (one-step delay buffer). Must have current units (pA). Can be scalar (broadcast to all neurons) or array with shape matching in_size. Default: 0 pA

Returns:

Binary spike tensor with dtype jnp.float64 and shape self.V.value.shape. A value of 1.0 indicates at least one internal spike event occurred during the integrated interval \((t, t+dt]\).

Return type:

ArrayLike

Raises:

ValueError – If RKF45 integration enters a guarded unstable regime (V < -1e3 mV), indicating divergent dynamics for the current parameter/input regime.

Notes

Integration is performed with an adaptive vectorized RKF45 loop, including in-loop spike/reset events and optional multiple spikes per step. All arithmetic is unit-aware via saiunit.math.