ac_generator#
- class brainpy.state.ac_generator(in_size=1, amplitude=Quantity(0., 'pA'), offset=Quantity(0., 'pA'), frequency=Quantity(0., 'Hz'), phase=0.0, start=Quantity(0., 'ms'), stop=None, origin=Quantity(0., 'ms'), name=None)#
AC current generator – NEST-compatible stimulation device.
Generate a sinusoidal current with a constant DC offset and gate the output with a half-open activity window using NEST-compatible parameter semantics.
1. Model equations
For each output channel, the emitted current is
\[\begin{split}I(t) = \begin{cases} I_0 + A\sin(\omega t + \phi) & \text{if } t_{\mathrm{start}} \le t < t_{\mathrm{stop}}, \\ 0 & \text{otherwise}, \end{cases}\end{split}\]where \(\omega = 2\pi f / 1000\) (rad/ms) when \(f\) is given in Hz and simulation time \(t\) is in ms, and
\[t_{\mathrm{start}} = t_0 + t_{\mathrm{start,rel}}, \qquad t_{\mathrm{stop}} = t_0 + t_{\mathrm{stop,rel}}.\]If
stop is None, then \(t_{\mathrm{stop}} = +\infty\).2. Rotation-matrix interpretation
The NEST reference implementation propagates the oscillator state with an exact rotation matrix (Rotter and Diesmann, 1999):
\[\begin{split}\begin{pmatrix} y_0^{n+1} \\ y_1^{n+1} \end{pmatrix} = \begin{pmatrix} \cos(\omega h) & -\sin(\omega h) \\ \sin(\omega h) & \cos(\omega h) \end{pmatrix} \begin{pmatrix} y_0^n \\ y_1^n \end{pmatrix},\end{split}\]with initial state \(y_0(0) = A\cos\phi\), \(y_1(0) = A\sin\phi\) and output \(I(t) = y_1(t) + I_0\). This implementation instead evaluates the equivalent closed-form expression \(A\sin(\omega t + \phi)\) directly via
jax.numpy.sin(), which is numerically identical but stateless.3. Timing semantics and computational implications
The active interval is the half-open set \([t_{\mathrm{start}},\, t_{\mathrm{stop}})\). Since neuron states are advanced from
ttot + dtin each step, a current enabled at \(t_{\mathrm{start}}\) first affects the membrane trajectory after that update (observable at \(t_{\mathrm{start}} + dt\)); the last active update starts at \(t_{\mathrm{stop}} - dt\). Because the phase is tied to absolute simulation timet, windowing bystart/stopdoes not reset the oscillator phase. Per-call complexity is \(O(\prod \mathrm{varshape})\), dominated by one sine evaluation and one conditional mask.- Parameters:
in_size (
Size, optional) – Output size/shape specification understood bybrainstate.nn.Dynamics. The emitted current shape isself.varshapederived fromin_size. Default is1.amplitude (
ArrayLike, optional) – Sinusoidal amplitude \(A\) (typically pA). Scalars or arrays are accepted and broadcast toself.varshapeviabraintools.init.param(). Default is0. * u.pA.offset (
ArrayLike, optional) – Constant DC offset \(I_0\) added to the sinusoid (typically pA), broadcast toself.varshape. Default is0. * u.pA.frequency (
ArrayLike, optional) – Oscillation frequency \(f\) in Hz (or a unitless numeric interpreted as Hz). Converted internally to \(\omega = 2\pi f / 1000\) (rad/ms). Broadcast toself.varshape. Default is0. * u.Hz.phase (
ArrayLike, optional) – Initial phase \(\phi_{\mathrm{deg}}\) in degrees (NEST convention). Converted internally as \(\phi = \phi_{\mathrm{deg}} \cdot 2\pi / 360\). Stored as a dimensionless scalar or array broadcast toself.varshape. Default is0..start (
ArrayLike, optional) – Relative activation time \(t_{\mathrm{start,rel}}\) (typically ms), broadcast toself.varshape. Effective start isorigin + start. Default is0. * u.ms.stop (
ArrayLikeorNone, optional) – Relative deactivation time \(t_{\mathrm{stop,rel}}\) (typically ms), broadcast toself.varshapewhen provided. Effective stop isorigin + stopand the upper bound is exclusive.Nonemeans the sinusoid is never deactivated. Default isNone.origin (
ArrayLike, optional) – Global time origin \(t_0\) (typically ms) added to bothstartandstop, broadcast toself.varshape. Default is0. * u.ms.name (
strorNone, optional) – Optional node name passed tobrainstate.nn.Dynamics.
Parameter Mapping
Table 24 Parameter mapping to model symbols# Parameter
Default
Math symbol
Semantics
amplitude0. * u.pA\(A\)
Peak sinusoidal excursion in current units (typically pA).
offset0. * u.pA\(I_0\)
Constant baseline current added to the sinusoid.
frequency0. * u.Hz\(f\)
Frequency in Hz; converted to \(\omega = 2\pi f/1000\) rad/ms.
phase0.\(\phi_{\mathrm{deg}}\)
Input phase in degrees; converted to radians each update step.
start0. * u.ms\(t_{\mathrm{start,rel}}\)
Relative start time; effective lower bound is
origin + start.stopNone\(t_{\mathrm{stop,rel}}\)
Relative stop time; effective upper bound is
origin + stop.origin0. * u.ms\(t_0\)
Global offset applied to both window boundaries.
- Raises:
ValueError – If
in_sizeis invalid or any parameter cannot be broadcast toself.varshapebybraintools.init.param().TypeError – If unitful/unitless arithmetic is invalid during parameter initialization (e.g., incompatible units in
amplitudeoroffset).
See also
dc_generatorConstant current stimulation device.
step_current_generatorPiecewise-constant current stimulation.
noise_generatorGaussian white-noise current stimulation.
References
Examples
>>> import brainpy >>> import brainstate >>> import saiunit as u >>> with brainstate.environ.context(dt=0.1 * u.ms): ... stim = brainpy.state.ac_generator( ... in_size=1, ... amplitude=500.0 * u.pA, ... offset=100.0 * u.pA, ... frequency=100.0 * u.Hz, ... phase=30.0, ... start=5.0 * u.ms, ... stop=50.0 * u.ms, ... ) ... with brainstate.environ.context(t=10.0 * u.ms): ... current = stim.update() ... _ = current.shape
>>> import brainpy >>> import saiunit as u >>> ac1 = brainpy.state.ac_generator( ... amplitude=200.0 * u.pA, ... offset=50.0 * u.pA, ... frequency=40.0 * u.Hz, ... phase=0.0, ... ) >>> ac2 = brainpy.state.ac_generator( ... amplitude=100.0 * u.pA, ... offset=0.0 * u.pA, ... frequency=80.0 * u.Hz, ... phase=90.0, ... start=10.0 * u.ms, ... stop=60.0 * u.ms, ... )
- update()[source]#
Compute the window-gated sinusoidal current at environment time
t.- Returns:
current – Current-like quantity with shape
self.varshape. For channels whereorigin + start <= t < origin + stop(ort >= origin + startwhenstop is None), values equal \(I_0 + A\sin(\omega t + \phi)\) where \(\omega = 2\pi f / 1000\) (rad/ms) and \(\phi = \phi_{\mathrm{deg}} \cdot 2\pi / 360\) (rad). Inactive channels are exactly zero.- Return type:
jax.Array- Raises:
Notes
Frequency and phase conversions are performed per call:
\[\omega = \frac{2\pi f}{1000} \, (\text{rad/ms}), \qquad \phi = \frac{\phi_{\mathrm{deg}} \cdot 2\pi}{360} \, (\text{rad}).\]The waveform depends only on absolute
t; the oscillator carries no internal state. Entering and leaving the activity window therefore does not reset or shift the phase. Start is inclusive and stop is exclusive, matching NEST semantics. Ifstop <= start(after addingorigin), the active set is empty and the output is always zero.See also
ac_generatorClass-level parameter definitions and model equations.
dc_generator.updateWindowed constant-current update rule.