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 * @author graphjs 45 */ 46 47 define(['jxg', 'math/math'], function (JXG) { 48 49 "use strict"; 50 51 /** 52 * Creates a new complex number. 53 * @class This class is for calculating with complex numbers. 54 * @constructor 55 * @param {Number} [x=0] Real part. 56 * @param {Number} [y=0] Imaginary part. 57 */ 58 JXG.Complex = function (x, y) { 59 /** 60 * This property is only to signalize that this object is of type JXG.Complex. Only 61 * used internally to distinguish between normal JavaScript numbers and JXG.Complex numbers. 62 * @type Boolean 63 * @default true 64 * @private 65 */ 66 this.isComplex = true; 67 68 /* is the first argument a complex number? if it is, 69 * extract real and imaginary part. */ 70 if (x && x.isComplex) { 71 y = x.imaginary; 72 x = x.real; 73 } 74 75 /** 76 * Real part of the complex number. 77 * @type Number 78 * @default 0 79 */ 80 this.real = x || 0; 81 82 /** 83 * Imaginary part of the complex number. 84 * @type Number 85 * @default 0 86 */ 87 this.imaginary = y || 0; 88 89 /** 90 * Absolute value in the polar form of the complex number. Currently unused. 91 * @type Number 92 */ 93 this.absval = 0; 94 95 /** 96 * Angle value in the polar form of the complex number. Currently unused. 97 * @type Number 98 */ 99 this.angle = 0; 100 }; 101 102 JXG.extend(JXG.Complex.prototype, /** @lends JXG.Complex.prototype */ { 103 /** 104 * Converts a complex number into a string. 105 * @returns {String} Formatted string containing the complex number in human readable form (algebraic form). 106 */ 107 toString: function () { 108 return this.real + ' + ' + this.imaginary + 'i'; 109 }, 110 111 /** 112 * Add another complex number to this complex number. 113 * @param {JXG.Complex,Number} c A JavaScript number or a JXG.Complex object to be added to the current object. 114 * @returns {JXG.Complex} Reference to this complex number 115 */ 116 add: function (c) { 117 if (typeof c === 'number') { 118 this.real += c; 119 } else { 120 this.real += c.real; 121 this.imaginary += c.imaginary; 122 } 123 124 return this; 125 }, 126 127 /** 128 * Subtract another complex number from this complex number. 129 * @param {JXG.Complex,Number} c A JavaScript number or a JXG.Complex object to subtract from the current object. 130 * @returns {JXG.Complex} Reference to this complex number 131 */ 132 sub: function (c) { 133 if (typeof c === 'number') { 134 this.real -= c; 135 } else { 136 this.real -= c.real; 137 this.imaginary -= c.imaginary; 138 } 139 140 return this; 141 }, 142 143 /** 144 * Multiply another complex number to this complex number. 145 * @param {JXG.Complex,Number} c A JavaScript number or a JXG.Complex object to 146 * multiply with the current object. 147 * @returns {JXG.Complex} Reference to this complex number 148 */ 149 mult: function (c) { 150 var re, im; 151 152 if (typeof c === 'number') { 153 this.real *= c; 154 this.imaginary *= c; 155 } else { 156 re = this.real; 157 im = this.imaginary; 158 159 // (a+ib)(x+iy) = ax-by + i(xb+ay) 160 this.real = re * c.real - im * c.imaginary; 161 this.imaginary = re * c.imaginary + im * c.real; 162 } 163 164 return this; 165 }, 166 167 /** 168 * Divide this complex number by the given complex number. 169 * @param {JXG.Complex,Number} c A JavaScript number or a JXG.Complex object to 170 * divide the current object by. 171 * @returns {JXG.Complex} Reference to this complex number 172 */ 173 div: function (c) { 174 var denom, im, re; 175 176 if (typeof c === 'number') { 177 if (Math.abs(c) < Math.eps) { 178 this.real = Infinity; 179 this.imaginary = Infinity; 180 181 return this; 182 } 183 184 this.real /= c; 185 this.imaginary /= c; 186 } else { 187 // (a+ib)(x+iy) = ax-by + i(xb+ay) 188 if ((Math.abs(c.real) < Math.eps) && (Math.abs(c.imaginary) < Math.eps)) { 189 this.real = Infinity; 190 this.imaginary = Infinity; 191 192 return this; 193 } 194 195 denom = c.real * c.real + c.imaginary * c.imaginary; 196 197 re = this.real; 198 im = this.imaginary; 199 this.real = (re * c.real + im * c.imaginary) / denom; 200 this.imaginary = (im * c.real - re * c.imaginary) / denom; 201 } 202 203 return this; 204 }, 205 206 /** 207 * Conjugate a complex number in place. 208 * @returns {JXG.Complex} Reference to this complex number 209 */ 210 conj: function () { 211 this.imaginary *= -1; 212 213 return this; 214 } 215 }); 216 217 /** 218 * @description 219 * JXG.C is the complex number (name)space. It provides functions to calculate with 220 * complex numbers (defined in {@link JXG.Complex}). With this namespace you don't have to modify 221 * your existing complex numbers, e.g. to add two complex numbers: 222 * <pre class="code"> var z1 = new JXG.Complex(1, 0); 223 * var z2 = new JXG.Complex(0, 1); 224 * z = JXG.C.add(z1, z1);</pre> 225 * z1 and z2 here remain unmodified. With the object oriented approach above this 226 * section the code would look like: 227 * <pre class="code"> var z1 = new JXG.Complex(1, 0); 228 * var z2 = new JXG.Complex(0, 1); 229 * var z = new JXG.Complex(z1); 230 * z.add(z2);</pre> 231 * @namespace Namespace for the complex number arithmetic functions. 232 */ 233 JXG.C = {}; 234 235 /** 236 * Add two (complex) numbers z1 and z2 and return the result as a (complex) number. 237 * @param {JXG.Complex,Number} z1 Summand 238 * @param {JXG.Complex,Number} z2 Summand 239 * @returns {JXG.Complex} A complex number equal to the sum of the given parameters. 240 */ 241 JXG.C.add = function (z1, z2) { 242 var z = new JXG.Complex(z1); 243 z.add(z2); 244 return z; 245 }; 246 247 /** 248 * Subtract two (complex) numbers z1 and z2 and return the result as a (complex) number. 249 * @param {JXG.Complex,Number} z1 Minuend 250 * @param {JXG.Complex,Number} z2 Subtrahend 251 * @returns {JXG.Complex} A complex number equal to the difference of the given parameters. 252 */ 253 JXG.C.sub = function (z1, z2) { 254 var z = new JXG.Complex(z1); 255 z.sub(z2); 256 return z; 257 }; 258 259 /** 260 * Multiply two (complex) numbers z1 and z2 and return the result as a (complex) number. 261 * @param {JXG.Complex,Number} z1 Factor 262 * @param {JXG.Complex,Number} z2 Factor 263 * @returns {JXG.Complex} A complex number equal to the product of the given parameters. 264 */ 265 JXG.C.mult = function (z1, z2) { 266 var z = new JXG.Complex(z1); 267 z.mult(z2); 268 return z; 269 }; 270 271 /** 272 * Divide two (complex) numbers z1 and z2 and return the result as a (complex) number. 273 * @param {JXG.Complex,Number} z1 Dividend 274 * @param {JXG.Complex,Number} z2 Divisor 275 * @returns {JXG.Complex} A complex number equal to the quotient of the given parameters. 276 */ 277 JXG.C.div = function (z1, z2) { 278 var z = new JXG.Complex(z1); 279 z.div(z2); 280 return z; 281 }; 282 283 /** 284 * Conjugate a complex number and return the result. 285 * @param {JXG.Complex,Number} z1 Complex number 286 * @returns {JXG.Complex} A complex number equal to the conjugate of the given parameter. 287 */ 288 JXG.C.conj = function (z1) { 289 var z = new JXG.Complex(z1); 290 z.conj(); 291 return z; 292 }; 293 294 /** 295 * Absolute value of a complex number. 296 * @param {JXG.Complex,Number} z1 Complex number 297 * @returns {Number} real number equal to the absolute value of the given parameter. 298 */ 299 JXG.C.abs = function (z1) { 300 var z = new JXG.Complex(z1); 301 302 z.conj(); 303 z.mult(z1); 304 305 return Math.sqrt(z.real); 306 }; 307 308 JXG.Complex.C = JXG.C; 309 310 return JXG.Complex; 311 });