Skip to content

Saloon: Hermitian (%cplx) eigendecomposition (eig Phase A2)#48

Merged
sigilante merged 1 commit into
mainfrom
sigilante/saloon-eig-hermitian
Jun 8, 2026
Merged

Saloon: Hermitian (%cplx) eigendecomposition (eig Phase A2)#48
sigilante merged 1 commit into
mainfrom
sigilante/saloon-eig-hermitian

Conversation

@sigilante
Copy link
Copy Markdown
Collaborator

Summary

Phase A2 of Saloon eigendecomposition: complex Hermitian matrices via complex cyclic Jacobi. +eig is now polymorphic — it dispatches on kind (%cplx → Hermitian path, else the symmetric A1 path) — so eig/eigvals/eigvecs work for both.

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ᴴ·A·J, V ← V·J. Returns real %i754 eigenvalues and %cplx (unitary) eigenvectors — matching NumPy eigh. 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-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 fix (also hardens A1)

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 (recover: dig: meme + segfault) while developing this. All 18 symmetric (A1) tests remain green.

Tests

tests/lib/saloon-eigh (generated by tools/eigh_check.py vs numpy.linalg.eigvalsh) covers @cs 2×2/3×3/4×4 and @cd 3×3/4×4 Hermitian matrices; checks sort(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: @rs for @cs, @rd for @cd.
  • The exact Hermitian assert is bit-exact, so ±0.0 mismatches in conjugate pairs are rejected (NumPy's -1j packs real as −0.0); callers should canonicalize/symmetrize. The oracle does this via x + 0.0.

⚠️ Stacking

This branch stacks on %cplx (PR #46) and eig A1 (PR #47) — it merges sigilante/lagoon-cplx to get %cplx + /lib/complex. The diff vs main therefore includes those; review the Saloon: Hermitian ... commit for A2 itself. Best merged after #46#47; then rebase.

Follow-on

  • Phase B: general real → complex (Hessenberg + Francis double-shift QR), its own design + PR.

🤖 Generated with Claude Code

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>
@sigilante sigilante force-pushed the sigilante/saloon-eig-hermitian branch from 27826d1 to 2fb2e2d Compare June 8, 2026 01:05
@sigilante sigilante merged commit 2cebf71 into main Jun 8, 2026
@sigilante sigilante deleted the sigilante/saloon-eig-hermitian branch June 8, 2026 01:23
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