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