Skip to content

Phase 1: /lib/complex + wire %cplx into Lagoon#46

Merged
sigilante merged 1 commit into
mainfrom
sigilante/lagoon-cplx
Jun 8, 2026
Merged

Phase 1: /lib/complex + wire %cplx into Lagoon#46
sigilante merged 1 commit into
mainfrom
sigilante/lagoon-cplx

Conversation

@sigilante

Copy link
Copy Markdown
Collaborator

Implements Phase 1 of the %cplx design (lagoon/CPLX-DESIGN.md, PR #45):
complex-number arrays with a SoftBLAS-interleaved atom layout, element-wise
ops, and complex linear algebra. Unblocks Saloon eigenvalues/eigenvectors.

/lib/complex (pure Hoon)

cs (@cs = two @rs) and cd (@cd = two @rd) doors keyed on rounding
mode. Packed atom = real low / imag high, matching SoftBLAS complexN_t
(validated on ~hex: (1+2i)·(3+4i) = -5+10i). Arms: add/sub/mul,
div (Smith's algorithm), neg, conj, abs (hypot, returns real-valued
complex), equ/neq (bit equality). No total order — no gth/lth.

Lagoon (sur + lib)

  • %cplx in the kind union; bloq 6=cs 7=cd (meta.tail unused).
  • fun-scalar: add/sub/mul/div, equ/neq → complex one/zero;
    gth/gte/lth/lte crash (complex is unordered).
  • New %conj op (identity on real kinds, so dotcdot there);
    trans-scalar %abs/%conj.
  • New ray arms conj and dotc (Hermitian inner product
    Σ conj(aᵢ)·bᵢ). Bilinear dot, mmul, cumsum use the generic
    round-each-step path (no exact complex accumulator).
  • get-term@c aura terms (%cs/%cd); eye/ones constant 1+0i;
    scale raw-pack; change out of complex refuses (lossy).

Tests — all green on ~hex

  • /tests/lib/complex (4): cs/cd arith, unary, compare.
  • /tests/lib/lagoon-cplx (7): arith, unary (abs/conj), compare, ones,
    cumsum, dot (-18+68i) vs dotc (70-8i), complex mmul.
  • Regressions: %unum (14) and %int2 (5) still pass.
  • Oracle: tools/complex_check.py (NumPy complex64/complex128).

Not in scope (per design)

Jets (Phase 2: add *dotu/cgemm/zgemm to our SoftBLAS); Saloon eig
(Phase 3); @ch/@cq widths; change into-complex.

🤖 Generated with Claude Code

Implements the %cplx design (CPLX-DESIGN.md): complex-number arrays with a
SoftBLAS-interleaved atom layout, element-wise ops, and complex linear algebra.

/lib/complex (pure Hoon): cs (@cs, two @rs) and cd (@cd, two @rd) doors keyed
on rounding mode.  Packed atom = real low / imag high, matching SoftBLAS
complexN_t.  add/sub/mul, div (Smith's algorithm), neg, conj, abs (hypot,
real-valued complex), equ/neq (bit equality).  No total order (no gth/lth).

Lagoon (sur + lib): %cplx in the kind union; bloq 6=cs 7=cd, prec needs no
meta.tail.  fun-scalar add/sub/mul/div + equ/neq (-> complex one/zero);
gth/gte/lth/lte crash (complex unordered).  New %conj op (identity on real
kinds, so dotc reduces to dot there).  trans-scalar %abs/%conj.  New ray arms
+conj and +dotc (Hermitian inner product, sum conj(a)*b).  Bilinear dot, mmul,
and cumsum use the generic round-each-step path (no exact complex accumulator).
get-term -> @c aura terms; eye/ones constant 1+0i; scale raw-pack; change out
of complex refuses (lossy).

Tests (all green on ~hex): /tests/lib/complex (4: cs/cd arith, unary, compare),
/tests/lib/lagoon-cplx (7: arith, unary, compare, ones, cumsum, dot vs dotc,
mmul); %unum (14) and %int2 (5) regressions still pass.  Oracle:
tools/complex_check.py (NumPy complex64/128).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sigilante sigilante merged commit 29d9f3c into main Jun 8, 2026
@sigilante sigilante deleted the sigilante/lagoon-cplx branch June 8, 2026 01:00
sigilante added a commit that referenced this pull request Jun 8, 2026
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>
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