      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