csharpfftfsharpintegrationinterpolationlinear-algebramathdifferentiationmatrixnumericsrandomregressionstatisticsmathnet
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
5.0 KiB
137 lines
5.0 KiB
// (c) Microsoft Corporation 2005-2009.
|
|
|
|
#nowarn "52" // defensive copy of structs warning
|
|
|
|
namespace Microsoft.FSharp.Math
|
|
|
|
open Microsoft.FSharp.Math
|
|
open System
|
|
open System.Globalization
|
|
|
|
[<Struct>]
|
|
[<StructuralEquality(false); StructuralComparison(false)>]
|
|
type Complex(real: float, imaginary: float) =
|
|
//new() = new Complex(0.0,0.0)
|
|
member x.r = real
|
|
member x.i = imaginary
|
|
override x.ToString() = x.ToString("g")
|
|
member x.ToString(fmt) = x.ToString(fmt,CultureInfo.InvariantCulture)
|
|
member x.ToString(fmt,fmtprovider:IFormatProvider) =
|
|
x.r.ToString(fmt,fmtprovider)+"r"+(if x.i < 0.0 then "-" else "+")+(System.Math.Abs x.i).ToString(fmt,fmtprovider)+"i"
|
|
interface IComparable with
|
|
member x.CompareTo(obj) =
|
|
match obj with
|
|
| :? Complex as y ->
|
|
let c = compare x.r y.r
|
|
if c <> 0 then c else compare x.i y.i
|
|
| _ -> invalidArg "obj" "not a Complex number"
|
|
override x.Equals(obj) =
|
|
match obj with
|
|
| :? Complex as y -> x.r = y.r && x.i = y.i
|
|
| _ -> false
|
|
override x.GetHashCode() =
|
|
(hash x.r >>> 5) ^^^ (hash x.r <<< 3) ^^^ (((hash x.i >>> 4) ^^^ (hash x.i <<< 4)) + 0x9e3779b9)
|
|
|
|
|
|
type complex = Complex
|
|
|
|
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
|
|
module Complex =
|
|
let mkRect(a,b) = new Complex(a,b)
|
|
let conjugate (c:complex) = mkRect (c.r, -c.i)
|
|
let mkPolar(a,b) = mkRect (a * Math.Cos(b), a * Math.Sin(b))
|
|
let cis b = mkPolar(1.0,b)
|
|
let zero = mkRect(0.,0.)
|
|
let one = mkRect(1.,0.)
|
|
let onei = mkRect(0.,1.)
|
|
let magnitude (c:complex) = sqrt(c.r*c.r + c.i*c.i)
|
|
let phase (c:complex) = Math.Atan2(c.i,c.r)
|
|
let realPart (c:complex) = c.r
|
|
let imagPart (c:complex) = c.i
|
|
let abs (a:complex) = sqrt (a.r**2.0 + a.i**2.0)
|
|
let add (a:complex) (b:complex) = mkRect(a.r + b.r, a.i+b.i)
|
|
let sub (a:complex) (b:complex) = mkRect(a.r - b.r, a.i-b.i)
|
|
let mul (a:complex) (b:complex) = mkRect(a.r * b.r - a.i * b.i, a.i*b.r + b.i*a.r)
|
|
let div (x:complex) (y:complex) =
|
|
let a = x.r in let b = x.i in
|
|
let c = y.r in let d = y.i in
|
|
//(a+ib)/(c+id)=(ac+bd+i(bc-ad))/(c2+d2)
|
|
let q = c*c + d*d in
|
|
mkRect((a*c+b*d)/q, (b*c - a*d)/q)
|
|
let neg (a:complex) = mkRect(-a.r,-a.i)
|
|
let smul (a:float)(b:complex) = mkRect(a * b.r, a*b.i)
|
|
let muls (a:complex) (b:float) = mkRect(a.r *b, a.i*b)
|
|
let fmt_of_string numstyle fmtprovider (s:string) =
|
|
mkRect (System.Double.Parse(s,numstyle,fmtprovider),0.0)
|
|
let of_string s = fmt_of_string NumberStyles.Any CultureInfo.InvariantCulture s
|
|
|
|
// ik.(r + i.th) = -k.th + i.k.r
|
|
let iscale k (x:complex) = mkRect (-k * x.i , k * x.r)
|
|
|
|
// LogN : 'a * 'a -> 'a
|
|
// Asin : 'a -> 'a
|
|
// Acos : 'a -> 'a
|
|
// Atan : 'a -> 'a
|
|
// Atan2 : 'a * 'a -> 'a
|
|
// Sinh : 'a -> 'a
|
|
// Cosh : 'a -> 'a
|
|
// Tanh : 'a -> 'a
|
|
|
|
let pi = mkRect (Math.PI,0.0)
|
|
|
|
// exp(r+it) = exp(r).(cos(t)+i.sin(t)) - De Moivre Theorem
|
|
let exp (x:complex) = smul (exp(x.r)) (mkRect(cos(x.i), sin(x.i)))
|
|
// x = mag.e^(i.th) = e^ln(mag).e^(i.th) = e^(ln(mag) + i.th)
|
|
let log x = mkRect (log(magnitude(x)),phase(x))
|
|
|
|
let sqrt x = mkPolar (sqrt(magnitude x),phase x / 2.0)
|
|
|
|
// cos(x) = (exp(i.x) + exp(-i.x))/2
|
|
let cos x = smul 0.5 (add (exp(iscale 1.0 x)) (exp(iscale -1.0 x)))
|
|
// sin(x) = (exp(i.x) - exp(-i.x))/2 . (-i)
|
|
let sin x = smul 0.5 (sub (exp(iscale 1.0 x)) (exp(iscale -1.0 x))) |> iscale (-1.0)
|
|
// tan(x) = (exp(i.x) - exp(-i.x)) . (-i) / (exp(i.x) + exp(-i.x))
|
|
// = (exp(2i.x) - 1.0) . (-i) / (exp(2i.x) + 1.0)
|
|
let tan x = let exp2ix = exp(iscale 2.0 x) in
|
|
(div (sub exp2ix one) (add exp2ix one)) |> iscale -1.0
|
|
|
|
|
|
type Complex with
|
|
static member Create(a,b) = Complex.mkRect (a,b)
|
|
static member CreatePolar(a,b) = Complex.mkPolar (a,b)
|
|
member x.Magnitude = Complex.magnitude x
|
|
member x.Phase = Complex.phase x
|
|
member x.RealPart = x.r
|
|
member x.ImaginaryPart = x.i
|
|
member x.Conjugate = Complex.conjugate x
|
|
|
|
static member Sin(x) = Complex.sin(x)
|
|
static member Cos(x) = Complex.cos(x)
|
|
static member Abs(x) = Complex.abs(x)
|
|
static member Tan(x) = Complex.tan(x)
|
|
static member Log(x) = Complex.log(x)
|
|
static member Exp(x) = Complex.exp(x)
|
|
static member Sqrt(x) = Complex.sqrt(x)
|
|
|
|
static member Zero = Complex.zero
|
|
static member One = Complex.one
|
|
static member OneI = Complex.onei
|
|
static member ( + ) (a,b) = Complex.add a b
|
|
static member ( - ) (a,b) = Complex.sub a b
|
|
[<OverloadID("Complex_Complex")>]
|
|
static member ( * ) (a,b) = Complex.mul a b
|
|
static member ( / ) (a,b) = Complex.div a b
|
|
static member ( ~- ) a = Complex.neg a
|
|
[<OverloadID("float_Complex")>]
|
|
static member ( * ) (a,b) = Complex.smul a b
|
|
[<OverloadID("Complex_float")>]
|
|
static member ( * ) (a,b) = Complex.muls a b
|
|
|
|
|
|
namespace Microsoft.FSharp.Core
|
|
|
|
type complex = Microsoft.FSharp.Math.Complex
|
|
|
|
module ComplexCommonExtensions =
|
|
let complex x y = Microsoft.FSharp.Math.Complex.mkRect (x,y)
|
|
|
|
|