policies
eigenkit.reservoir.policies
Reservoir policies — how each timestep maps the carried state and the
current input to the circuit's (initial_state, gate_inputs).
Two execution shapes, because they are genuinely different computations:
- Sequential (a fold over time). The quantum state is the memory: \(\psi_t\)
depends on \(\psi_{t-1}\), so timesteps must run in order. These policies implement
initial/inject/advance(Carry,LeakyCarry). - Parallel (a map over time). The quantum state carries nothing between steps — each
step's input is a pure function of the raw input sequence (e.g. a sliding window).
These policies expose
expand_inputs(sequences)and the driver runs allB·Tevaluations in one batched sweep instead of a Python timestep loop (Stateless).
The driver prefers expand_inputs when a policy has it (idiomatic optional
method, like the backends' statevector / probabilities).
Carry
dataclass
Policy that applies the circuit to the carried state: ψ_t = U(x_t) ψ_{t-1}.
The quantum state is the memory of the reservoir, and the first step starts
from |0…0⟩. This policy is equivalent to LeakyCarry(alpha=1.0).
advance(x_t, evolved, state)
Build the state for the next timestep from the result of this step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x_t
|
ndarray
|
The input of this timestep, of shape |
required |
evolved
|
ndarray
|
The statevector that the circuit produced. |
required |
state
|
ReservoirState
|
The state that went into this step. |
required |
Returns:
| Type | Description |
|---|---|
ReservoirState
|
The state for the next timestep. |
initial(batch)
Return the state carried into the first timestep.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
batch
|
int
|
The number of sequences that run in parallel. |
required |
Returns:
| Type | Description |
|---|---|
ReservoirState
|
The initial |
inject(x_t, state)
Turn the input of this timestep into the arguments of the circuit call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x_t
|
ndarray
|
The input of this timestep, of shape |
required |
state
|
ReservoirState
|
The state carried over from the previous step. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
initial_state |
ndarray | None
|
The state to evaluate the circuit from, or |
gate_inputs |
ndarray
|
The values to pass to the gates of the circuit. |
LeakyCarry
dataclass
Policy that mixes the carried state with a reset state and renormalises it.
It approximates a leaky, dissipative reservoir with pure states:
ψ_t = normalise(α U(x_t) ψ_{t-1} + (1 − α) reset).
reset defaults to |0…0⟩ and should be a normalised statevector; this is not
checked. With alpha=1, the policy is exactly
Carry. This is not a true dissipative
channel, which would need density matrices that the pure-state backends do not
provide. It is an approximation that uses pure states only.
Attributes:
| Name | Type | Description |
|---|---|---|
alpha |
float
|
The mixing weight of the carried state, in |
reset |
ndarray | None
|
The state that is mixed in, a normalised statevector. |
advance(x_t, evolved, state)
Build the state for the next timestep from the result of this step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x_t
|
ndarray
|
The input of this timestep, of shape |
required |
evolved
|
ndarray
|
The statevector that the circuit produced. |
required |
state
|
ReservoirState
|
The state that went into this step. |
required |
Returns:
| Type | Description |
|---|---|
ReservoirState
|
The state for the next timestep. |
initial(batch)
Return the state carried into the first timestep.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
batch
|
int
|
The number of sequences that run in parallel. |
required |
Returns:
| Type | Description |
|---|---|
ReservoirState
|
The initial |
inject(x_t, state)
Turn the input of this timestep into the arguments of the circuit call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x_t
|
ndarray
|
The input of this timestep, of shape |
required |
state
|
ReservoirState
|
The state carried over from the previous step. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
initial_state |
ndarray | None
|
The state to evaluate the circuit from, or |
gate_inputs |
ndarray
|
The values to pass to the gates of the circuit. |
ReservoirPolicy
Bases: Protocol
A reservoir policy that carries state from one timestep to the next.
Parallel policies, which carry no state, do not implement this protocol. They
provide expand_inputs(sequences), which returns the inputs of every timestep
with shape (B, T, n_inputs), and the driver evaluates all timesteps at once.
See Stateless.
advance(x_t, evolved, state)
Build the state for the next timestep from the result of this step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x_t
|
ndarray
|
The input of this timestep, of shape |
required |
evolved
|
ndarray
|
The statevector that the circuit produced. |
required |
state
|
ReservoirState
|
The state that went into this step. |
required |
Returns:
| Type | Description |
|---|---|
ReservoirState
|
The state for the next timestep. |
initial(batch)
Return the state carried into the first timestep.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
batch
|
int
|
The number of sequences that run in parallel. |
required |
Returns:
| Type | Description |
|---|---|
ReservoirState
|
The initial |
inject(x_t, state)
Turn the input of this timestep into the arguments of the circuit call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x_t
|
ndarray
|
The input of this timestep, of shape |
required |
state
|
ReservoirState
|
The state carried over from the previous step. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
initial_state |
ndarray | None
|
The state to evaluate the circuit from, or |
gate_inputs |
ndarray
|
The values to pass to the gates of the circuit. |
ReservoirState
dataclass
The state that sequential policies carry from one timestep to the next.
vector is the (B, 2**n) statevector to inject at the next step, and None
means that the step starts from |0…0⟩. history holds the recent raw inputs,
of shape (B, k, F), for a sequential policy that encodes a window of inputs.
Attributes:
| Name | Type | Description |
|---|---|---|
vector |
ndarray | None
|
The statevector to inject at the next step, of shape |
history |
ndarray | None
|
The last |
Stateless
dataclass
Parallel policy that carries no state.
Every step starts from |0…0⟩, and the last window inputs are encoded as
rotation angles of the circuit's gates. The memory is purely classical (the
window), and the quantum state carries nothing from one step to the next.
Every timestep is therefore independent, and the driver evaluates all of them
in one batched run. With window=1, the policy has no memory: it encodes only
the current input.
The circuit's n_inputs must equal window * F, where F is the number of
features per step, because each step passes the whole flattened window to the
encoding gates.
Attributes:
| Name | Type | Description |
|---|---|---|
window |
int
|
The number of consecutive inputs to encode at each step. |
expand_inputs(sequences)
Return the gate inputs of every timestep, with shape (B, T, window * F).
Step t encodes the inputs t - window + 1 to t. The first window - 1
steps are padded with zeros at the front. No quantum state is involved, so this
is only a reshaping of the input sequence.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sequences
|
ndarray
|
The whole input batch, of shape |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
The gate inputs for every timestep, of shape |