diff options
Diffstat (limited to '')
-rw-r--r-- | stdlib/source/lux/math/complex.lux | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/stdlib/source/lux/math/complex.lux b/stdlib/source/lux/math/complex.lux index 69e9f71f9..252e31d51 100644 --- a/stdlib/source/lux/math/complex.lux +++ b/stdlib/source/lux/math/complex.lux @@ -116,6 +116,15 @@ {#real (r./ param real) #imaginary (r./ param imaginary)})) +(def: #export (c.% param input) + (-> Complex Complex Complex) + (let [scaled (c./ param input) + quotient (|> scaled + (update@ #real math;floor) + (update@ #imaginary math;floor))] + (c.- (c.* quotient param) + input))) + (def: #export (cos subject) (-> Complex Complex) (let [(^slots [#real #imaginary]) subject] @@ -167,21 +176,37 @@ #imaginary (r./ d (math;sin i2))})) (def: #export (c.abs subject) - (-> Complex Real) + (-> Complex Complex) (let [(^slots [#real #imaginary]) subject] - (if (r.< (r/abs imaginary) - (r/abs real)) - (if (r.= 0.0 imaginary) - (r/abs real) - (let [q (r./ imaginary real)] - (r.* (math;sqrt (r.+ 1.0 (r.* q q))) - (r/abs imaginary)))) - (if (r.= 0.0 real) - (r/abs imaginary) - (let [q (r./ real imaginary)] - (r.* (math;sqrt (r.+ 1.0 (r.* q q))) - (r/abs real)))) - ))) + (complex (if (r.< (r/abs imaginary) + (r/abs real)) + (if (r.= 0.0 imaginary) + (r/abs real) + (let [q (r./ imaginary real)] + (r.* (math;sqrt (r.+ 1.0 (r.* q q))) + (r/abs imaginary)))) + (if (r.= 0.0 real) + (r/abs imaginary) + (let [q (r./ real imaginary)] + (r.* (math;sqrt (r.+ 1.0 (r.* q q))) + (r/abs real)))) + )))) + +(struct: #export _ (Number Complex) + (def: + c.+) + (def: - c.-) + (def: * c.*) + (def: / c./) + (def: % c.%) + (def: (negate x) + (|> x + (update@ #real r/negate) + (update@ #imaginary r/negate))) + (def: abs c.abs) + (def: (signum x) + (|> x + (update@ #real r/signum) + (update@ #imaginary r/signum)))) (def: #export (exp subject) (-> Complex Complex) @@ -193,7 +218,7 @@ (def: #export (log subject) (-> Complex Complex) (let [(^slots [#real #imaginary]) subject] - {#real (math;log (c.abs subject)) + {#real (|> subject c.abs (get@ #real) math;log) #imaginary (math;atan2 real imaginary)})) (do-template [<name> <type> <op>] @@ -211,7 +236,7 @@ (def: #export (sqrt (^@ input (^slots [#real #imaginary]))) (-> Complex Complex) - (let [t (|> input c.abs (r.+ (r/abs real)) (r./ 2.0) math;sqrt)] + (let [t (|> input c.abs (get@ #real) (r.+ (r/abs real)) (r./ 2.0) math;sqrt)] (if (r.>= 0.0 real) {#real t #imaginary (r./ (r.* 2.0 t) @@ -271,8 +296,7 @@ (if (n.= +0 nth) (list) (let [r-nth (|> nth nat-to-int int-to-real) - nth-root-of-abs (math;pow (r./ r-nth 1.0) - (c.abs input)) + nth-root-of-abs (|> input c.abs (get@ #real) (math;pow (r./ r-nth 1.0))) nth-phi (|> input argument (r./ r-nth)) slice (|> math;pi (r.* 2.0) (r./ r-nth))] (|> (list;n.range +0 (n.dec nth)) |