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 }