hh_cond_exp_traub#
- class brainpy.state.hh_cond_exp_traub(in_size, E_L=Quantity(-60., 'mV'), C_m=Quantity(200., 'pF'), g_Na=Quantity(20000., 'nS'), g_K=Quantity(6000., 'nS'), g_L=Quantity(10., 'nS'), E_Na=Quantity(50., 'mV'), E_K=Quantity(-90., 'mV'), V_T=Quantity(-63., 'mV'), E_ex=Quantity(0., 'mV'), E_in=Quantity(-80., 'mV'), t_ref=Quantity(2., 'ms'), tau_syn_ex=Quantity(5., 'ms'), tau_syn_in=Quantity(10., 'ms'), I_e=Quantity(0., 'pA'), V_m_init=None, Act_m_init=None, Inact_h_init=None, Act_n_init=None, gsl_error_tol=0.001, spk_fun=ReluGrad(alpha=0.3, width=1.0), spk_reset='hard', name=None)#
NEST-compatible
hh_cond_exp_traubneuron model.Hodgkin-Huxley model for Brette et al. (2007) review, based on Traub and Miles (1991) hippocampal pyramidal cell model.
This is a modified Hodgkin-Huxley neuron model specifically developed for the Brette et al. (2007) simulator review, based on a model of hippocampal pyramidal cells by Traub and Miles (1991). Key differences from the original Traub-Miles model:
This is a point neuron, not a compartmental model.
Only
I_NaandI_Kionic currents are included (no calcium dynamics), with simplifiedI_Kdynamics giving three gating variables instead of eight.Incoming spikes induce an instantaneous conductance change followed by exponential decay (conductance-based synapses), not activation over time.
- Parameters:
in_size (
int,tupleofint) – Population shape (number of neurons or spatial dimensions).E_L (
ArrayLike, default-60 mV) – Leak reversal potential. Must be finite.C_m (
ArrayLike, default200 pF) – Membrane capacitance. Must be strictly positive.g_Na (
ArrayLike, default20000 nS) – Sodium peak conductance. Must be non-negative.g_K (
ArrayLike, default6000 nS) – Potassium peak conductance. Must be non-negative.g_L (
ArrayLike, default10 nS) – Leak conductance. Must be non-negative.E_Na (
ArrayLike, default50 mV) – Sodium reversal potential. Must be finite.E_K (
ArrayLike, default-90 mV) – Potassium reversal potential. Must be finite.V_T (
ArrayLike, default-63 mV) – Voltage offset for gating dynamics. Shifts the effective threshold to approximately V_T + 30 mV.E_ex (
ArrayLike, default0 mV) – Excitatory synaptic reversal potential. Must be finite.E_in (
ArrayLike, default-80 mV) – Inhibitory synaptic reversal potential. Must be finite.t_ref (
ArrayLike, default2 ms) – Duration of refractory period. Must be non-negative. Traub and Miles used 3 ms; NEST default is 2 ms.tau_syn_ex (
ArrayLike, default5 ms) – Excitatory synaptic time constant. Must be strictly positive.tau_syn_in (
ArrayLike, default10 ms) – Inhibitory synaptic time constant. Must be strictly positive.I_e (
ArrayLike, default0 pA) – Constant external input current. Can be positive or negative.V_m_init (
ArrayLike, optional) – Initial membrane potential. If None, defaults to E_L.Act_m_init (
ArrayLike, optional) – Initial sodium activation gating variable (0 <= m <= 1). If None, computed from equilibrium at V_m_init.Inact_h_init (
ArrayLike, optional) – Initial sodium inactivation gating variable (0 <= h <= 1). If None, computed from equilibrium at V_m_init.Act_n_init (
ArrayLike, optional) – Initial potassium activation gating variable (0 <= n <= 1). If None, computed from equilibrium at V_m_init.gsl_error_tol (
ArrayLike) – Unitless local RKF45 error tolerance, broadcastable and strictly positive.spk_fun (
Callable, defaultbraintools.surrogate.ReluGrad()) – Surrogate spike function for differentiable spike generation.spk_reset (
str, default'hard') – Reset mode (‘hard’ or ‘soft’). Note: HH models do not reset voltage after spikes; this parameter affects gradient computation only.name (
str, optional) – Name of the neuron population.
- V#
Membrane potential with shape (*in_size,) in mV.
- Type:
brainstate.HiddenState
- m#
Sodium activation gating variable (0 <= m <= 1), shape (*in_size,).
- Type:
brainstate.HiddenState
- h#
Sodium inactivation gating variable (0 <= h <= 1), shape (*in_size,).
- Type:
brainstate.HiddenState
- n#
Potassium activation gating variable (0 <= n <= 1), shape (*in_size,).
- Type:
brainstate.HiddenState
- g_ex#
Excitatory synaptic conductance in nS, shape (*in_size,).
- Type:
brainstate.HiddenState
- g_in#
Inhibitory synaptic conductance in nS, shape (*in_size,).
- Type:
brainstate.HiddenState
- I_stim#
Stimulation current buffer in pA, shape (*in_size,).
- Type:
brainstate.ShortTermState
- refractory_step_count#
Refractory countdown in grid steps, shape (*in_size,), dtype int32.
- Type:
brainstate.ShortTermState
- integration_step#
Persistent RKF45 substep size estimate (ms).
- Type:
brainstate.ShortTermState
- last_spike_time#
Time of most recent spike in ms, shape (*in_size,).
- Type:
brainstate.ShortTermState
- Raises:
ValueError – If C_m <= 0, t_ref < 0, tau_syn_ex <= 0, or tau_syn_in <= 0.
Notes
Unlike IAF models, the HH model does not reset the membrane potential after a spike. Repolarization occurs naturally through the potassium current.
During the refractory period, subthreshold dynamics continue to evolve freely; only spike emission is suppressed.
Synaptic spike weights are interpreted in conductance units (nS). Positive weights drive excitatory synapses; negative weights drive inhibitory synapses (sign is flipped, i.e.
g_in += |w|).The numerical integration uses an adaptive RKF45 (Runge-Kutta-Fehlberg) integrator implemented in JAX with unit-aware arithmetic via saiunit. This is equivalent to NEST’s GSL RKF45 implementation for numerical correspondence.
Mathematical Formulation
1. Membrane and Ionic Current Dynamics
The membrane potential evolves as:
\[C_m \frac{dV_m}{dt} = -(I_{Na} + I_K + I_L + I_{syn,ex} + I_{syn,in}) + I_{stim} + I_e\]where the currents are:
\[\begin{split}I_{Na} &= g_{Na}\, m^3\, h\, (V_m - E_{Na}) \\ I_K &= g_K\, n^4\, (V_m - E_K) \\ I_L &= g_L\, (V_m - E_L) \\ I_{syn,ex} &= g_{ex}\, (V_m - E_{ex}) \\ I_{syn,in} &= g_{in}\, (V_m - E_{in})\end{split}\]2. Channel Gating Variables
Gating variables \(m\), \(h\), \(n\) obey first-order kinetics:
\[\frac{dx}{dt} = \alpha_x(V)(1 - x) - \beta_x(V)\,x = \alpha_x - (\alpha_x + \beta_x)\, x\]with Traub-Miles rate functions using shifted voltage \(V = V_m - V_T\) (voltage in mV, rates in 1/ms):
\[\begin{split}\alpha_n &= \frac{0.032\,(15 - V)}{e^{(15 - V)/5} - 1}, \quad \beta_n = 0.5\,e^{(10 - V)/40} \\ \alpha_m &= \frac{0.32\,(13 - V)}{e^{(13 - V)/4} - 1}, \quad \beta_m = \frac{0.28\,(V - 40)}{e^{(V - 40)/5} - 1} \\ \alpha_h &= 0.128\,e^{(17 - V)/18}, \quad \beta_h = \frac{4}{1 + e^{(40 - V)/5}}\end{split}\]The voltage offset \(V_T\) (default -63 mV) shifts the effective threshold to approximately -50 mV.
3. Exponential Conductance Synapses
Synaptic conductances decay exponentially:
\[\begin{split}\frac{dg_{ex}}{dt} &= -g_{ex} / \tau_{syn,ex} \\ \frac{dg_{in}}{dt} &= -g_{in} / \tau_{syn,in}\end{split}\]A presynaptic spike with weight \(w\) causes an instantaneous conductance jump:
\(w > 0\) – \(g_{ex} \leftarrow g_{ex} + w\)
\(w < 0\) – \(g_{in} \leftarrow g_{in} + |w|\)
4. Spike Detection
A spike is emitted when all three conditions are satisfied:
r == 0(not in refractory period), andV_m >= V_T + 30mV (threshold crossing), andV_old > V_m(local maximum, the potential is now falling).
Unlike integrate-and-fire models, no voltage reset occurs – the potassium current naturally repolarizes the membrane.
Warning
To avoid multiple spikes during the falling flank of a spike, it is essential to choose a sufficiently long refractory period. Traub and Miles used \(t_{ref} = 3\) ms, while the default here is \(t_{ref} = 2\) ms (matching NEST).
5. Numerical Integration
NEST uses GSL RKF45 (Runge-Kutta-Fehlberg 4/5) with adaptive step-size control. This implementation uses an adaptive RKF45 integrator implemented in JAX with unit-aware arithmetic via saiunit, matching NEST’s integration approach for numerical correspondence.
The ODE system is 6-dimensional per neuron: \([V_m, m, h, n, g_{ex}, g_{in}]\).
Parameter Mapping
The following table shows the correspondence between brainpy.state parameters and NEST/mathematical notation:
Parameter
Default
Math equivalent
Description
in_size(required)
–
Population shape
E_L-60 mV
\(E_L\)
Leak reversal potential
C_m200 pF
\(C_m\)
Membrane capacitance
g_Na20000 nS
\(g_{Na}\)
Sodium peak conductance
g_K6000 nS
\(g_K\)
Potassium peak conductance
g_L10 nS
\(g_L\)
Leak conductance
E_Na50 mV
\(E_{Na}\)
Sodium reversal potential
E_K-90 mV
\(E_K\)
Potassium reversal potential
V_T-63 mV
\(V_T\)
Voltage offset for gating dynamics
E_ex0 mV
\(E_{ex}\)
Excitatory synaptic reversal potential
E_in-80 mV
\(E_{in}\)
Inhibitory synaptic reversal potential
t_ref2 ms
\(t_{ref}\)
Duration of refractory period
tau_syn_ex5 ms
\(\tau_{syn,ex}\)
Excitatory synaptic time constant
tau_syn_in10 ms
\(\tau_{syn,in}\)
Inhibitory synaptic time constant
I_e0 pA
\(I_e\)
Constant external input current
V_m_initNone
–
Initial V_m (None -> E_L)
Act_m_initNone
–
Initial Na activation (None -> equilibrium)
Inact_h_initNone
–
Initial Na inactivation (None -> equilibrium)
Act_n_initNone
–
Initial K activation (None -> equilibrium)
gsl_error_tol1e-3
–
Local RKF45 error tolerance
spk_funReluGrad()
–
Surrogate spike function
spk_reset'hard'–
Reset mode
Examples
>>> import brainstate as bst >>> import saiunit as u >>> from brainpy_state import hh_cond_exp_traub >>> >>> # Create a population of 100 Traub HH neurons >>> neurons = hh_cond_exp_traub(100) >>> neurons.init_all_states() >>> >>> # Run a simulation with constant current injection >>> with bst.environ.context(dt=0.1*u.ms): ... for i in range(1000): ... spikes = neurons.update(I_e=200*u.pA)
>>> # Compare with NEST default parameters >>> import nest >>> nest_neuron = nest.Create('hh_cond_exp_traub') >>> nest.GetStatus(nest_neuron, ['V_m', 'E_L', 'C_m', 'g_Na', 'g_K']) [(-60.0, -60.0, 200.0, 20000.0, 6000.0)] >>> >>> # Match in brainpy.state >>> bp_neuron = hh_cond_exp_traub(1, E_L=-60*u.mV, C_m=200*u.pF, ... g_Na=20000*u.nS, g_K=6000*u.nS)
References
See also
hh_psc_alphaHodgkin-Huxley with alpha-shaped postsynaptic currents.
iaf_cond_expLeaky integrate-and-fire with conductance-based synapses.
- get_spike(V=None)[source]#
Compute differentiable spike output using surrogate gradient function.
Applies the surrogate spike function to the membrane potential. This is used for gradient-based learning; actual spike detection in the update method uses discrete threshold crossing logic (V >= V_T + 30 and local maximum).
- Parameters:
V (
ArrayLike, optional) – Membrane potential in mV, shape (*in_size,) or (batch_size, *in_size). If None, uses the current stateself.V.value.- Returns:
Differentiable spike output with the same shape as input V. Values are approximately 0 (no spike) or 1 (spike) with smooth gradients for backpropagation.
- Return type:
ArrayLike
Notes
The voltage is scaled to unitless values (mV) before applying the surrogate function. For Hodgkin-Huxley neurons, the actual spike threshold is V_T + 30 mV (default: -33 mV), but the surrogate function operates on the raw scaled voltage for gradient computation.
This method is primarily used for surrogate gradient learning. The discrete spike detection logic in the update method is independent and uses the three-condition test (refractory, threshold, local maximum).
Examples
>>> import saiunit as u >>> import jax.numpy as jnp >>> from brainpy_state import hh_cond_exp_traub >>> >>> neurons = hh_cond_exp_traub(10) >>> neurons.init_state() >>> >>> # Get spike output for current state >>> spikes = neurons.get_spike() >>> print(spikes.shape) (10,) >>> >>> # Get spike output for custom voltage >>> V_custom = jnp.array([-60., -50., -40.]) * u.mV >>> neurons_3 = hh_cond_exp_traub(3) >>> neurons_3.init_state() >>> spikes_custom = neurons_3.get_spike(V_custom)
See also
updateMain update method with discrete spike detection logic.
- init_state(**kwargs)[source]#
Initialize all state variables for the neuron population.
Initializes membrane potential, gating variables, synaptic conductances, stimulation current buffer, refractory counter, and last spike time. If initial values are not explicitly provided, they are computed as follows:
V: defaults toE_Lm, h, n: computed from equilibrium at initialVusing Traub-Miles rate equations (without V_T offset, matching NEST initialization)g_ex, g_in: initialized to zeroI_stim: initialized to zerorefractory_step_count: initialized to zero (not refractory)last_spike_time: initialized to -1e7 ms (far in the past)
- Parameters:
**kwargs – Unused compatibility parameters accepted by the base-state API.
Notes
The equilibrium gating variable computation uses the raw voltage V (not V - V_T) to match NEST’s initialization procedure. During dynamics, the rate equations use the shifted voltage V - V_T, but initialization uses the unshifted value for consistency with NEST’s
State_::State_constructor.This initialization ensures the neuron starts in a stable resting state when V_m_init = E_L (default). For custom initial voltages, gating variables are automatically adjusted to the corresponding equilibrium.
Examples
>>> import brainstate as bst >>> import saiunit as u >>> from brainpy_state import hh_cond_exp_traub >>> >>> # Initialize with default rest state >>> neurons = hh_cond_exp_traub(100) >>> neurons.init_state() >>> print(neurons.V.value[0]) # Should be E_L = -60 mV -60.0 mV >>> >>> # Initialize with custom voltage >>> neurons = hh_cond_exp_traub(100, V_m_init=-65*u.mV) >>> neurons.init_state() >>> print(neurons.V.value[0]) -65.0 mV
- Raises:
ValueError – If an initializer cannot be broadcast to requested shape.
TypeError – If initializer outputs have incompatible units/dtypes for the corresponding state variables.
See also
_hh_cond_exp_traub_equilibriumComputes equilibrium gating values.
- update(x=Quantity(0., 'pA'))[source]#
Update neuron state for one simulation step.
Integrates the 6-dimensional ODE system for one time step using adaptive RKF45 solver, processes incoming synaptic inputs, detects spikes based on threshold crossing and local maximum, and updates refractory state.
The update follows the NEST
hh_cond_exp_traubupdate order:Record pre-integration membrane potential (
V_old).Integrate the full 6-dimensional ODE system over one time step using an adaptive RKF45 solver.
Add arriving synaptic conductance jumps to
g_ex/g_in.Check spike condition:
V_m >= V_T + 30 and V_old > V_m(threshold + local maximum).Update refractory counter and record spike time.
Store buffered stimulation current for the next step.
- Parameters:
x (
ArrayLike, default0 pA) – External stimulation current input (in addition toI_e), shape () or (*in_size,). This current is added to the constantI_eparameter and any registered current inputs viaadd_current_input().- Returns:
Spike output with shape (*in_size,). Values are computed using the surrogate spike function for differentiability. Spikes occur only when the discrete spike condition is satisfied (not refractory, threshold crossed, and local maximum detected).
- Return type:
ArrayLike
Notes
Integration Details:
Each neuron’s state is integrated using an adaptive RKF45 integrator implemented in JAX with unit-aware arithmetic. This matches NEST’s GSL RKF45 solver. The ODE system is:
\[\begin{split}\frac{d}{dt}\begin{bmatrix} V_m \\ m \\ h \\ n \\ g_{ex} \\ g_{in} \end{bmatrix} = \begin{bmatrix} (-I_{Na} - I_K - I_L - I_{syn,ex} - I_{syn,in} + I_{stim} + I_e) / C_m \\ \alpha_m - (\alpha_m + \beta_m) m \\ \alpha_h - (\alpha_h + \beta_h) h \\ \alpha_n - (\alpha_n + \beta_n) n \\ -g_{ex} / \tau_{syn,ex} \\ -g_{in} / \tau_{syn,in} \end{bmatrix}\end{split}\]Spike Detection Logic:
A spike is detected when all three conditions are met:
refractory_step_count == 0(not in refractory period)V_m >= V_T + 30(threshold crossing)V_old > V_m(local maximum - voltage falling)
No voltage reset occurs; repolarization is handled by intrinsic currents.
Synaptic Input Processing:
Delta inputs (spike events) are collected and split by sign:
Positive weights -> excitatory conductance (
g_ex += w)Negative weights -> inhibitory conductance (
g_in += |w|)
Conductance jumps are applied after ODE integration, matching NEST’s update sequence.
Computational Complexity
Integration is performed with an adaptive vectorized RKF45 loop, including in-loop spike detection and refractory handling. All arithmetic is unit-aware via
saiunit.math.Failure Modes
If the integrator detects numerical instability (
V < -1e3 mVorV > 1e3 mV), a runtime error is raised.Extreme parameter values (very large conductances, very small time constants) may cause numerical instability.
See also
init_stateInitialize state variables.
get_spikeCompute surrogate spike output.