NSSDN#

class ns_sdn.spectral_decomposition.NSSDN(endog, *, exog=None, time=None, k=16, state_dim=128, alignment='filtered', transition='gru', positive_frequency=True, ordered_frequency=False, gating=True, objective='mse', delta=_HUBER_DELTA, penalties=None, schedule=None, scaling='minmax', seed=None, device='cpu')[source]#

Non-Stationary Spectral Decomposition Network specification.

The immutable statement of the model, validated at construction and estimated by fit(). The defaults are the configuration of the IEEE-ORSS DGS10 experiments: sixteen components, a 128-dimensional GRU state, positive frequencies, gating, the filtered alignment, mean squared error on a min-max scaled series, and the two-stage Adam schedule with amplitude and frequency drift penalties,

\[\mathcal{L} = \frac{1}{r}\sum_t \bigl(\hat y_t - y_t\bigr)^2 + \lambda_A\, \frac{1}{(r-1)K}\sum_{t,k} \bigl(g_{t,k}A_{t,k} - g_{t-1,k}A_{t-1,k}\bigr)^2 + \lambda_\omega\, \frac{1}{(r-1)K}\sum_{t,k} \bigl(\omega_{t,k} - \omega_{t-1,k}\bigr)^2,\]

evaluated on the scaled series, with \((\eta, \text{steps}, \lambda_A, \lambda_\omega)\) equal to \((10^{-3}, 1200, 2 \times 10^{-4}, 8 \times 10^{-4})\) in stage A and \((4 \times 10^{-4}, 1800, 3 \times 10^{-4}, 1.5 \times 10^{-3})\) in stage B. With no covariates that network has 58,849 trainable parameters, the count of the published run.

Parameters:
  • endog (ArrayLike) – The series, one-dimensional, at least three observations, finite throughout; a (n, 1) column is accepted.

  • exog (ArrayLike | None) – Optional (n, p) covariates known at each \(t\), used as given (no scaling) as extra columns of the transition input \(x_t\). A fit with covariates needs them again at forecast time.

  • time (ArrayLike | None) – Optional strictly increasing grid; defaults to \(0, 1, \ldots, n - 1\). Irregular spacing enters the phase recursion through \(\Delta t_t\) and, under the time-aware transition, the dynamics.

  • k (int) – Number of sinusoidal components \(K\), at least one.

  • state_dim (int) – Latent dimension \(d\), at least one.

  • alignment (str) – "filtered" (the published run: the emission at \(t\) conditions on \(y_t\)) or "predicted" (it conditions on \(y_{t-1}\), so the network trains as a one-step forecaster).

  • transition (str) – "gru" (a gated recurrent cell on \(x_t\)) or "timeaware" (the residual Euler update \(h_t = h_{t-1} + \Delta t_t\, g_\psi(h_{t-1}, x_t)\)).

  • positive_frequency (bool) – Softplus the frequency head so phase always advances; off, the head is linear and a component may run backwards.

  • ordered_frequency (bool) – Parameterize frequencies as cumulative positive gaps inside the Nyquist band \([\omega_{\min}, \pi / \operatorname{median}\Delta t]\), so \(\omega_{t,1} < \cdots < \omega_{t,K}\) at every \(t\) and the components are identified without permutation. Implies positivity. Off by default to reproduce the published run.

  • gating (bool) – Add the sigmoid gate head \(g_{t,k}\); off, every gate is one and amplitude equals amplitude_raw.

  • objective (str) – "mse" or "huber" for the prediction term.

  • delta (float) – Huber threshold on the scaled residual, strictly positive; unused under "mse".

  • penalties (Penalties | None) – Penalties for stages that carry none; the stage-A weights when None.

  • schedule (tuple[Stage, ...] | None) – Tuple of Stage; the published two stages when None.

  • scaling (str) – "minmax" (train on the series mapped to \([-1, 1]\), report on the original scale) or "none".

  • seed (int | None) – Initialization seed; None leaves the fit unreproducible. Seeding is scoped to construction and leaves torch’s global generator untouched.

  • device (str) – Torch device string, "cpu" by default.

Raises:
  • SpecificationError – If any option is outside its admissible set: an unknown alignment, transition, objective or scaling, a non-positive k, state_dim or delta, a malformed schedule or penalties record, a non-integer seed, or a time grid that is not strictly increasing.

  • DimensionError – If the data are mis-shaped or misaligned: a multi-dimensional series, fewer than three observations, or covariates or a grid whose length differs from the series.

  • NumericalError – If the data contain non-finite values, or (at fit()) training diverges.

Note

Training is one full-sequence gradient per step through the whole sample, so cost scales with \(n\) times the schedule length; the published run is 3,000 steps over 9,186 daily observations. Under the GRU transition the teacher-forced pass is a single recurrent call rather than a Python loop. The parameter count of a GRU network with input width \(u = 1 + p\) is

\[3\bigl(d(u + d) + 2d\bigr) + (d + 1)(1 + 4K) + 2K + d,\]

which is 58,849 at \(d = 128\), \(K = 16\), \(u = 1\); the ordered-frequency head adds \(d + 1\) and removing the gate removes \(K(d + 1)\).

See also

Example

>>> import numpy as np
>>> y = np.sin(0.3 * np.arange(200.0)) + 0.01 * np.arange(200.0)
>>> model = NSSDN(y, k=2, state_dim=8, schedule=(Stage(1e-2, 30),), seed=0)
>>> model.k, model.alignment, model.transition, len(model.schedule)
(2, 'filtered', 'gru', 1)
>>> NSSDN(y, transition="lstm")
Traceback (most recent call last):
    ...
ns_sdn.exceptions.SpecificationError: transition must be one of 'gru', 'timeaware'; ...

The published configuration is the default:

>>> published = NSSDN(y)
>>> published.k, published.state_dim, len(published.schedule), published.gating
(16, 128, 2, True)

Attributes#

alignment

"filtered" or "predicted".

device

The torch device string.

endog

The validated series, a (n,) float64 copy of what was given.

exog

The validated covariates as a (n, p) float64 copy, or None.

exog_dim

Number of covariate columns \(p\); zero without covariates.

gating

Whether the gate head is present.

k

Number of components \(K\).

nobs_total

Observations \(n\) in the sample, before the one-step shift to \(n - 1\).

objective

"mse" or "huber".

ordered_frequency

Whether frequencies are strictly increasing in \(k\) at every step.

penalties

Model-level penalty weights, used by stages that carry none of their own.

positive_frequency

Whether frequencies are constrained positive; ordering implies it.

scaling

"minmax" or "none".

schedule

The training stages, in order.

seed

The initialization seed, or None.

state_dim

Latent dimension \(d\).

time

The time grid, (n,) float64, strictly increasing.

transition

"gru" or "timeaware".

Methods#

fit()

Train the network on the sample and return the fitted result.