OptionalcClamp diagonal of C_smooth to >= 1e-7 after symmetrize. Off-diagonal entries (which can legitimately be negative) are left intact. Prevents negative variances from causing NaN in sqrt(diag(C_smooth)).
OptionalcTake abs of diagonal of C_smooth after symmetrize: diag(C) = |diag(C)|. Unlike cDiag (clamp to 1e-7) this is magnitude-preserving: if catastrophic cancellation yields C_ii = -0.003 the true value was ~+0.003, and abs gives back that physically meaningful value. Off-diagonal entries (which can legitimately be negative, representing correlation) are left intact.
OptionalcApply abs(diag(C_smooth)) after the backward smoother symmetrize step.
Matches MATLAB's dlmsmo.m lines 114-115.
Valid for both f32 and f64. For f64, cTriuSym is on by default so
cSmoAbsDiag can be used independently.
For f32 it acts on top of the existing symmetrize+cEps default.
OptionalcUse triu(C) + triu(C,1)' for covariance symmetrization instead of
(C + C') / 2. The upper triangle is taken as authoritative and mirrored
to the lower — matching MATLAB's dlmsmo.m line 77 (triu(C) + triu(C,1)').
Unlike (C+C')/2 which averages both triangles, triu+triu' discards the
lower triangle entirely. For f64 on the forward filter and backward smoother
this is what MATLAB does; combined with cSmoAbsDiag it reduces max |Δ|
from ~3.78e-8 to ~9e-11 without the Joseph-form overhead.
Valid for both f32 and f64 (unlike most other flags which are f32-only).
For f32 it replaces the default (C+C')/2 symmetrize step.
Defaults to true for f64 (matches MATLAB dlmsmo.m; ~500× better Octave
agreement vs unsymmetrized). Set cTriuSym: false to disable.
OptionalnClamp diagonal of N to >= 0 after each backward step. N is an information (Fisher) matrix and should be PSD; negative diagonal entries from f32 rounding cause C·N·C to undercorrect, widening C_smooth.
OptionalnTake abs of diagonal of N after each backward step: diag(N) = |diag(N)|. Stronger than nDiag: rather than flooring at 0, sign-flips negative entries. Rationale: if rounding makes N_ii barely negative the true value was near zero and the magnitude is still informative; reflecting it back to +|N_ii| preserves the scale of the correction rather than discarding it.
OptionalnMultiply N by (1 - 1e-5) after each backward step. Slight forgetting that prevents N from accumulating unboundedly over long series, which would cause C·N·C to overshoot and produce negative C_smooth.
OptionalnSymmetrize N after each backward step: N = 0.5*(N + N'). N is an information matrix and should be symmetric, but f32 rounding in the L'·N·L einsum introduces asymmetries that compound over many steps.
Fine-grained stabilization flags for the sequential scan smoother.
Most flags are f32-only (silently ignored for f64) and sit on top of the default Joseph + symmetrize +
C += 1e-6·Ibaseline. Two flags —cTriuSymandcSmoAbsDiag— also work for f64: they mirror the stabilization steps in MATLAB'sdlmsmo.m(triu+triu'symmetrize +abs(diag)on smoother output) and reduce the f64 max error vs the Octave reference by ~3000×.Applicable to the sequential scan path only; the assoc/WebGPU path has its own internal stabilization.
For most users, use the preset strings
'matlab'or'none'instead. Usepnpm run stab:search:fullto exhaustively search all flag combinations.