Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
507 changes: 507 additions & 0 deletions libmath/desk/lib/complex.hoon

Large diffs are not rendered by default.

66 changes: 66 additions & 0 deletions libmath/desk/lib/unum.hoon
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,72 @@
++ log-10 |=(x=@ ^-(@ (div (log x) log10)))
:: +pow: @ -> @ -> @ (x^y = exp(y * log x))
++ pow |=([x=@ y=@] ^-(@ (exp (mul y (log x)))))
:: +factorial: @ -> @ (x! by repeated multiplication)
:: Domain x >= 0 (NaR otherwise, and NaR propagates); for integer x this is
:: exact up to the precision, halting once x <= 1. Mirrors /lib/math.
++ factorial
|= x=@
^- @
?: =(nar x) nar
?: (lth x zero) nar
=/ t one
|- ^- @
?: (lte x one) t
$(x (sub x one), t (mul t x))
:: +cbrt: @ -> @ (cube root, x^(1/3) = exp(log x / 3))
:: Domain x > 0 (NaR for x < 0, like the rest of the exp/log-based ops);
:: cbrt(0) = 0. Mirrors /lib/math's `cbt = (pow x .0.33...)`.
++ cbrt
|= x=@
^- @
?: =(nar x) nar
?: =(zero x) zero
?: (lth x zero) nar
(pow x (div one (sun 3)))
:: +atan: @ -> @ (inverse tangent, Gauss/AGM iteration)
:: arctan(x) = x / ((1+x^2)^0.5 * b), with [a b] driven to the AGM of
:: (1+x^2)^-0.5 and 1. Fixed iteration count (AGM converges quadratically).
:: Odd in x, so negative arguments are handled by the carried sign.
++ atan
|= x=@
^- @
?: =(nar x) nar
=/ x2 (add one (mul x x))
=/ rt (sqt x2)
=/ a (div one rt)
=/ b one
=/ nn=@ 0
|- ^- @
?: (^gth nn 40)
(div x (mul rt b))
=/ ai (mul (div one (sun 2)) (add a b))
=/ bi (sqt (mul ai b))
$(a ai, b bi, nn +(nn))
:: +asin: @ -> @ (inverse sine)
:: arcsin(x) = atan(x / sqrt(1 - x^2)) for |x| < 1; +-pi/2 at x = +-1;
:: NaR outside [-1, 1]. Mirrors /lib/math.
++ asin
|= x=@
^- @
?: =(nar x) nar
?: (lth (abs x) one)
(atan (div x (sqt (sub one (mul x x)))))
?: (equ x one) (mul pi (div one (sun 2)))
?: (equ x (neg one)) (neg (mul pi (div one (sun 2))))
nar
:: +acos: @ -> @ (inverse cosine)
:: arccos(x) = atan(sqrt(1 - x^2) / x) for 0 < |x| < 1 (pi/2 at 0); 0 at
:: x = 1, pi at x = -1; NaR outside [-1, 1]. Mirrors /lib/math.
++ acos
|= x=@
^- @
?: =(nar x) nar
?: (lth (abs x) one)
?: (equ x zero) (mul pi (div one (sun 2)))
(atan (div (sqt (sub one (mul x x))) x))
?: (equ x one) zero
?: (equ x (neg one)) pi
nar
:: +is-close: @ -> @ -> @ -> ? (|a - b| <= tol)
++ is-close |=([a=@ b=@ tol=@] ^-(? (lte (abs (sub a b)) tol)))
::
Expand Down
99 changes: 99 additions & 0 deletions libmath/desk/tests/lib/complex-edge.hoon
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
:: /tests/lib/complex-edge -- %cplx transcendental edge cases (@cs).
::
:: Exercises the origin, the real and imaginary axes, the csqrt/clog branch cut
:: (-1, +-i), the csqrt sign branch, the clog(0) singularity, and the naive-
:: series breakdown at large arguments. All values validated against numpy
:: complex64.
::
/+ *test, complex
|%
++ s cs:complex
++ z00 `@`0x0 :: 0+0i
++ z10 `@`0x3f80.0000 :: 1+0i
++ zt0 `@`0x4120.0000 :: 10+0i
++ z0i `@`0x3f80.0000.0000.0000 :: 0+1i
++ z0n `@`0xbf80.0000.0000.0000 :: 0-1i
++ zn1 `@`0xbf80.0000 :: -1+0i
++ z11 `@`0x3f80.0000.3f80.0000 :: 1+1i
++ z34 `@`0x4080.0000.4040.0000 :: 3+4i
++ z0t `@`0x4120.0000.0000.0000 :: 0+10i
:: cexp: origin -> 1, real axis (e, 1/e), imaginary axis (cos1 + i sin1), off-axis.
++ test-cexp-origin (expect-eq !>(`@`0x3f80.0000) !>((~(cexp s %n) z00)))
++ test-cexp-1 (expect-eq !>(`@`0x402d.f855) !>((~(cexp s %n) z10)))
++ test-cexp-neg1 (expect-eq !>(`@`0x3ebc.5ab0) !>((~(cexp s %n) zn1)))
++ test-cexp-i (expect-eq !>(`@`0x3f57.6aa4.3f0a.5140) !>((~(cexp s %n) z0i)))
++ test-cexp-1p1i (expect-eq !>(`@`0x4012.6408.3fbb.fe2a) !>((~(cexp s %n) z11)))
++ test-cexp-3p4i (expect-eq !>(`@`0xc173.366f.c152.0f81) !>((~(cexp s %n) z34)))
:: clog: the singularity (log 0 = -inf) and the branch cut at -1 (iπ) and +-i.
++ test-clog-zero (expect-eq !>(`@`0xff80.0000) !>((~(clog s %n) z00)))
++ test-clog-neg1 (expect-eq !>(`@`0x4049.0fdb.0000.0000) !>((~(clog s %n) zn1)))
++ test-clog-i (expect-eq !>(`@`0x3fc9.0fdb.0000.0000) !>((~(clog s %n) z0i)))
++ test-clog-neg-i (expect-eq !>(`@`0xbfc9.0fdb.0000.0000) !>((~(clog s %n) z0n)))
:: csqrt: branch cut sqrt(-1) = i, and the sign branch sqrt(-i) = 0.707 - 0.707i.
++ test-csqrt-neg1 (expect-eq !>(`@`0x3f80.0000.0000.0000) !>((~(csqrt s %n) zn1)))
++ test-csqrt-neg-i (expect-eq !>(`@`0xbf35.04f3.3f35.04f3) !>((~(csqrt s %n) z0n)))
:: csin/ccos on the imaginary axis -> real sinh/cosh.
++ test-csin-i (expect-eq !>(`@`0x3f96.6cff.0000.0000) !>((~(csin s %n) z0i)))
++ test-ccos-i (expect-eq !>(`@`0x3fc5.83ab) !>((~(ccos s %n) z0i)))
:: KNOWN LIMITATION: the naive Taylor/AGM series diverges from the true value
:: far from the origin -- exp(10) is ~21991 here vs the true ~22026 (~0.16%
:: low), csin(0+10i) ~ i*10989 vs true ~ i*11013. Locked as regression (NOT as
:: correctness); #18's Chebyshev rewrite would tighten these.
++ test-cexp-large (expect-eq !>(`@`0x46ab.cef6) !>((~(cexp s %n) zt0)))
++ test-csin-large (expect-eq !>(`@`0x462b.b42b.0000.0000) !>((~(csin s %n) z0t)))
::
:: Same edges across the other widths: @cd (double), @ch (half), @cq (quad).
:: Origin, the csqrt/clog branch cut at -1, the clog(0)=-inf singularity, the
:: csqrt sign branch at -i, and the imaginary axis (csin -> sinh).
++ d cd:complex
++ h ch:complex
++ q cq:complex
++ d00 `@`0x0
++ dn1 `@`0xbff0.0000.0000.0000
++ d0i `@`0x3ff0.0000.0000.0000.0000.0000.0000.0000
++ d0n `@`0xbff0.0000.0000.0000.0000.0000.0000.0000
++ h00 `@`0x0
++ hn1 `@`0xbc00
++ h0i `@`0x3c00.0000
++ h0n `@`0xbc00.0000
++ q00 `@`0x0
++ qn1 `@`0xbfff.0000.0000.0000.0000.0000.0000.0000
++ test-cd-cexp-origin (expect-eq !>(`@`0x3ff0.0000.0000.0000) !>((~(cexp d %n) d00)))
++ test-cd-csqrt-neg1 (expect-eq !>(`@`0x3ff0.0000.0000.0000.0000.0000.0000.0000) !>((~(csqrt d %n) dn1)))
++ test-cd-clog-neg1 (expect-eq !>(`@`0x4009.21fb.5444.2d11.0000.0000.0000.0000) !>((~(clog d %n) dn1)))
++ test-cd-clog-zero (expect-eq !>(`@`0xfff0.0000.0000.0000) !>((~(clog d %n) d00)))
++ test-cd-csqrt-neg-i (expect-eq !>(`@`0xbfe6.a09e.667f.3bcd.3fe6.a09e.667f.3bcd) !>((~(csqrt d %n) d0n)))
++ test-cd-csin-i (expect-eq !>(`@`0x3ff2.cd9f.c44e.b983.0000.0000.0000.0000) !>((~(csin d %n) d0i)))
++ test-ch-cexp-origin (expect-eq !>(`@`0x3c00) !>((~(cexp h %n) h00)))
++ test-ch-csqrt-neg1 (expect-eq !>(`@`0x3c00.0000) !>((~(csqrt h %n) hn1)))
++ test-ch-clog-zero (expect-eq !>(`@`0xfc00) !>((~(clog h %n) h00)))
++ test-ch-csqrt-neg-i (expect-eq !>(`@`0xb9a8.39a8) !>((~(csqrt h %n) h0n)))
++ test-ch-csin-i (expect-eq !>(`@`0x3cb2.0000) !>((~(csin h %n) h0i)))
++ test-cq-cexp-origin (expect-eq !>(`@`0x3fff.0000.0000.0000.0000.0000.0000.0000) !>((~(cexp q %n) q00)))
++ test-cq-csqrt-neg1
(expect-eq !>(`@`0x3fff.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000) !>((~(csqrt q %n) qn1)))
++ test-cq-clog-zero (expect-eq !>(`@`0xffff.0000.0000.0000.0000.0000.0000.0000) !>((~(clog q %n) q00)))
::
:: cpow edge cases (@cs): z^0 = 1, integer powers, the branch sqrt via ^0.5,
:: and the 0^w corner.
++ cs2 `@`0x4000.0000 :: 2+0i
++ csi `@`0x3f80.0000.0000.0000 :: 0+1i
++ csn1 `@`0xbf80.0000 :: -1+0i
++ cwh `@`0x3f00.0000 :: 0.5+0i
++ test-cpow-pow0 (expect-eq !>(`@`0x3f80.0000) !>((~(cpow s %n) cs2 z00))) :: 2^0 = 1
++ test-cpow-pow2 (expect-eq !>(`@`0x4080.0000) !>((~(cpow s %n) cs2 cs2))) :: 2^2 = 4
++ test-cpow-i2 (expect-eq !>(`@`0xb182.92c0.bf80.0000) !>((~(cpow s %n) csi cs2))) :: i^2 = -1 (+~0i)
++ test-cpow-neg1-half (expect-eq !>(`@`0x3f7f.ffff.b386.2919) !>((~(cpow s %n) csn1 cwh))) :: (-1)^0.5 = i
:: KNOWN LIMITATION: 0^2 should be 0, but cpow = exp(w*clog z) routes through
:: clog(0)=-inf and exp(-inf) (which the naive series cannot represent), so it
:: yields NaN. Locked as a documented corner, not as correctness.
++ test-cpow-zero-pow2 (expect-eq !>(`@`0x7fc0.0000.7fc0.0000) !>((~(cpow s %n) z00 cs2)))
::
:: Rounding modes propagate through the complex ops: cexp(1+2i) gives four
:: distinct bit patterns under %n / %u / %d / %z.
++ z12 `@`0x4000.0000.3f80.0000 :: 1+2i
++ test-cexp-rnd-n (expect-eq !>(`@`0x401e.30c5.bf90.cb4e) !>((~(cexp s %n) z12)))
++ test-cexp-rnd-u (expect-eq !>(`@`0x401e.30d9.bf90.cb53) !>((~(cexp s %u) z12)))
++ test-cexp-rnd-d (expect-eq !>(`@`0x401e.30bd.bf90.cb53) !>((~(cexp s %d) z12)))
++ test-cexp-rnd-z (expect-eq !>(`@`0x401e.30bd.bf90.cb46) !>((~(cexp s %z) z12)))
--
35 changes: 35 additions & 0 deletions libmath/desk/tests/lib/complex-fns.hoon
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
:: /tests/lib/complex-fns -- complex elementary functions.
::
:: Expected values are the lib's own self-contained series outputs, validated
:: against numpy (complex64 / complex128) to display precision, e.g.
:: cexp(1+2i) = -1.1312 + 2.4717i, clog = 0.8047 + 1.1071i, csqrt = 1.2720 +
:: 0.7862i, csin = 3.1658 + 1.9596i, ccos = 2.0327 - 3.0519i, ctan = 0.0338 +
:: 1.0148i, (1+2i)^2 = -3 + 4i. Inputs: z = 1+2i at each width.
::
/+ *test, complex
|%
++ s cs:complex
++ d cd:complex
++ h ch:complex
++ q cq:complex
++ zs `@`0x4000.0000.3f80.0000
++ zd `@`0x4000.0000.0000.0000.3ff0.0000.0000.0000
++ zh `@`0x4000.3c00
++ zq `@`0x4000.0000.0000.0000.0000.0000.0000.0000.3fff.0000.0000.0000.0000.0000.0000.0000
:: @cs (single): the full set; cpow uses w = 2+0i, so (1+2i)^2 = -3+4i.
++ test-cs-cexp (expect-eq !>(`@`0x401e.30c5.bf90.cb4e) !>((~(cexp s %n) zs)))
++ test-cs-clog (expect-eq !>(`@`0x3f8d.b70a.3f4e.0210) !>((~(clog s %n) zs)))
++ test-cs-csqrt (expect-eq !>(`@`0x3f49.4138.3fa2.d18a) !>((~(csqrt s %n) zs)))
++ test-cs-csin (expect-eq !>(`@`0x3ffa.d435.404a.9c1e) !>((~(csin s %n) zs)))
++ test-cs-ccos (expect-eq !>(`@`0xc043.524b.4002.1823) !>((~(ccos s %n) zs)))
++ test-cs-ctan (expect-eq !>(`@`0x3f81.e4c1.3d0a.7f5c) !>((~(ctan s %n) zs)))
++ test-cs-cpow (expect-eq !>(`@`0x4080.0004.c03f.fff5) !>((~(cpow s %n) zs `@`0x4000.0000)))
:: @cd (double): exp/log/sqrt -- matches numpy complex128 to ~15 digits.
++ test-cd-cexp (expect-eq !>(`@`0x4003.c618.a227.4afe.bff2.1969.c495.3cd3) !>((~(cexp d %n) zd)))
++ test-cd-clog (expect-eq !>(`@`0x3ff1.b6e1.92eb.be45.3fe9.c041.f7ed.8d33) !>((~(clog d %n) zd)))
++ test-cd-csqrt (expect-eq !>(`@`0x3fe9.2826.ef25.8d1b.3ff4.5a31.46a8.8456) !>((~(csqrt d %n) zd)))
:: @ch (half) + @cq (quad): cexp spot check across the remaining widths.
++ test-ch-cexp (expect-eq !>(`@`0x40f1.bc86) !>((~(cexp h %n) zh)))
++ test-cq-cexp
(expect-eq !>(`@`0x4000.3c61.8a22.74af.d5ad.4589.2de9.748d.bfff.2196.9c49.53cd.175c.75fb.0c1e.697d) !>((~(cexp q %n) zq)))
--
59 changes: 59 additions & 0 deletions libmath/desk/tests/lib/unum-edge.hoon
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
:: /tests/lib/unum-edge -- posit (%unum) transcendental edge cases.
::
:: Exact identities, sign, NaR propagation, domain -> NaR, and the naive-series
:: breakdown / saturation at large arguments. Mostly at posit32 (rps), with a
:: posit8 (rpb) cross-width spot. Posits round-to-nearest-even, so there is no
:: rounding-mode variation to sweep.
::
/+ *test, unum
|%
++ u rps:unum
++ b rpb:unum
++ nar `@`0x8000.0000
++ s1 (sun:rps:unum 1)
++ s4 (sun:rps:unum 4)
++ s5 (sun:rps:unum 5)
++ sa (sun:rps:unum 10)
++ sb (sun:rps:unum 50)
++ sc (sun:rps:unum 100)
++ n1 (neg:rps:unum (sun:rps:unum 1))
:: exact identities (correctly rounded; series accurate near 0)
++ test-exp0 (expect-eq !>(`@`0x4000.0000) !>((exp:u 0x0))) :: exp 0 = 1
++ test-cos0 (expect-eq !>(`@`0x4000.0000) !>((cos:u 0x0))) :: cos 0 = 1
++ test-sin0 (expect-eq !>(`@`0x0) !>((sin:u 0x0))) :: sin 0 = 0
++ test-tan0 (expect-eq !>(`@`0x0) !>((tan:u 0x0)))
++ test-log1 (expect-eq !>(`@`0x0) !>((log:u s1))) :: log 1 = 0
++ test-sqt0 (expect-eq !>(`@`0x0) !>((sqt:u 0x0)))
++ test-sqt1 (expect-eq !>(`@`0x4000.0000) !>((sqt:u s1)))
++ test-sqt4 (expect-eq !>(`@`0x4800.0000) !>((sqt:u s4))) :: sqrt 4 = 2
++ test-fact0 (expect-eq !>(`@`0x4000.0000) !>((factorial:u 0x0))) :: 0! = 1
++ test-fact5 (expect-eq !>(`@`0x6b80.0000) !>((factorial:u s5))) :: 5! = 120
++ test-atan0 (expect-eq !>(`@`0x0) !>((atan:u 0x0)))
++ test-asin0 (expect-eq !>(`@`0x0) !>((asin:u 0x0)))
++ test-acos1 (expect-eq !>(`@`0x0) !>((acos:u s1))) :: acos 1 = 0
:: sign
++ test-exp-n1 (expect-eq !>(`@`0x33c5.ab1c) !>((exp:u n1))) :: 1/e
++ test-atan-n1 (expect-eq !>(`@`0xc36f.0255) !>((atan:u n1))) :: -pi/4 (atan is odd)
:: NaR propagation
++ test-exp-nar (expect-eq !>(`@`0x8000.0000) !>((exp:u nar)))
++ test-sin-nar (expect-eq !>(`@`0x8000.0000) !>((sin:u nar)))
++ test-sqt-nar (expect-eq !>(`@`0x8000.0000) !>((sqt:u nar)))
++ test-fact-nar (expect-eq !>(`@`0x8000.0000) !>((factorial:u nar)))
:: domain -> NaR
++ test-sqt-neg (expect-eq !>(`@`0x8000.0000) !>((sqt:u n1))) :: sqrt(-1) = NaR
:: posit8 cross-width spot: identity + NaR propagation (-1 @rpb = 0xc0)
++ test-rpb-exp0 (expect-eq !>(`@`0x40) !>((exp:b 0x0))) :: exp 0 = 1
++ test-rpb-exp-nar (expect-eq !>(`@`0x80) !>((exp:b 0x80)))
++ test-rpb-sqt-neg (expect-eq !>(`@`0x80) !>((sqt:b 0xc0))) :: sqrt(-1) = NaR
:: KNOWN LIMITATION: the naive Taylor series diverges far from the origin.
:: exp(10) ~ 21991 vs true 22026; exp(50)/exp(100) saturate near maxpos rather
:: than tracking the true value; sin(10) blows up to a huge magnitude instead
:: of staying in [-1, 1] (no range reduction). log (atanh form) holds up
:: better -- log(100) ~ 4.605. Locked as regression, NOT correctness; #18's
:: Chebyshev rewrite (range reduction) would fix these.
++ test-exp10 (expect-eq !>(`@`0x7a57.9ded) !>((exp:u sa)))
++ test-exp50 (expect-eq !>(`@`0x7ffe.1b02) !>((exp:u sb)))
++ test-exp100 (expect-eq !>(`@`0x7fff.f02b) !>((exp:u sc)))
++ test-sin10 (expect-eq !>(`@`0xc74b.a64a) !>((sin:u sa)))
++ test-log100 (expect-eq !>(`@`0x50e9.b7f7) !>((log:u sc)))
--
67 changes: 67 additions & 0 deletions libmath/desk/tests/lib/unum-fns.hoon
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,71 @@
%+ expect-eq !>(`@`0x80) !>((pow:u 0x0 (sun:u 2))) :: pow(0,2)=NaR
%+ expect-eq !>(`@`0x80) !>((pow:u 0xc0 (sun:u 2))) :: pow(-1,2)=NaR
==
:: New transcendentals (factorial, cbrt, atan, asin, acos) at posit8. Expected
:: values from tools/posit_check.py's series replica; all correctly rounded vs
:: mpmath at posit8. Inputs: 0x38 = .5, (sun 1) = 1, (sun 3/4) = 3/4.
++ test-transcendental-new-rpb ^- tang
=/ u rpb:unum
;: weld
%+ expect-eq !>(`@`0x54) !>((factorial:u (sun:u 3))) :: 3! = 6
%+ expect-eq !>(`@`0x62) !>((factorial:u (sun:u 4))) :: 4! = 24
%+ expect-eq !>(`@`0x40) !>((cbrt:u (sun:u 1))) :: cbrt 1 = 1
%+ expect-eq !>(`@`0x3d) !>((atan:u (sun:u 1))) :: atan 1 = pi/4
%+ expect-eq !>(`@`0x38) !>((atan:u 0x38)) :: atan .5
%+ expect-eq !>(`@`0x39) !>((asin:u 0x38)) :: asin .5
%+ expect-eq !>(`@`0x41) !>((acos:u 0x38)) :: acos .5
%+ expect-eq !>(`@`0x45) !>((acos:u 0x0)) :: acos 0 = pi/2
==
:: Domain guards for the new arms: out-of-range -> NaR (unum nar convention),
:: exact +-1 / 0 boundaries, cbrt(0)=0.
++ test-domain-new-rpb ^- tang
=/ u rpb:unum
;: weld
%+ expect-eq !>(`@`0x80) !>((cbrt:u 0xc0)) :: cbrt(-1)=NaR
%+ expect-eq !>(`@`0x0) !>((cbrt:u 0x0)) :: cbrt(0)=0
%+ expect-eq !>(`@`0x80) !>((factorial:u 0xb4)) :: factorial(-3)=NaR
%+ expect-eq !>(`@`0x80) !>((asin:u (sun:u 4))) :: asin(4)=NaR (|x|>1)
%+ expect-eq !>(`@`0x80) !>((acos:u (sun:u 4))) :: acos(4)=NaR
%+ expect-eq !>(`@`0x45) !>((asin:u (sun:u 1))) :: asin(1)=pi/2
%+ expect-eq !>(`@`0x0) !>((acos:u (sun:u 1))) :: acos(1)=0
==
:: Full transcendental set at posit16 (rph) and posit32 (rps). Expected values
:: from the series replica; the naive Taylor/AGM series is correctly rounded
:: near the expansion point and within ~1 ULP elsewhere (see tools/posit_check).
++ test-transcendental-rph ^- tang
=/ u rph:unum
;: weld
%+ expect-eq !>(`@`0x4531) !>((exp:u 0x3800)) :: exp .5
%+ expect-eq !>(`@`0x3757) !>((sin:u 0x3800)) :: sin .5
%+ expect-eq !>(`@`0x3e0b) !>((cos:u 0x3800)) :: cos .5
%+ expect-eq !>(`@`0x38bd) !>((tan:u 0x3800)) :: tan .5
%+ expect-eq !>(`@`0x3b18) !>((log:u (sun:u 2))) :: log 2
%+ expect-eq !>(`@`0x5400) !>((factorial:u (sun:u 3))) :: 3!
%+ expect-eq !>(`@`0x6200) !>((factorial:u (sun:u 4))) :: 4!
%+ expect-eq !>(`@`0x4000) !>((cbrt:u (sun:u 1))) :: cbrt 1
%+ expect-eq !>(`@`0x3c90) !>((atan:u (sun:u 1))) :: atan 1
%+ expect-eq !>(`@`0x36d5) !>((atan:u 0x3800)) :: atan .5
%+ expect-eq !>(`@`0x3861) !>((asin:u 0x3800)) :: asin .5
%+ expect-eq !>(`@`0x4060) !>((acos:u 0x3800)) :: acos .5
%+ expect-eq !>(`@`0x4491) !>((acos:u 0x0)) :: acos 0
%+ expect-eq !>(`@`0x5800) !>((pow-n:u (sun:u 2) 3)) :: 2^3
==
++ test-transcendental-rps ^- tang
=/ u rps:unum
;: weld
%+ expect-eq !>(`@`0x4530.94c8) !>((exp:u 0x3800.0000)) :: exp .5
%+ expect-eq !>(`@`0x3757.743a) !>((sin:u 0x3800.0000)) :: sin .5
%+ expect-eq !>(`@`0x3e0a.9404) !>((cos:u 0x3800.0000)) :: cos .5
%+ expect-eq !>(`@`0x38bd.a7ad) !>((tan:u 0x3800.0000)) :: tan .5
%+ expect-eq !>(`@`0x3b17.2180) !>((log:u (sun:u 2))) :: log 2
%+ expect-eq !>(`@`0x5400.0000) !>((factorial:u (sun:u 3)))
%+ expect-eq !>(`@`0x6200.0000) !>((factorial:u (sun:u 4)))
%+ expect-eq !>(`@`0x4000.0000) !>((cbrt:u (sun:u 1))) :: cbrt 1
%+ expect-eq !>(`@`0x3c90.fdab) !>((atan:u (sun:u 1))) :: atan 1
%+ expect-eq !>(`@`0x36d6.3381) !>((atan:u 0x3800.0000)) :: atan .5
%+ expect-eq !>(`@`0x3860.a91c) !>((asin:u 0x3800.0000)) :: asin .5
%+ expect-eq !>(`@`0x4060.a91d) !>((acos:u 0x3800.0000)) :: acos .5
%+ expect-eq !>(`@`0x4490.fdaa) !>((acos:u 0x0)) :: acos 0
%+ expect-eq !>(`@`0x5800.0000) !>((pow-n:u (sun:u 2) 3))
==
--
Loading