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>&lt;Complex real="2.34" imaginary="-0.4"/&gt;</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}