Developer Interfaces
These interfaces describe implementation contracts used to maintain and extend ReservoirComputing.jl. They are versioned and tested, but they are not ordinary end-user model constructors. Prefer the documented concrete models, cells, and ReservoirComputer composition API unless you are implementing a new reservoir family.
Reservoir Containers
ReservoirComputing.AbstractReservoirComputer — Type
AbstractReservoirComputer{Fields} <: AbstractLuxContainerLayer{Fields}Developer interface for a Lux-compatible reservoir-computing container.
Type parameters
Fields: theTupleof container field names reported to Lux. Reservoir containers use(:reservoir, :state_modifiers, :readout).
Required fields
Subtypes using the generic ReservoirComputing implementation must provide:
reservoir: a Lux-compatible layer that produces reservoir features.state_modifiers: aTupleof Lux-compatible layers applied in order to those features. Use()when no modifiers are required.readout: a Lux-compatible layer that maps features to model outputs.
Extension contract
Implement the fields above and the ordinary Lux layer call contract. The generic LuxCore.initialparameters, LuxCore.initialstates, function-call, and collectstates methods then compose the three components. Each component must accept its matching parameter and state entry and return (output, updated_state) through LuxCore.apply.
Ordinary state_modifiers receive the current feature array. An Extend modifier additionally receives the input to the model, or the input to the current layer of a deep model, and prepends that input to the wrapped modifier's output. High-level model constructors account for this extra width automatically when the operation wrapped by Extend preserves the feature width. Pass readout_in_dims when a custom modifier changes the feature width in another way. Parameter and state containers returned by the Lux generic functions have the named fields reservoir, state_modifiers, and readout in that order.
Example
struct MyReservoirComputer <: AbstractReservoirComputer{
(:reservoir, :state_modifiers, :readout)}
reservoir
state_modifiers
readout
endUse ReservoirComputer unless a new model type needs its own construction or presentation API.
ReservoirComputing.AbstractEchoStateNetwork — Type
AbstractEchoStateNetwork{Fields} <: AbstractReservoirComputer{Fields}Developer interface for an echo-state-network model container.
Type parameters
Fields: the Lux container field tuple. Most ESN models use(:reservoir, :state_modifiers, :readout).
Required fields
Subtypes follow the AbstractReservoirComputer field contract. Their reservoir must be a Lux-compatible reservoir layer, normally a StatefulLayer around an AbstractEchoStateNetworkCell. state_modifiers is a tuple of feature transforms and readout is the final Lux-compatible mapping.
Extension contract
This type adds ESN semantics to the generic reservoir-container contract; it does not introduce a separate dispatch hook. Subtypes inherit the generic LuxCore.initialparameters, LuxCore.initialstates, function-call, and collectstates behavior when their fields obey the container invariants. The reservoir must produce a consistent feature shape at every time step, and the readout must consume that shape after all modifiers.
Example
struct MyESN <: AbstractEchoStateNetwork{(:reservoir, :state_modifiers, :readout)}
reservoir
state_modifiers
readout
endRecurrent Cells
ReservoirComputing.AbstractReservoirRecurrentCell — Type
AbstractReservoirRecurrentCell <: AbstractLuxLayerDeveloper interface for a recurrent reservoir cell used by StatefulLayer.
Extension contract
Subtypes implement the Lux initialization functions and both recurrent call forms below:
cell(x, ps, st) -> ((output, (carry,)), st_new)initializes a carry when none is supplied.cell((x, (carry,)), ps, st) -> ((output, (carry_new,)), st_new)advances an existing carry.
StatefulLayer invokes these through LuxCore.apply. The returned carry must have the shape and element type accepted by the second form on the next call; the output may equal the carry but need not do so. The parameter and state objects are owned by the subtype's LuxCore.initialparameters and LuxCore.initialstates implementations.
Example
struct MyCell <: AbstractReservoirRecurrentCell endReservoirComputing.AbstractEchoStateNetworkCell — Type
AbstractEchoStateNetworkCell <: AbstractReservoirRecurrentCellDeveloper interface for an echo-state-network recurrent cell with the shared ESN parameter and state initialization implementation.
Required fields
The generic methods require these fields:
in_dims: input feature dimension.out_dims: reservoir-state dimension.init_input(rng, out_dims, in_dims): input-matrix initializer.init_reservoir(rng, out_dims, out_dims): recurrent-matrix initializer.init_state(rng, out_dims, batch_size): initial hidden-state initializer.use_bias:Static.True()orStatic.False(). When true,init_bias(rng, out_dims)is also required.
Extension contract
Subtypes inherit LuxCore.initialparameters and LuxCore.initialstates from this interface. Those methods create input_matrix and reservoir_matrix, an optional bias, and a replicated RNG state. Implement the recurrent call form from AbstractReservoirRecurrentCell: given (x, (carry,)), return ((output, (next_carry,)), st_new). The generic one-input method initializes a hidden state with init_state and delegates to that form.
input_matrix must have shape (out_dims, in_dims), reservoir_matrix must have shape (out_dims, out_dims), and every carry must be compatible with the chosen out_dims and batch dimension.
Example
struct MyESNCell <: AbstractEchoStateNetworkCell
in_dims
out_dims
init_input
init_reservoir
init_bias
init_state
use_bias
endReservoirComputing.AbstractReservoirCollectionLayer — Type
AbstractReservoirCollectionLayer <: AbstractLuxLayerDeveloper marker interface for a layer whose output is recorded by collectstates.
Extension contract
Subtypes implement the ordinary Lux layer contract through LuxCore.initialparameters, LuxCore.initialstates, and a call returning (output, updated_state). When a reservoir chain is collected, the output of each such layer is included in the feature vector. It must therefore be a vector or array that can be copied and concatenated with vcat with other collection-layer outputs at the same time step.
Do not use this marker for an ordinary transform merely because it is located before a readout: it changes the training features. A collection layer should preserve stable feature dimensions across all time steps.
Example
struct MyCollect <: AbstractReservoirCollectionLayer end
(layer::MyCollect)(x, ps, st) = (x, st)ReservoirComputing.AbstractReservoirTrainableLayer — Type
AbstractReservoirTrainableLayer <: AbstractLuxLayerDeveloper marker interface for the first trainable/readout layer in a reservoir chain.
Extension contract
Subtypes implement the usual Lux initialization and call contracts. During collectstates, this marker stops the reservoir-feature traversal: the marked layer and subsequent layers are not executed while generating training features. Mark only a layer that consumes the collected features, and ensure its input dimension matches the stable feature dimension produced before it.
Example
struct MyReadout <: AbstractReservoirTrainableLayer end
(layer::MyReadout)(x, ps, st) = (x, st)Continuous and Cellular Automata Reservoirs
ReservoirComputing.AbstractSciMLProblemReservoir — Type
AbstractSciMLProblemReservoir <: AbstractLuxLayerDeveloper interface for a Lux layer whose dynamics are defined by an AbstractSciMLProblem (typically ODEProblem, SDEProblem, or DDEProblem).
Required fields
Concrete subtypes used with the built-in continuous-reservoir extension should provide:
prob: the SciML problem template;sampler: anAbstractSampler;tspan: the integration interval used for each input sequence;args: positional solver arguments; andkwargs: keyword solver arguments that do not conflict with the sampling machinery.
Extension contract
Implement LuxCore.initialparameters and LuxCore.initialstates for any additional layer parameters or state. The continuous-reservoir extension then dispatches the following developer hooks:
__collectstates(res, rc, data, ps, st) -> (states, st′), wherestatesis an(state_dimension, n_samples)matrix;__predict(res, rc, data, ps, st) -> (outputs, st′)for teacher-forced prediction; and__predict(res, rc, steps, ps, st; initialdata) -> (outputs, st′)for autoregressive prediction.
The hooks must preserve the parameter/state layout expected by the enclosing AbstractReservoirComputer. Subtyping this type without implementing the hooks only provides the default empty Lux parameter/state containers; it does not make a new reservoir solvable.
Example
struct MyContinuousReservoir <: AbstractSciMLProblemReservoir
prob
sampler
tspan
args
kwargs
endThe continuous-time __collectstates implementation lives in the RCODEReservoirExt package extension and requires SciMLBase and DataInterpolations to be loaded. Pick any concrete solver package separately (e.g. OrdinaryDiffEqTsit5, OrdinaryDiffEq) — its solver types are what SciMLProblemReservoir's args[1] consumes.
ReservoirComputing.AbstractSampler — Type
AbstractSamplerDeveloper interface for a sampler that extracts a discrete state matrix from a continuous-time reservoir trajectory.
Fields
The marker itself requires no fields. A sampler may carry configuration such as a window statistic or a within-window sampling rule.
Extension contract
The continuous-reservoir extension calls __sample(sampler, sol) after solving with one saved endpoint per input column. A concrete method must return an AbstractMatrix with one column per saved sample and a stable row dimension for the readout. It may inspect the SciML solution object, but it must not change the solution or the input data.
Subtyping AbstractSampler alone is not enough: the matching __sample method must be defined in the extension that owns the continuous-reservoir implementation. This is a developer hook; ordinary users should use TerminalStateSampling.
Example
struct WindowMean <: AbstractSampler
width::Int
end
# Define `__sample(::WindowMean, sol)` in the continuous-reservoir extension.ReservoirComputing.AbstractInputEncoding — Type
AbstractInputEncodingDeveloper marker interface for a cellular-automata input-encoding specification.
Extension contract
This package currently provides no generic public function that consumes every AbstractInputEncoding subtype. An external encoding is therefore usable only with a concrete cellular-automata integration that documents how it consumes that type. Do not assume that merely subtyping this interface makes a value accepted by RECACell or RECA; those constructors presently use the concrete RandomMapping / RandomMaps workflow.
Use this marker to communicate an encoding specification in an extension API, and document the fields and conversion operation required by that extension.
Example
struct MyEncoding <: AbstractInputEncoding
width::Int
endReservoirComputing.AbstractEncodingData — Type
AbstractEncodingDataDeveloper marker interface for precomputed cellular-automata encoding data.
Extension contract
This package currently has no public generic operation over all AbstractEncodingData subtypes. A concrete cellular-automata layer must state the fields it reads and implement its own conversion from an AbstractInputEncoding. In particular, RECACell currently requires RandomMaps, so arbitrary subtypes are not interchangeable with it.
Use this marker only when defining a paired extension interface and document the feature size, lattice size, and mapping invariants required by that extension.
Example
struct MyEncodingData <: AbstractEncodingData
states_size::Int
endSpiking Reservoirs
ReservoirComputing.AbstractSpikingNeuron — Type
AbstractSpikingNeuronDeveloper marker for a neuron model used by the spiking reservoir interface.
Fields
The marker itself requires no fields. A concrete neuron type must document the state variables, parameter fields, and differential equations that its extension uses.
Extension contract
The current LSM implementation accepts only LIFNeuron. Subtyping AbstractSpikingNeuron does not by itself make a neuron valid for LSMCell: an extension must add the solver right-hand side, event handling, and feature extraction methods for the new neuron. Those hooks are developer APIs, not generic end-user dispatches.
Example
struct MyNeuron <: AbstractSpikingNeuron
tau_m::Float64
endThe example is only a type declaration; it is not accepted by LSMCell until the corresponding extension contract is implemented.
ReservoirComputing.AbstractInputEncoder — Type
AbstractInputEncoderDeveloper marker for an input-to-spike encoding used by LSMCell.
Fields
The marker itself requires no fields. A concrete encoder owns the parameters needed to turn an input vector into the external current or event process consumed by the neuron model.
Extension contract
The current implementation accepts CurrentInjection and PoissonRateEncoder only. A custom subtype must be integrated by an extension that defines its encoder state initialization, input/event generation, and solver callback behavior. Subtyping this marker alone does not make the encoder accepted by LSMCell.
Example
struct MyEncoder <: AbstractInputEncoder
scale::Float64
endReservoirComputing.AbstractSpikeFeature — Type
AbstractSpikeFeatureDeveloper marker for a feature map that converts a spiking trajectory into reservoir features for LSMCell.
Fields
The marker itself requires no fields. A concrete feature map should document its state, output feature dimension, and how each sample window is computed.
Extension contract
The current implementation accepts SpikeCountFeatures, ExponentialSpikeFilter, and MembraneVoltageFeature. A custom feature map must provide extension methods for its feature dimension, autoregressive support, and sampled feature calculation. The extension passes the spike times and unit indices together with the requested sample times; the implementation must return one feature column per sample time. Subtyping this marker alone does not add a feature map to LSMCell.
Example
struct MySpikeFeature <: AbstractSpikeFeature
window::Float64
endTraining
ReservoirComputing.AbstractReservoirComputingSolver — Type
AbstractReservoirComputingSolverDeveloper marker for the package's legacy reservoir-training solver family.
Extension contract
QRSolver is the only built-in subtype. The public train API also accepts LinearSolve.jl algorithms directly. There is currently no public generic extension point for arbitrary AbstractReservoirComputingSolver subtypes: a new subtype is rejected by ridge training unless ReservoirComputing adds a corresponding implementation itself.
For a custom solver, implement the documented LinearSolve.jl algorithm interface and pass that algorithm to train(...; solver=...). Do not extend private training helpers from another package.
Example
weights = train(RidgeRegression(1.0e-3), states, targets;
solver = QRFactorization())Initializer Output Extensions
ReservoirComputing.return_init_as — Function
return_init_as(::Val{return_sparse}, initializer_output)Convert an initializer output according to its return_sparse request.
This dispatch hook is for ReservoirComputing extension authors. End users should request sparse output through an initializer's return_sparse keyword rather than calling this function directly.
Arguments
return_sparse:Val(false)for the built-in dense path orVal(true)for an extension-provided sparse representation.initializer_output: an initializer result to return or convert.
Extension contract
An extension that provides a sparse representation must define ReservoirComputing.return_init_as(::Val{true}, output) for the output types it supports. The method must return a representation with the same shape and values. The built-in Val(false) method returns its input unchanged.
Example
ReservoirComputing.return_init_as(Val(false), ones(2, 2)) == ones(2, 2)