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  * @author graphjs
 45  */
 46 
 47 define(['jxg', 'math/math'], function (JXG) {
 48 
 49     "use strict";
 50 
 51     /**
 52      * Creates a new complex number.
 53      * @class This class is for calculating with complex numbers.
 54      * @constructor
 55      * @param {Number} [x=0] Real part.
 56      * @param {Number} [y=0] Imaginary part.
 57      */
 58     JXG.Complex = function (x, y) {
 59         /**
 60          * This property is only to signalize that this object is of type JXG.Complex. Only
 61          * used internally to distinguish between normal JavaScript numbers and JXG.Complex numbers.
 62          * @type Boolean
 63          * @default true
 64          * @private
 65          */
 66         this.isComplex = true;
 67 
 68         /* is the first argument a complex number? if it is,
 69          * extract real and imaginary part. */
 70         if (x && x.isComplex) {
 71             y = x.imaginary;
 72             x = x.real;
 73         }
 74 
 75         /**
 76          * Real part of the complex number.
 77          * @type Number
 78          * @default 0
 79          */
 80         this.real = x || 0;
 81 
 82         /**
 83          * Imaginary part of the complex number.
 84          * @type Number
 85          * @default 0
 86          */
 87         this.imaginary = y || 0;
 88 
 89         /**
 90          * Absolute value in the polar form of the complex number. Currently unused.
 91          * @type Number
 92          */
 93         this.absval = 0;
 94 
 95         /**
 96          * Angle value in the polar form of the complex number. Currently unused.
 97          * @type Number
 98          */
 99         this.angle = 0;
100     };
101 
102     JXG.extend(JXG.Complex.prototype, /** @lends JXG.Complex.prototype */ {
103         /**
104          * Converts a complex number into a string.
105          * @returns {String} Formatted string containing the complex number in human readable form (algebraic form).
106          */
107         toString: function () {
108             return this.real + ' + ' + this.imaginary + 'i';
109         },
110 
111         /**
112          * Add another complex number to this complex number.
113          * @param {JXG.Complex,Number} c A JavaScript number or a JXG.Complex object to be added to the current object.
114          * @returns {JXG.Complex} Reference to this complex number
115          */
116         add: function (c) {
117             if (typeof c === 'number') {
118                 this.real += c;
119             } else {
120                 this.real += c.real;
121                 this.imaginary += c.imaginary;
122             }
123 
124             return this;
125         },
126 
127         /**
128          * Subtract another complex number from this complex number.
129          * @param {JXG.Complex,Number} c A JavaScript number or a JXG.Complex object to subtract from the current object.
130          * @returns {JXG.Complex} Reference to this complex number
131          */
132         sub: function (c) {
133             if (typeof c === 'number') {
134                 this.real -= c;
135             } else {
136                 this.real -= c.real;
137                 this.imaginary -= c.imaginary;
138             }
139 
140             return this;
141         },
142 
143         /**
144          * Multiply another complex number to this complex number.
145          * @param {JXG.Complex,Number} c A JavaScript number or a JXG.Complex object to
146          * multiply with the current object.
147          * @returns {JXG.Complex} Reference to this complex number
148          */
149         mult: function (c) {
150             var re, im;
151 
152             if (typeof c === 'number') {
153                 this.real *= c;
154                 this.imaginary *= c;
155             } else {
156                 re = this.real;
157                 im = this.imaginary;
158 
159                 //  (a+ib)(x+iy) = ax-by + i(xb+ay)
160                 this.real = re * c.real - im * c.imaginary;
161                 this.imaginary = re * c.imaginary + im * c.real;
162             }
163 
164             return this;
165         },
166 
167         /**
168          * Divide this complex number by the given complex number.
169          * @param {JXG.Complex,Number} c A JavaScript number or a JXG.Complex object to
170          * divide the current object by.
171          * @returns {JXG.Complex} Reference to this complex number
172          */
173         div: function (c) {
174             var denom, im, re;
175 
176             if (typeof c === 'number') {
177                 if (Math.abs(c) < Math.eps) {
178                     this.real = Infinity;
179                     this.imaginary = Infinity;
180 
181                     return this;
182                 }
183 
184                 this.real /= c;
185                 this.imaginary /= c;
186             } else {
187                 //  (a+ib)(x+iy) = ax-by + i(xb+ay)
188                 if ((Math.abs(c.real) < Math.eps) && (Math.abs(c.imaginary) < Math.eps)) {
189                     this.real = Infinity;
190                     this.imaginary = Infinity;
191 
192                     return this;
193                 }
194 
195                 denom = c.real * c.real + c.imaginary * c.imaginary;
196 
197                 re = this.real;
198                 im = this.imaginary;
199                 this.real = (re * c.real + im * c.imaginary) / denom;
200                 this.imaginary = (im * c.real - re * c.imaginary) / denom;
201             }
202 
203             return this;
204         },
205 
206         /**
207          * Conjugate a complex number in place.
208          * @returns {JXG.Complex} Reference to this complex number
209          */
210         conj: function () {
211             this.imaginary *= -1;
212 
213             return this;
214         }
215     });
216 
217     /**
218      * @description
219      * JXG.C is the complex number (name)space. It provides functions to calculate with
220      * complex numbers (defined in {@link JXG.Complex}). With this namespace you don't have to modify
221      * your existing complex numbers, e.g. to add two complex numbers:
222      * <pre class="code">   var z1 = new JXG.Complex(1, 0);
223      *    var z2 = new JXG.Complex(0, 1);
224      *    z = JXG.C.add(z1, z1);</pre>
225      * z1 and z2 here remain unmodified. With the object oriented approach above this
226      * section the code would look like:
227      * <pre class="code">   var z1 = new JXG.Complex(1, 0);
228      *    var z2 = new JXG.Complex(0, 1);
229      *    var z = new JXG.Complex(z1);
230      *    z.add(z2);</pre>
231      * @namespace Namespace for the complex number arithmetic functions.
232      */
233     JXG.C = {};
234 
235     /**
236      * Add two (complex) numbers z1 and z2 and return the result as a (complex) number.
237      * @param {JXG.Complex,Number} z1 Summand
238      * @param {JXG.Complex,Number} z2 Summand
239      * @returns {JXG.Complex} A complex number equal to the sum of the given parameters.
240      */
241     JXG.C.add = function (z1, z2) {
242         var z = new JXG.Complex(z1);
243         z.add(z2);
244         return z;
245     };
246 
247     /**
248      * Subtract two (complex) numbers z1 and z2 and return the result as a (complex) number.
249      * @param {JXG.Complex,Number} z1 Minuend
250      * @param {JXG.Complex,Number} z2 Subtrahend
251      * @returns {JXG.Complex} A complex number equal to the difference of the given parameters.
252      */
253     JXG.C.sub = function (z1, z2) {
254         var z = new JXG.Complex(z1);
255         z.sub(z2);
256         return z;
257     };
258 
259     /**
260      * Multiply two (complex) numbers z1 and z2 and return the result as a (complex) number.
261      * @param {JXG.Complex,Number} z1 Factor
262      * @param {JXG.Complex,Number} z2 Factor
263      * @returns {JXG.Complex} A complex number equal to the product of the given parameters.
264      */
265     JXG.C.mult = function (z1, z2) {
266         var z = new JXG.Complex(z1);
267         z.mult(z2);
268         return z;
269     };
270 
271     /**
272      * Divide two (complex) numbers z1 and z2 and return the result as a (complex) number.
273      * @param {JXG.Complex,Number} z1 Dividend
274      * @param {JXG.Complex,Number} z2 Divisor
275      * @returns {JXG.Complex} A complex number equal to the quotient of the given parameters.
276      */
277     JXG.C.div = function (z1, z2) {
278         var z = new JXG.Complex(z1);
279         z.div(z2);
280         return z;
281     };
282 
283     /**
284      * Conjugate a complex number and return the result.
285      * @param {JXG.Complex,Number} z1 Complex number
286      * @returns {JXG.Complex} A complex number equal to the conjugate of the given parameter.
287      */
288     JXG.C.conj = function (z1) {
289         var z = new JXG.Complex(z1);
290         z.conj();
291         return z;
292     };
293 
294     /**
295      * Absolute value of a complex number.
296      * @param {JXG.Complex,Number} z1 Complex number
297      * @returns {Number} real number equal to the absolute value of the given parameter.
298      */
299     JXG.C.abs = function (z1) {
300         var z = new JXG.Complex(z1);
301 
302         z.conj();
303         z.mult(z1);
304 
305         return Math.sqrt(z.real);
306     };
307 
308     JXG.Complex.C = JXG.C;
309 
310     return JXG.Complex;
311 });