├── LICENSE ├── README.md └── src ├── tests └── lib │ └── saloon.hoon └── lib └── saloon.hoon /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Sigilante 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scientific ALgorithms in hOON 2 | 3 | **wip as of ~2023.3.24** 4 | 5 | Transcendental and algebraic functions in native Hoon (and later jets). 6 | 7 | It's time to supersede [`lazytrig`](https://github.com/sigilante/lazytrig). 8 | 9 | Arms in `++rs` and other `@r`-servicing cores will be provided with necessary transcendental and trigonometric functions. 10 | 11 | As a first pass, we implement operators for `@rs`, `@rd`, `@rq`, and `@rh`. After Lagoon is merged, we implement `@lvs`, `@lms`, `@lvd`, and `@lmd`. 12 | 13 | - [ ] `@rs` 14 | - [ ] `@rd` 15 | - [ ] `@rq` 16 | - [ ] `@rh` 17 | - [ ] `@rsc` 18 | - [ ] `@rdc` 19 | - [ ] `@rqc` 20 | - [ ] `@rhc` 21 | - [ ] `@lvs` 22 | - [ ] `@lvd` 23 | - [ ] `@lvq` 24 | - [ ] `@lvh` 25 | - [ ] `@lms` 26 | - [ ] `@lmd` 27 | - [ ] `@lmq` 28 | - [ ] `@lmh` 29 | 30 | This requires us to finally resolves the treatment of complex numbers in Hoon (which I've here noted as `@rsc` etc.). 31 | 32 | - Possible four-letter alternative names: sake, salt, saxe, soon, star 33 | - Possible two-letter core names: sa, sl 34 | 35 | Checkmarks are a first pass in `@rs` single-precision floating-point implementation: 36 | 37 | ## Constants 38 | 39 | - [x] `pi` 40 | - [x] `e` 41 | - [ ] `i` (complex only) 42 | - [x] `phi` 43 | - [x] `sqrt2` 44 | 45 | ## Comparison 46 | 47 | - [x] `isclose` 48 | - [x] `allclose` (over a `(list @r)`) 49 | - [x] `isint` 50 | - [ ] `isreal` (complex only) 51 | - [ ] `isimag` (complex only) 52 | 53 | ## Algebraic 54 | 55 | - [x] `sgn` (also `++sig` for compatibility) 56 | - [x] `abs` 57 | - [x] `sqrt` 58 | - [x] `cbrt` 59 | - [x] `arg` 60 | - [ ] `conj` (complex conjugate) (complex only) 61 | - [x] `pow` 62 | - [x] `pown` (faster integer `pow`) 63 | - [x] `log` 64 | - [x] `log10` 65 | - [x] `log2` 66 | - [x] `exp` 67 | - [x] `binomial` (Binomial coefficient) 68 | 69 | ## Trigonometric 70 | 71 | - [x] `sin` 72 | - [x] `cos` 73 | - [x] `tan` 74 | - [x] `csc` 75 | - [x] `sec` 76 | - [x] `cot` 77 | - [x] `arcsin` 78 | - [x] `arccos` 79 | - [x] `arctan` 80 | - [x] `arccsc` 81 | - [x] `arcsec` 82 | - [x] `arccot` 83 | - [x] `crd` (chord) 84 | - [x] `siv` (versine) 85 | 86 | ## Hyperbolic 87 | 88 | - [x] `sinh` 89 | - [x] `cosh` 90 | - [x] `tanh` 91 | - [x] `csch` 92 | - [x] `sech` 93 | - [x] `coth` 94 | - [x] `arcsinh` 95 | - [x] `arccosh` 96 | - [x] `arctanh` 97 | - [x] `arccsch` 98 | - [x] `arcsech` 99 | - [x] `arccoth` 100 | 101 | ## Analytical 102 | 103 | - [ ] `besselj` 104 | - [ ] `bessely` 105 | - [ ] `besseli` 106 | - [ ] `besselk` 107 | - [ ] `ai` 108 | - [ ] `bi` 109 | - [ ] `gamma` 110 | - [ ] `elliptic` 111 | - [x] `zeta` 112 | 113 | ## Operations 114 | 115 | - [x] `round` (regular banker's roundaing) 116 | - [x] `round-decimal` (rounding to specific accuracy, e.g. `.100.01`) 117 | - [x] `linspace` (`++gulf` which evenly spans a range in floating-point) 118 | - [x] `iota` (APL-style `++gulf` in floating-point) 119 | - [x] `diff` (placeholder for adaptive algorithm in future) 120 | - [x] `difffinite` (finite difference) 121 | - [ ] `diffpade` (Padé approximation) 122 | - [x] `integrate` (placeholder for adaptive algorithm as door in future) 123 | - [x] `inttrapez` (trapezoid rule) 124 | - [x] `intsimpson` (Simpson's rule) 125 | - [x] `newton` (locate a function zero using Newton's method) 126 | 127 | The library will pass through `++rs` behaviors for `++add` and so forth for ease of use. Thus Saloon's `++rs` can act as a drop-in core for almost all Hoon `++rs` arms (except `++exp` and `++ma`). 128 | 129 | ## References 130 | 131 | - Milton Abramowitz & Irene Stegun, _Handbook of Mathematical Functions with Formulas, Graphs, and Mathematical Tables_. 1964–2010. 132 | - Forman Acton, _Numerical Methods that (Usually) Work_, 1ed. 1997. 133 | - [Bartosz Ciechanowski, “Float Exposed” (webapp)](https://float.exposed/0x00000001) 134 | - [David Goldberg, “What Every Computer Scientist Should Know About Floating-Point Arithmetic”](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) 135 | - Parviz Moin, _Fundamentals of Engineering Numerical Analysis_. 2ed. 2001. 136 | -------------------------------------------------------------------------------- /src/tests/lib/saloon.hoon: -------------------------------------------------------------------------------- 1 | /+ *test 2 | /+ saloon 3 | :: 4 | :::: 5 | :: 6 | ^| 7 | |_ $: atol=_.1e-3 :: absolute tolerance for precision of operations 8 | rtol=_.1e-5 :: relative tolerance for precision of operations 9 | == 10 | :: Auxiliary tools 11 | ++ expect-near 12 | |= [expected=@rs actual=@rs] ^- tang 13 | ?: (~(isclose rs:saloon [%z rtol]) `@rs`expected `@rs`actual) 14 | ~ 15 | :~ [%palm [": " ~ ~ ~] [leaf+"expected" "{}"]] 16 | [%palm [": " ~ ~ ~] [leaf+"actual" "{}"]] 17 | == 18 | ++ expect-near-per 19 | |= [expected=@rs actual=@rs] ^- tang 20 | =/ pdif (div:rs:saloon (abs:rs:saloon (sub:rs:saloon actual expected)) expected) 21 | ?: (lth:rs:saloon pdif atol) 22 | ~ 23 | :~ [%palm [": " ~ ~ ~] [leaf+"expected" "{}"]] 24 | [%palm [": " ~ ~ ~] [leaf+"actual" "{}"]] 25 | == 26 | 27 | :: Comparison 28 | ::++ test-isclose !! 29 | ::++ test-allclose !! 30 | ++ test-factorial ^- tang 31 | ;: weld 32 | %+ expect-near 33 | .1 34 | (factorial:rs:saloon .0) 35 | %+ expect-near 36 | .1 37 | (factorial:rs:saloon .1) 38 | %+ expect-near 39 | .120 40 | (factorial:rs:saloon .5) 41 | == 42 | ++ test-abs ^- tang 43 | ;: weld 44 | %+ expect-near 45 | .1 46 | (abs:rs:saloon .-1) 47 | %+ expect-near 48 | .1 49 | (abs:rs:saloon .1) 50 | %+ expect-near 51 | .120 52 | (abs:rs:saloon .-120) 53 | == 54 | ++ test-exp ^- tang 55 | ;: weld 56 | %+ expect-near-per 57 | .148.413 58 | (exp:rs:saloon .5) 59 | %+ expect-near-per 60 | .26903.186 61 | (exp:rs:saloon .10.2) 62 | == 63 | ++ test-pow-n ^- tang 64 | ;: weld 65 | %+ expect-near-per 66 | .132.651 67 | (pow-n:rs:saloon .5.1 .3) 68 | %+ expect-near-per 69 | .-27 70 | (pow-n:rs:saloon .-3 .3) 71 | == 72 | ++ test-log-e-2 ^- tang 73 | ;: weld 74 | %+ expect-near-per 75 | .0.33647 76 | (log-e-2:rs:saloon .1.4) 77 | %+ expect-near-per 78 | .-0.5978 79 | (log-e-2:rs:saloon .0.55) 80 | == 81 | ++ test-log ^- tang 82 | ;: weld 83 | %+ expect-near-per 84 | .-2.30259 85 | (log:rs:saloon .0.1) 86 | %+ expect-near-per 87 | .4.094345 88 | (log:rs:saloon .60) 89 | == 90 | ++ test-log2 ^- tang 91 | ;: weld 92 | %+ expect-near-per 93 | .4.9069 94 | (log2:rs:saloon .30) 95 | %+ expect-near-per 96 | .-0.8625 97 | (log2:rs:saloon .0.55) 98 | == 99 | ++ test-log10 ^- tang 100 | ;: weld 101 | %+ expect-near-per 102 | .1.477121 103 | (log10:rs:saloon .30) 104 | %+ expect-near-per 105 | .-0.180456 106 | (log10:rs:saloon .0.66) 107 | == 108 | ++ test-pow ^- tang 109 | ;: weld 110 | %+ expect-near-per 111 | .202.582 112 | (pow:rs:saloon .5 .3.3) 113 | %+ expect-near-per 114 | .-391.35393 115 | (pow:rs:saloon .-3.3 .5) 116 | %+ expect-near-per 117 | .0.00493627 118 | (pow:rs:saloon .5 .-3.3) 119 | %+ expect-near-per 120 | .391.35393 121 | (pow:rs:saloon .3.3 .5) 122 | == 123 | ++ test-sqrt ^- tang 124 | ;: weld 125 | %+ expect-near-per 126 | .2 127 | (sqrt:rs:saloon .4) 128 | %+ expect-near-per 129 | .1.41421 130 | (sqrt:rs:saloon .2) 131 | == 132 | ++ test-cbrt ^- tang 133 | ;: weld 134 | %+ expect-near-per 135 | .3 136 | (cbrt:rs:saloon .27) 137 | %+ expect-near-per 138 | .1.63864 139 | (cbrt:rs:saloon .4.4) 140 | == 141 | ::++ test-binomial !! 142 | ++ test-sin ^- tang 143 | ;: weld 144 | %+ expect-near-per 145 | .-0.756802 146 | (sin:rs:saloon .4) 147 | %+ expect-near-per 148 | .0.522687 149 | (sin:rs:saloon .0.55) 150 | == 151 | ++ test-cos ^- tang 152 | ;: weld 153 | %+ expect-near-per 154 | .-0.65364 155 | (cos:rs:saloon .4) 156 | %+ expect-near-per 157 | .0.852525 158 | (cos:rs:saloon .0.55) 159 | == 160 | ++ test-tan ^- tang 161 | ;: weld 162 | %+ expect-near-per 163 | .1.15782 164 | (tan:rs:saloon .4) 165 | %+ expect-near-per 166 | .0.613105 167 | (tan:rs:saloon .0.55) 168 | == 169 | ++ test-csc ^- tang 170 | ;: weld 171 | %+ expect-near-per 172 | .-1.32135 173 | (csc:rs:saloon .4) 174 | %+ expect-near-per 175 | .1.91319 176 | (csc:rs:saloon .0.55) 177 | == 178 | ++ test-sec ^- tang 179 | ;: weld 180 | %+ expect-near-per 181 | .-1.52989 182 | (sec:rs:saloon .4) 183 | %+ expect-near-per 184 | .1.17299 185 | (sec:rs:saloon .0.55) 186 | == 187 | ++ test-cot ^- tang 188 | ;: weld 189 | %+ expect-near-per 190 | .0.86369 191 | (cot:rs:saloon .4) 192 | %+ expect-near-per 193 | .1.63104 194 | (cot:rs:saloon .0.55) 195 | == 196 | ++ test-arcsin ^- tang 197 | ;: weld 198 | %+ expect-near-per 199 | .1.11977 200 | (arcsin:rs:saloon .0.9) 201 | %+ expect-near-per 202 | .0.55 203 | (arcsin:rs:saloon .0.522687) 204 | == 205 | ++ test-arccos ^- tang 206 | ;: weld 207 | %+ expect-near-per 208 | .2.28318 209 | (arccos:rs:saloon .-0.65364) 210 | %+ expect-near-per 211 | .0.55 212 | (arccos:rs:saloon .0.852525) 213 | == 214 | ++ test-arctan ^- tang 215 | ;: weld 216 | %+ expect-near-per 217 | .0.732815 218 | (arctan:rs:saloon .0.9) 219 | %+ expect-near-per 220 | .0.55 221 | (arctan:rs:saloon .0.613105) 222 | == 223 | ++ test-arccsc ^- tang 224 | ;: weld 225 | %+ expect-near-per 226 | .-0.858406 227 | (arccsc:rs:saloon .-1.32135) 228 | %+ expect-near-per 229 | .0.55 230 | (arccsc:rs:saloon .1.91319) 231 | == 232 | ++ test-arcsec ^- tang 233 | ;: weld 234 | %+ expect-near-per 235 | .2.28318 236 | (arcsec:rs:saloon .-1.52989) 237 | %+ expect-near-per 238 | .0.55 239 | (arcsec:rs:saloon .1.17299) 240 | == 241 | ++ test-arccot ^- tang 242 | ;: weld 243 | %+ expect-near-per 244 | .0.24498 245 | (arccot:rs:saloon .4) 246 | %+ expect-near-per 247 | .0.55 248 | (arccot:rs:saloon .1.63104) 249 | == 250 | ::: https://en.wikipedia.org/wiki/Particular_values_of_the_gamma_function 251 | ::++ test-gamma ^- tang 252 | ::;: weld 253 | ::%+ expect-near 254 | ::.1.772453850 255 | ::(gamma:rs:saloon .0.5) 256 | ::%+ expect-near 257 | ::.0.886226925 258 | ::(gamma:rs:saloon .1.5) 259 | ::%+ expect-near 260 | ::.1.329340388 261 | ::(gamma:rs:saloon .2.5) 262 | ::%+ expect-near 263 | ::.3.32335097 264 | ::(gamma:rs:saloon .3.5) 265 | ::%+ expect-near 266 | ::.-3.544907701 267 | ::(gamma:rs:saloon .-0.5) 268 | ::== 269 | -- 270 | -------------------------------------------------------------------------------- /src/lib/saloon.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :::: Saloon: Scientific ALgorithms in hOON 3 | :: 4 | :: Transcendental functions library for Urbit. 5 | :: 6 | :: Pure Hoon implementations are generally naive formally correct algorithms, 7 | :: awaiting efficient jetting. 8 | :: 9 | :: @rs-compatible arm, single-precision floating-point 10 | |% 11 | ++ rs 12 | :: mathematics constants to single precision 13 | =/ tau .6.2831853 14 | =/ pi .3.14159265 15 | =/ e .2.7182818 16 | =/ phi .0.57721566 17 | =/ sqrt2 .1.4142135 18 | =/ ln2 .0.69314718 19 | =/ ln10 .2.30258509 20 | :: numerics constants to single precision 21 | =/ epsc .1e-5 :: C standard minimum epsilon for binary32 22 | =/ epsd `@rs`0b1 :: IEEE-754 dwarf (closest number to zero) 23 | ^| 24 | |_ $: r=$?(%n %u %d %z) :: round nearest, up, down, to zero 25 | rtol=_epsc :: relative tolerance for precision of operations 26 | == 27 | ++ sea sea:^rs 28 | ++ bit bit:^rs 29 | ++ sun sun:^rs 30 | ++ san san:^rs 31 | ::++ exp exp:^rs :: no pass-through because of exp function 32 | ++ toi toi:^rs 33 | ++ drg drg:^rs 34 | ++ grd grd:^rs 35 | :: 36 | :: Comparison 37 | :: 38 | ++ lth lth:^rs 39 | ++ lte lte:^rs 40 | ++ equ equ:^rs 41 | ++ gte gte:^rs 42 | ++ gth gth:^rs 43 | ++ isclose 44 | |= [p=@rs r=@rs] 45 | (lth (abs (sub p r)) rtol) 46 | ++ allclose 47 | |= [p=@rs q=(list @rs)] 48 | =/ i 0 49 | =/ n (lent q) 50 | |- ^- ? 51 | ?: =(n i) 52 | %.y 53 | ?. (isclose p (snag i q)) 54 | %.n 55 | $(i +(i)) 56 | :: use equality rather than isclose here 57 | ++ isint 58 | |= x=@rs ^- ? 59 | (equ x (san (need (toi x)))) 60 | :: 61 | :: Algebraic 62 | :: 63 | ++ add add:^rs 64 | ++ sub sub:^rs 65 | ++ mul mul:^rs 66 | ++ div div:^rs 67 | ++ fma fma:^rs 68 | ++ sig |=(x=@rs =(0 (rsh [0 31] x))) 69 | ++ sgn sig 70 | ++ neg |=(x=@rs (sub .0 x)) 71 | ++ factorial 72 | |= x=@rs ^- @rs 73 | =/ t=@rs .1 74 | ?: (isclose x .0) 75 | t 76 | |- ^- @rs 77 | ?: (isclose x .1) 78 | t 79 | $(x (sub x .1), t (mul t x)) 80 | ++ abs 81 | |= x=@rs ^- @rs 82 | ?:((sgn x) x (neg x)) 83 | ++ exp 84 | |= x=@rs ^- @rs 85 | =/ p .1 86 | =/ po .-1 87 | =/ i .1 88 | |- ^- @rs 89 | ?: (lth (abs (sub po p)) rtol) 90 | p 91 | $(i (add i .1), p (add p (div (pow-n x i) (factorial i))), po p) 92 | :: restricted pow, based on integers only 93 | ++ pow-n 94 | |= [x=@rs n=@rs] ^- @rs 95 | ?: =(n .0) .1 96 | =/ p x 97 | |- ^- @rs 98 | ?: (lth n .2) 99 | p 100 | $(n (sub n .1), p (mul p x)) 101 | :: natural logarithm, only converges for z < 2 102 | ++ log-e-2 103 | |= z=@rs ^- @rs 104 | =/ p .0 105 | =/ po .-1 106 | =/ i .1 107 | |- ^- @rs 108 | ?: (lth (abs (sub po p)) rtol) 109 | p 110 | =/ ii (add .1 i) 111 | =/ term (mul (pow-n .-1 (add .1 i)) (div (pow-n (sub z .1) i) i)) 112 | $(i (add i .1), p (add p term), po p) 113 | :: natural logarithm, z > 0 114 | ++ log 115 | |= z=@rs ^- @rs 116 | =/ p .0 117 | =/ po .-1 118 | =/ i .0 119 | |- ^- @rs 120 | ?: (lth (abs (sub po p)) rtol) 121 | (mul (div (mul .2 (sub z .1)) (add z .1)) p) 122 | =/ term1 (div .1 (add .1 (mul .2 i))) 123 | =/ term2 (mul (sub z .1) (sub z .1)) 124 | =/ term3 (mul (add z .1) (add z .1)) 125 | =/ term (mul term1 (pow-n (div term2 term3) i)) 126 | $(i (add i .1), p (add p term), po p) 127 | :: logarithm base 2 128 | ++ log2 129 | |= z=@rs 130 | (div (log z) ln2) 131 | :: logarithm base 10 132 | ++ log10 133 | |= z=@rs 134 | (div (log z) ln10) 135 | :: general power, based on logarithms 136 | :: x^n = exp(n ln x) 137 | ++ pow 138 | |= [x=@rs n=@rs] ^- @rs 139 | (exp (mul n (log x))) 140 | :: square root 141 | ++ sqt sqrt 142 | ++ sqrt 143 | |= x=@rs ^- @rs 144 | ?> (sgn x) 145 | (pow x .0.5) 146 | :: cubic root 147 | ++ cbrt 148 | |= x=@rs ^- @rs 149 | ?> (sgn x) 150 | (pow x .0.33333333) 151 | :: argument (real argument = absolute value) 152 | ++ arg abs 153 | :: binomial coefficient 154 | ++ binomial 155 | |= [p=@ud q=@ud] ^- @ud 156 | !! 157 | ::(div (factorial p) (mul (factorial q) (factorial (sub p q)))) 158 | :: 159 | :: Trigonometric functions 160 | :: 161 | :: sin x = x - x^3/3! + x^5/5! - x^7/7! + x^9/9! - ... 162 | ++ sin 163 | |= x=@rs ^- @rs 164 | =/ p .0 165 | =/ po .-1 166 | =/ i .0 167 | |- ^- @rs 168 | ?: (lth (abs (sub po p)) rtol) 169 | p 170 | =/ ii (add (mul .2 i) .1) 171 | =/ term (mul (pow-n .-1 i) (div (pow-n x ii) (factorial ii))) 172 | $(i (add i .1), p (add p term), po p) 173 | :: cos x = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8! - ... 174 | ++ cos 175 | |= x=@rs ^- @rs 176 | =/ p .1 177 | =/ po .-1 178 | =/ i .1 179 | |- ^- @rs 180 | ?: (lth (abs (sub po p)) rtol) 181 | p 182 | =/ ii (mul .2 i) 183 | =/ term (mul (pow-n .-1 i) (div (pow-n x ii) (factorial ii))) 184 | $(i (add i .1), p (add p term), po p) 185 | :: tan x = sin x / cos x 186 | ++ tan 187 | |= x=@rs ^- @rs 188 | (div (sin x) (cos x)) 189 | :: TODO domain errors 190 | :: reciprocal functions 191 | ++ csc |=(x=@rs (div .1 (sin x))) 192 | ++ sec |=(x=@rs (div .1 (cos x))) 193 | ++ cot |=(x=@rs (div .1 (tan x))) 194 | :: https://dsp.stackexchange.com/questions/25770/looking-for-an-arcsin-algorithm 195 | :: arcsin x = x + (1/2)*(x^3/3) + (3/8)(x^5/5) + (15/48)(x^7/7) + ... 196 | ++ arcsin 197 | |= x=@rs ^- @rs 198 | =/ p .0 199 | =/ po .-1 200 | =/ i .0 201 | ?: (gte (abs x) .1) 202 | !! 203 | |- ^- @rs 204 | ?: (lth (abs (sub po p)) rtol) 205 | p 206 | =/ ii (mul .2 i) 207 | =/ ti (mul (pow-n .2 i) (factorial i)) 208 | =/ oi (add (mul .2 i) .1) 209 | =/ term (mul (div (factorial ii) (mul ti ti)) (div (pow-n x oi) oi)) 210 | $(i (add i .1), p (add p term), po p) 211 | ++ arccos 212 | |= x=@rs ^- @rs 213 | (sub (div pi .2) (arcsin x)) 214 | ++ arctan 215 | |= x=@rs ^- @rs 216 | =/ p .0 217 | =/ po .-1 218 | =/ i .0 219 | ?: (gte (abs x) .1) 220 | !! 221 | |- ^- @rs 222 | ?: (lth (abs (sub po p)) rtol) 223 | p 224 | =/ ii (add (mul .2 i) .1) 225 | =/ term (div (mul (pow-n .-1 i) (pow-n x ii)) ii) 226 | $(i (add i .1), p (add p term), po p) 227 | ++ arccsc 228 | |= x=@rs ^- @rs 229 | (arcsin (div .1 x)) 230 | ++ arcsec 231 | |= x=@rs ^- @rs 232 | (arccos (div .1 x)) 233 | ++ arccot 234 | |= x=@rs ^- @rs 235 | (arctan (div .1 x)) 236 | :: chord 237 | ++ crd 238 | |= z=@rs ^- @rs 239 | (mul .2 (sin (mul z .0.5))) 240 | :: versine 241 | ++ siv 242 | |= z=@rs ^- @rs 243 | (mul (sin z) (tan (mul z .0.5))) 244 | :: 245 | :: Hyperbolic functions 246 | :: 247 | :: hyperbolic sine 248 | ++ sinh 249 | |= x=@rs ^- @rs 250 | (mul .0.5 (sub (exp x) (exp (neg x)))) 251 | :: hyperbolic cosine 252 | ++ cosh 253 | |= x=@rs ^- @rs 254 | (mul .0.5 (add (exp x) (exp (neg x)))) 255 | :: hyperbolic tangent 256 | ++ tanh 257 | |= x=@rs ^- @rs 258 | (div (sinh x) (cosh x)) 259 | :: reciprocal functions 260 | ++ csch |=(x=@rs (div .1 (sinh x))) 261 | ++ sech |=(x=@rs (div .1 (cosh x))) 262 | ++ coth |=(x=@rs (div .1 (tanh x))) 263 | :: hyperbolic arcsin 264 | ++ arcsinh 265 | |= x=@rs ^- @rs 266 | (log (add x (sqrt (add (mul x x) .1)))) 267 | :: hyperbolic arccos 268 | ++ arccosh 269 | |= x=@rs ^- @rs 270 | ?: (lth x .1) 271 | !! 272 | (log (add x (sqrt (sub (mul x x) .1)))) 273 | :: hyperbolic arctan 274 | ++ arctanh 275 | |= x=@rs ^- @rs 276 | ?: (gte (abs x) .1) 277 | !! 278 | (mul .0.5 (log (div (add .1 x) (sub .1 x)))) 279 | :: reciprocal functions 280 | ++ arccsch 281 | |= x=@rs ^- @rs 282 | ?: (isclose x .0) 283 | !! 284 | (log (add (div .1 x) (sqrt (add (div .1 (pow-n x .2)) .1)))) 285 | ++ arcsech 286 | |= x=@rs ^- @rs 287 | ?: (gth x .1) 288 | !! 289 | ?: (lte x .0) 290 | !! 291 | (log (div (add .1 (sqrt (sub .1 (pow-n x .2)))) x)) 292 | ++ arccoth 293 | |= x=@rs ^- @rs 294 | ?: (lte (abs x) .1) 295 | !! 296 | (mul .0.5 (log (div (add x .1) (sub x .1)))) 297 | :: 298 | :: Analytical 299 | :: 300 | :: Lanczos approximation for the Gamma function 301 | :: https://en.wikipedia.org/wiki/Lanczos_approximation 302 | ++ gamma 303 | !! 304 | :: Implementation of the Hurwitz Zeta function 305 | ++ zeta 306 | |= [x=@rs q=@rs] 307 | ^- @rs 308 | =/ p .0 309 | =/ po .-1 310 | =/ i .0 311 | |- ^- @rs 312 | ?: (lth (abs (sub po p)) rtol) 313 | p 314 | =/ kq (add i q) 315 | =/ term (div .1 (pow kq x)) 316 | $(i (add i .1), p (add p term), po p) 317 | :: 318 | :: Operations 319 | :: 320 | :: https://www.eetimes.com/an-introduction-to-different-rounding-algorithms/ 321 | ++ floor 322 | |= x=@rs ^- @rs 323 | ~& >> rs 324 | ~& >>> ^rs 325 | !! 326 | ::(need (~(toi rs %d) x)) 327 | ++ ceil 328 | |= x=@rs ^- @rs 329 | ~& >> rs 330 | ~& >>> ^rs 331 | !! 332 | ::(need (~(toi rs [%u rtol]) x)) 333 | :: regular round-half-up 334 | ++ round 335 | |= [x=@rs] ^- @rs 336 | (ceil (mul (floor (mul .2 x)) .0.5)) 337 | ++ round-decimal 338 | |= [x=@rs y=@sd] 339 | (div (round (mul x (pow .10 (san y)))) (pow .10 (san y))) 340 | ++ linspace 341 | |= [lims=[@rs @rs] n=@ud] ^- (list @rs) 342 | =/ i 0 343 | =| s=(list @rs) 344 | =/ f -:lims 345 | =/ dx (div (sub +:lims -:lims) (sun n)) 346 | %- flop 347 | |- ^+ s 348 | ?: =(i n) s 349 | %= $ 350 | i +(i) 351 | f (add f dx) 352 | s [f s] 353 | == 354 | ++ iota 355 | |= [l=@rs r=@rs] 356 | ?. &((isint l) (isint r)) !! 357 | (linspace [l r] `@ud`(round (sub r l))) 358 | :: Placeholder, probably as a door so can default to gate 359 | ++ diff !! 360 | :: Finite difference, central difference formula 361 | ++ difffinite 362 | |* [f=gate x=@rs dx=@rs] 363 | =/ fm1 (f (sub x dx)) 364 | =/ f2 (sub .0 (mul .2 (f x))) 365 | =/ fp1 (f (add x dx)) 366 | (div :(add fm1 f2 fp1) (mul dx dx)) 367 | ++ diffpade !! 368 | :: Placeholder, probably as a door so can default to gate 369 | ++ integrate !! 370 | :: Trapezoid rule integration 371 | ++ inttrapez 372 | |* [f=gate lims=[@rs @rs] dx=@rs n=@ud] 373 | =/ i 1 374 | =/ xs (linspace lims n) 375 | =/ s (mul .0.5 (add (f (snag 0 xs)) (f (snag (dec n) xs)))) 376 | %- (cury mul dx) 377 | |- ^- @rs 378 | ?: =(n +(i)) s 379 | $(i +(i), s (add (f (snag i xs)) s)) 380 | :: Trapezoid rule integration 381 | ::++ intsimpson 382 | ::|* [f=gate lims=[@rs @rs] dx=@rs n=@ud] 383 | ::=/ i 1 384 | ::=/ xs (linspace lims n) 385 | ::=/ s (mul .0.33333333 (add (f (snag 0 xs)) (f (snag (dec n) xs)))) 386 | ::%- (cury mul dx) 387 | ::|- ^- @rs 388 | ::?: =(n +(i)) s 389 | ::?: =(1 (mod n .2)) 390 | ::$(i +(i), s (add (mul .4 (f (snag i xs)) s))) 391 | ::$(i +(i), s (add (mul .2 (f (snag i xs)) s))) 392 | :: Newton's method for finding zero 393 | ++ newton 394 | |* [f=gate x0=@rs] 395 | =/ i 1 396 | =| x=@rs 397 | =/ dx .1 398 | |- ^- @rs 399 | ?: (isclose .0 (f x)) x 400 | %= $ 401 | dx (abs (sub x x0)) 402 | x (sub x0 (div x (difffinite f x dx))) 403 | x0 x 404 | == 405 | -- :: rs 406 | -- 407 | --------------------------------------------------------------------------------