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