tur/complex
Complex numbers as a plain re/im pair of doubles.
Since: Phase N2 (numeric-tower-rational-complex-plan)
Complex
(defstruct Complex :copy [re : float im : float])
a re/im pair of doubles.
Since: Phase N2
complex/of
(complex/of [re : float im : float] :)
build the complex number re + im*i.
| re | real part | |
| im | imaginary part |
The Complex re + im*i. This is what the `#cx{re im}` literal expands to.
(complex/re (complex/of 3.25 -1.5)) ; => 3.25
Since: Phase N2
complex/from-float
(complex/from-float [x : float] :)
embed a real number in the complex plane.
| x | the real value |
x + 0i.
(complex/im (complex/from-float 2.5)) ; => 0
Since: Phase N2
complex/zero
(complex/zero :)
the complex number 0.
0 + 0i.
(complex/re (complex/zero)) ; => 0
Since: Phase N2
complex/one
(complex/one :)
the complex number 1.
1 + 0i.
(complex/re (complex/one)) ; => 1
Since: Phase N2
complex/i
(complex/i :)
the imaginary unit.
0 + 1i.
(complex/im (complex/i)) ; => 1
Since: Phase N2
complex/re
(complex/re [z : Complex] :)
the real part.
| z | a Complex |
The real component.
(complex/re (complex/of 3.25 -1.5)) ; => 3.25
Since: Phase N2
complex/im
(complex/im [z : Complex] :)
the imaginary part.
| z | a Complex |
The imaginary component.
(complex/im (complex/of 3.25 -1.5)) ; => -1.5
Since: Phase N2
complex/real?
(complex/real? [z : Complex] :)
does this value lie on the real axis?
| z | a Complex |
true when the imaginary part is exactly 0.
(complex/real? (complex/from-float 2.5)) ; => true
Since: Phase N2
complex/add
(complex/add [x : Complex y : Complex] :)
sum of two complex numbers.
| x | left addend | |
| y | right addend |
(a+bi) + (c+di) = (a+c) + (b+d)i.
(complex/re (complex/add (complex/of 3.25 1.5) (complex/of 0.75 0.5))) ; => 4
Since: Phase N2
complex/sub
(complex/sub [x : Complex y : Complex] :)
difference of two complex numbers.
| x | minuend | |
| y | subtrahend |
(a+bi) - (c+di) = (a-c) + (b-d)i.
(complex/im (complex/sub (complex/of 3.25 1.5) (complex/of 0.75 0.5))) ; => 1
Since: Phase N2
complex/neg
(complex/neg [x : Complex] :)
negate a complex number.
| x | a Complex |
-(a+bi) = -a - bi.
(complex/re (complex/neg (complex/of 3.25 -1.5))) ; => -3.25
Since: Phase N2
complex/conj
(complex/conj [x : Complex] :)
complex conjugate.
| x | a Complex |
conj(a+bi) = a - bi.
(complex/im (complex/conj (complex/of 3.25 -1.5))) ; => 1.5
Since: Phase N2
complex/mul
(complex/mul [x : Complex y : Complex] :)
product of two complex numbers.
| x | left factor | |
| y | right factor |
(a+bi)(c+di) = (ac - bd) + (ad + bc)i, written out as arithmetic rather than deferred to a `__muldc3`-style compiler-runtime helper.
(complex/re (complex/mul (complex/of 3.25 1.5) (complex/of 0.5 2.0))) ; => -1.375
Since: Phase N2
complex/scale
(complex/scale [x : Complex k : float] :)
multiply a complex number by a real scalar.
| x | a Complex | |
| k | the real scale factor |
k*(a+bi) = ka + kb*i.
(complex/re (complex/scale (complex/of 3.25 -1.5) 2.0)) ; => 6.5
Since: Phase N2
complex/div
(complex/div [x : Complex y : Complex] :)
quotient of two complex numbers (Smith's algorithm).
| x | dividend | |
| y | divisor |
x/y. The naive `(ac+bd)/(c^2+d^2)` form overflows whenever `c` or `d` is large enough that its square leaves the double range, even when the true quotient is perfectly ordinary. Smith's algorithm divides through by the larger-magnitude denominator component first, so the intermediates stay near the magnitude of the result: |c| >= |d|: r = d/c, den = c + d*r, x/y = ((a + b*r) + (b - a*r)i)/den |c| < |d|: r = c/d, den = c*r + d, x/y = ((a*r + b) + (b*r - a)i)/den Dividing by the zero complex number yields the IEEE infinity/NaN result float division already produces; it is not an error here.
(complex/re (complex/div (complex/of 3.25 1.5) (complex/of 0.5 0.0))) ; => 6.5
Since: Phase N2
complex/abs2
(complex/abs2 [z : Complex] :)
squared magnitude |z|^2.
| z | a Complex |
re^2 + im^2, with no square root. Prefer this to `complex/abs` when only comparing magnitudes -- it is exact where the square root is not.
(complex/abs2 (complex/of 3.0 4.0)) ; => 25
Since: Phase N2
complex/abs
(complex/abs [z : Complex] :)
magnitude |z|.
| z | a Complex |
sqrt(re^2 + im^2), computed by scaling out the larger component first (`|a| * sqrt(1 + (b/a)^2)`) so a value whose square would overflow still reports its true magnitude.
(complex/abs (complex/of 3.0 4.0)) ; => 5
Since: Phase N2
complex/arg
(complex/arg [z : Complex] :)
principal argument (phase angle) of z, in radians.
| z | a Complex |
atan2(im, re), in (-pi, pi].
(complex/arg (complex/of 0.0 1.5)) ; => 1.5708
Since: Phase N2
complex/exp
(complex/exp [z : Complex] :)
e raised to a complex power.
| z | a Complex |
e^(a+bi) = e^a * (cos b + i sin b), built from the real libm wrappers in stdlib/math.tur rather than from a complex-valued runtime helper.
(complex/re (complex/exp (complex/of 0.0 0.0))) ; => 1
Since: Phase N2
complex/eq?
(complex/eq? [x : Complex y : Complex] :)
componentwise equality.
| x | left value | |
| y | right value |
true when both the real and the imaginary parts compare equal. This is IEEE float equality, with all the usual caveats.
(complex/eq? (complex/of 3.25 -1.5) (complex/of 3.25 -1.5)) ; => true
Since: Phase N2
complex->string
(complex->string [z : Complex] :)
render a Complex as "3.25+4.5i" / "3.25-4.5i".
| z | a Complex |
A fresh owned String. The sign of the imaginary part is ALWAYS explicit, so the output is unambiguous and never depends on how the imaginary part happens to format.
(complex->string (complex/of 3.25 -1.5)) ; => String "3.25-1.5i"
Since: Phase N2
Num[Complex]
(definstance Num [Complex])
hand-written complex arithmetic behind + - * /.
Eq[Complex]
(definstance Eq [Complex])
componentwise IEEE equality.
Show[Complex]
(definstance Show [Complex])
"3.25+4.5i" with an always-explicit imaginary sign.