StateWithDelay#

class brainstate.nn.StateWithDelay(target, item, init=None, interpolation='round', **kwargs)#

Delayed history buffer bound to a module state.

StateWithDelay is a specialized Delay that attaches to a concrete State living on a target module (for example a membrane potential V on a neuron). It automatically maintains a rolling history of that state and exposes convenient helpers to retrieve the value at a given delay either by step or by time.

In normal usage you rarely instantiate this class directly. It is created implicitly when using the prefetch-delay helpers on a Dynamics module, e.g.:

  • module.prefetch('V').delay.at(5.0 * u.ms)

  • module.prefetch_delay('V', 5.0 * u.ms)

Both will construct a StateWithDelay bound to module.V under the hood and register the requested delay, so you can retrieve the delayed value inside your update rules.

Parameters:
  • target (Node) – The module object that owns the state to track.

  • item (str) – The attribute name of the target state on target (must be a State).

  • init (Callable) – Optional initializer used to fill the history buffer before t0 when delays request values from the past that hasn’t been simulated yet. The callable receives (shape, dtype) and must return an array. If not provided, zeros are used. You may also pass a scalar/array literal via the underlying Delay API when constructing manually.

  • interpolation (str | None) – Interpolation method for continuous-time delay retrieval. Built-in methods: ‘nearest’, ‘linear’, ‘cubic’, ‘hermite’, ‘polynomial2’, ‘polynomial3’. Can also be a custom callable following the InterpolationMethod protocol.

state#

The concrete state object being tracked.

Type:

State

history#

Rolling time axis buffer with shape [length, *state.shape].

Type:

DelayState

max_time#

Maximum time span currently supported by the buffer.

Type:

float

max_length#

Buffer length in steps (ceil(max_time/dt)+1).

Type:

int

Notes

  • This class inherits all retrieval utilities from Delay: use retrieve_at_step() when you know the integer delay steps, or retrieve_at_time() for continuous-time queries with optional linear/round interpolation.

  • It is registered as an “after-update” hook on the owning Dynamics so the buffer is updated automatically after each simulation step.

Examples

Access a neuron’s membrane potential 5 ms in the past:

>>> import brainunit as u
>>> import brainstate
>>> import brainpy
>>> lif = brainpy.state.LIF(100)
>>> # Create a delayed accessor to V(t-5ms)
>>> v_delay = lif.prefetch_delay('V', 5.0 * u.ms)
>>> # Inside another module's update you can read the delayed value
>>> v_t_minus_5ms = v_delay()

Register multiple delay taps and index-specific delays:

>>> # Under the hood, a StateWithDelay is created and you can register
>>> # additional taps (in steps or time) via its Delay interface
>>> _ = lif.prefetch('V').delay.at(2.0 * u.ms)   # additional delay
>>> # Direct access to buffer by steps (advanced)
>>> # lif.get_after_update('V-prefetch-delay').retrieve_at_step(3)
init_state(*args, **kwargs)[source]#

State initialization function.

update(*args)[source]#

Update the delay variable with the new data.

Return type:

None