001/* 002 * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences. 003 * Copyright (C) 2006 - JScience (http://jscience.org/) 004 * All rights reserved. 005 * 006 * Permission to use, copy, modify, and distribute this software is 007 * freely granted, provided that this notice is preserved. 008 */ 009package org.jscience.mathematics.number; 010 011import java.io.IOException; 012 013import org.jscience.mathematics.structure.Field; 014 015import javolution.lang.MathLib; 016import javolution.text.Text; 017import javolution.text.TextFormat; 018import javolution.text.TypeFormat; 019import javolution.context.ObjectFactory; 020import javolution.xml.XMLFormat; 021import javolution.xml.stream.XMLStreamException; 022 023//@RETROWEAVER import javolution.text.Appendable; 024 025/** 026 * <p> This class represents an immutable complex number.</p> 027 * 028 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a> 029 * @version 3.0, February 13, 2006 030 * @see <a href="http://en.wikipedia.org/wiki/Complex_number"> 031 * Wikipedia: Complex number</a> 032 */ 033public final class Complex extends Number<Complex> implements Field<Complex> { 034 035 /** 036 * Holds the local text format for complex numbers (cartesian form 037 * by default, e.g.<code> "2.34 - 0.4i"</code>). 038 */ 039 private static final TextFormat<Complex> CARTESIAN_FORMAT = new TextFormat<Complex>() { 040 public Appendable format(Complex complex, Appendable appendable) 041 throws IOException { 042 TypeFormat.format(complex._real, appendable); 043 if (complex._imaginary < 0.0) { 044 appendable.append(" - "); 045 TypeFormat.format(-complex._imaginary, appendable); 046 } else { 047 appendable.append(" + "); 048 TypeFormat.format(complex._imaginary, appendable); 049 } 050 return appendable.append('i'); 051 } 052 053 public Complex parse(CharSequence csq, Cursor cursor) { 054 // Reads real part. 055 double real = TypeFormat.parseDouble(csq, cursor); 056 057 // Reads separator. 058 cursor.skip(' ', csq); 059 char op = cursor.next(csq); 060 if ((op != '+') && (op != '-')) 061 throw new NumberFormatException("'+' or '-' expected"); 062 cursor.skip(' ', csq); 063 064 // Reads imaginary part. 065 double imaginary = TypeFormat.parseDouble(csq, cursor); 066 char i = cursor.next(csq); 067 if (i != 'i') 068 throw new NumberFormatException("'i' expected"); 069 return Complex.valueOf(real, op == '-' ? -imaginary : imaginary); 070 } 071 }; 072 static { // Sets default format to cartesian, users can always change it to polar. 073 TextFormat.setInstance(Complex.class, CARTESIAN_FORMAT); 074 } 075 076 /** 077 * The complex number zero. 078 */ 079 public static final Complex ZERO = new Complex(0.0, 0.0); 080 081 /** 082 * The complex number one. 083 */ 084 public static final Complex ONE = new Complex(1.0, 0.0); 085 086 /** 087 * The imaginary unit <i><b>i</b></i>. 088 */ 089 public static final Complex I = new Complex(0.0, 1.0); 090 091 /** 092 * Holds the default XML representation for complex numbers. 093 * This representation consists of <code>real</code> and 094 * <code>imaginary</code> attributes (e.g. 095 * <code><Complex real="2.34" imaginary="-0.4"/></code>). 096 */ 097 static final XMLFormat<Complex> XML = new XMLFormat<Complex>(Complex.class) { 098 099 @Override 100 public Complex newInstance(Class<Complex> cls, InputElement xml) 101 throws XMLStreamException { 102 return Complex.valueOf(xml.getAttribute("real", 0.0), xml 103 .getAttribute("imaginary", 0.0)); 104 } 105 106 public void write(Complex complex, OutputElement xml) 107 throws XMLStreamException { 108 xml.setAttribute("real", complex._real); 109 xml.setAttribute("imaginary", complex._imaginary); 110 } 111 112 public void read(InputElement xml, Complex complex) { 113 // Nothing to do, immutable. 114 } 115 }; 116 117 /** 118 * Holds the factory constructing complex instances. 119 */ 120 private static final ObjectFactory<Complex> FACTORY = new ObjectFactory<Complex>() { 121 protected Complex create() { 122 return new Complex(); 123 } 124 }; 125 126 /** 127 * Holds the real component. 128 */ 129 private double _real; 130 131 /** 132 * Holds the imaginary component. 133 */ 134 private double _imaginary; 135 136 /** 137 * Default constructor. 138 */ 139 private Complex() { 140 } 141 142 /** 143 * Creates a complex number having the specified real and imaginary 144 * components. 145 * 146 * @param real the real component of this complex number. 147 * @param imaginary the imaginary component of this complex number. 148 */ 149 private Complex(double real, double imaginary) { 150 _real = real; 151 _imaginary = imaginary; 152 } 153 154 /** 155 * Returns the complex number having the specified real and imaginary 156 * components. 157 * 158 * @param real the real component of this complex number. 159 * @param imaginary the imaginary component of this complex number. 160 * @return the corresponding complex number. 161 * @see #getReal 162 * @see #getImaginary 163 */ 164 public static Complex valueOf(double real, double imaginary) { 165 Complex c = FACTORY.object(); 166 c._real = real; 167 c._imaginary = imaginary; 168 return c; 169 } 170 171 /** 172 * Returns the complex number for the specified character sequence. 173 * 174 * @param csq the character sequence. 175 * @return <code>TextFormat.getInstance(Complex.class).parse(csq)</code> 176 * @throws IllegalArgumentException if the character sequence does not 177 * contain a parsable complex number. 178 * @see TextFormat#getInstance(Class) 179 */ 180 public static Complex valueOf(CharSequence csq) { 181 return TextFormat.getInstance(Complex.class).parse(csq); 182 } 183 184 /** 185 * Indicates if either the real or imaginary component of this complex 186 * is infinite. 187 * 188 * @return <code>true</code> if this complex is infinite; 189 * <code>false</code> otherwise. 190 */ 191 public boolean isInfinite() { 192 return Double.isInfinite(_real) | Double.isInfinite(_imaginary); 193 } 194 195 /** 196 * Indicates if either the real or imaginary component of this complex 197 * is not a number. 198 * 199 * @return <code>true</code> if this complex is NaN; 200 * <code>false</code> otherwise. 201 */ 202 public boolean isNaN() { 203 return Double.isNaN(_real) | Double.isNaN(_imaginary); 204 } 205 206 /** 207 * Returns the real component of this complex number. 208 * 209 * @return the real component. 210 */ 211 public double getReal() { 212 return _real; 213 } 214 215 /** 216 * Returns the imaginary component of this complex number. 217 * 218 * @return the imaginary component. 219 */ 220 public double getImaginary() { 221 return _imaginary; 222 } 223 224 /** 225 * Returns the negation of this complex. 226 * 227 * @return <code>-this</code>. 228 */ 229 public Complex opposite() { 230 Complex c = FACTORY.object(); 231 c._real = -this._real; 232 c._imaginary = -this._imaginary; 233 return c; 234 } 235 236 /** 237 * Returns the sum of this complex with the one specified. 238 * 239 * @param that the complex to be added. 240 * @return <code>this + that</code>. 241 */ 242 public Complex plus(Complex that) { 243 Complex c = FACTORY.object(); 244 c._real = this._real + that._real; 245 c._imaginary = this._imaginary + that._imaginary; 246 return c; 247 } 248 249 /** 250 * Returns the difference between this complex and the one specified. 251 * 252 * @param that the complex to be subtracted. 253 * @return <code>this - that</code>. 254 */ 255 public Complex minus(Complex that) { 256 Complex c = FACTORY.object(); 257 c._real = this._real - that._real; 258 c._imaginary = this._imaginary - that._imaginary; 259 return c; 260 } 261 262 /** 263 * Returns this complex multiplied by the specified factor. 264 * 265 * @param k the factor multiplier. 266 * @return <code>this * k</code>. 267 */ 268 public Complex times(double k) { 269 Complex c = FACTORY.object(); 270 c._real = this._real * k; 271 c._imaginary = this._imaginary * k; 272 return c; 273 } 274 275 /** 276 * Returns the product of this complex with the one specified. 277 * 278 * @param that the complex multiplier. 279 * @return <code>this * that</code>. 280 */ 281 public Complex times(Complex that) { 282 Complex c = FACTORY.object(); 283 c._real = this._real * that._real - this._imaginary * that._imaginary; 284 c._imaginary = this._real * that._imaginary + this._imaginary 285 * that._real; 286 return c; 287 } 288 289 /** 290 * Returns the inverse of this complex. 291 * 292 * @return <code>1 / this</code>. 293 */ 294 public Complex inverse() { 295 Complex c = FACTORY.object(); 296 double tmp = (this._real * this._real) 297 + (this._imaginary * this._imaginary); 298 c._real = this._real / tmp; 299 c._imaginary = -this._imaginary / tmp; 300 return c; 301 } 302 303 /** 304 * Returns this complex divided by the specified factor. 305 * 306 * @param k the factor divisor. 307 * @return <code>this / k</code>. 308 */ 309 public Complex divide(double k) { 310 Complex c = FACTORY.object(); 311 c._real = this._real / k; 312 c._imaginary = this._imaginary / k; 313 return c; 314 } 315 316 /** 317 * Returns this complex divided by the specified complex. 318 * 319 * @param that the complex divisor. 320 * @return <code>this / that</code>. 321 */ 322 public Complex divide(Complex that) { 323 double tmp = (that._real * that._real) 324 + (that._imaginary * that._imaginary); 325 double thatInvReal = that._real / tmp; 326 double thatInvImaginary = -that._imaginary / tmp; 327 Complex c = FACTORY.object(); 328 c._real = this._real * thatInvReal - this._imaginary * thatInvImaginary; 329 c._imaginary = this._real * thatInvImaginary + this._imaginary 330 * thatInvReal; 331 return c; 332 } 333 334 /** 335 * Returns the conjugate of this complex number. 336 * 337 * @return <code>(this.real(), - this.imaginary())</code>. 338 */ 339 public Complex conjugate() { 340 Complex c = FACTORY.object(); 341 c._real = this._real; 342 c._imaginary = -this._imaginary; 343 return c; 344 } 345 346 /** 347 * Returns the magnitude of this complex number, also referred to 348 * as the "modulus" or "length". 349 * 350 * @return the magnitude of this complex number. 351 */ 352 public double magnitude() { 353 return MathLib.sqrt(_real * _real + _imaginary * _imaginary); 354 } 355 356 /** 357 * Returns the argument of this complex number. It is the angle 358 * in radians, measured counter-clockwise from the real axis. 359 * 360 * @return argument of this complex number. 361 */ 362 public double argument() { 363 return MathLib.atan2(_imaginary, _real); 364 } 365 366 /** 367 * Returns one of the two square root of this complex number. 368 * 369 * @return <code>sqrt(this)</code>. 370 */ 371 public Complex sqrt() { 372 Complex c = FACTORY.object(); 373 double m = MathLib.sqrt(this.magnitude()); 374 double a = this.argument() / 2.0; 375 c._real = m * MathLib.cos(a); 376 c._imaginary = m * MathLib.sin(a); 377 return c; 378 } 379 380 /** 381 * Returns the exponential number <i>e</i> raised to the power of 382 * this complex. 383 * Note: <code><i><b>e</b></i><sup><font size=+0><b>PI</b>*<i><b>i 384 * </b></i></font></sup> = -1</code> 385 * 386 * @return <code>exp(this)</code>. 387 */ 388 public Complex exp() { 389 Complex c = FACTORY.object(); 390 double m = MathLib.exp(this._real); 391 c._real = m * MathLib.cos(this._imaginary); 392 c._imaginary = m * MathLib.sin(this._imaginary); 393 return c; 394 } 395 396 /** 397 * Returns the principal natural logarithm (base e) of this complex. 398 * Note: There are an infinity of solutions. 399 * 400 * @return <code>log(this)</code>. 401 */ 402 public Complex log() { 403 Complex c = FACTORY.object(); 404 c._real = MathLib.log(this.magnitude()); 405 c._imaginary = this.argument(); 406 return c; 407 } 408 409 /** 410 * Returns this complex raised to the specified power. 411 * 412 * @param e the exponent. 413 * @return <code>this**e</code>. 414 */ 415 public Complex pow(double e) { 416 Complex c = FACTORY.object(); 417 double m = MathLib.pow(this.magnitude(), e); 418 double a = this.argument() * e; 419 c._real = m * MathLib.cos(a); 420 c._imaginary = m * MathLib.sin(a); 421 return c; 422 } 423 424 /** 425 * Returns this complex raised to the power of the specified complex 426 * exponent. 427 * 428 * @param that the exponent. 429 * @return <code>this**that</code>. 430 */ 431 public Complex pow(Complex that) { 432 Complex c = FACTORY.object(); 433 double r1 = MathLib.log(this.magnitude()); 434 double i1 = this.argument(); 435 double r2 = (r1 * that._real) - (i1 * that._imaginary); 436 double i2 = (r1 * that._imaginary) + (i1 * that._real); 437 double m = MathLib.exp(r2); 438 c._real = m * MathLib.cos(i2); 439 c._imaginary = m * MathLib.sin(i2); 440 return c; 441 } 442 443 /** 444 * Indicates if two complexes are "sufficiently" alike to be considered 445 * equal. 446 * 447 * @param that the complex to compare with. 448 * @param tolerance the maximum magnitude of the difference between 449 * them before they are considered <i>not</i> equal. 450 * @return <code>true</code> if they are considered equal; 451 * <code>false</code> otherwise. 452 */ 453 public boolean equals(Complex that, double tolerance) { 454 return MathLib.abs(this.minus(that).magnitude()) <= tolerance; 455 } 456 457 /** 458 * Compares this complex against the specified Object. 459 * 460 * @param that the object to compare with. 461 * @return <code>true</code> if the objects are the same; 462 * <code>false</code> otherwise. 463 */ 464 public boolean equals(Object that) { 465 return (that instanceof Complex) 466 && (this._real == ((Complex) that)._real) 467 && (this._imaginary == ((Complex) that)._imaginary); 468 } 469 470 /** 471 * Returns the hash code for this complex number. 472 * 473 * @return the hash code value. 474 */ 475 public int hashCode() { 476 int h = Float.floatToIntBits((float) _real) 477 ^ Float.floatToIntBits((float) (_imaginary * MathLib.PI)); 478 h += ~(h << 9); 479 h ^= (h >>> 14); 480 h += (h << 4); 481 return h ^ (h >>> 10); 482 } 483 484 /** 485 * Returns the text representation of this complex number. 486 * 487 * @return <code>TextFormat.getInstance(Complex.class).format(this)</code> 488 * @see TextFormat#getInstance(Class) 489 */ 490 public Text toText() { 491 return TextFormat.getInstance(Complex.class).format(this); 492 } 493 494 /** 495 * Returns the {@link #getReal real} component of this {@link Complex} 496 * number as a <code>long</code>. 497 * 498 * @return <code>(long) this.getReal()</code> 499 */ 500 public long longValue() { 501 return (long) _real; 502 } 503 504 /** 505 * Returns the {@link #getReal real} component of this {@link Complex} 506 * number as a <code>double</code>. 507 * 508 * @return <code>(double) this.getReal()</code> 509 */ 510 public double doubleValue() { 511 return _real; 512 } 513 514 /** 515 * Compares two complex numbers, the real components are compared first, 516 * then if equal, the imaginary components. 517 * 518 * @param that the complex number to be compared with. 519 * @return -1, 0, 1 based upon the ordering. 520 */ 521 public int compareTo(Complex that) { 522 if (this._real < that._real) 523 return -1; 524 if (this._real > that._real) 525 return 1; 526 long l1 = Double.doubleToLongBits(this._real); 527 long l2 = Double.doubleToLongBits(that._real); 528 if (l1 < l2) 529 return -1; 530 if (l2 > l1) 531 return 1; 532 if (this._imaginary < that._imaginary) 533 return -1; 534 if (this._imaginary > that._imaginary) 535 return 1; 536 l1 = Double.doubleToLongBits(this._imaginary); 537 l2 = Double.doubleToLongBits(that._imaginary); 538 if (l1 < l2) 539 return -1; 540 if (l2 > l1) 541 return 1; 542 return 0; 543 } 544 545 /** 546 * Compares the {@link #magnitude() magnitude} of this complex number 547 * with the magnitude of the complex number specified. 548 * 549 * @param that the complex number to be compared with. 550 * @return <code>|this| > |that|</code> 551 */ 552 public boolean isLargerThan(Complex that) { 553 return this.magnitude() > that.magnitude(); 554 } 555 556 @Override 557 public Complex copy() { 558 return Complex.valueOf(_real, _imaginary); 559 } 560 561 private static final long serialVersionUID = 1L; 562 563}