1 /*
  2     Copyright 2008,2009
  3         Matthias Ehmann,
  4         Michael Gerhaeuser,
  5         Carsten Miller,
  6         Bianca Valentin,
  7         Alfred Wassermann,
  8         Peter Wilfahrt
  9 
 10     This file is part of JSXGraph.
 11 
 12     JSXGraph is free software: you can redistribute it and/or modify
 13     it under the terms of the GNU Lesser General Public License as published by
 14     the Free Software Foundation, either version 3 of the License, or
 15     (at your option) any later version.
 16 
 17     JSXGraph is distributed in the hope that it will be useful,
 18     but WITHOUT ANY WARRANTY; without even the implied warranty of
 19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 20     GNU Lesser General Public License for more details.
 21 
 22     You should have received a copy of the GNU Lesser General Public License
 23     along with JSXGraph.  If not, see <http://www.gnu.org/licenses/>.
 24 */
 25 
 26 
 27 /**
 28  * @fileoverview A class for complex arithmetics JXG.Complex is defined in this
 29  * file. Also a namespace JXG.C is included to provide instance-independent
 30  * arithmetic functions.
 31  * @author graphjs
 32  */
 33 
 34 /**
 35  * Creates a new complex number.
 36  * @class This class is for calculating with complex numbers.
 37  * @param [x=0] Real part of the resulting complex number.
 38  * @param [y=0] Imaginary part of the resulting complex number.
 39  * @returns An object representing the complex number <tt>x + iy</tt>.
 40  */
 41 JXG.Complex = function(/** number */ x, /** number */ y) {
 42 	/**
 43 	 * This property is only to signalize that this object is of type JXG.Complex. Only
 44 	 * used internally to distinguish between normal JavaScript numbers and JXG.Complex numbers.
 45 	 * @type boolean
 46 	 * @default true
 47 	 * @private
 48 	 */
 49     this.isComplex = true;
 50     
 51     if (typeof x == 'undefined') {
 52         x = 0;
 53     }
 54     if (typeof y == 'undefined') {
 55         y = 0;
 56     }
 57 
 58     /* is the first argument a complex number? if it is,
 59      * extract real and imaginary part. */
 60     if (x.isComplex) {
 61         y = x.imaginary;
 62         x = x.real;
 63     }
 64 
 65     /**
 66      * Real part of the complex number.
 67      * @type number
 68      * @default 0
 69      */
 70     this.real = x;
 71 
 72     /**
 73      * Imaginary part of the complex number.
 74      * @type number
 75      * @default 0
 76      */
 77     this.imaginary = y;
 78 
 79     /**
 80      * Absolute value in the polar form of the complex number. Currently unused.
 81      * @type number
 82      */
 83     this.absval = 0;
 84 
 85     /**
 86      * Angle value in the polar form of the complex number. Currently unused.
 87      * @type number
 88      */
 89     this.angle = 0;
 90 };
 91 
 92 /**
 93  * Converts a complex number into a string.
 94  * @return Formatted string containing the complex number in human readable form (algebraic form).
 95  */
 96 JXG.Complex.prototype.toString = function() /** string */{
 97     return '' + this.real + ' + ' + this.imaginary + 'i';
 98 };
 99 
