reservoirpy.nodes.NVAR#
- class reservoirpy.nodes.NVAR( )[source]#
Non-linear Vector AutoRegressive machine.
NVAR is implemented as described in [1].
The state \(\mathbb{O}_{total}\) of the NVAR first contains a series of linear features \(\mathbb{O}_{lin}\) made of input data concatenated with delayed inputs:
\[\mathbb{O}_{lin}[t] = \mathbf{X}[t] \oplus \mathbf{X}[t - s] \oplus \mathbf{X}[t - 2s] \oplus \dots \oplus \mathbf{X}[t - (k-1)s]\]where \(\mathbf{X}[t]\) are the inputs at time \(t\), \(k\) is the delay and \(s\) is the strides (only one input every \(s\) inputs within the delayed inputs is used). The operator \(\oplus\) denotes the concatenation.
In addition to these linear features, nonlinear representations \(\mathbb{O}_{nonlin}^n\) of the inputs are constructed using all unique monomials of order \(n\) of these inputs:
\[\mathbb{O}_{nonlin}^n[t] = \mathbb{O}_{lin}[t] \otimes \mathbb{O}_{lin}[t] \overbrace{\otimes \dots \otimes}^{n-1~\mathrm{times}} \mathbb{O}_{lin}[t]\]where \(\otimes\) is the operator denoting an outer product followed by the selection of all unique monomials generated by this outer product.
Note
Under the hood, this product is computed by finding all unique combinations of input features and multiplying each combination of terms.
Finally, all representations are gathered to form the final feature vector \(\mathbb{O}_{total}\):
\[\mathbb{O}_{total} = \mathbb{O}_{lin}[t] \oplus \mathbb{O}_{nonlin}^n[t]\]- Parameters:
References
Example
>>> import numpy as np >>> from reservoirpy.nodes import NVAR, Ridge >>> nvar = NVAR(delay=2, order=2, strides=1) >>> readout = Ridge(ridge=2.5e-6, output_dim=3) >>> model = nvar >> readout
Using the
lorenz()timeseries and learning to predict the next difference:>>> from reservoirpy.datasets import lorenz >>> X = lorenz(5400, x0=[17.677, 12.931, 43.914], h=0.025, method="RK23") >>> Xi = X[:600] >>> dXi = X[1:601] - X[:600] # difference u[t+1] - u[t] >>> Y_test = X[600:] # testing data >>> _ = model.fit(Xi, dXi, warmup=200)
We can now predict the differences and integrate these predictions:
>>> u = X[600] >>> res = np.zeros((5400-600, readout.output_dim)) >>> for i in range(5400-600): ... u = u + model(u) ... res[i, :] = u ...
Methods
__init__(delay, order[, strides, input_dim, ...])initialize(x)Define input and output dimensions, and instantiate variables.
predict([x, iters, workers])Alias for
run()reset()Reset all Node state
run([x, iters, workers])Run the Node on a sequence of data.
step([x])Call the Node function on a single step of data and update the state of the Node.
Attributes
Expected dimension of the Node input.
Optional name of the Node.
Expected dimension of the Node input.
Time window over the inputs (of shape (delay * strides, features)).
Maximum delay of inputs (\(k\)).
Order of the non-linear monomials (\(n\)).
Strides between delayed inputs, by default 1 (\(s\)).
True if the Node has been initialized
Current state of the Node.
- initialize(x: Array2D | Array3D | Sequence[Timeseries] | Array1D)[source]#
Define input and output dimensions, and instantiate variables.
Only called once, before fitting or running the node.
- Parameters:
x (array of shape (input_dim,) or (timestep, input_dim)) – Input data to the node.
y (None) – Training data to the node. As it is not a trainable node,
yis expected to beNone.
- predict(
- x: array(t, d) | array(s, t, d) | ~typing.Sequence[array(t, d)] | None = None,
- iters: int | None = None,
- workers=1,
Alias for
run()Run the Node on a sequence of data. Can update the state of the Node several times.
- Parameters:
x (array-like of shape ([n_inputs,] timesteps, input_dim) or list of) – arrays of shape (timesteps, input_dim), optional A sequence of data of shape (timesteps, features).
iters (int, optional) – If
xisNone, a dimensionless timeseries of lengthitersis used instead.
- Returns:
A sequence of output vectors.
- Return type:
array of shape ([n_inputs,] timesteps, output_dim) or list of arrays
- reset() dict[str, ndarray][source]#
Reset all Node state
- Returns:
dict[str, np.array]
- Return type:
previous state of the Node.
- run(
- x: array(t, d) | array(s, t, d) | ~typing.Sequence[array(t, d)] | None = None,
- iters: int | None = None,
- workers=1,
Run the Node on a sequence of data. Can update the state of the Node several times.
- Parameters:
x (array-like of shape ([n_inputs,] timesteps, input_dim) or list of arrays of shape (timesteps, input_dim), optional) – A timeseries, array of shape (timesteps, features), or a sequence of timeseries. Input of the Node.
iters (int, optional) – If
xisNone, a dimensionless timeseries of lengthitersis used instead.workers (int, default to 1) – Number of workers used for parallelization. If set to -1, all available workers (threads or processes) are used.
- Returns:
A sequence of output vectors.
- Return type:
array of shape ([n_inputs,] timesteps, output_dim) or list of arrays
- step(x: array(d) | None = None)[source]#
Call the Node function on a single step of data and update the state of the Node.
- Parameters:
x (array of shape (input_dim,), optional) – One single step of input data. If None, an empty array is used instead and the Node is assumed to have an input_dim of 0
- Returns:
An output vector.
- Return type:
array of shape (output_dim,)