View Javadoc

1   /*
2    * Copyright 2003-2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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                 // ignore exception
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 }