1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math.complex;
18
19 import java.io.Serializable;
20
21 /***
22 * Representation of a Complex number - a number which has both a
23 * real and imaginary part.
24 *
25 * @author Apache Software Foundation
26 * @version $Revision: 1.9 $ $Date: 2004/06/23 16:26:16 $
27 */
28 public class Complex implements Serializable {
29
30 /*** Serializable version identifier */
31 static final long serialVersionUID = -6530173849413811929L;
32
33 /*** The square root of -1. A number representing "0.0 + 1.0i".*/
34 public static final Complex I = new Complex(0.0, 1.0);
35
36 /*** A complex number representing "(Double.NaN) + (Double.NaN)i" */
37 public static final Complex NaN = new Complex(Double.NaN, Double.NaN);
38
39 /*** A complex number representing "1.0 + 0.0i" */
40 public static final Complex ONE = new Complex(1.0, 0.0);
41
42 /*** The imaginary part. */
43 protected double imaginary;
44
45 /*** The real part. */
46 protected double real;
47
48 /***
49 * Create a complex number given the real and imaginary parts.
50 *
51 * @param real the real part.
52 * @param imaginary the imaginary part.
53 */
54 public Complex(double real, double imaginary) {
55 super();
56 this.real = real;
57 this.imaginary = imaginary;
58 }
59
60 /***
61 * Return the absolute value of this complex number.
62 *
63 * @return the absolute value.
64 */
65 public double abs() {
66 if (isNaN()) {
67 return Double.NaN;
68 }
69 return Math.sqrt(squareSum());
70 }
71
72 /***
73 * Return the sum of this complex number and the given complex number.
74 *
75 * @param rhs the other complex number.
76 * @return the complex number sum.
77 */
78 public Complex add(Complex rhs) {
79 if (isNaN() || rhs.isNaN()) {
80 return NaN;
81 }
82
83 return new Complex(real + rhs.getReal(),
84 imaginary + rhs.getImaginary());
85 }
86
87 /***
88 * Return the conjugate of this complex number. The conjugate of
89 * "A + Bi" is "A - Bi". Complex.NaN is returned if either the real or imaginary part of
90 * this Complex number equals Double.NaN.
91 *
92 * @return the conjugate of this Complex object
93 */
94 public Complex conjugate() {
95 if (isNaN()) {
96 return NaN;
97 }
98
99 return new Complex(real, -imaginary);
100 }
101
102 /***
103 * Return the quotient of this complex number and the given complex number.
104 * @param rhs the other complex number.
105 * @return the complex number quotient.
106 */
107 public Complex divide(Complex rhs) {
108 if (isNaN() || rhs.isNaN()) {
109 return NaN;
110 }
111
112 if (Math.abs(rhs.getReal()) < Math.abs(rhs.getImaginary())) {
113 double q = rhs.getReal() / rhs.getImaginary();
114 double d = (rhs.getReal() * q) + rhs.getImaginary();
115 return new Complex(((real * q) + imaginary) / d,
116 ((imaginary * q) - real) / d);
117 } else {
118 double q = rhs.getImaginary() / rhs.getReal();
119 double d = (rhs.getImaginary() * q) + rhs.getReal();
120 return new Complex(((imaginary * q) + real) / d,
121 (imaginary - (real * q)) / d);
122 }
123 }
124
125 /***
126 * Test for the equality of two Complex objects. If both the
127 * real and imaginary parts of two Complex numbers are exactly
128 * the same, the two Complex objects are considered to be equal.
129 *
130 * @param other Object to test for equality to this
131 * @return true if two Complex objects are equal, false if
132 * object is null, not an instance of Complex, or
133 * not equal to this Complex instance.
134 *
135 */
136 public boolean equals(Object other) {
137 boolean ret;
138
139 if (this == other) {
140 ret = true;
141 } else if (other == null) {
142 ret = false;
143 } else {
144 try {
145 Complex rhs = (Complex)other;
146 ret = (Double.doubleToRawLongBits(real) ==
147 Double.doubleToRawLongBits(rhs.getReal())) &&
148 (Double.doubleToRawLongBits(imaginary) ==
149 Double.doubleToRawLongBits(rhs.getImaginary()));
150 } catch (ClassCastException ex) {
151
152 ret = false;
153 }
154 }
155
156 return ret;
157 }
158
159 /***
160 * Access the imaginary part.
161 *
162 * @return the imaginary part.
163 */
164 public double getImaginary() {
165 return imaginary;
166 }
167
168 /***
169 * Access the real part.
170 *
171 * @return the real part.
172 */
173 public double getReal() {
174 return real;
175 }
176
177 /***
178 * Returns true if this complex number is the special Not-a-Number (NaN)
179 * value.
180 *
181 * @return true if the value represented by this object is NaN; false
182 * otherwise.
183 */
184 public boolean isNaN() {
185 return Double.isNaN(real) || Double.isNaN(imaginary);
186 }
187
188 /***
189 * Return the product of this complex number and the given complex number.
190 *
191 * @param rhs the other complex number.
192 * @return the complex number product.
193 */
194 public Complex multiply(Complex rhs) {
195 if (isNaN() || rhs.isNaN()) {
196 return NaN;
197 }
198
199 double p = (real + imaginary) * (rhs.getReal() + rhs.getImaginary());
200 double ac = real * rhs.getReal();
201 double bd = imaginary * rhs.getImaginary();
202 return new Complex(ac - bd, p - ac - bd);
203 }
204
205 /***
206 * Return the additive inverse of this complex number.
207 *
208 * @return the negation of this complex number.
209 */
210 public Complex negate() {
211 if (isNaN()) {
212 return NaN;
213 }
214
215 return new Complex(-real, -imaginary);
216 }
217
218 /***
219 * Return the sum of the squared terms.
220 *
221 * @return the square sum.
222 */
223 private double squareSum() {
224 return real * real + imaginary * imaginary;
225 }
226
227 /***
228 * Return the difference between this complex number and the given complex
229 * number.
230 *
231 * @param rhs the other complex number.
232 * @return the complex number difference.
233 */
234 public Complex subtract(Complex rhs) {
235 if (isNaN() || rhs.isNaN()) {
236 return NaN;
237 }
238
239 return new Complex(real - rhs.getReal(),
240 imaginary - rhs.getImaginary());
241 }
242 }