aeif_cond_alpha_multisynapse#

class brainpy.state.aeif_cond_alpha_multisynapse(in_size, V_peak=Quantity(0., "mV"), V_reset=Quantity(-60., "mV"), t_ref=Quantity(0., "ms"), g_L=Quantity(30., "nS"), C_m=Quantity(281., "pF"), E_L=Quantity(-70.6, "mV"), Delta_T=Quantity(2., "mV"), tau_w=Quantity(144., "ms"), a=Quantity(4., "nS"), b=Quantity(80.5, "pA"), V_th=Quantity(-50.4, "mV"), tau_syn=Quantity([2.], "ms"), E_rev=Quantity([0.], "mV"), I_e=Quantity(0., "pA"), gsl_error_tol=1e-06, V_initializer=Constant(value=-70.6 mV), g_initializer=Constant(value=0. nS), w_initializer=Constant(value=0. pA), spk_fun=ReluGrad(alpha=0.3, width=1.0), spk_reset='hard', ref_var=False, name=None)#

NEST-compatible aeif_cond_alpha_multisynapse neuron model.

Conductance-based adaptive exponential integrate-and-fire neuron with alpha-shaped synapses and an arbitrary number of receptor ports.

Parameters:
  • in_size (Size) – Population shape. All per-neuron states use self.varshape derived from in_size.

  • V_peak (ArrayLike) – Spike detection voltage in mV, broadcastable to self.varshape. Used as detection threshold only when Delta_T > 0.

  • V_reset (ArrayLike) – Reset and refractory clamp voltage in mV, broadcastable to self.varshape.

  • t_ref (ArrayLike) – Absolute refractory duration in ms, broadcastable to self.varshape. Converted to integer grid counts by ceil(t_ref / dt).

  • g_L (ArrayLike) – Leak conductance in nS, broadcastable to self.varshape.

  • C_m (ArrayLike) – Membrane capacitance in pF, broadcastable to self.varshape.

  • E_L (ArrayLike) – Leak reversal potential in mV, broadcastable to self.varshape.

  • Delta_T (ArrayLike) – Exponential slope factor in mV, broadcastable to self.varshape. Delta_T == 0 disables the exponential current and switches detection to V_th.

  • tau_w (ArrayLike) – Adaptation time constant in ms, broadcastable to self.varshape.

  • a (ArrayLike) – Subthreshold adaptation conductance in nS, broadcastable to self.varshape.

  • b (ArrayLike) – Spike-triggered adaptation jump in pA, broadcastable to self.varshape.

  • V_th (ArrayLike) – Exponential soft-threshold voltage in mV, broadcastable to self.varshape.

  • tau_syn (ArrayLike) – Receptor time constants in ms. Values are flattened to shape (n_receptors,); each entry must be strictly positive.

  • E_rev (ArrayLike) – Receptor reversal potentials in mV. Values are flattened to shape (n_receptors,) and must have the same length as tau_syn.

  • I_e (ArrayLike) – Constant external current in pA, broadcastable to self.varshape.

  • gsl_error_tol (ArrayLike) – Unitless local absolute tolerance for RKF45, broadcastable to self.varshape and strictly positive.

  • V_initializer (Callable) – Initializer for membrane voltage V (mV domain). Must support shape self.varshape (and optional batch axis via framework init helpers).

  • g_initializer (Callable) – Initializer for conductance state g (nS domain). Must support shape self.varshape + (n_receptors,).

  • w_initializer (Callable) – Initializer for adaptation current w (pA domain), shape self.varshape.

  • spk_fun (Callable) – Surrogate spike function used by get_spike().

  • spk_reset (str) – Reset policy from Neuron; 'hard' matches NEST semantics.

  • ref_var (bool) – If True, allocates a boolean refractory state variable self.refractory.

  • name (str | None) – Optional node name.

Parameter Mapping

Table 15 Parameter mapping to model symbols#

Parameter

Type / shape / unit

Default

Math symbol

Semantics

in_size

Size; scalar or tuple

required

Population shape defining self.varshape.

V_peak

ArrayLike, broadcastable to self.varshape (mV)

0.0 * u.mV

\(V_\mathrm{peak}\)

Spike detection threshold when Delta_T > 0 and membrane RHS clamp bound via \(\min(V, V_{\mathrm{peak}})\).

V_reset

ArrayLike, broadcastable (mV)

-60.0 * u.mV

\(V_\mathrm{reset}\)

Reset value and refractory clamp voltage.

t_ref

ArrayLike, broadcastable (ms)

