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.imagina