StochasticForceInference 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. SFI/__init__.py +64 -0
  2. SFI/bases/__init__.py +85 -0
  3. SFI/bases/constants.py +492 -0
  4. SFI/bases/linear.py +325 -0
  5. SFI/bases/monomials.py +218 -0
  6. SFI/bases/pairs.py +998 -0
  7. SFI/bases/spde.py +1537 -0
  8. SFI/diagnostics/__init__.py +60 -0
  9. SFI/diagnostics/assess.py +87 -0
  10. SFI/diagnostics/dynamics_order.py +621 -0
  11. SFI/diagnostics/plotting.py +226 -0
  12. SFI/diagnostics/report.py +238 -0
  13. SFI/diagnostics/residual_tests.py +395 -0
  14. SFI/diagnostics/residuals.py +688 -0
  15. SFI/inference/__init__.py +58 -0
  16. SFI/inference/base.py +1460 -0
  17. SFI/inference/optimizers.py +200 -0
  18. SFI/inference/overdamped.py +1214 -0
  19. SFI/inference/parametric_core/__init__.py +34 -0
  20. SFI/inference/parametric_core/covariance.py +232 -0
  21. SFI/inference/parametric_core/driver.py +272 -0
  22. SFI/inference/parametric_core/flow.py +149 -0
  23. SFI/inference/parametric_core/flow_multi.py +362 -0
  24. SFI/inference/parametric_core/flow_ud.py +168 -0
  25. SFI/inference/parametric_core/jacobians.py +540 -0
  26. SFI/inference/parametric_core/objective.py +286 -0
  27. SFI/inference/parametric_core/objective_ud.py +253 -0
  28. SFI/inference/parametric_core/precision.py +229 -0
  29. SFI/inference/parametric_core/solve.py +763 -0
  30. SFI/inference/result.py +362 -0
  31. SFI/inference/serialization.py +245 -0
  32. SFI/inference/sparse/__init__.py +67 -0
  33. SFI/inference/sparse/base.py +43 -0
  34. SFI/inference/sparse/beam.py +303 -0
  35. SFI/inference/sparse/greedy.py +151 -0
  36. SFI/inference/sparse/hillclimb.py +307 -0
  37. SFI/inference/sparse/lasso.py +178 -0
  38. SFI/inference/sparse/metrics.py +78 -0
  39. SFI/inference/sparse/result.py +278 -0
  40. SFI/inference/sparse/scorer.py +323 -0
  41. SFI/inference/sparse/stlsq.py +165 -0
  42. SFI/inference/sparsity.py +40 -0
  43. SFI/inference/underdamped.py +1355 -0
  44. SFI/integrate/__init__.py +38 -0
  45. SFI/integrate/api.py +920 -0
  46. SFI/integrate/integrand.py +402 -0
  47. SFI/integrate/rk4.py +156 -0
  48. SFI/integrate/timeops.py +174 -0
  49. SFI/langevin/__init__.py +29 -0
  50. SFI/langevin/base.py +863 -0
  51. SFI/langevin/chunked.py +225 -0
  52. SFI/langevin/noise.py +446 -0
  53. SFI/langevin/overdamped.py +560 -0
  54. SFI/langevin/underdamped.py +448 -0
  55. SFI/statefunc/__init__.py +49 -0
  56. SFI/statefunc/basis.py +87 -0
  57. SFI/statefunc/core/runtime.py +47 -0
  58. SFI/statefunc/factory.py +346 -0
  59. SFI/statefunc/interactor.py +90 -0
  60. SFI/statefunc/layout/__init__.py +29 -0
  61. SFI/statefunc/layout/_base.py +186 -0
  62. SFI/statefunc/layout/_eval_compiler.py +453 -0
  63. SFI/statefunc/layout/_fd_atoms.py +196 -0
  64. SFI/statefunc/layout/_grid.py +878 -0
  65. SFI/statefunc/layout/_sectors.py +166 -0
  66. SFI/statefunc/memhint.py +222 -0
  67. SFI/statefunc/nodes/__init__.py +56 -0
  68. SFI/statefunc/nodes/base.py +318 -0
  69. SFI/statefunc/nodes/contract.py +422 -0
  70. SFI/statefunc/nodes/interactions/__init__.py +23 -0
  71. SFI/statefunc/nodes/interactions/dispatcher.py +1365 -0
  72. SFI/statefunc/nodes/interactions/prepare.py +161 -0
  73. SFI/statefunc/nodes/interactions/specs.py +362 -0
  74. SFI/statefunc/nodes/interactions/stencils.py +718 -0
  75. SFI/statefunc/nodes/leaf.py +530 -0
  76. SFI/statefunc/nodes/ops/__init__.py +27 -0
  77. SFI/statefunc/nodes/ops/concat.py +28 -0
  78. SFI/statefunc/nodes/ops/derivative.py +447 -0
  79. SFI/statefunc/nodes/ops/einsum.py +120 -0
  80. SFI/statefunc/nodes/ops/linear.py +153 -0
  81. SFI/statefunc/nodes/ops/mapn.py +138 -0
  82. SFI/statefunc/nodes/ops/reshape_rank.py +158 -0
  83. SFI/statefunc/nodes/ops/slice.py +83 -0
  84. SFI/statefunc/params.py +309 -0
  85. SFI/statefunc/psf.py +112 -0
  86. SFI/statefunc/sf.py +104 -0
  87. SFI/statefunc/stateexpr.py +1243 -0
  88. SFI/statefunc/structexpr.py +1003 -0
  89. SFI/trajectory/__init__.py +31 -0
  90. SFI/trajectory/collection.py +1122 -0
  91. SFI/trajectory/dataset.py +1164 -0
  92. SFI/trajectory/degrade.py +1108 -0
  93. SFI/trajectory/io.py +1027 -0
  94. SFI/trajectory/reserved_extras.py +129 -0
  95. SFI/utils/__init__.py +17 -0
  96. SFI/utils/formatting.py +308 -0
  97. SFI/utils/maths.py +185 -0
  98. SFI/utils/neighbors.py +162 -0
  99. SFI/utils/plotting.py +1936 -0
  100. stochasticforceinference-2.0.0.dist-info/METADATA +203 -0
  101. stochasticforceinference-2.0.0.dist-info/RECORD +104 -0
  102. stochasticforceinference-2.0.0.dist-info/WHEEL +5 -0
  103. stochasticforceinference-2.0.0.dist-info/licenses/LICENSE +21 -0
  104. stochasticforceinference-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,60 @@
1
+ """SFI diagnostics — residual-consistency checks for inference results.
2
+
3
+ Top-level user-facing entry point::
4
+
5
+ from SFI.diagnostics import assess
6
+ report = assess(inferer, level="standard")
7
+ report.print_summary()
8
+
9
+ The module reuses the fitted force and the inferred constant diffusion to
10
+ recompute standardised residuals (innovations) and test whether they look
11
+ like an independent ``N(0, 1)`` sample:
12
+
13
+ * mean, variance, skewness and kurtosis (pooled and per spatial
14
+ component), plus the per-component covariance;
15
+ * Ljung--Box autocorrelation of the residuals and their squares;
16
+ * Kolmogorov--Smirnov normality against ``N(0, 1)``;
17
+ * predicted-vs-realised normalised mean squared error of the force
18
+ (a sampling-noise-aware chi-square check).
19
+
20
+ See :mod:`SFI.diagnostics.residual_tests`. Two preset levels are exposed:
21
+
22
+ * ``"minimal"`` — residual moments only;
23
+ * ``"standard"`` — adds autocorrelation, normality, and MSE consistency.
24
+
25
+ All backends (overdamped / underdamped, single / multi-particle, SPDE)
26
+ share a unified residual definition: the Euler--Maruyama innovation
27
+ :math:`r_t = \\Delta x_t - F(x_t)\\,\\Delta t` (overdamped) or the
28
+ secant-velocity innovation
29
+ :math:`r_t = \\Delta v_t - F(x_t, v_t)\\,\\Delta t` (underdamped), both
30
+ whitened by :math:`(2 \\bar D \\Delta t)^{-1/2}`.
31
+
32
+ References
33
+ ----------
34
+ Ljung & Box (1978); Diebold, Gunther & Tay (1998).
35
+ """
36
+
37
+ from .assess import assess
38
+ from .dynamics_order import DynamicsOrderReport, classify_dynamics
39
+ from .plotting import (
40
+ plot_dynamics_order,
41
+ plot_qq,
42
+ plot_residual_acf,
43
+ plot_residual_histogram,
44
+ plot_summary,
45
+ )
46
+ from .report import DiagnosticsReport
47
+ from .residual_tests import parametric_four_point_diagnostic
48
+
49
+ __all__ = [
50
+ "assess",
51
+ "classify_dynamics",
52
+ "DiagnosticsReport",
53
+ "DynamicsOrderReport",
54
+ "parametric_four_point_diagnostic",
55
+ "plot_dynamics_order",
56
+ "plot_qq",
57
+ "plot_residual_acf",
58
+ "plot_residual_histogram",
59
+ "plot_summary",
60
+ ]
@@ -0,0 +1,87 @@
1
+ """Top-level diagnostic dispatcher.
2
+
3
+ See :func:`assess` for the user-facing entry point.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing import Optional
9
+
10
+ from .report import DiagnosticsReport
11
+ from .residual_tests import (
12
+ autocorrelation_tests,
13
+ mse_consistency,
14
+ normality_test,
15
+ residual_moments,
16
+ )
17
+ from .residuals import build_residuals
18
+
19
+ _LEVELS = ("minimal", "standard")
20
+
21
+
22
+ def assess(
23
+ inferer,
24
+ *,
25
+ level: str = "standard",
26
+ n_lags: Optional[int] = None,
27
+ data=None,
28
+ ) -> DiagnosticsReport:
29
+ """Run residual-consistency checks on a fitted inference object.
30
+
31
+ Recomputes the standardised residuals (Euler--Maruyama innovations,
32
+ whitened by the inferred constant diffusion) and tests whether they
33
+ look like an independent ``N(0, 1)`` sample.
34
+
35
+ Parameters
36
+ ----------
37
+ inferer :
38
+ A fitted ``OverdampedLangevinInference`` or
39
+ ``UnderdampedLangevinInference``. Must have a callable
40
+ ``force_inferred`` (run e.g. ``infer_force_linear`` first) and an
41
+ inferred constant diffusion (``A_inv``).
42
+ level :
43
+ ``"minimal"`` — pooled residual moments only;
44
+ ``"standard"`` (default) — adds autocorrelation, normality, and
45
+ predicted-vs-realised MSE consistency.
46
+ n_lags :
47
+ Number of autocorrelation lags. Default ``min(20, n_eff // 5)``.
48
+ data :
49
+ Optional independent :class:`~SFI.trajectory.TrajectoryCollection`
50
+ on which to evaluate the residuals (held-out diagnostics).
51
+ Default: the training data attached to the inferer.
52
+
53
+ Returns
54
+ -------
55
+ DiagnosticsReport
56
+ Container with a ``residuals`` section and ``meta``.
57
+
58
+ Notes
59
+ -----
60
+ The Euler-style residual is exact for the linear estimators; for the
61
+ parametric estimators it is an approximation that
62
+ is still asymptotically consistent under correct specification, so
63
+ the autocorrelation and normality tests remain valid for flagging
64
+ misspecification.
65
+ """
66
+ if level not in _LEVELS:
67
+ raise ValueError(f"level must be one of {_LEVELS!r}; got {level!r}.")
68
+
69
+ bundle = build_residuals(inferer, data=data)
70
+
71
+ residuals: dict = {"moments": residual_moments(bundle)}
72
+ if level == "standard":
73
+ residuals["autocorr"] = autocorrelation_tests(bundle, n_lags=n_lags)
74
+ residuals["normality"] = normality_test(bundle)
75
+ residuals["mse_consistency"] = mse_consistency(inferer, bundle)
76
+
77
+ meta = {
78
+ "backend": bundle.backend,
79
+ "regime": bundle.regime,
80
+ "n_obs": bundle.n_obs,
81
+ "n_particles": bundle.n_particles,
82
+ "d": bundle.d,
83
+ "level": level,
84
+ "inferer_class": type(inferer).__name__,
85
+ }
86
+
87
+ return DiagnosticsReport(residuals=residuals, meta=meta)