fix(#152): refuse Liouvillians whose assembly overflows to non-finite entries - #153
Draft
marcohost33-maker wants to merge 6 commits into
Draft
fix(#152): refuse Liouvillians whose assembly overflows to non-finite entries#153marcohost33-maker wants to merge 6 commits into
marcohost33-maker wants to merge 6 commits into
Conversation
…4f9592b) Rejection tests for both builders (overflowing diagonal difference, overflowing dissipator product, finite rate overflowing a finite dissipator), controls that must stay accepted (diag(1,-1) closed form, large-but-representable diagonal and dissipator, dense/sparse parity), and tests for the shared output guard (non-canonical CSR/COO duplicates, no densification). 11 failed / 8 passed on 4f9592b. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019UEuRxXvWxUfXVYHKT68z4
… entries Both builders now pass their assembled generator through a shared output guard, numerics.generator_guard.require_finite_generator, which raises ValueError (the family of the existing non-finite input gates) when any entry is NaN/inf. Dense: all entries. Sparse: .data of the canonical form, O(nnz), never densified; non-canonical duplicates are summed on a copy first because finite duplicates can overflow when summed. Assembly runs under np.errstate(over/invalid=ignore): an overflow can never return to a finite value through the remaining finite +,-,* so the guard sees every one, and callers get the ValueError instead of a RuntimeWarning cascade. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019UEuRxXvWxUfXVYHKT68z4
pytest.raises reports a silent accept as Failed (DID NOT RAISE), which is not an assertion; the refusal helpers now catch broadly and assert both that something was raised and that it is a ValueError. Still red on the 4f9592b sources (11 failed, 8 passed) and green on the fix. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019UEuRxXvWxUfXVYHKT68z4
… guard Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019UEuRxXvWxUfXVYHKT68z4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #152.
The defect (present on
main4f9592b)A Hamiltonian with finite entries whose differences overflow was accepted, and the returned Liouvillian contained non-finite entries. The Hermiticity gate checks the input; nothing checked the output. Reproduction from the issue (
H = diag(1e308, -1e308)) returned a non-finite generator from both builders (core/lindblad.py:173-188,sparse/build.py:105-117on4f9592b).What changes
src/liouscope/numerics/generator_guard.py:require_finite_generatorraisesValueError— the error family of the other non-representable-input guards (lindblad.py:101,:157;build.py:43,:93) — naming how many entries are non-finite and the overflow cause..dataof the canonical form, O(nnz), no densification. Why.datasuffices: entries outside the stored structure are exactly 0, SciPy only drops results equal to 0, and inf/NaN never compare equal to 0. The one exception — duplicate entries whose sum overflows — is handled by summing duplicates on a copy first.np.errstate(over="ignore", invalid="ignore")and check afterwards. Behaviour change (accepted, fail-closed): callers who previously got aRuntimeWarningplus a broken generator now get aValueError.diag(1, -1)(against the closed form),diag(4e307, -4e307), a dissipator with entries1e150.Evidence
d2d8338): against4f9592bsources, 11 failed / 8 passed (builder's run, not re-measured by the orchestrator); builder cases die atAssertionError: expected ValueError, got RuntimeWarning. Refusal tests fail at an assertion, not at "DID NOT RAISE" (5b671f0).Tools/diskriminierung.py, re-run by the orchestrator on headeff950e: dense 4/4 (DK-20260912T210845-eff8e2ef270c), sparse 4/4 (DK-20260912T210909-b3f99c91079b), helper 3/3 (DK-20260912T210859-e04045778b07); file hashes restored after each run.eff950e, Python 3.14.4, import verified from this worktree: 1243 passed, exit 0. The builder additionally ran ruff, mypy, coverage (--cov-fail-under=90), the qutip marker,check_workflow_hardening.pyandcheck_claim_safety.pyon 3.10 / 3.12 / 3.14 with exit 0 (builder's run, not repeated here). 3.13 not available locally.Known interaction
PR #127 also edits
core/lindblad.py,sparse/build.pyand CHANGELOGUnreleased. Expected conflicts are small (CHANGELOG, neighbouring imports); the assembly blocks #127 touches are not the ones changed here. Merge order to be decided when both are ready.Draft per AGENTS.md until the Codex round and the independent review are terminal.
🤖 Generated with Claude Code
https://claude.ai/code/session_019UEuRxXvWxUfXVYHKT68z4