ns_sdn.spectral_decomposition#
The Non-Stationary Spectral Decomposition Network: specification and result.
The model is a neural state-space representation of a scalar series \(y_t\) as a trend plus \(K\) sinusoids whose amplitude, instantaneous frequency, phase offset and participation evolve with a latent state (IEEE-ORSS equations 1-5),
where \(x_t\) stacks the series input and any covariates and \(\Delta t_t = t_t - t_{t-1}\) is the step of the time grid. Every spectral quantity is read off \(h_t \in \mathbb{R}^d\) by one linear head followed by the link that gives it its range,
with \(\varepsilon_A, \varepsilon_\omega > 0\) small floors that keep
every component audible and every phase advancing, \(\sigma\) the
logistic function, and \(w \in \mathbb{R}^K\) the learned mixing
vector of the paper’s implementation note. Under ordered_frequency
the frequency head instead emits \(K + 1\) logits whose softmax gaps
are accumulated inside the Nyquist band, so
\(\omega_{t,1} < \cdots < \omega_{t,K}\) at every \(t\). The phase
integrates the frequency, so each component is a chirp whose frequency the
state can move; the sum of the \(K\) chirps and the trend is the
emission.
Held under the three-object discipline: NSSDN is the immutable,
validated specification; training belongs to the family base it
inherits; NSSDNResult is the frozen record the user handles.
The decomposition is the point of the model, so the result carries every
path the figures of the paper are drawn from – trend (Fig. 3),
amplitude (Fig. 4, the gated \(g_{t,k} A_{t,k}\)), frequency
(Fig. 5), gate (Fig. 6), phase, phase_offset, state, and
the per-component components whose sum with trend is the
emission (Fig. 1) – on the original scale by default and in training
units through decompose(scaled=True), with one-step fittedvalues
(Fig. 2) aligned with endog[1:] whatever the alignment.
Two alignments are available. "filtered", the default and the
published run, conditions the emission at \(t\) on \(y_t\): the
decomposition is a filtered reading of the observed series, the emission
reconstructs it, and the one-step forecast of \(y_{t+1}\) is the
emission at \(t\) (the paper’s holdout protocol). "predicted"
conditions the emission at \(t\) on \(y_{t-1}\), so every path is
a one-step-ahead prediction and the network trains as a forecaster. The
summary says which one a result is and what that means for its numbers.
Layout. NSSDN validates its arguments through _validators
against the typing aliases and inherits _fit_family
from _SpectralDecompositionModel in engine._internals._models,
which builds the _SpectralNetwork (_modules), runs the staged
trainer (_trainers) on the _criterion (_objectives), and packs
a _SpectralFit whose predictor is the trained network behind a
numpy interface (_predictors). NSSDNResult is assembled by
_from_fit and composes _SummaryMixin, _SeriesMixin and
_ComparisonMixin from _internals._mixins. The coordinates that
read the decomposition as a time-local spectral measure live in
spectral_state.
References
Sunder, N. & Leon, M. (2026). Non-Stationary Spectral Decomposition Network: Adaptive Spectral Emission Heads and Frequency Modulation. 2026 IEEE Opportunity Research Scholars Symposium (ORSS), Atlanta, GA, USA, pp. 1-5. https://doi.org/10.1109/ORSS71174.2026.11684282
Sunder, N. (2026). Non-Stationary Spectral Decomposition Network for Econometric Time Series Forecasting. The International FLAIRS Conference Proceedings, 39(1). https://doi.org/10.32473/flairs.39.1.141588
Huang, N. E. et al. (1998). The empirical mode decomposition and the Hilbert spectrum for nonlinear and non-stationary time series analysis. Proc. R. Soc. A, 454, 903-995.
Sitzmann, V. et al. (2020). Implicit neural representations with periodic activation functions. Advances in Neural Information Processing Systems, 33.
Durbin, J. & Koopman, S. J. (2012). Time Series Analysis by State Space Methods (2nd ed.). Oxford University Press.
Example
A chirp with a drifting amplitude and a linear trend, fitted with a short schedule; the paths have one row per observation under the default alignment, the one-step fit one fewer:
>>> import numpy as np
>>> t = np.arange(300.0)
>>> amplitude = 0.4 + 0.3 * (t > 150)
>>> phase = np.cumsum(0.15 + 0.0004 * t)
>>> noise = 0.02 * np.random.default_rng(0).standard_normal(300)
>>> y = 0.002 * t + amplitude * np.sin(phase) + noise
>>> res = NSSDN(y, k=3, state_dim=16, schedule=(Stage(1e-2, 150),), seed=0).fit()
>>> res.emission.shape, res.amplitude.shape, res.fittedvalues.shape, res.nobs
((300,), (300, 3), (299,), 299)
>>> bool(np.allclose(res.trend + res.components.sum(axis=1), res.emission, atol=1e-5))
True
>>> res.forecast(5).shape
(5,)
Classes#
Non-Stationary Spectral Decomposition Network specification. |
|
A fitted spectral decomposition network. |
|
Weights on the drift and sparsity penalties added to the prediction loss. |
|
One stage of the training schedule: a fresh Adam run at one learning rate. |