Skip to content

Fix report_value misclassifying monotone convergence as diverging (#674)#676

Merged
InauguralPhysicist merged 1 commit into
InauguralSystems:mainfrom
Nitjsefnie-OSC:fix-convergence-classification
Jul 20, 2026
Merged

Fix report_value misclassifying monotone convergence as diverging (#674)#676
InauguralPhysicist merged 1 commit into
InauguralSystems:mainfrom
Nitjsefnie-OSC:fix-convergence-classification

Conversation

@Nitjsefnie

Copy link
Copy Markdown
Contributor

Closes #674.

report_value labeled a monotonically converging sequence diverging whenever the per-step decay ratio was above ~0.87 — i.e. essentially every real iterative solver.

Root cause (observer_slot_raw_nonvanishing, eigenscript.c): the "non-vanishing steps" test was recent >= 0.5 * older. That admits any geometric decay whose per-half-window ratio is ≥ 0.5 — for a 10-sample window that's r ≳ 0.871 — as "non-vanishing", so a monotone approach to zero read as diverging. But a geometric decay's steps vanish (their sum converges); only non-shrinking steps (a linear runaway's constant Δv, or a growing Δv) sum without bound.

Fix: the bar becomes "steps are not shrinking" — recent >= older * (1.0 - 1e-9) (the 1e-9 slack absorbs fp rounding for exactly-constant steps). Same-sign non-shrinking steps still → diverging; sign-alternating → oscillating; a decaying approach → converged.

Tests (test_report_value_convergence.eigs, regression from the issue repro): decay ratios 0.88/0.90/0.95 now classify converged (were diverging); a geometric growth r=1.05 and a linear runaway still classify diverging; r=0.5 unchanged. Full suite green (the one unrelated failure is a bundle test that needs an exec-capable /tmp, which this sandbox denies — it fails identically on pristine main). Repro before → 0.90/0.95 diverging; after → all rows converged. Docs + CHANGELOG updated.

One behavior nuance worth your confirmation: observer_slot_raw_nonvanishing is shared with the oscillation path, so the tightened bar also means a slowly-damped, sub-deadband oscillation now falls through to the relative verdicts (settles converged) rather than reading oscillating. That matches the documented #422 intent ("a damped oscillation has decaying steps, fails non-vanishing, settles to converged"); all pinned oscillation tests use non-decaying amplitude and are unaffected, and above-deadband damped oscillations are still caught by the relative channel's flip counter. Flagging in case you'd rather treat that regime differently.


Generated by Claude Opus 4.8 (brief, review), Kimi K3 (implementation)

A sequence whose magnitude shrinks toward zero converges for any decay ratio in
(0,1); the previous heuristic flagged ratios above ~0.87 as diverging, covering
essentially every real iterative solver. Classify by whether magnitude grows
(diverging) vs shrinks (converging), with a regression test from InauguralSystems#674.

Closes InauguralSystems#674

Co-Authored-By: Kimi K3 <noreply@kimi.com>
@Nitjsefnie
Nitjsefnie force-pushed the fix-convergence-classification branch from dea3113 to 337ff27 Compare July 20, 2026 16:06
@InauguralPhysicist
InauguralPhysicist merged commit c3be48d into InauguralSystems:main Jul 20, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

observer: report_value classifies monotone CONVERGENCE as 'diverging' (rate > ~0.87)

2 participants