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