diff options
author | Marvin Borner | 2024-08-06 01:53:19 +0200 |
---|---|---|
committer | Marvin Borner | 2024-08-06 01:53:19 +0200 |
commit | 0c3b464d3c73fcd1a6fde3f2f5882eddd5c79685 (patch) | |
tree | 6ae5ac53ca8c4feff7902b0df9d6c5c94bf3eb87 /std/Math | |
parent | e2c3965f929556dda9f779c237f4ba96c8f6c542 (diff) |
Complex updates
Diffstat (limited to 'std/Math')
-rw-r--r-- | std/Math/Complex.bruijn | 64 | ||||
-rw-r--r-- | std/Math/Rational.bruijn | 50 | ||||
-rw-r--r-- | std/Math/Real.bruijn | 63 |
3 files changed, 120 insertions, 57 deletions
diff --git a/std/Math/Complex.bruijn b/std/Math/Complex.bruijn index d3b5a7d..03ae8d5 100644 --- a/std/Math/Complex.bruijn +++ b/std/Math/Complex.bruijn @@ -3,69 +3,60 @@ :import std/Combinator . :import std/Pair . +:import std/Number N +:import std/Math/Rational Q :import std/Math/Real R -ι (+0.0+1.0i) +i (+0.0+1.0i) # converts a balanced ternary number to a complex number -number→complex [[0 (R.number→real 1) (+0.0r)]] ⧗ Number → Complex +number→complex [[(R.number→real 1 0) : ((+0.0r) 0)]] ⧗ Number → Complex :test (number→complex (+5)) ((+5.0+0.0i)) # returns real part of a complex number -real fst ⧗ Complex → Real +real [[1 0 [[1]]]] ⧗ Complex → Real :test (real (+5.0+2.0i)) ((+5.0r)) # returns imaginary part of a complex number -imag snd ⧗ Complex → Real +imag [[1 0 [[0]]]] ⧗ Complex → Real :test (imag (+5.0+2.0i)) ((+2.0r)) -# approximates complex number by turning it into a pair of rationals -approx &[[[(2 0) : (1 0)]]] ⧗ Complex → Number → (Pair Rational Rational) - -:test (approx (+5.0+2.0i) (+2)) ((+5.0q) : (+2.0q)) - -# returns true if two complex numbers are equal approximately -approx-eq? [[[R.approx-eq? 2 (1 2) (0 2)]]] ⧗ Number → Complex → Complex → Boolean - -# TODO: bigger value (higher performance first!) -…≈?… approx-eq? (+1000) - # adds two complex numbers -add &[[&[[(R.add 3 1) : (R.add 2 0)]]]] ⧗ Complex → Complex → Complex +add φ &[[&[[(Q.add 3 1) : (Q.add 2 0)]]]] ⧗ Complex → Complex → Complex …+… add # subtracts two complex numbers -sub &[[&[[(R.sub 3 1) : (R.sub 2 0)]]]] ⧗ Complex → Complex → Complex +sub φ &[[&[[(Q.sub 3 1) : (Q.sub 2 0)]]]] ⧗ Complex → Complex → Complex -…+… sub +…-… sub # multiplies two complex numbers -mul &[[&[[p : q]]]] ⧗ Complex → Complex → Complex - p R.sub (R.mul 3 1) (R.mul 2 0) - q R.add (R.mul 3 0) (R.mul 2 1) +mul φ &[[&[[p : q]]]] ⧗ Complex → Complex → Complex + p Q.sub (Q.mul 3 1) (Q.mul 2 0) + q Q.add (Q.mul 3 0) (Q.mul 2 1) …⋅… mul # divides two complex numbers -div &[[&[[p : q]]]] ⧗ Complex → Complex → Complex - p R.div (R.add (R.mul 3 1) (R.mul 2 0)) (R.add (R.mul 1 1) (R.mul 0 0)) - q R.div (R.sub (R.mul 2 1) (R.mul 1 0)) (R.add (R.mul 1 1) (R.mul 0 0)) +div φ &[[&[[p : q]]]] ⧗ Complex → Complex → Complex + p Q.div (Q.add (Q.mul 3 1) (Q.mul 2 0)) (Q.add (Q.mul 1 1) (Q.mul 0 0)) + q Q.div (Q.sub (Q.mul 2 1) (Q.mul 3 0)) (Q.add (Q.mul 1 1) (Q.mul 0 0)) …/… div # negates a complex number -negate &[[(R.negate 1) : (R.negate 0)]] ⧗ Complex → Complex +negate b &[[(Q.negate 1) : (Q.negate 0)]] ⧗ Complex → Complex -‣ negate # inverts a complex number -invert &[[p : q]] ⧗ Complex → Complex - p R.div 1 (R.add (R.mul 1 1) (R.mul 0 0)) - q R.div 0 (R.add (R.mul 1 1) (R.mul 0 0)) +invert b &[[p : q]] ⧗ Complex → Complex + p Q.div 1 (Q.add (Q.mul 1 1) (Q.mul 0 0)) + q Q.div 0 (Q.add (Q.mul 1 1) (Q.mul 0 0)) ~‣ invert @@ -76,6 +67,17 @@ invert &[[p : q]] ⧗ Complex → Complex # power function: complex^number pow-n [L.nth-iterate (mul 0) (+1.0+0.0i)] ⧗ Complex → Number → Complex -ln [p : q] ⧗ Complex → Complex - p R.ln (&R.hypot 0) - q &R.atan2 0 +exp [[L.nth-iterate &[[[[op]]]] start 0 [[[[1]]]] 0]] ⧗ Complex → Complex + start [0 (+1.0+0.0i) (+1.0+0.0i) (+1.0+0.0i) (+1)] + op [[[2 1 0 (4 + (1 / 0)) N.++3]] pow fac] + pow 6 â‹… 4 + fac 3 â‹… (number→complex 1) + +ln [[[p : q] (1 0)]] ⧗ Complex → Complex + p R.ln (&[[R.hypot [2] [1]]] 0) 1 + q &[[\R.atan2 [2] [1]]] 0 1 + +# complex power function: complex^complex +pow [[exp (0 â‹… (ln 1))]] ⧗ Complex → Complex → Complex + +…**… pow diff --git a/std/Math/Rational.bruijn b/std/Math/Rational.bruijn index e72b6a9..3b7f461 100644 --- a/std/Math/Rational.bruijn +++ b/std/Math/Rational.bruijn @@ -1,11 +1,10 @@ # ideas by u/DaVinci103 # MIT License, Copyright (c) 2024 Marvin Borner -# (p : q) ⇔ (1 / (q + 1)) +# (p : q) ⇔ (p / (q + 1)) :import std/Logic . :import std/Combinator . -:import std/Logic . :import std/Pair . :import std/Math N @@ -24,6 +23,36 @@ eq? &[[&[[N.eq? (N.mul 3 N.++0) (N.mul N.++2 1)]]]] ⧗ Rational → Rational ↠:test ((+42.0) =? (+42.0)) (true) :test ((+0.4) =? (+0.5)) (false) +# returns true if a rational number is greater than another +gt? &[[&[[N.gt? (N.mul 3 N.++0) (N.mul N.++2 1)]]]] ⧗ Rational → Rational → Boolean + +…>?… gt? + +# returns true if a rational number is less than another +lt? &[[&[[N.lt? (N.mul 3 N.++0) (N.mul N.++2 1)]]]] ⧗ Rational → Rational → Boolean + +…<?… lt? + +# returns true if a rational number is positive +positive? \gt? (+0.0) ⧗ Rational → Boolean + +>?‣ positive? + +# returns true if a real number is negative +negative? \lt? (+0.0) ⧗ Rational → Boolean + +<?‣ negative? + +# returns true if a rational number is zero +zero? &[[N.=?1]] ⧗ Rational → Boolean + +=?‣ zero? + +# negates a rational number if <0 +abs &[[N.|1 : N.|0]] ⧗ Rational → Rational + +|‣ abs + # finds smallest equivalent representation of a rational number compress &[[[(N.div 2 0) : N.--(N.div N.++1 0)] (N.gcd 1 N.++0)]] ⧗ Rational → Rational @@ -34,7 +63,7 @@ compress &[[[(N.div 2 0) : N.--(N.div N.++1 0)] (N.gcd 1 N.++0)]] ⧗ Rational â # adds two rational numbers add &[[&[[p : q]]]] ⧗ Rational → Rational → Rational - p N.add (N.mul 3 N.++0) (N.mul 1 N.++2) + p N.add (N.mul 3 N.++0) (N.mul N.++2 1) q N.add (N.mul 2 0) (N.add 2 0) …+… add @@ -43,15 +72,15 @@ add &[[&[[p : q]]]] ⧗ Rational → Rational → Rational :test ((+1.8) + (+1.2) =? (+3.0)) (true) :test ((-1.8) + (+1.2) =? (-0.6)) (true) -reduce [[[(N.div 2 0) : N.--(N.div 1 0)] (N.gcd 1 0)]] +reduce [[[(N.div 2 0) : N.--(N.div 1 0)] (N.gcd 1 0)]] ⧗ Number → Number → Rational add' &[[&[[reduce p q]]]] - p N.add (N.mul 3 N.++0) (N.mul 1 N.++2) + p N.add (N.mul 3 N.++0) (N.mul N.++2 1) q N.mul N.++0 N.++2 # subtracts two rational numbers sub &[[&[[p : q]]]] ⧗ Rational → Rational → Rational - p N.sub (N.mul 3 N.++0) (N.mul 1 N.++2) + p N.sub (N.mul 3 N.++0) (N.mul N.++2 1) q N.add (N.mul 2 0) (N.add 2 0) …-… sub @@ -98,10 +127,6 @@ div [[1 â‹… ~0]] ⧗ Rational → Rational → Rational :test ((+8.0) / (+4.0) =? (+2.0)) (true) :test ((+18.0) / (+12.0) =? (+1.5)) (true) -gt? &[[&[[(N.gt? 1 3) â‹€? (N.gt? 0 2)]]]] - -lt? &[[&[[(N.lt? 1 3) â‹€? (N.lt? 0 2)]]]] - # increments a rational number inc add (+1.0) ⧗ Rational → Rational @@ -112,6 +137,11 @@ dec \sub (+1.0) ⧗ Rational → Rational --‣ dec +# approximates a rational number to n digits +approximate &[[[&[[int : float]] (N.quot-rem 2 N.++1)]]] ⧗ Rational → Number → (List Number) + int 1 + float N.number→list (N.div (N.mul 0 (N.pow (+10) 2)) N.++3) + # TODO: Regression? Importing this into . won't find Q.eq? anymore :import std/List L diff --git a/std/Math/Real.bruijn b/std/Math/Real.bruijn index 9a4b1bd..d334117 100644 --- a/std/Math/Real.bruijn +++ b/std/Math/Real.bruijn @@ -7,7 +7,7 @@ :import std/Math/Rational Q :import std/Math N -# a Real is just a Unary → Rational! +# a Real is just a Number → Rational! # converts a balanced ternary number to a real number number→real [[Q.number→rational 1]] ⧗ Number → Real @@ -18,7 +18,27 @@ number→real [[Q.number→rational 1]] ⧗ Number → Real approx-eq? [[[Q.eq? (1 2) (0 2)]]] ⧗ Number → Real → Real → Boolean # TODO: bigger value?? -…≈?… approx-eq? (+100u) +…≈?… approx-eq? (+100) + +# returns true if a real number is greater than another +gt? [[[Q.gt? (1 2) (0 2)]]] ⧗ Number → Real → Real → Boolean + +…>?… gt? + +# returns true if a real number is less than another +lt? [[[Q.lt? (1 2) (0 2)]]] ⧗ Number → Real → Real → Boolean + +…<?… lt? + +# returns true if a real number is positive +positive? [\(gt? 0) (+0.0r)] ⧗ Number → Real → Boolean + +>?‣ positive? + +# returns true if a real number is negative +negative? [\(lt? 0) (+0.0r)] ⧗ Number → Real → Boolean + +<?‣ negative? # adds two real numbers add φ Q.add ⧗ Real → Real → Real @@ -93,7 +113,7 @@ dec \sub (+1.0r) ⧗ Real → Real # e^x using Taylor expansion # tex: \sum_{n=0}^\infty \frac{x^n}{n!} -unary-exp [[0 &[[[[[[[2 1 0 (Q.add 4 (1 : N.--0)) N.++3]] pow fac]]]]] start [[[[1]]]]]] ⧗ Number → Real +unary-exp [[0 &[[[[[[[2 1 0 (Q.add 4 (1 : N.--0)) N.++3]] pow fac]]]]] start [[[[1]]]]]] ⧗ Unary → Real pow N.mul 6 4 fac N.mul 1 3 start [0 (+1) (+1) (+1.0q) (+1)] @@ -114,7 +134,7 @@ lim-exp [[pow-n [(N.add 2 1) : N.--1] 0]] ⧗ Number → Real # natural logarithm using Taylor expansion # tex: \sum_{n=0}^\infty\frac{2}{2n+1}(\frac{x-1}{x+1})^{2n+1} -# error: O((x-1)/2)^{2n+1} +# error: O(((x-1)/2)^{2n+1}) ln [[[L.nth-iterate &[[[op]]] start 1] (--1 / ++1 0) [[[1]]]]] ⧗ Real → Real start [0 1 (+0.0q) (+0)] op [0 pow (Q.add 2 go) N.++1] @@ -123,7 +143,8 @@ ln [[[L.nth-iterate &[[[op]]] start 1] (--1 / ++1 0) [[[1]]]]] ⧗ Real → Real :test (Q.eq? (ln (+2.0r) (+2)) ((+168) : (+242))) (true) -derive [[[[((3 (0 + 1)) - (3 0)) / 1]] ((+1.0r) / 0) 0]] ⧗ (Real → Real) → (Real → Real) +derive [[[[((3 (2 + 0)) - (3 2)) / 0] ((+1.0r) / conv) 0]]] ⧗ (Real → Real) → (Real → Real) + conv number→real (N.pow (+2) (N.mul (+2) 0)) # power function: real^real pow [[exp (0 â‹… (ln 1))]] ⧗ Real → Real → Real @@ -151,9 +172,9 @@ hypot [[sqrt ((0 â‹… 0) + (1 â‹… 1))]] ⧗ Real → Real → Real # tex: \sum_{n=0}^\infty\frac{2^n n!^2}{(2n+1)!} Ï€/2 [L.nth-iterate &[[[[[op]]]]] start 0 [[[[[3]]]]]] ⧗ Real start [0 (+1) (+0.0q) (+1) (+1) (+1)] - op [0 N.++5 (Q.add 4 ((N.mul 3 2) : N.--1)) enum-pow enum-fac denom] - enum-pow N.mul 3 (+2) - enum-fac N.mul 2 (N.mul 5 5) + op [0 N.++5 (Q.add 4 ((N.mul 3 2) : N.--1)) num-pow num-fac denom] + num-pow N.mul 3 (+2) + num-fac N.mul 2 (N.mul 5 5) denom [N.mul 2 (N.mul 0 N.++0)] (N.mul (+2) 5) # ratio of circle's circumference to its diameter @@ -177,21 +198,31 @@ hypot [[sqrt ((0 â‹… 0) + (1 â‹… 1))]] ⧗ Real → Real → Real ψ -(~φ) # golden ratio from fibonacci convergence -φ* [(L.index (L.iterate &[[0 : (N.add 1 0)]] ((+0) : (+1))) 0) [[1 : N.--0]]] +φ* ++[(L.nth-iterate &[[0 : (N.add 1 0)]] ((+0) : (+1)) 0) [[1 : N.--0]]] # real fibonacci fib [((pow φ 0) - (pow ψ 0)) / (sqrt (+5.0r))] # arctan by Taylor expansion, only for |x|<=1 # tex: \sum_{n=0}^\infty(-1)^n \frac{x^{2n+1}}{2n+1} -arctan* [[[L.nth-iterate &[[[[op]]]] start 1] (1 0) [[[[3]]]]]] ⧗ Real → Real +atan* [[[L.nth-iterate &[[[[op]]]] start 1] (1 0) [[[[3]]]]]] ⧗ Real → Real start [0 1 [[0]] (Q.pow-n 1 (+3)) (+3.0q)] - op [0 ((3 Q.add Q.sub) 4 (Q.div 2 1)) \3 enum denom] - enum Q.mul 2 (Q.mul 5 5) + op [0 ((3 Q.add Q.sub) 4 (Q.div 2 1)) \3 num denom] + num Q.mul 2 (Q.mul 5 5) denom Q.add 1 (+2.0q) # actual arctan for arbitrary x -arctan [[Q.sub (Ï€/2 0) (arctan* [Q.div (+1.0q) (2 1)] 0)]] ⧗ Real → Real - -# TODO: atan2 -atan2 [0] ⧗ Real → Real +atan [[[fallback] (1 0)]] ⧗ Real → Real + normal Q.sub Ï€/2-pm conj-atan + Ï€/2-pm Q.mul (Q.>?0 (+1.0q) (-1.0q)) (Ï€/2 1) + conj-atan atan* [Q.div (+1.0q) 1] 1 + fallback Q.lt? Q.|0 (+1.0) (atan* [1] 1) normal + +# 2-argument arctan +atan2 [[[[[go]] (2 0) (1 0)]]] ⧗ Real → Real → Real + go Q.add a (Q.mul b (Q.add c d)) + z (+0.0q) + a Q.=?0 z (atan [Q.div 2 1] 2) + b Q.sub (+1.0q) (Q.<?1 (+2.0q) z) + c Q.<?0 (Ï€ 2) z + d Q.=?0 (Ï€/2 2) z |