Skip to content

ntpstats.noisefit

Power-law noise model: fit h_α (S_y(f) = Σ h_α f^α) to stability curves and spectra.

The five coefficients h₂ (white PM), h₁ (flicker PM), h₀ (white FM), h₋₁ (flicker FM) and h₋₂ (random-walk FM) summarise a clock, and are what the simulator, Kalman filters and holdover prediction need.

Model. Sampled phase with power-law noise is the Kasdin–Walter process x = h_α * w (w white, variance Q), whose discrete spectrum is S_x(f) = 2 Q τ0 / (2 sin πfτ0)^(2-α). For f ≪ 1/τ0 this is h_α f^α / (2πf)² with h_α = 2 Q (2π)^α τ0^(α-1). The expected value of every estimator (ADEV, OADEV, MDEV, TDEV, HDEV) is then an exact linear function of the h_α (the same filter algebra as :mod:ntpstats.edf), so no continuous-time bandwidth assumption is needed for white and flicker PM.

Fit. Non-negative weighted least squares on the variances, with weights from the equivalent degrees of freedom (Var σ̂² ≈ 2σ⁴/EDF, iterated with the model values), over every subset of noise types; the subset with the lowest BIC (χ² + k ln n) wins, so a noise type is only reported when the data need it. Confidence intervals come from the covariance of the active coefficients (log-normal, so they stay positive; approximate, because points of a stability curve are correlated) or, by default in :func:fit_series, from a parametric bootstrap that re-simulates the fitted model with the same length.

NoiseFit dataclass

predict(kind, taus)

Model deviation at taus, including a fitted drift.

dominant(kind, taus)

Noise type contributing most to kind at each tau.

scenario_clock()

[clock] table for a simulator scenario reproducing this noise.

q_from_h(h, alpha, tau0)

Innovation variance Q of the Kasdin–Walter phase filter giving coefficient h.

simulate(h, n, tau0, seed=None)

Phase samples (s) with the given h_α (Kasdin–Walter, as in :func:simulate.powerlaw_phase).

basis(kind, m, alpha, tau0)

Expected variance (dev²) of kind at averaging factor m for h_α = 1.

spectrum_basis(kind, f, alpha, tau0)

Discrete-model PSD for h_α = 1: S_x (kind 'x') or S_y of first differences (kind 'y').

predict(h, kind, taus, tau0)

Deviation predicted by the model at taus (multiples of tau0).

drift_basis(kind, m, tau0)

Variance a linear frequency drift D = 1 adds to kind (AVAR, MVAR: D²τ²/2; HVAR: 0).

fit(results=(), spectra=(), alphas=ALPHAS, ci=0.683, iterations=6, selection='bic', drift=False)

Fit h_α to stability results (ADEV/OADEV/MDEV/TDEV/HDEV, with EDF) and/or spectra.

drift=True also fits a linear frequency drift (D²τ²/2 in AVAR/MVAR), so drift in the data is not mistaken for random-walk FM.

corner_taus(nf, kind='oadev', max_tau=None)

Averaging times (up to max_tau, default the longest fitted tau) where the dominant noise type changes.

fit_phase(x, tau0, kinds=('oadev',), spectrum=False, ci=0.683, bootstrap=100, seed=0, alphas=ALPHAS, selection='bic', drift=False)

Fit h_α to evenly sampled phase x (s; NaN marks gaps).

bootstrap=N (default 100) replaces the analytic intervals by a basic bootstrap interval on a log scale from N refits of data simulated with the fitted model (same length, gaps and tau grid). The analytic intervals treat the points of a curve as independent, which they are not, so they are too narrow; in Monte Carlo tests the bootstrap intervals hold their stated coverage. bootstrap=0 is fast and approximate.

fit_series(series, kinds=('oadev',), spectrum=False, ci=0.683, bootstrap=100, seed=0, alphas=ALPHAS, tau0=None, max_gap=3.0, detrend='linear', drift=False)

:func:fit_phase on a :class:TimeSeries (resampled; detrend removes offset/frequency/drift).