    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017
    018    package org.apache.commons.math3.complex;
    019
    020    import java.io.Serializable;
    021    import java.util.ArrayList;
    022    import java.util.List;
    023
    024    import org.apache.commons.math3.FieldElement;
    025    import org.apache.commons.math3.exception.NotPositiveException;
    026    import org.apache.commons.math3.exception.NullArgumentException;
    027    import org.apache.commons.math3.exception.util.LocalizedFormats;
    028    import org.apache.commons.math3.util.FastMath;
    029    import org.apache.commons.math3.util.MathUtils;
    030
    031    /**
    032     * Representation of a Complex number, i.e. a number which has both a
    033     * real and imaginary part.
    034     * <br/>
    035     * Implementations of arithmetic operations handle {@code NaN} and
    036     * infinite values according to the rules for {@link java.lang.Double}, i.e.
    037     * {@link #equals} is an equivalence relation for all instances that have
    038     * a {@code NaN} in either real or imaginary part, e.g. the following are
    039     * considered equal:
    040     * <ul>
    041     *  <li>{@code 1 + NaNi}</li>
    042     *  <li>{@code NaN + i}</li>
    043     *  <li>{@code NaN + NaNi}</li>
    044     * </ul>
    045     * Note that this is in contradiction with the IEEE-754 standard for floating
    046     * point numbers (according to which the test {@code x == x} must fail if
    047     * {@code x} is {@code NaN}). The method
    048     * {@link org.apache.commons.math3.util.Precision#equals(double,double,int)
    049     * equals for primitive double} in {@link org.apache.commons.math3.util.Precision}
    050     * conforms with IEEE-754 while this class conforms with the standard behavior
    051     * for Java object types.
    052     * <br/>
    053     * Implements Serializable since 2.0
    054     *
    055     * @version $Id: Complex.java 1416643 2012-12-03 19:37:14Z tn $
    056     */
    057    public class Complex implements FieldElement<Complex>, Serializable  {
    058        /** The square root of -1. A number representing "0.0 + 1.0i" */
    059        public static final Complex I = new Complex(0.0, 1.0);
    060        // CHECKSTYLE: stop ConstantName
    061        /** A complex number representing "NaN + NaNi" */
    062        public static final Complex NaN = new Complex(Double.NaN, Double.NaN);
    063        // CHECKSTYLE: resume ConstantName
    064        /** A complex number representing "+INF + INFi" */
    065        public static final Complex INF = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
    066        /** A complex number representing "1.0 + 0.0i" */
    067        public static final Complex ONE = new Complex(1.0, 0.0);
    068        /** A complex number representing "0.0 + 0.0i" */
    069        public static final Complex ZERO = new Complex(0.0, 0.0);
    070
    071        /** Serializable version identifier */
    072        private static final long serialVersionUID = -6195664516687396620L;
    073
    074        /** The imaginary part. */
    075        private final double imaginary;
    076        /** The real part. */
    077        private final double real;
    078        /** Record whether this complex number is equal to NaN. */
    079        private final transient boolean isNaN;
    080        /** Record whether this complex number is infinite. */
    081        private final transient boolean isInfinite;
    082
    083        /**
    084         * Create a complex number given only the real part.
    085         *
    086         * @param real Real part.
    087         */
    088        public Complex(double real) {
    089            this(real, 0.0);
    090        }
    091
    092        /**
    093         * Create a complex number given the real and imaginary parts.
    094         *
    095         * @param real Real part.
    096         * @param imaginary Imaginary part.
    097         */
    098        public Complex(double real, double imaginary) {
    099            this.real = real;
    100            this.imaginary = imaginary;
    101
    102            isNaN = Double.isNaN(real) || Double.isNaN(imaginary);
    103            isInfinite = !isNaN &&
    104                (Double.isInfinite(real) || Double.isInfinite(imaginary));
    105        }
    106
    107        /**
    108         * Return the absolute value of this complex number.
    109         * Returns {@code NaN} if either real or imaginary part is {@code NaN}
    110         * and {@code Double.POSITIVE_INFINITY} if neither part is {@code NaN},
    111         * but at least one part is infinite.
    112         *
    113         * @return the absolute value.
    114         */
    115        public double abs() {
    116            if (isNaN) {
    117                return Double.NaN;
    118            }
    119            if (isInfinite()) {
    120                return Double.POSITIVE_INFINITY;
    121            }
    122            if (FastMath.abs(real) < FastMath.abs(imaginary)) {
    123                if (imaginary == 0.0) {
    124                    return FastMath.abs(real);
    125                }
    126                double q = real / imaginary;
    127                return FastMath.abs(imaginary) * FastMath.sqrt(1 + q * q);
    128            } else {
    129                if (real == 0.0) {
    130                    return FastMath.abs(imaginary);
    131                }
    132                double q = imaginary / real;
    133                return FastMath.abs(real) * FastMath.sqrt(1 + q * q);
    134            }
    135        }
    136
    137        /**
    138         * Returns a {@code Complex} whose value is
    139         * {@code (this + addend)}.
    140         * Uses the definitional formula
    141         * <pre>
    142         *  <code>
    143         *   (a + bi) + (c + di) = (a+c) + (b+d)i
    144         *  </code>
    145         * </pre>
    146         * <br/>
    147         * If either {@code this} or {@code addend} has a {@code NaN} value in
    148         * either part, {@link #NaN} is returned; otherwise {@code Infinite}
    149         * and {@code NaN} values are returned in the parts of the result
    150         * according to the rules for {@link java.lang.Double} arithmetic.
    151         *
    152         * @param  addend Value to be added to this {@code Complex}.
    153         * @return {@code this + addend}.
    154         * @throws NullArgumentException if {@code addend} is {@code null}.
    155         */
    156        public Complex add(Complex addend) throws NullArgumentException {
    157            MathUtils.checkNotNull(addend);
    158            if (isNaN || addend.isNaN) {
    159                return NaN;
    160            }
    161
    162            return createComplex(real + addend.getReal(),
    163                                 imaginary + addend.getImaginary());
    164        }
    165
    166        /**
    167         * Returns a {@code Complex} whose value is {@code (this + addend)},
    168         * with {@code addend} interpreted as a real number.
    169         *
    170         * @param addend Value to be added to this {@code Complex}.
    171         * @return {@code this + addend}.
    172         * @see #add(Complex)
    173         */
    174        public Complex add(double addend) {
    175            if (isNaN || Double.isNaN(addend)) {
    176                return NaN;
    177            }
    178
    179            return createComplex(real + addend, imaginary);
    180        }
    181
    182         /**
    183         * Return the conjugate of this complex number.
    184         * The conjugate of {@code a + bi} is {@code a - bi}.
    185         * <br/>
    186         * {@link #NaN} is returned if either the real or imaginary
    187         * part of this Complex number equals {@code Double.NaN}.
    188         * <br/>
    189         * If the imaginary part is infinite, and the real part is not
    190         * {@code NaN}, the returned value has infinite imaginary part
    191         * of the opposite sign, e.g. the conjugate of
    192         * {@code 1 + POSITIVE_INFINITY i} is {@code 1 - NEGATIVE_INFINITY i}.
    193         *
    194         * @return the conjugate of this Complex object.
    195         */
    196        public Complex conjugate() {
    197            if (isNaN) {
    198                return NaN;
    199            }
    200
    201            return createComplex(real, -imaginary);
    202        }
    203
    204        /**
    205         * Returns a {@code Complex} whose value is
    206         * {@code (this / divisor)}.
    207         * Implements the definitional formula
    208         * <pre>
    209         *  <code>
    210         *    a + bi          ac + bd + (bc - ad)i
    211         *    ----------- = -------------------------
    212         *    c + di         c<sup>2</sup> + d<sup>2</sup>
    213         *  </code>
    214         * </pre>
    215         * but uses
    216         * <a href="http://doi.acm.org/10.1145/1039813.1039814">
    217         * prescaling of operands</a> to limit the effects of overflows and
    218         * underflows in the computation.
    219         * <br/>
    220         * {@code Infinite} and {@code NaN} values are handled according to the
    221         * following rules, applied in the order presented:
    222         * <ul>
    223         *  <li>If either {@code this} or {@code divisor} has a {@code NaN} value
    224         *   in either part, {@link #NaN} is returned.
    225         *  </li>
    226         *  <li>If {@code divisor} equals {@link #ZERO}, {@link #NaN} is returned.
    227         *  </li>
    228         *  <li>If {@code this} and {@code divisor} are both infinite,
    229         *   {@link #NaN} is returned.
    230         *  </li>
    231         *  <li>If {@code this} is finite (i.e., has no {@code Infinite} or
    232         *   {@code NaN} parts) and {@code divisor} is infinite (one or both parts
    233         *   infinite), {@link #ZERO} is returned.
    234         *  </li>
    235         *  <li>If {@code this} is infinite and {@code divisor} is finite,
    236         *   {@code NaN} values are returned in the parts of the result if the
    237         *   {@link java.lang.Double} rules applied to the definitional formula
    238         *   force {@code NaN} results.
    239         *  </li>
    240         * </ul>
    241         *
    242         * @param divisor Value by which this {@code Complex} is to be divided.
    243         * @return {@code this / divisor}.
    244         * @throws NullArgumentException if {@code divisor} is {@code null}.
    245         */
    246        public Complex divide(Complex divisor)
    247            throws NullArgumentException {
    248            MathUtils.checkNotNull(divisor);
    249            if (isNaN || divisor.isNaN) {
    250                return NaN;
    251            }
    252
    253            final double c = divisor.getReal();
    254            final double d = divisor.getImaginary();
    255            if (c == 0.0 && d == 0.0) {
    256                return NaN;
    257            }
    258
    259            if (divisor.isInfinite() && !isInfinite()) {
    260                return ZERO;
    261            }
    262
    263            if (FastMath.abs(c) < FastMath.abs(d)) {
    264                double q = c / d;
    265                double denominator = c * q + d;
    266                return createComplex((real * q + imaginary) / denominator,
    267                    (imaginary * q - real) / denominator);
    268            } else {
    269                double q = d / c;
    270                double denominator = d * q + c;
    271                return createComplex((imaginary * q + real) / denominator,
    272                    (imaginary - real * q) / denominator);
    273            }
    274        }
    275
    276        /**
    277         * Returns a {@code Complex} whose value is {@code (this / divisor)},
    278         * with {@code divisor} interpreted as a real number.
    279         *
    280         * @param  divisor Value by which this {@code Complex} is to be divided.
    281         * @return {@code this / divisor}.
    282         * @see #divide(Complex)
    283         */
    284        public Complex divide(double divisor) {
    285            if (isNaN || Double.isNaN(divisor)) {
    286                return NaN;
    287            }
    288            if (divisor == 0d) {
    289                return NaN;
    290            }
    291            if (Double.isInfinite(divisor)) {
    292                return !isInfinite() ? ZERO : NaN;
    293            }
    294            return createComplex(real / divisor,
    295                                 imaginary  / divisor);
    296        }
    297
    298        /** {@inheritDoc} */
    299        public Complex reciprocal() {
    300            if (isNaN) {
    301                return NaN;
    302            }
    303
    304            if (real == 0.0 && imaginary == 0.0) {
    305                return NaN;
    306            }
    307
    308            if (isInfinite) {
    309                return ZERO;
    310            }
    311
    312            if (FastMath.abs(real) < FastMath.abs(imaginary)) {
    313                double q = real / imaginary;
    314                double scale = 1. / (real * q + imaginary);
    315                return createComplex(scale * q, -scale);
    316            } else {
    317                double q = imaginary / real;
    318                double scale = 1. / (imaginary * q + real);
    319                return createComplex(scale, -scale * q);
    320            }
    321        }
    322
    323        /**
    324         * Test for the equality of two Complex objects.
    325         * If both the real and imaginary parts of two complex numbers
    326         * are exactly the same, and neither is {@code Double.NaN}, the two
    327         * Complex objects are considered to be equal.
    328         * All {@code NaN} values are considered to be equal - i.e, if either
    329         * (or both) real and imaginary parts of the complex number are equal
    330         * to {@code Double.NaN}, the complex number is equal to
    331         * {@code NaN}.
    332         *
    333         * @param other Object to test for equality to this
    334         * @return true if two Complex objects are equal, false if object is
    335         * {@code null}, not an instance of Complex, or not equal to this Complex
    336         * instance.
    337         */
    338        @Override
    339        public boolean equals(Object other) {
    340            if (this == other) {
    341                return true;
    342            }
    343            if (other instanceof Complex){
    344                Complex c = (Complex)other;
    345                if (c.isNaN) {
    346                    return isNaN;
    347                } else {
    348                    return (real == c.real) && (imaginary == c.imaginary);
    349                }
    350            }
    351            return false;
    352        }
    353
    354        /**
    355         * Get a hashCode for the complex number.
    356         * Any {@code Double.NaN} value in real or imaginary part produces
    357         * the same hash code {@code 7}.
    358         *
    359         * @return a hash code value for this object.
    360         */
    361        @Override
    362        public int hashCode() {
    363            if (isNaN) {
    364                return 7;
    365            }
    366            return 37 * (17 * MathUtils.hash(imaginary) +
    367                MathUtils.hash(real));
    368        }
    369
    370        /**
    371         * Access the imaginary part.
    372         *
    373         * @return the imaginary part.
    374         */
    375        public double getImaginary() {
    376            return imaginary;
    377        }
    378
    379        /**
    380         * Access the real part.
    381         *
    382         * @return the real part.
    383         */
    384        public double getReal() {
    385            return real;
    386        }
    387
    388        /**
    389         * Checks whether either or both parts of this complex number is
    390         * {@code NaN}.
    391         *
    392         * @return true if either or both parts of this complex number is
    393         * {@code NaN}; false otherwise.
    394         */
    395        public boolean isNaN() {
    396            return isNaN;
    397        }
    398
    399        /**
    400         * Checks whether either the real or imaginary part of this complex number
    401         * takes an infinite value (either {@code Double.POSITIVE_INFINITY} or
    402         * {@code Double.NEGATIVE_INFINITY}) and neither part
    403         * is {@code NaN}.
    404         *
    405         * @return true if one or both parts of this complex number are infinite
    406         * and neither part is {@code NaN}.
    407         */
    408        public boolean isInfinite() {
    409            return isInfinite;
    410        }
    411
    412        /**
    413         * Returns a {@code Complex} whose value is {@code this * factor}.
    414         * Implements preliminary checks for {@code NaN} and infinity followed by
    415         * the definitional formula:
    416         * <pre>
    417         *  <code>
    418         *   (a + bi)(c + di) = (ac - bd) + (ad + bc)i
    419         *  </code>
    420         * </pre>
    421         * Returns {@link #NaN} if either {@code this} or {@code factor} has one or
    422         * more {@code NaN} parts.
    423         * <br/>
    424         * Returns {@link #INF} if neither {@code this} nor {@code factor} has one
    425         * or more {@code NaN} parts and if either {@code this} or {@code factor}
    426         * has one or more infinite parts (same result is returned regardless of
    427         * the sign of the components).
    428         * <br/>
    429         * Returns finite values in components of the result per the definitional
    430         * formula in all remaining cases.
    431         *
    432         * @param  factor value to be multiplied by this {@code Complex}.
    433         * @return {@code this * factor}.
    434         * @throws NullArgumentException if {@code factor} is {@code null}.
    435         */
    436        public Complex multiply(Complex factor)
    437            throws NullArgumentException {
    438            MathUtils.checkNotNull(factor);
    439            if (isNaN || factor.isNaN) {
    440                return NaN;
    441            }
    442            if (Double.isInfinite(real) ||
    443                Double.isInfinite(imaginary) ||
    444                Double.isInfinite(factor.real) ||
    445                Double.isInfinite(factor.imaginary)) {
    446                // we don't use isInfinite() to avoid testing for NaN again
    447                return INF;
    448            }
    449            return createComplex(real * factor.real - imaginary * factor.imaginary,
    450                                 real * factor.imaginary + imaginary * factor.real);
    451        }
    452
    453        /**
    454         * Returns a {@code Complex} whose value is {@code this * factor}, with {@code factor}
    455         * interpreted as a integer number.
    456         *
    457         * @param  factor value to be multiplied by this {@code Complex}.
    458         * @return {@code this * factor}.
    459         * @see #multiply(Complex)
    460         */
    461        public Complex multiply(final int factor) {
    462            if (isNaN) {
    463                return NaN;
    464            }
    465            if (Double.isInfinite(real) ||
    466                Double.isInfinite(imaginary)) {
    467                return INF;
    468            }
    469            return createComplex(real * factor, imaginary * factor);
    470        }
    471
    472        /**
    473         * Returns a {@code Complex} whose value is {@code this * factor}, with {@code factor}
    474         * interpreted as a real number.
    475         *
    476         * @param  factor value to be multiplied by this {@code Complex}.
    477         * @return {@code this * factor}.
    478         * @see #multiply(Complex)
    479         */
    480        public Complex multiply(double factor) {
    481            if (isNaN || Double.isNaN(factor)) {
    482                return NaN;
    483            }
    484            if (Double.isInfinite(real) ||
    485                Double.isInfinite(imaginary) ||
    486                Double.isInfinite(factor)) {
    487                // we don't use isInfinite() to avoid testing for NaN again
    488                return INF;
    489            }
    490            return createComplex(real * factor, imaginary * factor);
    491        }
    492
    493        /**
    494         * Returns a {@code Complex} whose value is {@code (-this)}.
    495         * Returns {@code NaN} if either real or imaginary
    496         * part of this Complex number equals {@code Double.NaN}.
    497         *
    498         * @return {@code -this}.
    499         */
    500        public Complex negate() {
    501            if (isNaN) {
    502                return NaN;
    503            }
    504
    505            return createComplex(-real, -imaginary);
    506        }
    507
    508        /**
    509         * Returns a {@code Complex} whose value is
    510         * {@code (this - subtrahend)}.
    511         * Uses the definitional formula
    512         * <pre>
    513         *  <code>
    514         *   (a + bi) - (c + di) = (a-c) + (b-d)i
    515         *  </code>
    516         * </pre>
    517         * If either {@code this} or {@code subtrahend} has a {@code NaN]} value in either part,
    518         * {@link #NaN} is returned; otherwise infinite and {@code NaN} values are
    519         * returned in the parts of the result according to the rules for
    520         * {@link java.lang.Double} arithmetic.
    521         *
    522         * @param  subtrahend value to be subtracted from this {@code Complex}.
    523         * @return {@code this - subtrahend}.
    524         * @throws NullArgumentException if {@code subtrahend} is {@code null}.
    525         */
    526        public Complex subtract(Complex subtrahend)
    527            throws NullArgumentException {
    528            MathUtils.checkNotNull(subtrahend);
    529            if (isNaN || subtrahend.isNaN) {
    530                return NaN;
    531            }
    532
    533            return createComplex(real - subtrahend.getReal(),
    534                                 imaginary - subtrahend.getImaginary());
    535        }
    536
    537        /**
    538         * Returns a {@code Complex} whose value is
    539         * {@code (this - subtrahend)}.
    540         *
    541         * @param  subtrahend value to be subtracted from this {@code Complex}.
    542         * @return {@code this - subtrahend}.
    543         * @see #subtract(Complex)
    544         */
    545        public Complex subtract(double subtrahend) {
    546            if (isNaN || Double.isNaN(subtrahend)) {
    547                return NaN;
    548            }
    549            return createComplex(real - subtrahend, imaginary);
    550        }
    551
    552        /**
    553         * Compute the
    554         * <a href="http://mathworld.wolfram.com/InverseCosine.html" TARGET="_top">
    555         * inverse cosine</a> of this complex number.
    556         * Implements the formula:
    557         * <pre>
    558         *  <code>
    559         *   acos(z) = -i (log(z + i (sqrt(1 - z<sup>2</sup>))))
    560         *  </code>
    561         * </pre>
    562         * Returns {@link Complex#NaN} if either real or imaginary part of the
    563         * input argument is {@code NaN} or infinite.
    564         *
    565         * @return the inverse cosine of this complex number.
    566         * @since 1.2
    567         */
    568        public Complex acos() {
    569            if (isNaN) {
    570                return NaN;
    571            }
    572
    573            return this.add(this.sqrt1z().multiply(I)).log().multiply(I.negate());
    574        }
    575
    576        /**
    577         * Compute the
    578         * <a href="http://mathworld.wolfram.com/InverseSine.html" TARGET="_top">
    579         * inverse sine</a> of this complex number.
    580         * Implements the formula:
    581         * <pre>
    582         *  <code>
    583         *   asin(z) = -i (log(sqrt(1 - z<sup>2</sup>) + iz))
    584         *  </code>
    585         * </pre>
    586         * Returns {@link Complex#NaN} if either real or imaginary part of the
    587         * input argument is {@code NaN} or infinite.
    588         *
    589         * @return the inverse sine of this complex number.
    590         * @since 1.2
    591         */
    592        public Complex asin() {
    593            if (isNaN) {
    594                return NaN;
    595            }
    596
    597            return sqrt1z().add(this.multiply(I)).log().multiply(I.negate());
    598        }
    599
    600        /**
    601         * Compute the
    602         * <a href="http://mathworld.wolfram.com/InverseTangent.html" TARGET="_top">
    603         * inverse tangent</a> of this complex number.
    604         * Implements the formula:
    605         * <pre>
    606         *  <code>
    607         *   atan(z) = (i/2) log((i + z)/(i - z))
    608         *  </code>
    609         * </pre>
    610         * Returns {@link Complex#NaN} if either real or imaginary part of the
    611         * input argument is {@code NaN} or infinite.
    612         *
    613         * @return the inverse tangent of this complex number
    614         * @since 1.2
    615         */
    616        public Complex atan() {
    617            if (isNaN) {
    618                return NaN;
    619            }
    620
    621            return this.add(I).divide(I.subtract(this)).log()
    622                    .multiply(I.divide(createComplex(2.0, 0.0)));
    623        }
    624
    625        /**
    626         * Compute the
    627         * <a href="http://mathworld.wolfram.com/Cosine.html" TARGET="_top">
    628         * cosine</a>
    629         * of this complex number.
    630         * Implements the formula:
    631         * <pre>
    632         *  <code>
    633         *   cos(a + bi) = cos(a)cosh(b) - sin(a)sinh(b)i
    634         *  </code>
    635         * </pre>
    636         * where the (real) functions on the right-hand side are
    637         * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
    638         * {@link FastMath#cosh} and {@link FastMath#sinh}.
    639         * <br/>
    640         * Returns {@link Complex#NaN} if either real or imaginary part of the
    641         * input argument is {@code NaN}.
    642         * <br/>
    643         * Infinite values in real or imaginary parts of the input may result in
    644         * infinite or NaN values returned in parts of the result.
    645         * <pre>
    646         *  Examples:
    647         *  <code>
    648         *   cos(1 &plusmn; INFINITY i) = 1 &#x2213; INFINITY i
    649         *   cos(&plusmn;INFINITY + i) = NaN + NaN i
    650         *   cos(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
    651         *  </code>
    652         * </pre>
    653         *
    654         * @return the cosine of this complex number.
    655         * @since 1.2
    656         */
    657        public Complex cos() {
    658            if (isNaN) {
    659                return NaN;
    660            }
    661
    662            return createComplex(FastMath.cos(real) * FastMath.cosh(imaginary),
    663                                 -FastMath.sin(real) * FastMath.sinh(imaginary));
    664        }
    665
    666        /**
    667         * Compute the
    668         * <a href="http://mathworld.wolfram.com/HyperbolicCosine.html" TARGET="_top">
    669         * hyperbolic cosine</a> of this complex number.
    670         * Implements the formula:
    671         * <pre>
    672         *  <code>
    673         *   cosh(a + bi) = cosh(a)cos(b) + sinh(a)sin(b)i}
    674         *  </code>
    675         * </pre>
    676         * where the (real) functions on the right-hand side are
    677         * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
    678         * {@link FastMath#cosh} and {@link FastMath#sinh}.
    679         * <br/>
    680         * Returns {@link Complex#NaN} if either real or imaginary part of the
    681         * input argument is {@code NaN}.
    682         * <br/>
    683         * Infinite values in real or imaginary parts of the input may result in
    684         * infinite or NaN values returned in parts of the result.
    685         * <pre>
    686         *  Examples:
    687         *  <code>
    688         *   cosh(1 &plusmn; INFINITY i) = NaN + NaN i
    689         *   cosh(&plusmn;INFINITY + i) = INFINITY &plusmn; INFINITY i
    690         *   cosh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
    691         *  </code>
    692         * </pre>
    693         *
    694         * @return the hyperbolic cosine of this complex number.
    695         * @since 1.2
    696         */
    697        public Complex cosh() {
    698            if (isNaN) {
    699                return NaN;
    700            }
    701
    702            return createComplex(FastMath.cosh(real) * FastMath.cos(imaginary),
    703                                 FastMath.sinh(real) * FastMath.sin(imaginary));
    704        }
    705
    706        /**
    707         * Compute the
    708         * <a href="http://mathworld.wolfram.com/ExponentialFunction.html" TARGET="_top">
    709         * exponential function</a> of this complex number.
    710         * Implements the formula:
    711         * <pre>
    712         *  <code>
    713         *   exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i
    714         *  </code>
    715         * </pre>
    716         * where the (real) functions on the right-hand side are
    717         * {@link java.lang.Math#exp}, {@link java.lang.Math#cos}, and
    718         * {@link java.lang.Math#sin}.
    719         * <br/>
    720         * Returns {@link Complex#NaN} if either real or imaginary part of the
    721         * input argument is {@code NaN}.
    722         * <br/>
    723         * Infinite values in real or imaginary parts of the input may result in
    724         * infinite or NaN values returned in parts of the result.
    725         * <pre>
    726         *  Examples:
    727         *  <code>
    728         *   exp(1 &plusmn; INFINITY i) = NaN + NaN i
    729         *   exp(INFINITY + i) = INFINITY + INFINITY i
    730         *   exp(-INFINITY + i) = 0 + 0i
    731         *   exp(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
    732         *  </code>
    733         * </pre>
    734         *
    735         * @return <code><i>e</i><sup>this</sup></code>.
    736         * @since 1.2
    737         */
    738        public Complex exp() {
    739            if (isNaN) {
    740                return NaN;
    741            }
    742
    743            double expReal = FastMath.exp(real);
    744            return createComplex(expReal *  FastMath.cos(imaginary),
    745                                 expReal * FastMath.sin(imaginary));
    746        }
    747
    748        /**
    749         * Compute the
    750         * <a href="http://mathworld.wolfram.com/NaturalLogarithm.html" TARGET="_top">
    751         * natural logarithm</a> of this complex number.
    752         * Implements the formula:
    753         * <pre>
    754         *  <code>
    755         *   log(a + bi) = ln(|a + bi|) + arg(a + bi)i
    756         *  </code>
    757         * </pre>
    758         * where ln on the right hand side is {@link java.lang.Math#log},
    759         * {@code |a + bi|} is the modulus, {@link Complex#abs},  and
    760         * {@code arg(a + bi) = }{@link java.lang.Math#atan2}(b, a).
    761         * <br/>
    762         * Returns {@link Complex#NaN} if either real or imaginary part of the
    763         * input argument is {@code NaN}.
    764         * <br/>
    765         * Infinite (or critical) values in real or imaginary parts of the input may
    766         * result in infinite or NaN values returned in parts of the result.
    767         * <pre>
    768         *  Examples:
    769         *  <code>
    770         *   log(1 &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;/2)i
    771         *   log(INFINITY + i) = INFINITY + 0i
    772         *   log(-INFINITY + i) = INFINITY + &pi;i
    773         *   log(INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;/4)i
    774         *   log(-INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (3&pi;/4)i
    775         *   log(0 + 0i) = -INFINITY + 0i
    776         *  </code>
    777         * </pre>
    778         *
    779         * @return the value <code>ln &nbsp; this</code>, the natural logarithm
    780         * of {@code this}.
    781         * @since 1.2
    782         */
    783        public Complex log() {
    784            if (isNaN) {
    785                return NaN;
    786            }
    787
    788            return createComplex(FastMath.log(abs()),
    789                                 FastMath.atan2(imaginary, real));
    790        }
    791
    792        /**
    793         * Returns of value of this complex number raised to the power of {@code x}.
    794         * Implements the formula:
    795         * <pre>
    796         *  <code>
    797         *   y<sup>x</sup> = exp(x&middot;log(y))
    798         *  </code>
    799         * </pre>
    800         * where {@code exp} and {@code log} are {@link #exp} and
    801         * {@link #log}, respectively.
    802         * <br/>
    803         * Returns {@link Complex#NaN} if either real or imaginary part of the
    804         * input argument is {@code NaN} or infinite, or if {@code y}
    805         * equals {@link Complex#ZERO}.
    806         *
    807         * @param  x exponent to which this {@code Complex} is to be raised.
    808         * @return <code> this<sup>{@code x}</sup></code>.
    809         * @throws NullArgumentException if x is {@code null}.
    810         * @since 1.2
    811         */
    812        public Complex pow(Complex x)
    813            throws NullArgumentException {
    814            MathUtils.checkNotNull(x);
    815            return this.log().multiply(x).exp();
    816        }
    817
    818        /**
    819         * Returns of value of this complex number raised to the power of {@code x}.
    820         *
    821         * @param  x exponent to which this {@code Complex} is to be raised.
    822         * @return <code>this<sup>x</sup></code>.
    823         * @see #pow(Complex)
    824         */
    825         public Complex pow(double x) {
    826            return this.log().multiply(x).exp();
    827        }
    828
    829        /**
    830         * Compute the
    831         * <a href="http://mathworld.wolfram.com/Sine.html" TARGET="_top">
    832         * sine</a>
    833         * of this complex number.
    834         * Implements the formula:
    835         * <pre>
    836         *  <code>
    837         *   sin(a + bi) = sin(a)cosh(b) - cos(a)sinh(b)i
    838         *  </code>
    839         * </pre>
    840         * where the (real) functions on the right-hand side are
    841         * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
    842         * {@link FastMath#cosh} and {@link FastMath#sinh}.
    843         * <br/>
    844         * Returns {@link Complex#NaN} if either real or imaginary part of the
    845         * input argument is {@code NaN}.
    846         * <br/>
    847         * Infinite values in real or imaginary parts of the input may result in
    848         * infinite or {@code NaN} values returned in parts of the result.
    849         * <pre>
    850         *  Examples:
    851         *  <code>
    852         *   sin(1 &plusmn; INFINITY i) = 1 &plusmn; INFINITY i
    853         *   sin(&plusmn;INFINITY + i) = NaN + NaN i
    854         *   sin(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
    855         *  </code>
    856         * </pre>
    857         *
    858         * @return the sine of this complex number.
    859         * @since 1.2
    860         */
    861        public Complex sin() {
    862            if (isNaN) {
    863                return NaN;
    864            }
    865
    866            return createComplex(FastMath.sin(real) * FastMath.cosh(imaginary),
    867                                 FastMath.cos(real) * FastMath.sinh(imaginary));
    868        }
    869
    870        /**
    871         * Compute the
    872         * <a href="http://mathworld.wolfram.com/HyperbolicSine.html" TARGET="_top">
    873         * hyperbolic sine</a> of this complex number.
    874         * Implements the formula:
    875         * <pre>
    876         *  <code>
    877         *   sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i
    878         *  </code>
    879         * </pre>
    880         * where the (real) functions on the right-hand side are
    881         * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
    882         * {@link FastMath#cosh} and {@link FastMath#sinh}.
    883         * <br/>
    884         * Returns {@link Complex#NaN} if either real or imaginary part of the
    885         * input argument is {@code NaN}.
    886         * <br/>
    887         * Infinite values in real or imaginary parts of the input may result in
    888         * infinite or NaN values returned in parts of the result.
    889         * <pre>
    890         *  Examples:
    891         *  <code>
    892         *   sinh(1 &plusmn; INFINITY i) = NaN + NaN i
    893         *   sinh(&plusmn;INFINITY + i) = &plusmn; INFINITY + INFINITY i
    894         *   sinh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
    895         *  </code>
    896         * </pre>
    897         *
    898         * @return the hyperbolic sine of {@code this}.
    899         * @since 1.2
    900         */
    901        public Complex sinh() {
    902            if (isNaN) {
    903                return NaN;
    904            }
    905
    906            return createComplex(FastMath.sinh(real) * FastMath.cos(imaginary),
    907                FastMath.cosh(real) * FastMath.sin(imaginary));
    908        }
    909
    910        /**
    911         * Compute the
    912         * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
    913         * square root</a> of this complex number.
    914         * Implements the following algorithm to compute {@code sqrt(a + bi)}:
    915         * <ol><li>Let {@code t = sqrt((|a| + |a + bi|) / 2)}</li>
    916         * <li><pre>if {@code  a &#8805; 0} return {@code t + (b/2t)i}
    917         *  else return {@code |b|/2t + sign(b)t i }</pre></li>
    918         * </ol>
    919         * where <ul>
    920         * <li>{@code |a| = }{@link Math#abs}(a)</li>
    921         * <li>{@code |a + bi| = }{@link Complex#abs}(a + bi)</li>
    922         * <li>{@code sign(b) =  }{@link FastMath#copySign(double,double) copySign(1d, b)}
    923         * </ul>
    924         * <br/>
    925         * Returns {@link Complex#NaN} if either real or imaginary part of the
    926         * input argument is {@code NaN}.
    927         * <br/>
    928         * Infinite values in real or imaginary parts of the input may result in
    929         * infinite or NaN values returned in parts of the result.
    930         * <pre>
    931         *  Examples:
    932         *  <code>
    933         *   sqrt(1 &plusmn; INFINITY i) = INFINITY + NaN i
    934         *   sqrt(INFINITY + i) = INFINITY + 0i
    935         *   sqrt(-INFINITY + i) = 0 + INFINITY i
    936         *   sqrt(INFINITY &plusmn; INFINITY i) = INFINITY + NaN i
    937         *   sqrt(-INFINITY &plusmn; INFINITY i) = NaN &plusmn; INFINITY i
    938         *  </code>
    939         * </pre>
    940         *
    941         * @return the square root of {@code this}.
    942         * @since 1.2
    943         */
    944        public Complex sqrt() {
    945            if (isNaN) {
    946                return NaN;
    947            }
    948
    949            if (real == 0.0 && imaginary == 0.0) {
    950                return createComplex(0.0, 0.0);
    951            }
    952
    953            double t = FastMath.sqrt((FastMath.abs(real) + abs()) / 2.0);
    954            if (real >= 0.0) {
    955                return createComplex(t, imaginary / (2.0 * t));
    956            } else {
    957                return createComplex(FastMath.abs(imaginary) / (2.0 * t),
    958                                     FastMath.copySign(1d, imaginary) * t);
    959            }
    960        }
    961
    962        /**
    963         * Compute the
    964         * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
    965         * square root</a> of <code>1 - this<sup>2</sup></code> for this complex
    966         * number.
    967         * Computes the result directly as
    968         * {@code sqrt(ONE.subtract(z.multiply(z)))}.
    969         * <br/>
    970         * Returns {@link Complex#NaN} if either real or imaginary part of the
    971         * input argument is {@code NaN}.
    972         * <br/>
    973         * Infinite values in real or imaginary parts of the input may result in
    974         * infinite or NaN values returned in parts of the result.
    975         *
    976         * @return the square root of <code>1 - this<sup>2</sup></code>.
    977         * @since 1.2
    978         */
    979        public Complex sqrt1z() {
    980            return createComplex(1.0, 0.0).subtract(this.multiply(this)).sqrt();
    981        }
    982
    983        /**
    984         * Compute the
    985         * <a href="http://mathworld.wolfram.com/Tangent.html" TARGET="_top">
    986         * tangent</a> of this complex number.
    987         * Implements the formula:
    988         * <pre>
    989         *  <code>
    990         *   tan(a + bi) = sin(2a)/(cos(2a)+cosh(2b)) + [sinh(2b)/(cos(2a)+cosh(2b))]i
    991         *  </code>
    992         * </pre>
    993         * where the (real) functions on the right-hand side are
    994         * {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and
    995         * {@link FastMath#sinh}.
    996         * <br/>
    997         * Returns {@link Complex#NaN} if either real or imaginary part of the
    998         * input argument is {@code NaN}.
    999         * <br/>
    1000         * Infinite (or critical) values in real or imaginary parts of the input may
    1001         * result in infinite or NaN values returned in parts of the result.
    1002         * <pre>
    1003         *  Examples:
    1004         *  <code>
    1005         *   tan(a &plusmn; INFINITY i) = 0 &plusmn; i
    1006         *   tan(&plusmn;INFINITY + bi) = NaN + NaN i
    1007         *   tan(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
    1008         *   tan(&plusmn;&pi;/2 + 0 i) = &plusmn;INFINITY + NaN i
    1009         *  </code>
    1010         * </pre>
    1011         *
    1012         * @return the tangent of {@code this}.
    1013         * @since 1.2
    1014         */
    1015        public Complex tan() {
    1016            if (isNaN || Double.isInfinite(real)) {
    1017                return NaN;
    1018            }
    1019            if (imaginary > 20.0) {
    1020                return createComplex(0.0, 1.0);
    1021            }
    1022            if (imaginary < -20.0) {
    1023                return createComplex(0.0, -1.0);
    1024            }
    1025
    1026            double real2 = 2.0 * real;
    1027            double imaginary2 = 2.0 * imaginary;
    1028            double d = FastMath.cos(real2) + FastMath.cosh(imaginary2);
    1029
    1030            return createComplex(FastMath.sin(real2) / d,
    1031                                 FastMath.sinh(imaginary2) / d);
    1032        }
    1033
    1034        /**
    1035         * Compute the
    1036         * <a href="http://mathworld.wolfram.com/HyperbolicTangent.html" TARGET="_top">
    1037         * hyperbolic tangent</a> of this complex number.
    1038         * Implements the formula:
    1039         * <pre>
    1040         *  <code>
    1041         *   tan(a + bi) = sinh(2a)/(cosh(2a)+cos(2b)) + [sin(2b)/(cosh(2a)+cos(2b))]i
    1042         *  </code>
    1043         * </pre>
    1044         * where the (real) functions on the right-hand side are
    1045         * {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and
    1046         * {@link FastMath#sinh}.
    1047         * <br/>
    1048         * Returns {@link Complex#NaN} if either real or imaginary part of the
    1049         * input argument is {@code NaN}.
    1050         * <br/>
    1051         * Infinite values in real or imaginary parts of the input may result in
    1052         * infinite or NaN values returned in parts of the result.
    1053         * <pre>
    1054         *  Examples:
    1055         *  <code>
    1056         *   tanh(a &plusmn; INFINITY i) = NaN + NaN i
    1057         *   tanh(&plusmn;INFINITY + bi) = &plusmn;1 + 0 i
    1058         *   tanh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
    1059         *   tanh(0 + (&pi;/2)i) = NaN + INFINITY i
    1060         *  </code>
    1061         * </pre>
    1062         *
    1063         * @return the hyperbolic tangent of {@code this}.
    1064         * @since 1.2
    1065         */
    1066        public Complex tanh() {
    1067            if (isNaN || Double.isInfinite(imaginary)) {
    1068                return NaN;
    1069            }
    1070            if (real > 20.0) {
    1071                return createComplex(1.0, 0.0);
    1072            }
    1073            if (real < -20.0) {
    1074                return createComplex(-1.0, 0.0);
    1075            }
    1076            double real2 = 2.0 * real;
    1077            double imaginary2 = 2.0 * imaginary;
    1078            double d = FastMath.cosh(real2) + FastMath.cos(imaginary2);
    1079
    1080            return createComplex(FastMath.sinh(real2) / d,
    1081                                 FastMath.sin(imaginary2) / d);
    1082        }
    1083
    1084
    1085
    1086        /**
    1087         * Compute the argument of this complex number.
    1088         * The argument is the angle phi between the positive real axis and
    1089         * the point representing this number in the complex plane.
    1090         * The value returned is between -PI (not inclusive)
    1091         * and PI (inclusive), with negative values returned for numbers with
    1092         * negative imaginary parts.
    1093         * <br/>
    1094         * If either real or imaginary part (or both) is NaN, NaN is returned.
    1095         * Infinite parts are handled as {@code Math.atan2} handles them,
    1096         * essentially treating finite parts as zero in the presence of an
    1097         * infinite coordinate and returning a multiple of pi/4 depending on
    1098         * the signs of the infinite parts.
    1099         * See the javadoc for {@code Math.atan2} for full details.
    1100         *
    1101         * @return the argument of {@code this}.
    1102         */
    1103        public double getArgument() {
    1104            return FastMath.atan2(getImaginary(), getReal());
    1105        }
    1106
    1107        /**
    1108         * Computes the n-th roots of this complex number.
    1109         * The nth roots are defined by the formula:
    1110         * <pre>
    1111         *  <code>
    1112         *   z<sub>k</sub> = abs<sup>1/n</sup> (cos(phi + 2&pi;k/n) + i (sin(phi + 2&pi;k/n))
    1113         *  </code>
    1114         * </pre>
    1115         * for <i>{@code k=0, 1, ..., n-1}</i>, where {@code abs} and {@code phi}
    1116         * are respectively the {@link #abs() modulus} and
    1117         * {@link #getArgument() argument} of this complex number.
    1118         * <br/>
    1119         * If one or both parts of this complex number is NaN, a list with just
    1120         * one element, {@link #NaN} is returned.
    1121         * if neither part is NaN, but at least one part is infinite, the result
    1122         * is a one-element list containing {@link #INF}.
    1123         *
    1124         * @param n Degree of root.
    1125         * @return a List<Complex> of all {@code n}-th roots of {@code this}.
    1126         * @throws NotPositiveException if {@code n <= 0}.
    1127         * @since 2.0
    1128         */
    1129        public List<Complex> nthRoot(int n) throws NotPositiveException {
    1130
    1131            if (n <= 0) {
    1132                throw new NotPositiveException(LocalizedFormats.CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N,
    1133                                               n);
    1134            }
    1135
    1136            final List<Complex> result = new ArrayList<Complex>();
    1137
    1138            if (isNaN) {
    1139                result.add(NaN);
    1140                return result;
    1141            }
    1142            if (isInfinite()) {
    1143                result.add(INF);
    1144                return result;
    1145            }
    1146
    1147            // nth root of abs -- faster / more accurate to use a solver here?
    1148            final double nthRootOfAbs = FastMath.pow(abs(), 1.0 / n);
    1149
    1150            // Compute nth roots of complex number with k = 0, 1, ... n-1
    1151            final double nthPhi = getArgument() / n;
    1152            final double slice = 2 * FastMath.PI / n;
    1153            double innerPart = nthPhi;
    1154            for (int k = 0; k < n ; k++) {
    1155                // inner part
    1156                final double realPart = nthRootOfAbs *  FastMath.cos(innerPart);
    1157                final double imaginaryPart = nthRootOfAbs *  FastMath.sin(innerPart);
    1158                result.add(createComplex(realPart, imaginaryPart));
    1159                innerPart += slice;
    1160            }
    1161
    1162            return result;
    1163        }
    1164
    1165        /**
    1166         * Create a complex number given the real and imaginary parts.
    1167         *
    1168         * @param realPart Real part.
    1169         * @param imaginaryPart Imaginary part.
    1170         * @return a new complex number instance.
    1171         * @since 1.2
    1172         * @see #valueOf(double, double)
    1173         */
    1174        protected Complex createComplex(double realPart,
    1175                                        double imaginaryPart) {
    1176            return new Complex(realPart, imaginaryPart);
    1177        }
    1178
    1179        /**
    1180         * Create a complex number given the real and imaginary parts.
    1181         *
    1182         * @param realPart Real part.
    1183         * @param imaginaryPart Imaginary part.
    1184         * @return a Complex instance.
    1185         */
    1186        public static Complex valueOf(double realPart,
    1187                                      double imaginaryPart) {
    1188            if (Double.isNaN(realPart) ||
    1189                Double.isNaN(imaginaryPart)) {
    1190                return NaN;
    1191            }
    1192            return new Complex(realPart, imaginaryPart);
    1193        }
    1194
    1195        /**
    1196         * Create a complex number given only the real part.
    1197         *
    1198         * @param realPart Real part.
    1199         * @return a Complex instance.
    1200         */
    1201        public static Complex valueOf(double realPart) {
    1202            if (Double.isNaN(realPart)) {
    1203                return NaN;
    1204            }
    1205            return new Complex(realPart);
    1206        }
    1207
    1208        /**
    1209         * Resolve the transient fields in a deserialized Complex Object.
    1210         * Subclasses will need to override {@link #createComplex} to
    1211         * deserialize properly.
    1212         *
    1213         * @return A Complex instance with all fields resolved.
    1214         * @since 2.0
    1215         */
    1216        protected final Object readResolve() {
    1217            return createComplex(real, imaginary);
    1218        }
    1219
    1220        /** {@inheritDoc} */
    1221        public ComplexField getField() {
    1222            return ComplexField.getInstance();
    1223        }
    1224
    1225        /** {@inheritDoc} */
    1226        @Override
    1227        public String toString() {
    1228            return "(" + real + ", " + imaginary + ")";
    1229        }
    1230
    1231    }