0.0 * u.ms

\(t_\mathrm{ref}\)

Absolute refractory duration converted to integer step counts.

g_L and C_m

ArrayLike, broadcastable (nS, pF)

30.0 * u.nS, 281.0 * u.pF

\(g_L\), \(C_m\)

Leak conductance and membrane capacitance in AdEx membrane dynamics.

E_L, Delta_T, and V_th

ArrayLike, broadcastable (mV)

-70.6 * u.mV, 2.0 * u.mV, -50.4 * u.mV

\(E_L\), \(\Delta_T\), \(V_\mathrm{th}\)

Leak reversal, exponential slope, and soft threshold.

tau_w, a, and b

ArrayLike, broadcastable (ms, nS, pA)

144.0 * u.ms, 4.0 * u.nS, 80.5 * u.pA

\(\tau_w\), \(a\), \(b\)

Adaptation time scale, coupling, and spike-triggered jump.

tau_syn

ArrayLike, flattened to (n_receptors,) (ms)

(2.0,) * u.ms

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

Receptor-specific alpha time constants; each > 0.

E_rev

ArrayLike, flattened to (n_receptors,) (mV)

(0.0,) * u.mV

\(E_{\mathrm{rev},k}\)

Receptor-specific reversal potentials, same length as tau_syn.

I_e

ArrayLike, broadcastable (pA)

0.0 * u.pA

\(I_e\)

Constant current added every RKF45 substep.

gsl_error_tol

ArrayLike, broadcastable, unitless, > 0

1e-6

Embedded RKF45 local error tolerance.

V_initializer

Callable

Constant(-70.6 * u.mV)

Initializer for V.

g_initializer

Callable

Constant(0.0 * u.nS)

Initializer for g with shape [..., n_receptors].

w_initializer

Callable

Constant(0.0 * u.pA)

Initializer for adaptation current w.

spk_fun

Callable

ReluGrad()

Surrogate nonlinearity used by get_spike().

spk_reset

str

'hard'

Reset mode inherited from Neuron.

ref_var

bool

False

If True, exposes boolean self.refractory.

name

str | None

None

Optional node name.

Raises:

ValueError – Raised at initialization or update time if any of the following holds: - E_rev and tau_syn lengths differ. - Any tau_syn <= 0, tau_w <= 0, C_m <= 0, gsl_error_tol <= 0, or t_ref < 0. - Any V_peak < V_th or V_reset >= V_peak. - Any Delta_T < 0 or overflow guard on (V_peak - V_th) / Delta_T is violated for Delta_T > 0. - Incoming spike event receptor index is outside [1, n_receptors]. - Incoming conductance weights are negative (both explicit spike_events and default add_delta_input path). - Nonzero default delta-conductance input is provided when n_receptors == 0. - Runtime instability guard is triggered during integration (V < -1e3 mV or w outside [-1e6, 1e6] pA).

Description

aeif_cond_alpha_multisynapse follows NEST models/aeif_cond_alpha_multisynapse.{h,cpp}. It extends aeif_cond_alpha by replacing fixed excitatory/inhibitory channels with receptor-indexed alpha conductances.

Each receptor k has:

  • synaptic time constant tau_syn[k],

  • reversal potential E_rev[k],

  • alpha states dg[k] and g[k].

Receptor ports are 1-based (NEST convention): 1..n_receptors.

1. Continuous dynamics

Let \(V\) be membrane voltage, \(w\) adaptation current, and \(g_k\) receptor conductances.

\[C_m \frac{dV}{dt} = -g_L (V - E_L) + g_L \Delta_T \exp\!\left(\frac{V - V_{th}}{\Delta_T}\right) + \sum_k g_k (E_{\mathrm{rev},k} - V) - w + I_e + I_{stim}.\]

Adaptation dynamics:

\[\tau_w \frac{dw}{dt} = a (V - E_L) - w.\]

Receptor alpha states:

\[\frac{d\,dg_k}{dt} = -\frac{dg_k}{\tau_{\mathrm{syn},k}}, \qquad \frac{d g_k}{dt} = dg_k - \frac{g_k}{\tau_{\mathrm{syn},k}}.\]

Incoming spike weights w_k (in nS) are applied as:

\[dg_k \leftarrow dg_k + \frac{e}{\tau_{\mathrm{syn},k}} w_k.\]

The \(e/\tau_{\mathrm{syn},k}\) factor is the alpha-kernel normalization from NEST. For a single spike with weight \(w_k\), the resulting conductance is:

