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
018package org.apache.commons.math3.complex;
019
020import java.io.Serializable;
021import java.util.ArrayList;
022import java.util.List;
023
024import org.apache.commons.math3.FieldElement;
025import org.apache.commons.math3.exception.NotPositiveException;
026import org.apache.commons.math3.exception.NullArgumentException;
027import org.apache.commons.math3.exception.util.LocalizedFormats;
028import org.apache.commons.math3.util.FastMath;
029import 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 1459927 2013-03-22 18:55:58Z luc $
056 */
057public 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 INF;
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}