SFI.diagnostics.residual_tests module

Statistical tests on standardised residuals.

A well-specified fit produces whitened residuals that are an independent, identically distributed standard-normal sample. The four checks here probe that claim from complementary angles:

  • residual_moments() — mean, variance, skewness and kurtosis (pooled and per spatial component) plus the per-component covariance, which should equal the identity when the diffusion is correct;

  • autocorrelation_tests() — Ljung–Box test on the residuals and on their squares, measured strictly along time;

  • normality_test() — Kolmogorov–Smirnov test against N(0, 1) with Q–Q data for plotting;

  • mse_consistency() — predicted vs realised normalised mean squared error of the inferred force.

References

Ljung, G. M., & Box, G. E. P. (1978). On a measure of lack of fit in time series models. Biometrika, 65(2), 297–303.

SFI.diagnostics.residual_tests.autocorrelation_tests(bundle, n_lags=None)[source]

Ljung–Box tests on the residuals and their squares.

Autocorrelation of z flags missing dynamics or a too-small basis; autocorrelation of z**2 flags state-dependent noise that a constant diffusion misses. Both are measured strictly along time (see _unit_series()).

Returns keys "acf", "acf_squared", "ljung_box", "ljung_box_squared" and "n_eff". The default lag count is min(20, n_eff // 5).

Parameters:
Return type:

dict

SFI.diagnostics.residual_tests.mse_consistency(inferer, bundle)[source]

Compare predicted vs realised Itô NMSE for the inferred force.

The whitened residuals satisfy r^T A^{-1} r / dt = ||z||^2. Under a correctly specified model each ||z_t||^2 follows a \(\chi^2_d\) law (mean d, variance 2d), so the sample mean of the squared norms has standard error sqrt(2d / n). We report a z-score for the excess (mean - d); |z| > 5 signals bias or a misspecified diffusion. The realised NMSE divides the systematic part of that excess by the mean force magnitude <F^T A^{-1} F> and is compared to force_predicted_MSE.

Parameters:

bundle (ResidualBundle)

Return type:

dict

SFI.diagnostics.residual_tests.normality_test(bundle)[source]

Kolmogorov–Smirnov test of the pooled residuals against N(0, 1).

Returns {"ks": {statistic, pvalue}, "qq": {sample_quantiles, theoretical_quantiles}}. The residuals are whitened to known mean 0 and variance 1 by construction, so the fully-specified N(0, 1) reference is appropriate (no parameters are estimated from z).

Parameters:

bundle (ResidualBundle)

Return type:

dict

SFI.diagnostics.residual_tests.parametric_four_point_diagnostic(data, drift_fn, dt, n_substeps=4)[source]

Four-point diagnostic: test that Cov[r_i, r_{i+2}] = 0.

Under correct model specification and i.i.d. measurement noise, midpoint flow residuals separated by two steps share no measurement noise source, so their cross-covariance should vanish. Deviations indicate model misspecification, correlated measurement noise, or higher-order effects.

Parameters:
  • data (TrajectoryCollection or TrajectoryDataset) – Observed trajectory data.

  • drift_fn (callable (d,) (d,)) – Drift function with parameters already closed over.

  • dt (float) – Observation time step.

  • n_substeps (int) – RK4 micro-steps per interval.

Returns:

resultC_02 : (d, d) empirical cross-covariance of r_0 and r_2. frobenius_norm : ||C_02||_F. n_quadruplets : number of quadruplets used.

Return type:

dict

SFI.diagnostics.residual_tests.residual_moments(bundle)[source]

Pooled and per-component moments of the standardised residuals.

The per-component covariance should be the identity if the inferred diffusion correctly describes the noise; deviations are summarised by the Frobenius distance from I and the worst off-diagonal entry.

Parameters:

bundle (ResidualBundle)

Return type:

dict