\[g_k(t) = w_k \frac{t}{\tau_{\mathrm{syn},k}} \exp\!\left(1 - \frac{t}{\tau_{\mathrm{syn},k}}\right), \quad t \ge 0,\]

which peaks at \(t=\tau_{\mathrm{syn},k}\) with peak value \(w_k\).

2. Spike and refractory semantics

  • During refractory integration, effective voltage is clamped to V_reset and \(dV/dt = 0\).

  • Outside refractory period, the RHS uses \(\min(V, V_{peak})\).

  • Spike detection threshold is: - V_peak if Delta_T > 0, - V_th if Delta_T == 0.

  • On each detected spike (inside RKF45 substeps): - V <- V_reset - w <- w + b - refractory counter r <- refractory_counts + 1 if refractory is enabled.

3. Update order per simulation step (NEST semantics)

  1. Integrate ODEs on \((t, t+dt]\) using adaptive RKF45.

  2. Inside integration loop: refractory clamp and spike/reset/adaptation.

  3. Decrement refractory counter once.

  4. Apply incoming receptor-specific spike events to dg.

  5. Store continuous current input x into one-step delayed I_stim.

4. Event semantics

spike_events passed to update() must be an iterable of (receptor_type, weight) or dictionaries with keys receptor_type/receptor and weight.

  • Receptor types are 1-based and must satisfy 1 <= receptor_type <= n_receptors.

  • Weights are conductances (nS) and must be non-negative, matching NEST conductance multisynapse constraints.

  • add_delta_input stream is mapped to receptor 1 by default; those values must also be non-negative.

State variables

  • V: membrane potential \(V_m\).

  • w: adaptation current.

  • dg: alpha auxiliary states per receptor [..., n_receptors].

  • g: receptor conductances [..., n_receptors].

  • refractory_step_count: remaining refractory grid steps.

  • integration_step: persistent RKF45 internal step size.

  • I_stim: one-step delayed current buffer.

  • last_spike_time: last emitted spike time (\(t+dt\) on spike).

  • refractory: optional boolean refractory indicator.

Recordables

Dynamic recordables follow NEST naming:

  • V_m

  • w

  • g_1, g_2, …, g_n

Notes

  • Default t_ref = 0 matches NEST and can allow multiple spikes inside one simulation step.

  • This implementation targets source-level parity with NEST update ordering rather than high-performance vectorization.

  • Computational cost scales with prod(self.V.value.shape) * n_receptors and is dominated by scalar RKF45 substepping in Python loops.

Examples

>>> import brainstate
>>> import saiunit as u
>>> from brainpy_state._nest.aeif_cond_alpha_multisynapse import (
...     aeif_cond_alpha_multisynapse,
... )
>>> _ = brainstate.environ.context(dt=0.1 * u.ms, t=0.0 * u.ms)
>>> neu = aeif_cond_alpha_multisynapse(
...     in_size=4,
...     tau_syn=(0.5, 2.0) * u.ms,
...     E_rev=(0.0, -75.0) * u.mV,
... )
>>> neu.init_state()
>>> spikes = neu.update(
...     x=120.0 * u.pA,
...     spike_events=[{'receptor_type': 1, 'weight': 0.8 * u.nS}],
... )
>>> spikes.shape
(4,)

References

get_spike(V=None)[source]#

Generate spikes based on neuron state variables.

This abstract method must be implemented by subclasses to define the spike generation mechanism. The method should use the surrogate gradient function self.spk_fun to enable gradient-based learning.

Parameters:
  • *args – Positional arguments (typically state variables like membrane potential)

  • **kwargs – Keyword arguments

Returns:

Binary spike tensor where 1 indicates a spike and 0 indicates no spike.

Return type:

ArrayLike

Raises:

NotImplementedError – If the subclass does not implement this method.

init_state(**kwargs)[source]#

Initialize persistent and short-term state variables.

Parameters:

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

Raises:
  • ValueError – If an initializer cannot be broadcast to requested shape.

  • TypeError – If initializer outputs have incompatible units/dtypes for the corresponding state variables.

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

Advance the neuron by one simulation step.

Parameters:
  • x (ArrayLike, optional) – Continuous external current input in pA, broadcastable to self.varshape. This value is stored into I_stim and applied at the next simulation step (one-step delay).

  • spike_events (Iterable, optional) – Receptor-specific spike events. Each element should be a dict with keys receptor_type (or receptor) and weight, or a (receptor_type, weight) tuple.

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:

jax.Array

Raises:

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

Notes

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