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