New tests.
[mono.git] / mcs / class / System.Numerics / System.Numerics / Complex.cs
1 //
2 // Complex.cs: Complex number support
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@gnome.org)
6 //   Marek Safar (marek.safar@gmail.com)
7 //
8 // Copyright 2009, 2010 Novell, Inc.
9 //
10 //
11 //
12 // TODO:
13 // string ToString (string format, IFormatProvider)
14 // string ToString (string format)
15 // string ToString (IFormatProvider)
16 //
17 // Acos, Asin, Atan, Exp, Log, Log10, Pow, Sqrt
18
19 using System;
20
21 namespace System.Numerics {
22
23         public struct Complex : IEquatable<Complex>
24         {
25                 double real, imaginary;
26
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);
30                 
31                 public Complex (double real, double imaginary)
32                 {
33                         this.imaginary = imaginary;
34                         this.real = real;
35                 }
36
37                 public static Complex FromPolarCoordinates (double magnitude, double phase)
38                 {
39                         return new Complex (magnitude * Math.Cos (phase), magnitude * Math.Sin (phase));
40                 }
41
42                 public static Complex operator + (Complex left, Complex right)
43                 {
44                         return new Complex (left.real + right.real, left.imaginary + right.imaginary);
45                 }
46
47                 public static Complex Add (Complex left, Complex right)
48                 {
49                         return new Complex (left.real + right.real, left.imaginary + right.imaginary);
50                 }
51                 
52                 public static Complex operator - (Complex left, Complex right)
53                 {
54                         return new Complex (left.real - right.real, left.imaginary - right.imaginary);
55                 }
56
57                 public static Complex Subtract (Complex left, Complex right)
58                 {
59                         return new Complex (left.real - right.real, left.imaginary - right.imaginary);
60                 }
61                 
62                 public static Complex operator * (Complex left, Complex right)
63                 {
64                         return new Complex (
65                                 left.real * right.real - left.imaginary * right.imaginary,
66                                 left.real * right.imaginary + left.imaginary * right.real);
67                 }
68
69                 public static Complex Multiply (Complex left, Complex right)
70                 {
71                         return new Complex (
72                                 left.real * right.real - left.imaginary * right.imaginary,
73                                 left.real * right.imaginary + left.imaginary * right.real);
74                 }
75
76                 public static Complex operator / (Complex left, Complex right)
77                 {
78                         double rsri = right.real * right.real + right.imaginary * right.imaginary;
79                         return new Complex (
80                                 (left.real * right.real + left.imaginary * right.imaginary) / rsri,
81
82                                 (left.imaginary * right.real - left.real * right.imaginary) / rsri);
83                 }
84
85                 public static Complex Divide (Complex left, Complex right)
86                 {
87                         double rsri = right.real * right.real + right.imaginary * right.imaginary;
88                         return new Complex (
89                                 (left.real * right.real + left.imaginary * right.imaginary) / rsri,
90
91                                 (left.imaginary * right.real - left.real * right.imaginary) / rsri);
92                 }
93
94                 public static bool operator == (Complex left, Complex right)
95                 {
96                         return left.real == right.real && left.imaginary == right.imaginary;
97                 }
98
99                 public bool Equals (Complex value)
100                 {
101                         return real == value.real && imaginary == value.imaginary;
102                 }
103
104                 public override bool Equals (object value)
105                 {
106                         if (value == null || !(value is Complex))
107                                 return false;
108
109                         Complex r = (Complex) value;
110                         return real == r.real && imaginary == r.imaginary;
111                 }
112                 
113                 public static bool operator != (Complex left, Complex right)
114                 {
115                         return left.real != right.real || left.imaginary != right.imaginary;
116                 }
117                 
118                 public static Complex operator - (Complex value)
119                 {
120                         return new Complex (-value.real, -value.imaginary);
121                 }
122
123                 public static implicit operator Complex (byte value)
124                 {
125                         return new Complex (value, 0);
126                 }
127
128                 public static implicit operator Complex (double value)
129                 {
130                         return new Complex (value, 0);
131                 }
132                 
133                 public static implicit operator Complex (short value)
134                 {
135                         return new Complex (value, 0);
136                 }
137                 
138                 public static implicit operator Complex (int value)
139                 {
140                         return new Complex (value, 0);
141                 }
142                 
143                 public static implicit operator Complex (long value)
144                 {
145                         return new Complex (value, 0);
146                 }
147
148                 [CLSCompliant (false)]
149                 public static implicit operator Complex (sbyte value)
150                 {
151                         return new Complex (value, 0);
152                 }
153
154                 public static implicit operator Complex (float value)
155                 {
156                         return new Complex (value, 0);
157                 }
158
159                 [CLSCompliant (false)]
160                 public static implicit operator Complex (ushort value)
161                 {
162                         return new Complex (value, 0);
163                 }
164
165                 [CLSCompliant (false)]
166                 public static implicit operator Complex (uint value)
167                 {
168                         return new Complex (value, 0);
169                 }
170
171                 [CLSCompliant (false)]
172                 public static implicit operator Complex (ulong value)
173                 {
174                         return new Complex (value, 0);
175                 }
176
177                 public static explicit operator Complex (decimal value)
178                 {
179                         return new Complex ((double) value, 0);
180                 }
181
182                 public static explicit operator Complex (BigInteger value)
183                 {
184                         return new Complex ((double) value, 0);
185                 }
186
187                 public override string ToString ()
188                 {
189                         return String.Format ("({0:G}, {1:G})", real, imaginary);
190                 }
191
192                 public static double Abs (Complex value)
193                 {
194                         return Math.Sqrt (value.imaginary * value.imaginary + value.real * value.real);
195                 }
196                 
197                 public static Complex Conjugate (Complex value)
198                 {
199                         return new Complex (value.real, -value.imaginary);
200                 }
201
202                 public static Complex Cos (Complex value)
203                 {
204                         return new Complex (Math.Cos (value.real) * Math.Cosh (value.imaginary),
205                                             -Math.Sin (value.real)  * Math.Sinh (value.imaginary));
206                 }
207
208                 public static Complex Cosh (Complex value)
209                 {
210                         return new Complex (Math.Cosh (value.real) * Math.Cos (value.imaginary),
211                                             -Math.Sinh (value.real)  * Math.Sin (value.imaginary));
212                 }
213                 
214                 public static Complex Negate (Complex value)
215                 {
216                         return -value;
217                 }
218
219                 public static Complex Sin (Complex value)
220                 {
221                         return new Complex (Math.Sin (value.real) * Math.Cosh (value.imaginary),
222                                             Math.Cos (value.real)  * Math.Sinh (value.imaginary));
223                 }
224                 
225                 public static Complex Sinh (Complex value)
226                 {
227                         return new Complex (Math.Sinh (value.real) * Math.Cos (value.imaginary),
228                                             Math.Cosh (value.real)  * Math.Sin (value.imaginary));
229                 }
230                 
231                 public static Complex Reciprocal (Complex value)
232                 {
233                         if (value == Zero)
234                                 return value;
235                                 
236                         return One / value;
237                 }
238                 
239                 public static Complex Tan (Complex value)
240                 {
241                         return Sin (value) / Cos (value);
242                 }
243                 
244                 public static Complex Tanh (Complex value)
245                 {
246                         return Sinh (value) / Cosh (value);
247                 }
248                 
249                 public override int GetHashCode ()
250                 {
251                         return real.GetHashCode () ^ imaginary.GetHashCode ();
252                 }
253                 
254                 public double Imaginary { get { return imaginary; } }
255                 public double Real { get { return real; } }
256
257                 public double Magnitude {
258                         get {
259                                 return Math.Sqrt (imaginary * imaginary + real * real);
260                         }
261                 }
262
263                 public double Phase {
264                         get {
265                                 return Math.Atan (imaginary / real);
266                         }
267                 }
268         }
269 }