Skip to content

Use non-mutating eigen in expT! to avoid corrupting the Lanczos diagonal - #278

Open
KristofferC wants to merge 2 commits into
SciML:masterfrom
KristofferC:kc/nondestructive-eigen
Open

Use non-mutating eigen in expT! to avoid corrupting the Lanczos diagonal#278
KristofferC wants to merge 2 commits into
SciML:masterfrom
KristofferC:kc/nondestructive-eigen

Conversation

@KristofferC

@KristofferC KristofferC commented Aug 31, 2026

Copy link
Copy Markdown

Since v1.34.0, expT! calls eigen!(SymTridiagonal(α, β)) where α is a view into Ks.H. LAPACK's stegr! overwrites its diagonal input, so each call corrupts α[1:j] — every subsequent Lanczos iteration in the error-estimate variant of expv! then diagonalizes garbage, giving wrong results and spurious early termination on all Julia versions. The pre-#258 workspace path was unaffected because it copied first (copyto!(sw.dv, α)); #258 replaced it with the mutating eigen!. Using non-mutating eigen restores correctness.

Evidence (Julia 1.12, seeded n=300 Hermitian, the "Alternative Lanczos expv Interface" setup, error vs dense exp):

version error checksum of result
v1.33.0 (last before #258) 5.1e-11 -19.894705577535643 - 210.2630548621702im
current master 13.0 (stops after 3 iterations) -18.6848732770996 - 210.70186885565363im
this PR 5.1e-11 bit-identical to v1.33.0

Why CI never caught this: the "Alternative Lanczos expv Interface" testset is vacuous. Inside the testset (a local scope), the inner function

function fullexp(A, v)
    w = similar(v)
    ...

does not create a local w — it captures and overwrites the testset-local w holding the expv result. δw = norm(w - w′) then compares the dense exponential with itself (w === w′), so δw is exactly 0.0 no matter how wrong expv is. The second commit renames the inner variable so the test actually checks the Krylov result; with the fix here the honest testset passes (and it fails against current master, err ≈ 13 vs the 1e-10 tolerance).

🤖 Generated with Claude Code

LAPACK stegr! overwrites its diagonal input, and α is a view into Ks.H,
so eigen! corrupted α[1:j] for all subsequent Lanczos iterations,
giving wrong results and spurious early termination in error-estimate
mode since v1.34.0. The pre-SciML#258 workspace path copied α first;
non-mutating eigen restores that behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Inside the testset (a local scope), the assignment `w = similar(v)` in
the inner function `fullexp` captures and overwrites the testset-local
`w` holding the expv result, so `norm(w - w′)` compared the dense
exponential with itself and was always exactly 0. Rename the inner
variable so the test actually checks the Krylov result.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant