LTE formulation (physics-first)
This page describes the Feb2026 LTE pipeline as a sequence of physically meaningful transforms. The implementation is deliberately split so that configuration/bookkeeping and generic numeric primitives do not obscure the physics.
Notation
- Time is represented in years (floating) at the sampling points: $t_i$.
- Observed climate index: $d(t_i)$.
- Tidal constituent list: periods $P_k$ (days) with amplitude/phase $(A_k,\phi_k)$.
- Year length (days): $Y$.
- Forcing coordinate (“manifold”): $F(t)$.
Pipeline overview
1) Tidal synthesis → raw tide coordinate $T(t)$
2) Seasonal impulse comb → impulsed tide $I(t)$
3) Lagged accumulation (IIR-like) → forcing manifold $F(t)$
4) Bessel-like expansion of the forcing coordinate (nonlinear adjustment)
5) Regression fit to obtain LTE coefficients
6) LTE reconstruction $\hat d(t)$ and metrics (CC, dLOD reference)
1) Tidal input → raw tide coordinate
We synthesize a tide-like coordinate by summing constituents evaluated at the sample times.
A representative form is:
\[T(t) = \sum_k A_k \cos\big(2\pi f_k t + \phi_k\big) \; + \; \text{(optional integration/phase term)}\]with (dimensionless) frequency:
\[f_k = \frac{Y}{P_k}\]Code:
tide_sum_diff(...)inexperiments/Feb2026/lte_physics.py
2) Seasonal impulse comb → impulsed tide
A discrete seasonal impulse comb selects months (or sampling slots) where impulses fire.
Define the within-year sample index:
\[n(t) = \operatorname{AdaInt}\Big( (t - \lfloor t \rfloor)\,S \Big)\]where $S$ is samples-per-year (typically 12). The “comb position” is:
\[n_B = \operatorname{AdaInt}(|\Delta B|\,S)\]The impulse magnitude is:
\[\delta(t) = \begin{cases} \Delta A, & n(t)=n_B\\ \text{asym}, & n(t)= (n_B + S/2)\bmod 12\\ 0, & \text{otherwise} \end{cases}\]Then the impulsed tide is:
\[I(t) = T(t)\,\delta(t)\]Important parity note: Ada’s Integer(real) conversion is round-to-nearest, ties away from zero. Python’s int() truncates; using Ada-compatible rounding is required for the impulse month to land correctly.
Code:
impulse_delta(...),amplify(...)inlte_physics.py- Ada rounding helper:
ada_int(...)inexperiments/Feb2026/lte_primitives.py
3) Lagged accumulation → forcing manifold
We convert impulsed inputs into a lagged forcing coordinate via a causal/anti-causal pass that behaves like an IIR with a sign-dependent ramp term.
Forward pass (conceptually):
\[F_{i} = I_i + m\,F_{i-1} - \operatorname{sign}(F_{i-1})\,c\]Backward pass (conceptually):
\[F_{i-1} = -I_{i-1} + m\,F_i + \operatorname{sign}(F_i)\,c\]with memory $m\in[0,1]$ derived from parameters.
Code:
iir(...)inlte_physics.py
4) Bessel-like expansion (forcing coordinate adjustment)
A compact nonlinear expansion is applied to the forcing coordinate (this is “Bessel-like” in the sense of a truncated harmonic/nonlinear expansion in $x$):
\[F'(t) = x + e_s\sin(2\pi k x) + e_c\cos(2\pi k x) + e_{s2} e_s\sin(2\pi k_2 x) + e_{c2} e_c\cos(2\pi k_2 x)\]where $x=F(t)$ and $k,k_2$ come from the modulation periods list $M$.
Code:
bessel(...)inlte_physics.py
5) Regression fit (normal equations)
We fit coefficients by solving the normal equations:
\[(X^T X)\,c = X^T y\]where $y$ is the observed data and $X$ contains:
- constant term
- linear term in forcing $F$
- sin/cos terms $\sin(2\pi\omega_j F)$, $\cos(2\pi\omega_j F)$
- optional seasonal harmonics in time and secular trend/acceleration
Code:
regression_factors(...)inexperiments/Feb2026/lte_solver.py- Gaussian elimination primitive:
gauss_solve(...)inlte_primitives.py
6) LTE reconstruction
Given fitted coefficients, we reconstruct the model time series:
\[\hat d(t) = \text{offset} + k_0 F(t) + \sum_j a_j\,g_j(F(t)) + \text{(trend/annual terms)}\]where $g_j$ are the nonlinear sin/cos basis functions (with optional nonlinearity exponent) and annual terms are sin/cos in $t$ and $2t$.
Code:
lte(...)inlte_solver.py
Metrics and gates
Correlation coefficient (CC)
The gate uses the correlation coefficient computed on training and out-of-band segments.
Code:
cc(...)inlte_primitives.py
dLOD reference comparison
A reference comparison against dlod3.dat provides an additional stability signature.
Code:
dlod_fit_amp_phase(...),compare_ref(...)inlte_solver.py
Regression test harness (must stay green)
experiments/Feb2026/test_amo.shruns the CLI with fixed seed and single-thread settings.experiments/Feb2026/expect_test_amo.expvalidates the summary signature.
Links:
Code map (where to read what)
- Bookkeeping / config / I/O:
lte_config.py - Generic math primitives:
lte_primitives.py - Physics transforms (formulation):
lte_physics.py - Regression + LTE reconstruction:
lte_solver.py - Entrypoint (pipeline assembly):
experiments/Feb2026/lt