2 // Complex.cs: Complex number support
5 // Miguel de Icaza (miguel@gnome.org)
6 // Marek Safar (marek.safar@gmail.com)
8 // Copyright 2009, 2010 Novell, Inc.
13 // string ToString (string format, IFormatProvider)
14 // string ToString (string format)
15 // string ToString (IFormatProvider)
17 // Acos, Asin, Atan, Exp, Log, Log10, Pow, Sqrt
21 namespace System.Numerics {
23 public struct Complex : IEquatable<Complex>
25 double real, imaginary;
27 public static readonly Complex ImaginaryOne = new Complex (0, 1);
28 public static readonly Complex One = new Complex (1, 0);
29 public static readonly Complex Zero = new Complex (0, 0);
31 public Complex (double real, double imaginary)
33 this.imaginary = imaginary;
37 public static Complex FromPolarCoordinates (double magnitude, double phase)
39 return new Complex (magnitude * Math.Cos (phase), magnitude * Math.Sin (phase));
42 public static Complex operator + (Complex left, Complex right)
44 return new Complex (left.real + right.real, left.imaginary + right.imaginary);
47 public static Complex Add (Complex left, Complex right)
49 return new Complex (left.real + right.real, left.imaginary + right.imaginary);
52 public static Complex operator - (Complex left, Complex right)
54 return new Complex (left.real - right.real, left.imaginary - right.imaginary);
57 public static Complex Subtract (Complex left, Complex right)
59 return new Complex (left.real - right.real, left.imaginary - right.imaginary);
62 public static Complex operator * (Complex left, Complex right)
65 left.real * right.real - left.imaginary * right.imaginary,
66 left.real * right.imaginary + left.imaginary * right.real);
69 public static Complex Multiply (Complex left, Complex right)
72 left.real * right.real - left.imaginary * right.imaginary,
73 left.real * right.imaginary + left.imaginary * right.real);
76 public static Complex operator / (Complex left, Complex right)
78 double rsri = right.real * right.real + right.imaginary * right.imaginary;
80 (left.real * right.real + left.imaginary * right.imaginary) / rsri,
82 (left.imaginary * right.real - left.real * right.imaginary) / rsri);
85 public static Complex Divide (Complex left, Complex right)
87 double rsri = right.real * right.real + right.imaginary * right.imaginary;
89 (left.real * right.real + left.imaginary * right.imaginary) / rsri,
91 (left.imaginary * right.real - left.real * right.imaginary) / rsri);
94 public static bool operator == (Complex left, Complex right)
96 return left.real == right.real && left.imaginary == right.imaginary;
99 public bool Equals (Complex value)
101 return real == value.real && imaginary == value.imaginary;
104 public override bool Equals (object value)
106 if (value == null || !(value is Complex))
109 Complex r = (Complex) value;
110 return real == r.real && imaginary == r.imaginary;
113 public static bool operator != (Complex left, Complex right)
115 return left.real != right.real || left.imaginary != right.imaginary;
118 public static Complex operator - (Complex value)
120 return new Complex (-value.real, -value.imaginary);
123 public static implicit operator Complex (byte value)
125 return new Complex (value, 0);
128 public static implicit operator Complex (double value)
130 return new Complex (value, 0);
133 public static implicit operator Complex (short value)
135 return new Complex (value, 0);
138 public static implicit operator Complex (int value)
140 return new Complex (value, 0);
143 public static implicit operator Complex (long value)
145 return new Complex (value, 0);
148 [CLSCompliant (false)]
149 public static implicit operator Complex (sbyte value)
151 return new Complex (value, 0);
154 public static implicit operator Complex (float value)
156 return new Complex (value, 0);
159 [CLSCompliant (false)]
160 public static implicit operator Complex (ushort value)
162 return new Complex (value, 0);
165 [CLSCompliant (false)]
166 public static implicit operator Complex (uint value)
168 return new Complex (value, 0);
171 [CLSCompliant (false)]
172 public static implicit operator Complex (ulong value)
174 return new Complex (value, 0);
177 public static explicit operator Complex (decimal value)
179 return new Complex ((double) value, 0);
182 public static explicit operator Complex (BigInteger value)
184 return new Complex ((double) value, 0);
187 public override string ToString ()
189 return String.Format ("({0:G}, {1:G})", real, imaginary);
192 public static double Abs (Complex value)
194 return Math.Sqrt (value.imaginary * value.imaginary + value.real * value.real);
197 public static Complex Conjugate (Complex value)
199 return new Complex (value.real, -value.imaginary);
202 public static Complex Cos (Complex value)
204 return new Complex (Math.Cos (value.real) * Math.Cosh (value.imaginary),
205 -Math.Sin (value.real) * Math.Sinh (value.imaginary));
208 public static Complex Cosh (Complex value)
210 return new Complex (Math.Cosh (value.real) * Math.Cos (value.imaginary),
211 -Math.Sinh (value.real) * Math.Sin (value.imaginary));
214 public static Complex Negate (Complex value)
219 public static Complex Sin (Complex value)
221 return new Complex (Math.Sin (value.real) * Math.Cosh (value.imaginary),
222 Math.Cos (value.real) * Math.Sinh (value.imaginary));
225 public static Complex Sinh (Complex value)
227 return new Complex (Math.Sinh (value.real) * Math.Cos (value.imaginary),
228 Math.Cosh (value.real) * Math.Sin (value.imaginary));
231 public static Complex Reciprocal (Complex value)
239 public static Complex Tan (Complex value)
241 return Sin (value) / Cos (value);
244 public static Complex Tanh (Complex value)
246 return Sinh (value) / Cosh (value);
249 public override int GetHashCode ()
251 return real.GetHashCode () ^ imaginary.GetHashCode ();
254 public double Imaginary { get { return imaginary; } }
255 public double Real { get { return real; } }
257 public double Magnitude {
259 return Math.Sqrt (imaginary * imaginary + real * real);
263 public double Phase {
265 return Math.Atan (imaginary / real);