1 9 package org.jscience.mathematics.numbers; 10 11 import java.io.IOException ; 12 13 import org.jscience.mathematics.structures.Field; 14 15 import javolution.lang.MathLib; 16 import javolution.text.Text; 17 import javolution.text.TextFormat; 18 import javolution.text.TypeFormat; 19 import javolution.context.LocalContext.Reference; 20 import javolution.xml.XMLFormat; 21 import javolution.xml.stream.XMLStreamException; 22 24 32 public final class Complex extends Number <Complex> implements Field<Complex> { 33 34 38 public static final Reference<TextFormat<Complex>> FORMAT = new Reference<TextFormat<Complex>>( 39 new TextFormat<Complex>() { 40 public Appendable format(Complex complex, Appendable appendable) 41 throws IOException { 42 TypeFormat.format(complex._real, appendable); 43 if (complex._imaginary < 0.0) { 44 appendable.append(" - "); 45 TypeFormat.format(-complex._imaginary, appendable); 46 } else { 47 appendable.append(" + "); 48 TypeFormat.format(complex._imaginary, appendable); 49 } 50 return appendable.append('i'); 51 } 52 53 public Complex parse(CharSequence csq, Cursor cursor) { 54 double real = TypeFormat.parseDouble(csq, cursor); 56 57 cursor.skip(' ', csq); 59 char op = cursor.next(csq); 60 if ((op != '+') && (op != '-')) 61 throw new NumberFormatException ("'+' or '-' expected"); 62 cursor.skip(' ', csq); 63 64 double imaginary = TypeFormat.parseDouble(csq, cursor); 66 char i = cursor.next(csq); 67 if (i != 'i') 68 throw new NumberFormatException ("'i' expected"); 69 return Complex.valueOf(real, op == '-' ? -imaginary 70 : imaginary); 71 } 72 }); 73 74 80 protected static final XMLFormat<Complex> XML = new XMLFormat<Complex>(Complex.class) { 81 82 @Override 83 public Complex newInstance(Class <Complex> cls, InputElement xml) throws XMLStreamException { 84 return Complex.valueOf(xml.getAttribute("real", 0.0), xml 85 .getAttribute("imaginary", 0.0)); 86 } 87 88 public void write(Complex complex, OutputElement xml) throws XMLStreamException { 89 xml.setAttribute("real", complex._real); 90 xml.setAttribute("imaginary", complex._imaginary); 91 } 92 93 public void read(InputElement xml, Complex complex) { 94 } 96 }; 97 98 101 public static final Complex ZERO = new Complex(0.0, 0.0); 102 103 106 public static final Complex ONE = new Complex(1.0, 0.0); 107 108 111 public static final Complex I = new Complex(0.0, 1.0); 112 113 116 private static final Factory<Complex> FACTORY = new Factory<Complex>() { 117 public Complex create() { 118 return new Complex(); 119 } 120 }; 121 122 125 private double _real; 126 127 130 private double _imaginary; 131 132 135 private Complex() { 136 } 137 138 145 private Complex(double real, double imaginary) { 146 _real = real; 147 _imaginary = imaginary; 148 } 149 150 160 public static Complex valueOf(double real, double imaginary) { 161 Complex c = FACTORY.object(); 162 c._real = real; 163 c._imaginary = imaginary; 164 return c; 165 } 166 167 176 public static Complex valueOf(CharSequence csq) { 177 return Complex.FORMAT.get().parse(csq); 178 } 179 180 187 public boolean isInfinite() { 188 return Double.isInfinite(_real) | Double.isInfinite(_imaginary); 189 } 190 191 198 public boolean isNaN() { 199 return Double.isNaN(_real) | Double.isNaN(_imaginary); 200 } 201 202 207 public double getReal() { 208 return _real; 209 } 210 211 216 public double getImaginary() { 217 return _imaginary; 218 } 219 220 225 public Complex opposite() { 226 Complex c = FACTORY.object(); 227 c._real = -this._real; 228 c._imaginary = -this._imaginary; 229 return c; 230 } 231 232 238 public Complex plus(Complex that) { 239 Complex c = FACTORY.object(); 240 c._real = this._real + that._real; 241 c._imaginary = this._imaginary + that._imaginary; 242 return c; 243 } 244 245 251 public Complex minus(Complex that) { 252 Complex c = FACTORY.object(); 253 c._real = this._real - that._real; 254 c._imaginary = this._imaginary - that._imaginary; 255 return c; 256 } 257 258 264 public Complex times(double k) { 265 Complex c = FACTORY.object(); 266 c._real = this._real * k; 267 c._imaginary = this._imaginary * k; 268 return c; 269 } 270 271 277 public Complex times(Complex that) { 278 Complex c = FACTORY.object(); 279 c._real = this._real * that._real - this._imaginary * that._imaginary; 280 c._imaginary = this._real * that._imaginary + this._imaginary 281 * that._real; 282 return c; 283 } 284 285 290 public Complex inverse() { 291 Complex c = FACTORY.object(); 292 double tmp = (this._real * this._real) 293 + (this._imaginary * this._imaginary); 294 c._real = this._real / tmp; 295 c._imaginary = -this._imaginary / tmp; 296 return c; 297 } 298 299 305 public Complex divide(double k) { 306 Complex c = FACTORY.object(); 307 c._real = this._real / k; 308 c._imaginary = this._imaginary / k; 309 return c; 310 } 311 312 318 public Complex divide(Complex that) { 319 double tmp = (that._real * that._real) 320 + (that._imaginary * that._imaginary); 321 double thatInvReal = that._real / tmp; 322 double thatInvImaginary = -that._imaginary / tmp; 323 Complex c = FACTORY.object(); 324 c._real = this._real * thatInvReal - this._imaginary * thatInvImaginary; 325 c._imaginary = this._real * thatInvImaginary + this._imaginary 326 * thatInvReal; 327 return c; 328 } 329 330 335 public Complex conjugate() { 336 Complex c = FACTORY.object(); 337 c._real = this._real; 338 c._imaginary = -this._imaginary; 339 return c; 340 } 341 342 348 public double magnitude() { 349 return MathLib.sqrt(_real * _real + _imaginary * _imaginary); 350 } 351 352 358 public double argument() { 359 return MathLib.atan2(_imaginary, _real); 360 } 361 362 367 public Complex sqrt() { 368 Complex c = FACTORY.object(); 369 double m = MathLib.sqrt(this.magnitude()); 370 double a = this.argument() / 2.0; 371 c._real = m * MathLib.cos(a); 372 c._imaginary = m * MathLib.sin(a); 373 return c; 374 } 375 376 384 public Complex exp() { 385 Complex c = FACTORY.object(); 386 double m = MathLib.exp(this._real); 387 c._real = m * MathLib.cos(this._imaginary); 388 c._imaginary = m * MathLib.sin(this._imaginary); 389 return c; 390 } 391 392 398 public Complex log() { 399 Complex c = FACTORY.object(); 400 c._real = MathLib.log(this.magnitude()); 401 c._imaginary = this.argument(); 402 return c; 403 } 404 405 411 public Complex pow(double e) { 412 Complex c = FACTORY.object(); 413 double m = MathLib.pow(this.magnitude(), e); 414 double a = this.argument() * e; 415 c._real = m * MathLib.cos(a); 416 c._imaginary = m * MathLib.sin(a); 417 return c; 418 } 419 420 427 public Complex pow(Complex that) { 428 Complex c = FACTORY.object(); 429 double r1 = MathLib.log(this.magnitude()); 430 double i1 = this.argument(); 431 double r2 = (r1 * that._real) - (i1 * that._imaginary); 432 double i2 = (r1 * that._imaginary) + (i1 * that._real); 433 double m = MathLib.exp(r2); 434 c._real = m * MathLib.cos(i2); 435 c._imaginary = m * MathLib.sin(i2); 436 return c; 437 } 438 439 449 public boolean equals(Complex that, double tolerance) { 450 return MathLib.abs(this.minus(that).magnitude()) <= tolerance; 451 } 452 453 460 public boolean equals(Object that) { 461 return (that instanceof Complex) 462 && (this._real == ((Complex) that)._real) 463 && (this._imaginary == ((Complex) that)._imaginary); 464 } 465 466 471 public int hashCode() { 472 int h = Float.floatToIntBits((float) _real) 473 ^ Float.floatToIntBits((float) (_imaginary * MathLib.PI)); 474 h += ~(h << 9); 475 h ^= (h >>> 14); 476 h += (h << 4); 477 return h ^ (h >>> 10); 478 } 479 480 486 public Text toText() { 487 return Complex.FORMAT.get().format(this); 488 } 489 490 496 public long longValue() { 497 return (long) _real; 498 } 499 500 506 public double doubleValue() { 507 return _real; 508 } 509 510 517 public int compareTo(Complex that) { 518 if (this._real < that._real) 519 return -1; 520 if (this._real > that._real) 521 return 1; 522 long l1 = Double.doubleToLongBits(this._real); 523 long l2 = Double.doubleToLongBits(that._real); 524 if (l1 < l2) 525 return -1; 526 if (l2 > l1) 527 return 1; 528 if (this._imaginary < that._imaginary) 529 return -1; 530 if (this._imaginary > that._imaginary) 531 return 1; 532 l1 = Double.doubleToLongBits(this._imaginary); 533 l2 = Double.doubleToLongBits(that._imaginary); 534 if (l1 < l2) 535 return -1; 536 if (l2 > l1) 537 return 1; 538 return 0; 539 } 540 541 548 public boolean isLargerThan(Complex that) { 549 return this.magnitude() > that.magnitude(); 550 } 551 552 private static final long serialVersionUID = 1L; 553 } | Popular Tags |