When both Route A (legacy Euler-Lagrange) and Route B (chunked-Riccati) are available — for example with the concurrent dual-route execution proposed in the companion issue — compare the first eigenvalue et[1] from each path on every run and emit:
- >1% relative discrepancy →
@warn
- >10% relative discrepancy →
@error
Write Route B's odet_riccati to HDF5 as a diagnostic so users can inspect the two estimates side by side.
Why: the cross-check is a cheap sanity check that has already caught real drift. On feature/forcefreestates-rewrite (PR #252), it flagged ~4.5% drift on a Solovev case that was otherwise silent. It also serves as a regression net while the chunked-Riccati path matures.
Reference implementation: cross-check logic in src/ForceFreeStates/Integration.jl on feature/forcefreestates-rewrite (PR #252).
Acceptance:
- Cross-check runs when both
odet (Route A) and odet_riccati (Route B) are populated.
- Tolerances configurable but default to >1% warn / >10% error.
odet_riccati written to HDF5 under a clearly named diagnostic group.
- One regression test exercising both the warn and error branches with synthetic eigenvalues.
When both Route A (legacy Euler-Lagrange) and Route B (chunked-Riccati) are available — for example with the concurrent dual-route execution proposed in the companion issue — compare the first eigenvalue
et[1]from each path on every run and emit:@warn@errorWrite Route B's
odet_riccatito HDF5 as a diagnostic so users can inspect the two estimates side by side.Why: the cross-check is a cheap sanity check that has already caught real drift. On
feature/forcefreestates-rewrite(PR #252), it flagged ~4.5% drift on a Solovev case that was otherwise silent. It also serves as a regression net while the chunked-Riccati path matures.Reference implementation: cross-check logic in
src/ForceFreeStates/Integration.jlonfeature/forcefreestates-rewrite(PR #252).Acceptance:
odet(Route A) andodet_riccati(Route B) are populated.odet_riccatiwritten to HDF5 under a clearly named diagnostic group.