complex+saloon: implement complex transcendentals; wire %cplx into Saloon#59
Merged
sigilante merged 5 commits intoJun 9, 2026
Conversation
…loon /lib/complex gains complex elementary functions (cexp, clog, csqrt, csin, ccos, ctan, cpow) in all four width doors (cs/cd/ch/cq). Kept self-contained -- like /lib/unum, /lib/fixed, /lib/twoc -- by giving each door its OWN real exp/sin/ cos/log/atan as naive Taylor/AGM series over the stdlib component float door, rather than depending on /lib/math (which would couple the kind-primitive to the special-functions lib and pull it into Lagoon's build). Saloon's Tier-B dispatch (+trans-scalar / +fun-scalar) gains a %cplx branch (complex bloqs 5/6/7/8 = ch/cs/cd/cq), so exp/sin/cos/tan/log/sqrt/pow now work on %cplx rays. Real-only / ordered functions (factorial, log-10, log-2, cbrt, pow-n) are undefined on complex and crash. Tests (validated vs numpy, all green on ~hex): - tests/lib/complex-fns: the full set at @cs, exp/log/sqrt at @cd, exp at @ch/@cq (cd matches complex128 to ~15 digits, cq to ~34). - tests/lib/saloon-cplx: ray-level %cplx dispatch through Saloon Tier B, plus factorial/cbrt crash-on-complex guards. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Edge-case testing surfaced a bug: the self-contained real +rlog lacked the x<=0 domain guard the unum +log has, so clog(0+0i) ran the atanh series on y=-1 and returned garbage (~-5.4) instead of the -inf singularity. Add a log(0) -> -inf guard to +rlog in all four doors (|z| is always >= 0, so 0 is the only singular input). Add /tests/lib/complex-edge: origin, real/imaginary axes, the csqrt/clog branch cut (-1, +-i), the csqrt sign branch (sqrt(-i) = 0.707 - 0.707i), the clog(0) singularity, off-axis (1+1i, 3+4i), and two large-argument cases locked as documented limitations (the naive series is ~0.2% off far from the origin). All validated against numpy complex64. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
complex-edge now covers the same edges across all four widths -- @cd/@ch/@cq get origin, the csqrt/clog branch cut (-1, -i), the clog(0)=-inf singularity, and the imaginary axis -- plus: - cpow edges: 2^0=1, 2^2=4, i^2=-1, (-1)^0.5=i, and the 0^2 corner (documented: yields NaN, since cpow routes through clog(0)=-inf -> exp(-inf), which the naive series can't represent -- locked as a known limitation, not correctness). - rounding: cexp(1+2i) under %n/%u/%d/%z gives four distinct bit patterns, confirming the rounding mode propagates bit-exactly through the complex ops. 39 cases total, all validated against numpy complex64/128. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds tests/lib/unum-edge (28 cases), the %unum analogue of complex-edge: - exact identities (exp0=1, cos0=1, sqt4=2, fact5=120, log1=0, acos1=0, ...) - sign (exp(-1)=1/e, atan(-1)=-pi/4) - NaR propagation (exp/sin/sqt/factorial of NaR -> NaR) - domain -> NaR (sqrt(-1)) - a posit8 cross-width spot (identity + NaR propagation) - large-argument breakdown / saturation, locked as DOCUMENTED limitations: exp(10)~21991 vs 22026; exp(50)/exp(100) saturate near maxpos; sin(10) blows up out of [-1,1] (no range reduction); log (atanh) holds up (log(100)~4.605). No bug found (the unum domain guards from the transcendental PR already hold); posits round-to-nearest-even so there is no rounding-mode axis to sweep. The large-arg cases are the #18 hazard made explicit, not asserted as correct. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
unum: posit transcendental edge-case sweep
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.
Stacked on #58 (unum transcendentals). Completes the
%cplxTier-B story so Saloon's transcendentals work on complex rays./lib/complex— complex elementary functionscexp,clog,csqrt,csin,ccos,ctan,cpowin all four width doors (cs/cd/ch/cq).Self-contained (no
/+ math): per the architecture discussion, each door carries its own realexp/sin/cos/log/atanas naive Taylor/AGM series over the stdlib component float door — consistent with/lib/unum//lib/fixed//lib/twoc, and avoids coupling the complex kind-primitive to the special-functions lib (or pullingmathinto Lagoon's build). Closed forms documented in the header;#18's Chebyshev rewrite would upgrade the real series in lockstep.Saloon —
%cplxdispatch+trans-scalar/+fun-scalargain a%cplxbranch (complex bloqs 5/6/7/8 = ch/cs/cd/cq).exp/sin/cos/tan/log/sqrt/powmap to the complex ops; real-only/ordered functions (factorial/log-10/log-2/cbrt/pow-n) are undefined on complex and crash.Tests (validated vs numpy, all green on
~hex)tests/lib/complex-fns— full set at@cs;exp/log/sqrtat@cd;expat@ch/@cq. (@cdmatches numpy complex128 to ~15 digits,@cqto ~34.)tests/lib/saloon-cplx— ray-level%cplxdispatch through Saloon Tier B (withsake %nfor deterministic rounding), plusfactorial/cbrtcrash-on-complex guards.Note: bare
+sa's default rnd isn't%n(the same "set rnd via+sake" expectation the eig tests follow); the%cplxtests usesake %nsince complex rounding is rnd-sensitive (unlike posits).🤖 Generated with Claude Code