Saloon: Hermitian (%cplx) eigendecomposition (eig Phase A2)#48
Merged
Conversation
Extends +eig to complex Hermitian matrices via complex cyclic Jacobi. +eig now dispatches on kind: %cplx -> Hermitian path, else the symmetric path. The unitary rotation J that zeros a_pq has real diagonal c and complex off-diagonal b = s*(a_pq/|a_pq|) with J[q,p] = -conj(b); updates are A <- J^H*A*J, V <- V*J. Eigenvalues are real (%i754), eigenvectors unitary (%cplx) -- matching NumPy eigh. Works on @cs (bloq 6) and @cd (bloq 7); asserts exact Hermitian. Adds complex scalar helpers (cadd/csub/cmul/cdiv/cconj/cre/cpak/cabs-re over /lib/complex) and the Hermitian arms (hermitian, off-norm-h, frob-h, diag-real, rot-cols-h, rot-rows-h, sweep-herm, eig-herm). Durability: replaced the unbounded /lib/math Newton sqrt with an iteration-capped fsqt (50-step backstop, width-fixed feps). A sub-ULP rtol otherwise makes Newton oscillate between two adjacent floats forever, which OOM-crashed the ship while developing this. This also hardens the A1 path (regression-checked: all 18 symmetric tests still green). Tests (tests/lib/saloon-eigh, generated by tools/eigh_check.py vs numpy.linalg.eigvalsh) cover @cs 2x2/3x3/4x4 and @cd 3x3/4x4 Hermitian matrices; sort(computed eigenvalues) = sort(eigh). All 5 pass. Caveats documented in EIG-DESIGN.md: rtol width must match the component width (@rs for @cs, @rd for @cd); the exact Hermitian assert rejects +-0.0 mismatches in conjugate pairs. Note: this branch stacks on %cplx (PR #46) and eig A1 (PR #47); rebase once those land. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
27826d1 to
2fb2e2d
Compare
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.
Summary
Phase A2 of Saloon eigendecomposition: complex Hermitian matrices via complex cyclic Jacobi.
+eigis now polymorphic — it dispatches on kind (%cplx→ Hermitian path, else the symmetric A1 path) — soeig/eigvals/eigvecswork for both.The unitary rotation
Jthat zerosa_pqhas real diagonalcand complex off-diagonalb = s·(a_pq/|a_pq|)withJ[q,p] = −conj(b); updates areA ← Jᴴ·A·J,V ← V·J. Returns real%i754eigenvalues and%cplx(unitary) eigenvectors — matching NumPyeigh. Works on@cs(bloq 6, single) and@cd(bloq 7, double); asserts exact Hermitian.Adds complex scalar helpers (
cadd/csub/cmul/cdiv/cconj/cre/cpak/cabs-reover/lib/complex) and the Hermitian arms (hermitian,off-norm-h,frob-h,diag-real,rot-cols-h,rot-rows-h,sweep-herm,eig-herm).Durability fix (also hardens A1)
Replaced the unbounded
/lib/mathNewton sqrt with an iteration-cappedfsqt(50-step backstop, width-fixedfeps). A sub-ULPrtolotherwise makes Newton oscillate between two adjacent floats forever — which OOM-crashed the ship (recover: dig: meme+ segfault) while developing this. All 18 symmetric (A1) tests remain green.Tests
tests/lib/saloon-eigh(generated bytools/eigh_check.pyvsnumpy.linalg.eigvalsh) covers@cs2×2/3×3/4×4 and@cd3×3/4×4 Hermitian matrices; checkssort(computed) = sort(eigh). All 5 pass. The canonical[[2,i],[−i,2]] → {1,3}is included.Caveats (documented in EIG-DESIGN.md)
rtol's width must match the component width:@rsfor@cs,@rdfor@cd.±0.0mismatches in conjugate pairs are rejected (NumPy's-1jpacks real as−0.0); callers should canonicalize/symmetrize. The oracle does this viax + 0.0.This branch stacks on
%cplx(PR #46) and eig A1 (PR #47) — it mergessigilante/lagoon-cplxto get%cplx+/lib/complex. The diff vsmaintherefore includes those; review theSaloon: Hermitian ...commit for A2 itself. Best merged after #46 → #47; then rebase.Follow-on
🤖 Generated with Claude Code