Repository navigation
Conversation
evd_imp reduced and iterated on the matrix as given. ?GEEV first scales it into [smlnum, bignum] (smlnum = sqrt(safmin) / eps). Without that, entries below about 2^-90 (32-bit) or 2^-960 (64-bit) went through the Hessenberg reduction and the Schur iteration in subnormals and the eigenvectors lost every digit (GET22 1e5 to 2e15, LAPACK 2 to 70), and the complex Schur iteration near the top of the range lost the factor that kept the c32 LAPACK group failing. The scaling is a power of two, so it is exact, and the eigenvalues are scaled back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
faer-029 reproduces the lost eigenvectors of a tiny matrix on faer 0.24.4 (f64 2^-960: GET22 1.1e15; f32 2^-100: 1.8e6; LAPACK 16 and 16) and on the fork prints 17.7 and 15.2 at every scale. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…view) faer's complex modulus is inf for 2^1023 + 0i and zero for 2^-1074 + 0i, so a modulus-based scan selected a zero factor (NaN eigenvalue with Ok) or no scaling at all. The tests reject nonfinite results before f64::max can drop them; the report notes that faer 0.24.4 returns nonfinite eigenvectors with Ok at 2^-1000 (f64) and 2^-100 (f32); the docs restrict their claims to the measured families. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
shinaoka
force-pushed
the
fix/112-c32-evd
branch
from
October 29, 2026 11:29
a4692cd to
ca4ec0a
Compare
Member
Author
This was referenced Oct 29, 2026
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 #112.
Summary
As the maintainer asked (2026-10-29), I compared faer's nonsymmetric EVD with LAPACK
?GEEVstage by stage. faer skipped?GEEV's first step: when the largest entry is belowsmlnum = sqrt(safmin) / epsor abovebignum = 1 / smlnum, LAPACK scales the matrix to that bound before the Hessenberg reduction and scales the eigenvalues back at the end.evd_impnow does the same with a power of two, which scales every entry exactly and does not change the eigenvectors.Stage-by-stage comparison (c32 kinds 6/7, n = 63 to 65)
cgeev: 29 to 40)So the gap arises in the complex QR iteration on the unscaled matrix.
Where the gap grows
I swept 372 matrices over f32/f64/c32/c64, n = 16, 64, 128 and 257, and four families: random, Grcar, near-Jordan, and graded
D A D^-1with D spanning 1e±6. Scales went up to the range limits, and LAPACK?geev(scipy/OpenBLAS) was run on the same files. Below the bound the gap was far worse than #112's factor of 1.5:2^-802^-90NoConvergence2^-100NoConvergence2^-110,2^-1202^-9002^-9602^-1000,2^-1010At
2^-100, f32 near-Jordan n = 128 and 257 did not return at all. That hang is a separate defect, #144: with the scaling,Mat::eigenno longer reaches it.After the change, every non-graded series is at most 1.74 times LAPACK, at every n, scale and type. The two cells above 1.5 are at n = 16, where the absolute values are small: f32 near-Jordan gives 9.15 against 5.26 (the same at scale 1), and c32 random at
2^-60and2^-100gives 3.74 against 2.25.The graded family has a different, serious defect in the real eigenvector back substitution. It is unrelated to scaling: GET22 reaches 2.6e9 against LAPACK below 5e-4, and upstream 0.24.4 also fails. It is filed as #145 and not touched here.
Changes
faer/src/linalg/evd/mod.rs:geev_scalingand its use inevd_imp. The bound is tested on the largest|re|or|im|, not on faer's complex modulus, which is inf for2^1023 + 0iand zero for2^-1074 + 0i(post-review finding: a modulus scan picked a zero factor and returned a NaN eigenvalue withOk;evd_scaling_at_the_complex_range_endscovers it and fails with the modulus scan). Also the testgeev_scaling_tests::evd_scales_its_input_into_range. The test covers Grcar and pseudo-random n = 32, all four types,2^-120to2^120(32-bit) and2^-1010to2^1015(64-bit), right and left vectors, and the GET22 threshold20 * max(1, sqrt(n / 16)).scripts/lapack-known-failures.json: the LAPACK validation: the nonsymmetric EVD fixtures exceed the GET22-style residual threshold (4 dtypes) #112 entry is removed, because the c32 group now passes.docs/lapack-validation.md,PATCHSET.md: one row and one paragraph.upstream-reports/faer-028-evd-input-not-scaled: reproduces the defect onfaer0.24.4: f642^-960gives GET22 1.1e15, and f642^-1000and f322^-100return eigenvectors with NaN/inf entries, withOk. Not posted upstream.LAPACK sources were read only; no code was copied.
Verification (primerose, 4 cores)
2^-120, right: GET22 1.7e6) and passes with it.scripts/run-lapack-validation.py: every family exits 0, including nonsymmetric_evd 28/28, hessenberg, schur, balance and self_adjoint_evd. The known-failures list is now empty.cargo test -p t4a-faer --lib linalg::evd: 106 passed. The LAPACK nonsymmetric EVD tests (--include-ignored), rerun after the post-review fix: 158 passed.f64::max), both fixed. The MINOR findings (the left side is checked as the right eigenvectors ofA^H; universal wording in the docs) were addressed by narrowing the claims.faer-028against this branch prints 17.7 (f64) and 15.2 (f32) at every scale.🤖 Generated with Claude Code