pydynamicestimator.tests.baselines.report_inverter_drift ======================================================== .. py:module:: pydynamicestimator.tests.baselines.report_inverter_drift .. autoapi-nested-parse:: Quantify how far the CURRENT inverter trajectories drift from the committed byte-identical baselines -- the diagnostic companion to ``test_recur_{sim,est}_inverter.py`` (which only give boolean pass/fail). Run from the repo root: .venv/bin/python -m pydynamicestimator.tests.baselines.report_inverter_drift .venv/bin/python -m pydynamicestimator.tests.baselines.report_inverter_drift sim_ld Purpose. The vectorization pass (A1 in docs/inverter_remaining_work.md) is the one inverter change that is *not* byte-identical: re-associating floating-point arithmetic shifts the trajectory at the ULP level, amplified by the nonlinear integrator + init Newton solves to ~1e-9..1e-6. The byte-identical gates can only say "diverged"; this tool says *by how much* and *in which states*, so you can (a) confirm the drift is reassociation-scale rather than a transcription bug, and (b) watch the actual margin against the 1e-6 sim / 1e-5 est gate tolerances. It does NOT modify the baselines -- it loads them read-only and compares. Capture a fresh reference only via ``create_baseline_inverter.py``, and only when an intentional, validated numerics change makes the new trajectories the reference. For each case it reports the array shape, the np.allclose gate verdict (same semantics as the test: atol gate + numpy's default rtol=1e-5), the global max-abs / max-rel / RMS difference with the location of the worst element, and a per-state table of the largest-drifting rows -- named when the row->name reconstruction matches the array (else bare indices, never a wrong label). Attributes ---------- .. autoapisummary:: pydynamicestimator.tests.baselines.report_inverter_drift.GATE_ATOL pydynamicestimator.tests.baselines.report_inverter_drift._REL_FLOOR pydynamicestimator.tests.baselines.report_inverter_drift._DEVICE_ABBREV Functions --------- .. autoapisummary:: pydynamicestimator.tests.baselines.report_inverter_drift._reconstruct_state_names pydynamicestimator.tests.baselines.report_inverter_drift.report_case pydynamicestimator.tests.baselines.report_inverter_drift.main Module Contents --------------- .. py:data:: GATE_ATOL .. py:data:: _REL_FLOOR :value: 1e-09 .. py:data:: _DEVICE_ABBREV .. py:function:: _reconstruct_state_names(case: str, n_rows: int) -> List[str] Rebuild the per-row state names of ``x_full`` from the module globals that ``run_inverter_case`` just populated, mirroring the exact device -> entry -> state -> (dynamic-line tail) ordering system.py uses to build the state vector. The reconstruction is *length-guarded*: if anything is off (attribute missing, or the rebuilt list does not match ``n_rows``) it returns plain ``x{i}`` indices rather than risk pinning a drift number on the wrong state. .. py:function:: report_case(case: str) -> Optional[dict] Run one baseline ``case`` on the current code, diff it against the committed reference, print the report, and return the metrics dict (None if the baseline is missing or the shapes differ). .. py:function:: main(argv: List[str]) -> int