KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jscience > mathematics > numbers > Complex


1 /*
2  * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
3  * Copyright (C) 2006 - JScience (http://jscience.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */

9 package org.jscience.mathematics.numbers;
10
11 import java.io.IOException JavaDoc;
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 //@RETROWEAVER import javolution.text.Appendable;
23

24 /**
25  * <p> This class represents an immutable complex number.</p>
26  *
27  * @author <a HREF="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
28  * @version 3.0, February 13, 2006
29  * @see <a HREF="http://en.wikipedia.org/wiki/Complex_number">
30  * Wikipedia: Complex number</a>
31  */

32 public final class Complex extends Number JavaDoc<Complex> implements Field<Complex> {
33
34     /**
35      * Holds the local text format for complex numbers (cartesian form
36      * by default, e.g.<code> "2.34 - 0.4i"</code>).
37      */

38     public static final Reference<TextFormat<Complex>> FORMAT = new Reference<TextFormat<Complex>>(
39             new TextFormat<Complex>() {
40                 public Appendable JavaDoc format(Complex complex, Appendable JavaDoc appendable)
41                         throws IOException JavaDoc {
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 JavaDoc csq, Cursor cursor) {
54                     // Reads real part.
55
double real = TypeFormat.parseDouble(csq, cursor);
56
57                     // Reads separator.
58
cursor.skip(' ', csq);
59                     char op = cursor.next(csq);
60                     if ((op != '+') && (op != '-'))
61                         throw new NumberFormatException JavaDoc("'+' or '-' expected");
62                     cursor.skip(' ', csq);
63
64                     // Reads imaginary part.
65
double imaginary = TypeFormat.parseDouble(csq, cursor);
66                     char i = cursor.next(csq);
67                     if (i != 'i')
68                         throw new NumberFormatException JavaDoc("'i' expected");
69                     return Complex.valueOf(real, op == '-' ? -imaginary
70                             : imaginary);
71                 }
72             });
73
74     /**
75      * Holds the default XML representation for complex numbers.
76      * This representation consists of <code>real</code> and
77      * <code>imaginary</code> attributes (e.g.
78      * <code>&lt;Complex real="2.34" imaginary="-0.4"/&gt;</code>).
79      */

80    protected static final XMLFormat<Complex> XML = new XMLFormat<Complex>(Complex.class) {
81        
82        @Override JavaDoc
83        public Complex newInstance(Class JavaDoc<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             // Nothing to do, immutable.
95
}
96     };
97
98     /**
99      * The complex number zero.
100      */

101     public static final Complex ZERO = new Complex(0.0, 0.0);
102
103     /**
104      * The complex number one.
105      */

106     public static final Complex ONE = new Complex(1.0, 0.0);
107
108     /**
109      * The imaginary unit <i><b>i</b></i>.
110      */

111     public static final Complex I = new Complex(0.0, 1.0);
112
113     /**
114      * Holds the factory constructing complex instances.
115      */

116     private static final Factory<Complex> FACTORY = new Factory<Complex>() {
117         public Complex create() {
118             return new Complex();
119         }
120     };
121
122     /**
123      * Holds the real component.
124      */

125     private double _real;
126
127     /**
128      * Holds the imaginary component.
129      */

130     private double _imaginary;
131
132     /**
133      * Default constructor.
134      */

135     private Complex() {
136     }
137
138     /**
139      * Creates a complex number having the specified real and imaginary
140      * components.
141      *
142      * @param real the real component of this complex number.
143      * @param imaginary the imaginary component of this complex number.
144      */

145     private Complex(double real, double imaginary) {
146         _real = real;
147         _imaginary = imaginary;
148     }
149
150     /**
151      * Returns the complex number having the specified real and imaginary
152      * components.
153      *
154      * @param real the real component of this complex number.
155      * @param imaginary the imaginary component of this complex number.
156      * @return the corresponding complex number.
157      * @see #getReal
158      * @see #getImaginary
159      */

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     /**
168      * Returns the complex number for the specified character sequence.
169      *
170      * @param csq the character sequence.
171      * @return <code>Complex.FORMAT.get().parse(csq)</code>
172      * @throws IllegalArgumentException if the character sequence does not
173      * contain a parsable complex number.
174      * @see Complex#FORMAT
175      */

176     public static Complex valueOf(CharSequence JavaDoc csq) {
177         return Complex.FORMAT.get().parse(csq);
178     }
179
180     /**
181      * Indicates if either the real or imaginary component of this complex
182      * is infinite.
183      *
184      * @return <code>true</code> if this complex is infinite;
185      * <code>false</code> otherwise.
186      */

187     public boolean isInfinite() {
188         return Double.isInfinite(_real) | Double.isInfinite(_imaginary);
189     }
190
191     /**
192      * Indicates if either the real or imaginary component of this complex
193      * is not a number.
194      *
195      * @return <code>true</code> if this complex is NaN;
196      * <code>false</code> otherwise.
197      */

198     public boolean isNaN() {
199         return Double.isNaN(_real) | Double.isNaN(_imaginary);
200     }
201
202     /**
203      * Returns the real component of this complex number.
204      *
205      * @return the real component.
206      */

207     public double getReal() {
208         return _real;
209     }
210
211     /**
212      * Returns the imaginary component of this complex number.
213      *
214      * @return the imaginary component.
215      */

216     public double getImaginary() {
217         return _imaginary;
218     }
219
220     /**
221      * Returns the negation of this complex.
222      *
223      * @return <code>-this</code>.
224      */

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     /**
233      * Returns the sum of this complex with the one specified.
234      *
235      * @param that the complex to be added.
236      * @return <code>this + that</code>.
237      */

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     /**
246      * Returns the difference between this complex and the one specified.
247      *
248      * @param that the complex to be subtracted.
249      * @return <code>this - that</code>.
250      */

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     /**
259      * Returns this complex multiplied by the specified factor.
260      *
261      * @param k the factor multiplier.
262      * @return <code>this * k</code>.
263      */

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     /**
272      * Returns the product of this complex with the one specified.
273      *
274      * @param that the complex multiplier.
275      * @return <code>this * that</code>.
276      */

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     /**
286      * Returns the inverse of this complex.
287      *
288      * @return <code>1 / this</code>.
289      */

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     /**
300      * Returns this complex divided by the specified factor.
301      *
302      * @param k the factor divisor.
303      * @return <code>this / k</code>.
304      */

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     /**
313      * Returns this complex divided by the specified complex.
314      *
315      * @param that the complex divisor.
316      * @return <code>this / that</code>.
317      */

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     /**
331      * Returns the conjugate of this complex number.
332      *
333      * @return <code>(this.real(), - this.imaginary())</code>.
334      */

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     /**
343      * Returns the magnitude of this complex number, also referred to
344      * as the "modulus" or "length".
345      *
346      * @return the magnitude of this complex number.
347      */

348     public double magnitude() {
349         return MathLib.sqrt(_real * _real + _imaginary * _imaginary);
350     }
351
352     /**
353      * Returns the argument of this complex number. It is the angle
354      * in radians, measured counter-clockwise from the real axis.
355      *
356      * @return argument of this complex number.
357      */

358     public double argument() {
359         return MathLib.atan2(_imaginary, _real);
360     }
361
362     /**
363      * Returns one of the two square root of this complex number.
364      *
365      * @return <code>sqrt(this)</code>.
366      */

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     /**
377      * Returns the exponential number <i>e</i> raised to the power of
378      * this complex.
379      * Note: <code><i><b>e</b></i><sup><font size=+0><b>PI</b>*<i><b>i
380      * </b></i></font></sup> = -1</code>
381      *
382      * @return <code>exp(this)</code>.
383      */

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     /**
393      * Returns the principal natural logarithm (base e) of this complex.
394      * Note: There are an infinity of solutions.
395      *
396      * @return <code>log(this)</code>.
397      */

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     /**
406      * Returns this complex raised to the specified power.
407      *
408      * @param e the exponent.
409      * @return <code>this**e</code>.
410      */

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     /**
421      * Returns this complex raised to the power of the specified complex
422      * exponent.
423      *
424      * @param that the exponent.
425      * @return <code>this**that</code>.
426      */

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     /**
440      * Indicates if two complexes are "sufficiently" alike to be considered
441      * equal.
442      *
443      * @param that the complex to compare with.
444      * @param tolerance the maximum magnitude of the difference between
445      * them before they are considered <i>not</i> equal.
446      * @return <code>true</code> if they are considered equal;
447      * <code>false</code> otherwise.
448      */

449     public boolean equals(Complex that, double tolerance) {
450         return MathLib.abs(this.minus(that).magnitude()) <= tolerance;
451     }
452
453     /**
454      * Compares this complex against the specified Object.
455      *
456      * @param that the object to compare with.
457      * @return <code>true</code> if the objects are the same;
458      * <code>false</code> otherwise.
459      */

460     public boolean equals(Object JavaDoc that) {
461         return (that instanceof Complex)
462                 && (this._real == ((Complex) that)._real)
463                 && (this._imaginary == ((Complex) that)._imaginary);
464     }
465
466     /**
467      * Returns the hash code for this complex number.
468      *
469      * @return the hash code value.
470      */

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     /**
481      * Returns the text representation of this complex number.
482      *
483      * @return <code>Complex.FORMAT.get().format(this)</code>
484      * @see Complex#FORMAT
485      */

486     public Text toText() {
487         return Complex.FORMAT.get().format(this);
488     }
489
490     /**
491      * Returns the {@link #getReal real} component of this {@link Complex}
492      * number as a <code>long</code>.
493      *
494      * @return <code>(long) this.getReal()</code>
495      */

496     public long longValue() {
497         return (long) _real;
498     }
499
500     /**
501      * Returns the {@link #getReal real} component of this {@link Complex}
502      * number as a <code>double</code>.
503      *
504      * @return <code>(double) this.getReal()</code>
505      */

506     public double doubleValue() {
507         return _real;
508     }
509
510     /**
511      * Compares two complex numbers, the real components are compared first,
512      * then if equal, the imaginary components.
513      *
514      * @param that the complex number to be compared with.
515      * @return -1, 0, 1 based upon the ordering.
516      */

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     /**
542      * Compares the {@link #magnitude() magnitude} of this complex number
543      * with the magnitude of the complex number specified.
544      *
545      * @param that the complex number to be compared with.
546      * @return <code>|this| > |that|</code>
547      */

548     public boolean isLargerThan(Complex that) {
549         return this.magnitude() > that.magnitude();
550     }
551
552     private static final long serialVersionUID = 1L;
553 }
Popular Tags