      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 JXG.extend(JXG.Complex.prototype, /** @lends JXG.Complex.prototype */ {
     93     /**
     94      * Converts a complex number into a string.
     95      * @return Formatted string containing the complex number in human readable form (algebraic form).
     96      */
     97     toString: function() /** string */{
     98         return '' + this.real + ' + ' + this.imaginary + 'i';
     99     },
    100
    101     /**
    102      * Add another complex number to this complex number.
    103      * @param c A JavaScript number or a JXG.Complex object to be added to the current object.
    104      */
    105     add: function(/** JXG.Complex,number */ c) /** undefined */ {
    106         if(typeof c == 'number') {
    107             this.real += c;
    108         } else {
    109             this.real += c.real;
    110             this.imaginary += c.imaginary;
    111         }
    112     },
    113
    114     /**
    115      * Subtract another complex number from this complex number.
    116      * @param c A JavaScript number or a JXG.Complex object to subtract from the current object.
    117      */
    118     sub: function(/** JXG.Complex,number */ c) /** undefined */{
    119         if(typeof c == 'number') {
    120             this.real -= c;
    121         } else {
    122             this.real -= c.real;
    123             this.imaginary -= c.imaginary;
    124         }
    125     },
    126
    127     /**
    128      * Multiply another complex number to this complex number.
    129      * @param c A JavaScript number or a JXG.Complex object to
    130      * multiply with the current object.
    131      */
    132     mult: function(/** JXG.Complex,number */ c) /** undefined */{
    133         var re, im;
    134         if(typeof c == 'number') {
    135             this.real *= c;
    136             this.imaginary *= c;
    137         } else {
    138             re = this.real;
    139             im = this.imaginary;
    140             //  (a+ib)(x+iy) = ax-by + i(xb+ay)
    141             this.real = re*c.real - im*c.imaginary;
    142             this.imaginary = re*c.imaginary + im*c.real;
    143         }
    144     },
    145
    146     /**
    147      * Divide this complex number by the given complex number.
    148      * @param c A JavaScript number or a JXG.Complex object to
    149      * divide the current object by.
    150      */
    151     div: function(/** JXG.Complex,number */ c) /** undefined */{
    152         var denom, im, re;
    153
    154         if(typeof c == 'number') {
    155             if(Math.abs(c) < Math.eps) {
    156                 this.real = Infinity;
    157                 this.imaginary = Infinity;
    158
    159                 return;
    160             }
    161             this.real /= c;
    162             this.imaginary /= c;
    163         } else {
    164             //  (a+ib)(x+iy) = ax-by + i(xb+ay)
    165             if( (Math.abs(c.real) < Math.eps) && (Math.abs(c.imaginary) < Math.eps) ){
    166                 this.real = Infinity;
    167                 this.imaginary = Infinity;
    168
    169                 return;
    170             }
    171
    172             denom = c.real*c.real + c.imaginary*c.imaginary;
    173
    174             re = this.real;
    175             im = this.imaginary;
    176             this.real = (re*c.real + im*c.imaginary)/denom;
    177             this.imaginary = (im*c.real - re*c.imaginary)/denom;
    178         }
    179     },
    180
    181     /**
    182      * Conjugate a complex number in place.
    183      * @param c A JavaScript number or a JXG.Complex object
    184      */
    185     conj: function() /** undefined */ {
    186         this.imaginary *= -1;
    187     }
    188 });
    189
    190 /**
    191  * @description
    192  * JXG.C is the complex number (name)space. It provides functions to calculate with
    193  * complex numbers (defined in {@link JXG.Complex}). With this namespace you don't have to modify
    194  * your existing complex numbers, e.g. to add two complex numbers:
    195  * <pre class="code">   var z1 = new JXG.Complex(1, 0);
    196  *    var z2 = new JXG.Complex(0, 1);
    197  *    z = JXG.C.add(z1, z1);</pre>
    198  * z1 and z2 here remain unmodified. With the object oriented approach above this
    199  * section the code would look like:
    200  * <pre class="code">   var z1 = new JXG.Complex(1, 0);
    201  *    var z2 = new JXG.Complex(0, 1);
    202  *    var z = new JXG.Complex(z1);
    203  *    z.add(z2);</pre>
    204  * @namespace Namespace for the complex number arithmetic functions.
    205  */
    206 JXG.C = {};
    207
    208 /**
    209  * Add two (complex) numbers z1 and z2 and return the result as a (complex) number.
    210  * @param z1 Summand
    211  * @param z2 Summand
    212  * @return A complex number equal to the sum of the given parameters.
    213  */
    214 JXG.C.add = function(/** JXG.Complex,number */ z1, /** JXG.Complex,number */ z2) /** JXG.Complex */{
    215     var z = new JXG.Complex(z1);
    216     z.add(z2);
    217     return z;
    218 };
    219
    220 /**
    221  * Subtract two (complex) numbers z1 and z2 and return the result as a (complex) number.
    222  * @param z1 Minuend
    223  * @param z2 Subtrahend
    224  * @return A complex number equal to the difference of the given parameters.
    225  */
    226 JXG.C.sub = function(/** JXG.Complex,number */ z1, /** JXG.Complex,number */ z2) /** JXG.Complex */{
    227     var z = new JXG.Complex(z1);
    228     z.sub(z2);
    229     return z;
    230 };
    231
    232 /**
    233  * Multiply two (complex) numbers z1 and z2 and return the result as a (complex) number.
    234  * @param z1 Factor
    235  * @param z2 Factor
    236  * @return A complex number equal to the product of the given parameters.
    237  */
    238 JXG.C.mult = function(/** JXG.Complex,number */ z1, /** JXG.Complex,number */ z2) /** JXG.Complex */{
    239     var z = new JXG.Complex(z1);
    240     z.mult(z2);
    241     return z;
    242 };
    243
    244 /**
    245  * Divide two (complex) numbers z1 and z2 and return the result as a (complex) number.
    246  * @param z1 Dividend
    247  * @param z2 Divisor
    248  * @return A complex number equal to the quotient of the given parameters.
    249  */
    250 JXG.C.div = function(/** JXG.Complex,number */ z1, /** JXG.Complex,number */ z2) /** JXG.Complex */{
    251     var z = new JXG.Complex(z1);
    252     z.div(z2);
    253     return z;
    254 };
    255
    256 /**
    257  * Conjugate a complex number and return the result.
    258  * @param z1 Complex number
    259  * @return A complex number equal to the conjugate of the given parameter.
    260  */
    261 JXG.C.conj = function(/** JXG.Complex,number */ z1) /** JXG.Complex */{
    262     var z = new JXG.Complex(z1);
    263     z.conj();
    264     return z;
    265 };
    266
    267 /**
    268  * Absolute value of a complex number.
    269  * @param z1 Complex number
    270  * @return real number equal to the absolute value of the given parameter.
    271  */
    272 JXG.C.abs = function(/** JXG.Complex,number */ z1) /** JXG.Complex */{
    273     var z = new JXG.Complex(z1);
    274     z.conj();
    275     z.mult(z1);
    276     return Math.sqrt(z.real);
    277 };
    278
    279