_modules#
- ns_sdn.engine._internals._modules = <module 'ns_sdn.engine._internals._modules' from '/home/runner/work/ns-sdn/ns-sdn/src/ns_sdn/engine/_internals/_modules.py'>[source]#
latent transition, spectral emission heads, synthesis.
This is the only module in the package that defines
nn.Modulesubclasses. Everything it emits is a plain tensor; the predictor layer turns those into numpy and the result layer never sees torch.The network is the IEEE-ORSS configuration, equation by equation. A latent state \(h_t \in \mathbb{R}^d\) evolves under a GRU driven by the input row \(x_t = [y; x]\) (or a residual time-aware cell that also takes \(\Delta t_t\)),
\[h_t = F_\psi(h_{t-1}, x_t, \Delta t_t), \qquad h_0 \text{ learned};\]five linear heads read \(h_t\) into a trend, raw amplitudes, instantaneous frequencies, phase offsets and gates,
\[B_t = W_B h_t + b_B, \quad A_{t} = \operatorname{softplus}(W_A h_t + b_A) + \varepsilon_A, \quad \omega_{t} = \operatorname{softplus}(W_\omega h_t + b_\omega) + \varepsilon_\omega,\]\[\phi_{t} = W_\phi h_t + b_\phi, \qquad g_{t} = \sigma(W_g h_t + b_g);\]the phase integrates the frequency from a learned \(\theta_0\),
\[\theta_{t} = \theta_{t-1} + \omega_{t}\,\Delta t_t \quad\Longleftrightarrow\quad \theta_t = \theta_0 + \sum_{s \le t} \omega_s\,\Delta t_s;\]and the learned mixing vector \(w \in \mathbb{R}^K\) of the paper’s equation (4) combines the components,
\[\hat y_t = B_t + \sum_{k=1}^{K} w_k\, g_{t,k}\, A_{t,k}\, \sin\!\bigl(\theta_{t,k} + \phi_{t,k}\bigr).\]With \(K = 16\), \(d = 128\), a GRU and no covariates the network has 58,849 trainable parameters, the count of the published run. The per-component frequency anchor the paper’s text describes was a fixed zero buffer in that run and is the frequency head’s bias here.
Under teacher forcing the inputs are known in advance, so the GRU runs as one
nn.GRUcall over the sequence and the phase recursion is a cumulative sum; no Python loop over time. The recursive forecast must loop, because each input is the previous output.Example
>>> import torch >>> net = _SpectralNetwork( ... input_dim=1, state_dim=128, k=16, transition="gru", positive_frequency=True, ... ordered_frequency=False, gating=True, frequency_min=1e-3, frequency_max=3.14, ... ) >>> net.n_parameters 58849 >>> paths = net.forward_sequence(torch.zeros(10, 1), torch.ones(10)) >>> paths["yhat"].shape, paths["phase"].shape, paths["state"].shape (torch.Size([10]), torch.Size([10, 16]), torch.Size([10, 128]))
- Type:
The torch network