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