100 /**
101  * Add another complex number to this complex number.
102  * @param c A JavaScript number or a JXG.Complex object to be added to the current object.
103  */
104 JXG.Complex.prototype.add = function(/** JXG.Complex,number */ c) /** undefined */ {
105     if(typeof c == 'number') {
106         this.real += c;
107     } else {
108         this.real += c.real;
109         this.imaginary += c.imaginary;
110     }
111 };
112 
113 /**
114  * Subtract another complex number from this complex number.
115  * @param c A JavaScript number or a JXG.Complex object to subtract from the current object.
116  */
117 JXG.Complex.prototype.sub = function(/** JXG.Complex,number */ c) /** undefined */{
118     if(typeof c == 'number') {
119         this.real -= c;
120     } else {
121         this.real -= c.real;
122         this.imaginary -= c.imaginary;
123     }
124 };
125 
126 /**
127  * Multiply another complex number to this complex number.
128  * @param c A JavaScript number or a JXG.Complex object to
129  * multiply with the current object.
130  */
131 JXG.Complex.prototype.mult = function(/** JXG.Complex,number */ c) /** undefined */{
132     var re, im;
133     if(typeof c == 'number') {
134         this.real *= c;
135         this.imaginary *= c;
136     } else {
137         re = this.real;
138         im = this.imaginary;
139         //  (a+ib)(x+iy) = ax-by + i(xb+ay)
140         this.real = re*c.real - im*c.imaginary;
141         this.imaginary = re*c.imaginary + im*c.real;
142     }
143 };
144 
145 /**
146  * Divide this complex number by the given complex number.
147  * @param c A JavaScript number or a JXG.Complex object to
148  * divide the current object by.
149  */
150 JXG.Complex.prototype.div = function(/** JXG.Complex,number */ c) /** undefined */{
151     var denom, im, re;
152 
153     if(typeof c == 'number') {
154         if(Math.abs(c) < Math.eps) {
155             this.real = Infinity;
156             this.imaginary = Infinity;
157             
158             return;
159         }
160         this.real /= c;
161         this.imaginary /= c;
162     } else {
163         //  (a+ib)(x+iy) = ax-by + i(xb+ay)
164         if( (Math.abs(c.real) < Math.eps) && (Math.abs(c.imaginary) < Math.eps) ){
165             this.real = Infinity;
166             this.imaginary = Infinity;
167 
168             return;
169         }
170 
171         denom = c.real*c.real + c.imaginary*c.imaginary;
172 
173         re = this.real;
174         im = this.imaginary;
175         this.real = (re*c.real + im*c.imaginary)/denom;
176         this.imaginary = (im*c.real - re*c.imaginary)/denom;
177     }
178 };
179 
180 /**
181  * Conjugate a complex number in place.
182  * @param c A JavaScript number or a JXG.Complex object 
183  */
184 JXG.Complex.prototype.conj = function() /** undefined */ {
185     this.imaginary *= -1;
186 };
187 
188 /**
189  * @description
190  * JXG.C is the complex number (name)space. It provides functions to calculate with
191  * complex numbers (defined in {@link JXG.Complex}). With this namespace you don't have to modify
192  * your existing complex numbers, e.g. to add two complex numbers:
193  * <pre class="code">   var z1 = new JXG.Complex(1, 0);
194  *    var z2 = new JXG.Complex(0, 1);
195  *    z = JXG.C.add(z1, z1);</pre>
196  * z1 and z2 here remain unmodified. With the object oriented approach above this
197  * section the code would look like:
198  * <pre class="code">   var z1 = new JXG.Complex(1, 0);
199  *    var z2 = new JXG.Complex(0, 1);
200  *    var z = new JXG.Complex(z1);
201  *    z.add(z2);</pre>
202  * @namespace Namespace for the complex number arithmetic functions.
203  */
204 JXG.C = {};
205 
206 /**
207  * Add two (complex) numbers z1 and z2 and return the result as a (complex) number.
208  * @param z1 Summand
209  * @param z2 Summand
210  * @return A complex number equal to the sum of the given parameters.
211  */
212 JXG.C.add = function(/** JXG.Complex,number */ z1, /** JXG.Complex,number */ z2) /** JXG.Complex */{
213     var z = new JXG.Complex(z1);
214     z.add(z2);
215     return z;
216 };
217 
218 /**
219  * Subtract two (complex) numbers z1 and z2 and return the result as a (complex) number.
220  * @param z1 Minuend
221  * @param z2 Subtrahend
222  * @return A complex number equal to the difference of the given parameters.
223  */
224 JXG.C.sub = function(/** JXG.Complex,number */ z1, /** JXG.Complex,number */ z2) /** JXG.Complex */{
225     var z = new JXG.Complex(z1);
226     z.sub(z2);
227     return z;
228 };
229 
230 /**
231  * Multiply two (complex) numbers z1 and z2 and return the result as a (complex) number.
232  * @param z1 Factor
233  * @param z2 Factor
234  * @return A complex number equal to the product of the given parameters.
235  */
236 JXG.C.mult = function(/** JXG.Complex,number */ z1, /** JXG.Complex,number */ z2) /** JXG.Complex */{
237     var z = new JXG.Complex(z1);
238     z.mult(z2);
239     return z;
240 };
241 
242 /**
243  * Divide two (complex) numbers z1 and z2 and return the result as a (complex) number.
244  * @param z1 Dividend
245  * @param z2 Divisor
246  * @return A complex number equal to the quotient of the given parameters.
247  */
248 JXG.C.div = function(/** JXG.Complex,number */ z1, /** JXG.Complex,number */ z2) /** JXG.Complex */{
249     var z = new JXG.Complex(z1);
250     z.div(z2);
251     return z;
252 };
253 
254 /**
255  * Conjugate a complex number and return the result.
256  * @param z1 Complex number
257  * @return A complex number equal to the conjugate of the given parameter.
258  */
259 JXG.C.conj = function(/** JXG.Complex,number */ z1) /** JXG.Complex */{
260     var z = new JXG.Complex(z1);
261     z.conj();
262     return z;
263 };
264 
265 /**
266  * Absolute value of a complex number.
267  * @param z1 Complex number
268  * @return real number equal to the absolute value of the given parameter.
269  */
270 JXG.C.abs = function(/** JXG.Complex,number */ z1) /** JXG.Complex */{
271     var z = new JXG.Complex(z1);
272     z.conj();
273     z.mult(z1);
274     return Math.sqrt(z.real);
275 };
276 
277