diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2009-06-08 08:06:25 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2009-06-08 08:06:25 +0200 |
commit | 4d4b3b1c04d41868ebb58bd9ccba7b303007e900 (patch) | |
tree | 909ed0aad0b145733521f4ac2bfb938dd4b43785 /lib/pure/complex.nim | |
parent | ce88dc3e67436939b03f97e624c11ca6058fedce (diff) | |
download | Nim-4d4b3b1c04d41868ebb58bd9ccba7b303007e900.tar.gz |
version0.7.10
Diffstat (limited to 'lib/pure/complex.nim')
-rw-r--r-- | lib/pure/complex.nim | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/lib/pure/complex.nim b/lib/pure/complex.nim new file mode 100644 index 000000000..f50ff4bd0 --- /dev/null +++ b/lib/pure/complex.nim @@ -0,0 +1,106 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2006 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + + + +## This module implements complex numbers. + +{.push checks:off, line_dir:off, stack_trace:off, debugger:off.} +# the user does not want to trace a part +# of the standard library! + +import + math + +type + TComplex* = tuple[re, im: float] + ## a complex number, consisting of a real and an imaginary part + +proc `==` *(x, y: TComplex): bool = + ## Compare two complex numbers `x` and `y` for equality. + result = x.re == y.re and x.im == y.im + +proc `+` *(x, y: TComplex): TComplex = + ## Add two complex numbers. + result.re = x.re + y.re + result.im = x.im + y.im + +proc `-` *(x, y: TComplex): TComplex = + ## Subtract two complex numbers. + result.re = x.re - y.re + result.im = x.im - y.im + +proc `-` *(z: TComplex): TComplex = + ## Unary minus for complex numbers. + result.re = -z.re + result.im = -z.im + +proc `/` *(x, y: TComplex): TComplex = + ## Divide `x` by `y`. + var + r, den: float + if abs(y.re) < abs(y.im): + r = y.re / y.im + den = y.im + r * y.re + result.re = (x.re * r + x.im) / den + result.im = (x.im * r - x.re) / den + else: + r = y.im / y.re + den = y.re + r * y.im + result.re = (x.re + r * x.im) / den + result.im = (x.im - r * x.re) / den + +proc `*` *(x, y: TComplex): TComplex = + ## Multiply `x` with `y`. + result.re = x.re * y.re - x.im * y.im + result.im = x.im * y.re + x.re * y.im + +proc abs*(z: TComplex): float = + ## Return the distance from (0,0) to `z`. + + # optimized by checking special cases (sqrt is expensive) + var x, y, temp: float + + x = abs(z.re) + y = abs(z.im) + if x == 0.0: + result = y + elif y == 0.0: + result = x + elif x > y: + temp = y / x + result = x * sqrt(1.0 + temp * temp) + else: + temp = x / y + result = y * sqrt(1.0 + temp * temp) + +proc sqrt*(z: TComplex): TComplex = + ## Square root for a complex number `z`. + var x, y, w, r: float + + if z.re == 0.0 and z.im == 0.0: + result = z + else: + x = abs(z.re) + y = abs(z.im) + if x >= y: + r = y / x + w = sqrt(x) * sqrt(0.5 * (1.0 + sqrt(1.0 + r * r))) + else: + r = x / y + w = sqrt(y) * sqrt(0.5 * (r + sqrt(1.0 + r * r))) + if z.re >= 0.0: + result.re = w + result.im = z.im / (w * 2) + else: + if z.im >= 0.0: result.im = w + else: result.im = -w + result.re = z.im / (c.im + c.im) + +{.pop.} |