View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  
23  package org.hipparchus.complex;
24  
25  import java.io.Serializable;
26  import java.util.ArrayList;
27  import java.util.List;
28  
29  import org.hipparchus.CalculusFieldElement;
30  import org.hipparchus.exception.LocalizedCoreFormats;
31  import org.hipparchus.exception.MathIllegalArgumentException;
32  import org.hipparchus.exception.NullArgumentException;
33  import org.hipparchus.util.FastMath;
34  import org.hipparchus.util.FieldSinCos;
35  import org.hipparchus.util.FieldSinhCosh;
36  import org.hipparchus.util.MathArrays;
37  import org.hipparchus.util.MathUtils;
38  import org.hipparchus.util.Precision;
39  import org.hipparchus.util.SinCos;
40  import org.hipparchus.util.SinhCosh;
41  
42  /**
43   * Representation of a Complex number, i.e. a number which has both a
44   * real and imaginary part.
45   * <p>
46   * Implementations of arithmetic operations handle {@code NaN} and
47   * infinite values according to the rules for {@link java.lang.Double}, i.e.
48   * {@link #equals} is an equivalence relation for all instances that have
49   * a {@code NaN} in either real or imaginary part, e.g. the following are
50   * considered equal:
51   * <ul>
52   *  <li>{@code 1 + NaNi}</li>
53   *  <li>{@code NaN + i}</li>
54   *  <li>{@code NaN + NaNi}</li>
55   * </ul>
56   * <p>
57   * Note that this contradicts the IEEE-754 standard for floating
58   * point numbers (according to which the test {@code x == x} must fail if
59   * {@code x} is {@code NaN}). The method
60   * {@link org.hipparchus.util.Precision#equals(double,double,int)
61   * equals for primitive double} in {@link org.hipparchus.util.Precision}
62   * conforms with IEEE-754 while this class conforms with the standard behavior
63   * for Java object types.
64   */
65  public class Complex implements CalculusFieldElement<Complex>, Comparable<Complex>, Serializable  {
66      /** The square root of -1. A number representing "0.0 + 1.0i". */
67      public static final Complex I = new Complex(0.0, 1.0);
68      /** The square root of -1. A number representing "0.0 - 1.0i".
69       * @since 1.7
70       */
71      public static final Complex MINUS_I = new Complex(0.0, -1.0);
72      // CHECKSTYLE: stop ConstantName
73      /** A complex number representing "NaN + NaNi". */
74      public static final Complex NaN = new Complex(Double.NaN, Double.NaN);
75      // CHECKSTYLE: resume ConstantName
76      /** A complex number representing "+INF + INFi" */
77      public static final Complex INF = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
78      /** A complex number representing "1.0 + 0.0i". */
79      public static final Complex ONE = new Complex(1.0, 0.0);
80      /** A complex number representing "-1.0 + 0.0i".
81       * @since 1.7
82       */
83      public static final Complex MINUS_ONE = new Complex(-1.0, 0.0);
84      /** A complex number representing "0.0 + 0.0i". */
85      public static final Complex ZERO = new Complex(0.0, 0.0);
86      /** A complex number representing "π + 0.0i". */
87      public static final Complex PI   = new Complex(FastMath.PI, 0.0);
88  
89      /** A real number representing log(10). */
90      private static final double LOG10 = 2.302585092994045684;
91  
92      /** Serializable version identifier */
93      private static final long serialVersionUID = 20160305L;
94  
95      /** The imaginary part. */
96      private final double imaginary;
97      /** The real part. */
98      private final double real;
99      /** Record whether this complex number is equal to NaN. */
100     private final transient boolean isNaN;
101     /** Record whether this complex number is infinite. */
102     private final transient boolean isInfinite;
103 
104     /**
105      * Create a complex number given only the real part.
106      *
107      * @param real Real part.
108      */
109     public Complex(double real) {
110         this(real, 0.0);
111     }
112 
113     /**
114      * Create a complex number given the real and imaginary parts.
115      *
116      * @param real Real part.
117      * @param imaginary Imaginary part.
118      */
119     public Complex(double real, double imaginary) {
120         this.real = real;
121         this.imaginary = imaginary;
122 
123         isNaN = Double.isNaN(real) || Double.isNaN(imaginary);
124         isInfinite = !isNaN &&
125             (Double.isInfinite(real) || Double.isInfinite(imaginary));
126     }
127 
128     /**
129      * Return the absolute value of this complex number.
130      * Returns {@code NaN} if either real or imaginary part is {@code NaN}
131      * and {@code Double.POSITIVE_INFINITY} if neither part is {@code NaN},
132      * but at least one part is infinite.
133      *
134      * @return the norm.
135      * @since 2.0
136      */
137     @Override
138     public Complex abs() {
139         // we check NaN here because FastMath.hypot checks it after infinity
140         return isNaN ? NaN : createComplex(FastMath.hypot(real, imaginary), 0.0);
141     }
142 
143     /** {@inheritDoc} */
144     @Override
145     public double norm() {
146         // we check NaN here because FastMath.hypot checks it after infinity
147         return isNaN ? Double.NaN : FastMath.hypot(real, imaginary);
148     }
149 
150     /**
151      * Returns a {@code Complex} whose value is
152      * {@code (this + addend)}.
153      * Uses the definitional formula
154      * <p>
155      *   {@code (a + bi) + (c + di) = (a+c) + (b+d)i}
156      * </p>
157      * If either {@code this} or {@code addend} has a {@code NaN} value in
158      * either part, {@link #NaN} is returned; otherwise {@code Infinite}
159      * and {@code NaN} values are returned in the parts of the result
160      * according to the rules for {@link java.lang.Double} arithmetic.
161      *
162      * @param  addend Value to be added to this {@code Complex}.
163      * @return {@code this + addend}.
164      * @throws NullArgumentException if {@code addend} is {@code null}.
165      */
166     @Override
167     public Complex add(Complex addend) throws NullArgumentException {
168         MathUtils.checkNotNull(addend);
169         if (isNaN || addend.isNaN) {
170             return NaN;
171         }
172 
173         return createComplex(real + addend.getRealPart(),
174                              imaginary + addend.getImaginaryPart());
175     }
176 
177     /**
178      * Returns a {@code Complex} whose value is {@code (this + addend)},
179      * with {@code addend} interpreted as a real number.
180      *
181      * @param addend Value to be added to this {@code Complex}.
182      * @return {@code this + addend}.
183      * @see #add(Complex)
184      */
185     @Override
186     public Complex add(double addend) {
187         if (isNaN || Double.isNaN(addend)) {
188             return NaN;
189         }
190 
191         return createComplex(real + addend, imaginary);
192     }
193 
194      /**
195      * Returns the conjugate of this complex number.
196      * The conjugate of {@code a + bi} is {@code a - bi}.
197      * <p>
198      * {@link #NaN} is returned if either the real or imaginary
199      * part of this Complex number equals {@code Double.NaN}.
200      * </p><p>
201      * If the imaginary part is infinite, and the real part is not
202      * {@code NaN}, the returned value has infinite imaginary part
203      * of the opposite sign, e.g. the conjugate of
204      * {@code 1 + POSITIVE_INFINITY i} is {@code 1 - NEGATIVE_INFINITY i}.
205      * </p>
206      * @return the conjugate of this Complex object.
207      */
208     public Complex conjugate() {
209         if (isNaN) {
210             return NaN;
211         }
212 
213         return createComplex(real, -imaginary);
214     }
215 
216     /**
217      * Returns a {@code Complex} whose value is
218      * {@code (this / divisor)}.
219      * Implements the definitional formula
220      * <pre>
221      *  <code>
222      *    a + bi          ac + bd + (bc - ad)i
223      *    ----------- = -------------------------
224      *    c + di         c<sup>2</sup> + d<sup>2</sup>
225      *  </code>
226      * </pre>
227      * but uses
228      * <a href="http://doi.acm.org/10.1145/1039813.1039814">
229      * prescaling of operands</a> to limit the effects of overflows and
230      * underflows in the computation.
231      * <p>
232      * {@code Infinite} and {@code NaN} values are handled according to the
233      * following rules, applied in the order presented:
234      * <ul>
235      *  <li>If either {@code this} or {@code divisor} has a {@code NaN} value
236      *   in either part, {@link #NaN} is returned.
237      *  </li>
238      *  <li>If {@code divisor} equals {@link #ZERO}, {@link #NaN} is returned.
239      *  </li>
240      *  <li>If {@code this} and {@code divisor} are both infinite,
241      *   {@link #NaN} is returned.
242      *  </li>
243      *  <li>If {@code this} is finite (i.e., has no {@code Infinite} or
244      *   {@code NaN} parts) and {@code divisor} is infinite (one or both parts
245      *   infinite), {@link #ZERO} is returned.
246      *  </li>
247      *  <li>If {@code this} is infinite and {@code divisor} is finite,
248      *   {@code NaN} values are returned in the parts of the result if the
249      *   {@link java.lang.Double} rules applied to the definitional formula
250      *   force {@code NaN} results.
251      *  </li>
252      * </ul>
253      *
254      * @param divisor Value by which this {@code Complex} is to be divided.
255      * @return {@code this / divisor}.
256      * @throws NullArgumentException if {@code divisor} is {@code null}.
257      */
258     @Override
259     public Complex divide(Complex divisor)
260         throws NullArgumentException {
261         MathUtils.checkNotNull(divisor);
262         if (isNaN || divisor.isNaN) {
263             return NaN;
264         }
265 
266         final double c = divisor.getRealPart();
267         final double d = divisor.getImaginaryPart();
268         if (c == 0.0 && d == 0.0) {
269             return NaN;
270         }
271 
272         if (divisor.isInfinite() && !isInfinite()) {
273             return ZERO;
274         }
275 
276         if (FastMath.abs(c) < FastMath.abs(d)) {
277             double q = c / d;
278             double denominator = c * q + d;
279             return createComplex((real * q + imaginary) / denominator,
280                                  (imaginary * q - real) / denominator);
281         } else {
282             double q = d / c;
283             double denominator = d * q + c;
284             return createComplex((imaginary * q + real) / denominator,
285                                  (imaginary - real * q) / denominator);
286         }
287     }
288 
289     /**
290      * Returns a {@code Complex} whose value is {@code (this / divisor)},
291      * with {@code divisor} interpreted as a real number.
292      *
293      * @param  divisor Value by which this {@code Complex} is to be divided.
294      * @return {@code this / divisor}.
295      * @see #divide(Complex)
296      */
297     @Override
298     public Complex divide(double divisor) {
299         if (isNaN || Double.isNaN(divisor)) {
300             return NaN;
301         }
302         if (divisor == 0d) {
303             return NaN;
304         }
305         if (Double.isInfinite(divisor)) {
306             return !isInfinite() ? ZERO : NaN;
307         }
308         return createComplex(real / divisor,
309                              imaginary  / divisor);
310     }
311 
312     /** {@inheritDoc} */
313     @Override
314     public Complex reciprocal() {
315         if (isNaN) {
316             return NaN;
317         }
318 
319         if (real == 0.0 && imaginary == 0.0) {
320             return INF;
321         }
322 
323         if (isInfinite) {
324             return ZERO;
325         }
326 
327         if (FastMath.abs(real) < FastMath.abs(imaginary)) {
328             double q = real / imaginary;
329             double scale = 1. / (real * q + imaginary);
330             return createComplex(scale * q, -scale);
331         } else {
332             double q = imaginary / real;
333             double scale = 1. / (imaginary * q + real);
334             return createComplex(scale, -scale * q);
335         }
336     }
337 
338     /**
339      * Test for equality with another object.
340      * If both the real and imaginary parts of two complex numbers
341      * are exactly the same, and neither is {@code Double.NaN}, the two
342      * Complex objects are considered to be equal.
343      * The behavior is the same as for JDK's {@link Double#equals(Object)
344      * Double}:
345      * <ul>
346      *  <li>All {@code NaN} values are considered to be equal,
347      *   i.e, if either (or both) real and imaginary parts of the complex
348      *   number are equal to {@code Double.NaN}, the complex number is equal
349      *   to {@code NaN}.
350      *  </li>
351      *  <li>
352      *   Instances constructed with different representations of zero (i.e.
353      *   either "0" or "-0") are <em>not</em> considered to be equal.
354      *  </li>
355      * </ul>
356      *
357      * @param other Object to test for equality with this instance.
358      * @return {@code true} if the objects are equal, {@code false} if object
359      * is {@code null}, not an instance of {@code Complex}, or not equal to
360      * this instance.
361      */
362     @Override
363     public boolean equals(Object other) {
364         if (this == other) {
365             return true;
366         }
367         if (other instanceof Complex){
368             Complex c = (Complex) other;
369             if (c.isNaN) {
370                 return isNaN;
371             } else {
372                 return MathUtils.equals(real, c.real) &&
373                        MathUtils.equals(imaginary, c.imaginary);
374             }
375         }
376         return false;
377     }
378 
379     /**
380      * Test for the floating-point equality between Complex objects.
381      * It returns {@code true} if both arguments are equal or within the
382      * range of allowed error (inclusive).
383      *
384      * @param x First value (cannot be {@code null}).
385      * @param y Second value (cannot be {@code null}).
386      * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
387      * values between the real (resp. imaginary) parts of {@code x} and
388      * {@code y}.
389      * @return {@code true} if there are fewer than {@code maxUlps} floating
390      * point values between the real (resp. imaginary) parts of {@code x}
391      * and {@code y}.
392      *
393      * @see Precision#equals(double,double,int)
394      */
395     public static boolean equals(Complex x, Complex y, int maxUlps) {
396         return Precision.equals(x.real, y.real, maxUlps) &&
397                Precision.equals(x.imaginary, y.imaginary, maxUlps);
398     }
399 
400     /**
401      * Returns {@code true} iff the values are equal as defined by
402      * {@link #equals(Complex,Complex,int) equals(x, y, 1)}.
403      *
404      * @param x First value (cannot be {@code null}).
405      * @param y Second value (cannot be {@code null}).
406      * @return {@code true} if the values are equal.
407      */
408     public static boolean equals(Complex x, Complex y) {
409         return equals(x, y, 1);
410     }
411 
412     /**
413      * Returns {@code true} if, both for the real part and for the imaginary
414      * part, there is no double value strictly between the arguments or the
415      * difference between them is within the range of allowed error
416      * (inclusive).  Returns {@code false} if either of the arguments is NaN.
417      *
418      * @param x First value (cannot be {@code null}).
419      * @param y Second value (cannot be {@code null}).
420      * @param eps Amount of allowed absolute error.
421      * @return {@code true} if the values are two adjacent floating point
422      * numbers or they are within range of each other.
423      *
424      * @see Precision#equals(double,double,double)
425      */
426     public static boolean equals(Complex x, Complex y, double eps) {
427         return Precision.equals(x.real, y.real, eps) &&
428                Precision.equals(x.imaginary, y.imaginary, eps);
429     }
430 
431     /**
432      * Returns {@code true} if, both for the real part and for the imaginary
433      * part, there is no double value strictly between the arguments or the
434      * relative difference between them is smaller or equal to the given
435      * tolerance. Returns {@code false} if either of the arguments is NaN.
436      *
437      * @param x First value (cannot be {@code null}).
438      * @param y Second value (cannot be {@code null}).
439      * @param eps Amount of allowed relative error.
440      * @return {@code true} if the values are two adjacent floating point
441      * numbers or they are within range of each other.
442      *
443      * @see Precision#equalsWithRelativeTolerance(double,double,double)
444      */
445     public static boolean equalsWithRelativeTolerance(Complex x,
446                                                       Complex y,
447                                                       double eps) {
448         return Precision.equalsWithRelativeTolerance(x.real, y.real, eps) &&
449                Precision.equalsWithRelativeTolerance(x.imaginary, y.imaginary, eps);
450     }
451 
452     /**
453      * Get a hashCode for the complex number.
454      * Any {@code Double.NaN} value in real or imaginary part produces
455      * the same hash code {@code 7}.
456      *
457      * @return a hash code value for this object.
458      */
459     @Override
460     public int hashCode() {
461         if (isNaN) {
462             return 7;
463         }
464         return 37 * (17 * MathUtils.hash(imaginary) +
465             MathUtils.hash(real));
466     }
467 
468     /** {@inheritDoc}
469      * <p>
470      * This implementation considers +0.0 and -0.0 to be equal for both
471      * real and imaginary components.
472      * </p>
473      * @since 1.8
474      */
475     @Override
476     public boolean isZero() {
477         return real == 0.0 && imaginary == 0.0;
478     }
479 
480     /**
481      * Access the imaginary part.
482      *
483      * @return the imaginary part.
484      */
485     public double getImaginary() {
486         return imaginary;
487     }
488 
489     /**
490      * Access the imaginary part.
491      *
492      * @return the imaginary part.
493      * @since 2.0
494      */
495     public double getImaginaryPart() {
496         return imaginary;
497     }
498 
499     /**
500      * Access the real part.
501      *
502      * @return the real part.
503      */
504     @Override
505     public double getReal() {
506         return real;
507     }
508 
509     /** {@inheritDoc} */
510     @Override
511     public Complex getAddendum() {
512         return new Complex(0, imaginary);
513     }
514 
515     /**
516      * Access the real part.
517      *
518      * @return the real part.
519      * @since 2.0
520      */
521     public double getRealPart() {
522         return real;
523     }
524 
525     /**
526      * Checks whether either or both parts of this complex number is
527      * {@code NaN}.
528      *
529      * @return true if either or both parts of this complex number is
530      * {@code NaN}; false otherwise.
531      */
532     @Override
533     public boolean isNaN() {
534         return isNaN;
535     }
536 
537     /** Check whether the instance is real (i.e. imaginary part is zero).
538      * @return true if imaginary part is zero
539      * @since 1.7
540      */
541     public boolean isReal() {
542         return imaginary == 0.0;
543     }
544 
545     /** Check whether the instance is an integer (i.e. imaginary part is zero and real part has no fractional part).
546      * @return true if imaginary part is zero and real part has no fractional part
547      * @since 1.7
548      */
549     public boolean isMathematicalInteger() {
550         return isReal() && Precision.isMathematicalInteger(real);
551     }
552 
553     /**
554      * Checks whether either the real or imaginary part of this complex number
555      * takes an infinite value (either {@code Double.POSITIVE_INFINITY} or
556      * {@code Double.NEGATIVE_INFINITY}) and neither part
557      * is {@code NaN}.
558      *
559      * @return true if one or both parts of this complex number are infinite
560      * and neither part is {@code NaN}.
561      */
562     @Override
563     public boolean isInfinite() {
564         return isInfinite;
565     }
566 
567     /**
568      * Returns a {@code Complex} whose value is {@code this * factor}.
569      * Implements preliminary checks for {@code NaN} and infinity followed by
570      * the definitional formula:
571      * <p>
572      *   {@code (a + bi)(c + di) = (ac - bd) + (ad + bc)i}
573      * </p>
574      * Returns {@link #NaN} if either {@code this} or {@code factor} has one or
575      * more {@code NaN} parts.
576      * <p>
577      * Returns {@link #INF} if neither {@code this} nor {@code factor} has one
578      * or more {@code NaN} parts and if either {@code this} or {@code factor}
579      * has one or more infinite parts (same result is returned regardless of
580      * the sign of the components).
581      * </p><p>
582      * Returns finite values in components of the result per the definitional
583      * formula in all remaining cases.</p>
584      *
585      * @param  factor value to be multiplied by this {@code Complex}.
586      * @return {@code this * factor}.
587      * @throws NullArgumentException if {@code factor} is {@code null}.
588      */
589     @Override
590     public Complex multiply(Complex factor)
591         throws NullArgumentException {
592         MathUtils.checkNotNull(factor);
593         if (isNaN || factor.isNaN) {
594             return NaN;
595         }
596         if (Double.isInfinite(real) ||
597             Double.isInfinite(imaginary) ||
598             Double.isInfinite(factor.real) ||
599             Double.isInfinite(factor.imaginary)) {
600             // we don't use isInfinite() to avoid testing for NaN again
601             return INF;
602         }
603         return createComplex(MathArrays.linearCombination(real, factor.real, -imaginary, factor.imaginary),
604                              MathArrays.linearCombination(real, factor.imaginary, imaginary, factor.real));
605     }
606 
607     /**
608      * Returns a {@code Complex} whose value is {@code this * factor}, with {@code factor}
609      * interpreted as a integer number.
610      *
611      * @param  factor value to be multiplied by this {@code Complex}.
612      * @return {@code this * factor}.
613      * @see #multiply(Complex)
614      */
615     @Override
616     public Complex multiply(final int factor) {
617         if (isNaN) {
618             return NaN;
619         }
620         if (Double.isInfinite(real) ||
621             Double.isInfinite(imaginary)) {
622             return INF;
623         }
624         return createComplex(real * factor, imaginary * factor);
625     }
626 
627     /**
628      * Returns a {@code Complex} whose value is {@code this * factor}, with {@code factor}
629      * interpreted as a real number.
630      *
631      * @param  factor value to be multiplied by this {@code Complex}.
632      * @return {@code this * factor}.
633      * @see #multiply(Complex)
634      */
635     @Override
636     public Complex multiply(double factor) {
637         if (isNaN || Double.isNaN(factor)) {
638             return NaN;
639         }
640         if (Double.isInfinite(real) ||
641             Double.isInfinite(imaginary) ||
642             Double.isInfinite(factor)) {
643             // we don't use isInfinite() to avoid testing for NaN again
644             return INF;
645         }
646         return createComplex(real * factor, imaginary * factor);
647     }
648 
649     /** Compute this * i.
650      * @return this * i
651      * @since 2.0
652      */
653     public Complex multiplyPlusI() {
654         return createComplex(-imaginary, real);
655     }
656 
657     /** Compute this *- -i.
658      * @return this * i
659      * @since 2.0
660      */
661     public Complex multiplyMinusI() {
662         return createComplex(imaginary, -real);
663     }
664 
665     /** {@inheritDoc} */
666     @Override
667     public Complex square() {
668         return multiply(this);
669     }
670 
671     /**
672      * Returns a {@code Complex} whose value is {@code (-this)}.
673      * Returns {@code NaN} if either real or imaginary
674      * part of this Complex number is {@code Double.NaN}.
675      *
676      * @return {@code -this}.
677      */
678     @Override
679     public Complex negate() {
680         if (isNaN) {
681             return NaN;
682         }
683 
684         return createComplex(-real, -imaginary);
685     }
686 
687     /**
688      * Returns a {@code Complex} whose value is
689      * {@code (this - subtrahend)}.
690      * Uses the definitional formula
691      * <p>
692      *  {@code (a + bi) - (c + di) = (a-c) + (b-d)i}
693      * </p>
694      * If either {@code this} or {@code subtrahend} has a {@code NaN]} value in either part,
695      * {@link #NaN} is returned; otherwise infinite and {@code NaN} values are
696      * returned in the parts of the result according to the rules for
697      * {@link java.lang.Double} arithmetic.
698      *
699      * @param  subtrahend value to be subtracted from this {@code Complex}.
700      * @return {@code this - subtrahend}.
701      * @throws NullArgumentException if {@code subtrahend} is {@code null}.
702      */
703     @Override
704     public Complex subtract(Complex subtrahend)
705         throws NullArgumentException {
706         MathUtils.checkNotNull(subtrahend);
707         if (isNaN || subtrahend.isNaN) {
708             return NaN;
709         }
710 
711         return createComplex(real - subtrahend.getRealPart(),
712                              imaginary - subtrahend.getImaginaryPart());
713     }
714 
715     /**
716      * Returns a {@code Complex} whose value is
717      * {@code (this - subtrahend)}.
718      *
719      * @param  subtrahend value to be subtracted from this {@code Complex}.
720      * @return {@code this - subtrahend}.
721      * @see #subtract(Complex)
722      */
723     @Override
724     public Complex subtract(double subtrahend) {
725         if (isNaN || Double.isNaN(subtrahend)) {
726             return NaN;
727         }
728         return createComplex(real - subtrahend, imaginary);
729     }
730 
731     /**
732      * Compute the
733      * <a href="http://mathworld.wolfram.com/InverseCosine.html" TARGET="_top">
734      * inverse cosine</a> of this complex number.
735      * Implements the formula:
736      * <p>
737      *  {@code acos(z) = -i (log(z + i (sqrt(1 - z<sup>2</sup>))))}
738      * </p>
739      * Returns {@link Complex#NaN} if either real or imaginary part of the
740      * input argument is {@code NaN} or infinite.
741      *
742      * @return the inverse cosine of this complex number.
743      */
744     @Override
745     public Complex acos() {
746         if (isNaN) {
747             return NaN;
748         }
749 
750         return this.add(this.sqrt1z().multiplyPlusI()).log().multiplyMinusI();
751     }
752 
753     /**
754      * Compute the
755      * <a href="http://mathworld.wolfram.com/InverseSine.html" TARGET="_top">
756      * inverse sine</a> of this complex number.
757      * Implements the formula:
758      * <p>
759      *  {@code asin(z) = -i (log(sqrt(1 - z<sup>2</sup>) + iz))}
760      * </p><p>
761      * Returns {@link Complex#NaN} if either real or imaginary part of the
762      * input argument is {@code NaN} or infinite.</p>
763      *
764      * @return the inverse sine of this complex number.
765      */
766     @Override
767     public Complex asin() {
768         if (isNaN) {
769             return NaN;
770         }
771 
772         return sqrt1z().add(this.multiplyPlusI()).log().multiplyMinusI();
773     }
774 
775     /**
776      * Compute the
777      * <a href="http://mathworld.wolfram.com/InverseTangent.html" TARGET="_top">
778      * inverse tangent</a> of this complex number.
779      * Implements the formula:
780      * <p>
781      * {@code atan(z) = (i/2) log((1 - iz)/(1 + iz))}
782      * </p><p>
783      * Returns {@link Complex#NaN} if either real or imaginary part of the
784      * input argument is {@code NaN} or infinite.</p>
785      *
786      * @return the inverse tangent of this complex number
787      */
788     @Override
789     public Complex atan() {
790         if (isNaN) {
791             return NaN;
792         }
793 
794         if (real == 0.0) {
795 
796             // singularity at ±i
797             if (imaginary * imaginary - 1.0 == 0.0) {
798                 return NaN;
799             }
800 
801             // branch cut on imaginary axis
802             final Complex tmp = createComplex((1 + imaginary) / (1 - imaginary), 0.0).log().multiplyPlusI().multiply(0.5);
803             return createComplex(FastMath.copySign(tmp.real, real), tmp.imaginary);
804 
805         } else if (imaginary == 0.0) {
806             // taking care to preserve the sign of the zero imaginary part
807             return createComplex(FastMath.atan(real), imaginary);
808         } else {
809             // regular formula
810             final Complex n = createComplex(1 + imaginary, -real);
811             final Complex d = createComplex(1 - imaginary,  real);
812             return n.divide(d).log().multiplyPlusI().multiply(0.5);
813         }
814 
815     }
816 
817     /**
818      * Compute the
819      * <a href="http://mathworld.wolfram.com/Cosine.html" TARGET="_top">
820      * cosine</a> of this complex number.
821      * Implements the formula:
822      * <p>
823      *  {@code cos(a + bi) = cos(a)cosh(b) - sin(a)sinh(b)i}
824      * </p><p>
825      * where the (real) functions on the right-hand side are
826      * {@link FastMath#sin}, {@link FastMath#cos},
827      * {@link FastMath#cosh} and {@link FastMath#sinh}.
828      * </p><p>
829      * Returns {@link Complex#NaN} if either real or imaginary part of the
830      * input argument is {@code NaN}.
831      * </p><p>
832      * Infinite values in real or imaginary parts of the input may result in
833      * infinite or NaN values returned in parts of the result.</p>
834      * <pre>
835      *  Examples:
836      *  <code>
837      *   cos(1 &plusmn; INFINITY i) = 1 ∓ INFINITY i
838      *   cos(&plusmn;INFINITY + i) = NaN + NaN i
839      *   cos(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
840      *  </code>
841      * </pre>
842      *
843      * @return the cosine of this complex number.
844      */
845     @Override
846     public Complex cos() {
847         if (isNaN) {
848             return NaN;
849         }
850 
851         final SinCos   scr  = FastMath.sinCos(real);
852         final SinhCosh schi = FastMath.sinhCosh(imaginary);
853         return createComplex(scr.cos() * schi.cosh(), -scr.sin() * schi.sinh());
854     }
855 
856     /**
857      * Compute the
858      * <a href="http://mathworld.wolfram.com/HyperbolicCosine.html" TARGET="_top">
859      * hyperbolic cosine</a> of this complex number.
860      * Implements the formula:
861      * <pre>
862      *  <code>
863      *   cosh(a + bi) = cosh(a)cos(b) + sinh(a)sin(b)i
864      *  </code>
865      * </pre>
866      * where the (real) functions on the right-hand side are
867      * {@link FastMath#sin}, {@link FastMath#cos},
868      * {@link FastMath#cosh} and {@link FastMath#sinh}.
869      * <p>
870      * Returns {@link Complex#NaN} if either real or imaginary part of the
871      * input argument is {@code NaN}.
872      * </p>
873      * Infinite values in real or imaginary parts of the input may result in
874      * infinite or NaN values returned in parts of the result.
875      * <pre>
876      *  Examples:
877      *  <code>
878      *   cosh(1 &plusmn; INFINITY i) = NaN + NaN i
879      *   cosh(&plusmn;INFINITY + i) = INFINITY &plusmn; INFINITY i
880      *   cosh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
881      *  </code>
882      * </pre>
883      *
884      * @return the hyperbolic cosine of this complex number.
885      */
886     @Override
887     public Complex cosh() {
888         if (isNaN) {
889             return NaN;
890         }
891 
892         final SinhCosh schr = FastMath.sinhCosh(real);
893         final SinCos   sci  = FastMath.sinCos(imaginary);
894         return createComplex(schr.cosh() * sci.cos(), schr.sinh() * sci.sin());
895     }
896 
897     /**
898      * Compute the
899      * <a href="http://mathworld.wolfram.com/ExponentialFunction.html" TARGET="_top">
900      * exponential function</a> of this complex number.
901      * Implements the formula:
902      * <pre>
903      *  <code>
904      *   exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i
905      *  </code>
906      * </pre>
907      * where the (real) functions on the right-hand side are
908      * {@link FastMath#exp(double)} p}, {@link FastMath#cos(double)}, and
909      * {@link FastMath#sin(double)}.
910      * <p>
911      * Returns {@link Complex#NaN} if either real or imaginary part of the
912      * input argument is {@code NaN}.
913      * </p>
914      * Infinite values in real or imaginary parts of the input may result in
915      * infinite or NaN values returned in parts of the result.
916      * <pre>
917      *  Examples:
918      *  <code>
919      *   exp(1 &plusmn; INFINITY i) = NaN + NaN i
920      *   exp(INFINITY + i) = INFINITY + INFINITY i
921      *   exp(-INFINITY + i) = 0 + 0i
922      *   exp(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
923      *  </code>
924      * </pre>
925      *
926      * @return <code><i>e</i><sup>this</sup></code>.
927      */
928     @Override
929     public Complex exp() {
930         if (isNaN) {
931             return NaN;
932         }
933 
934         final double expReal = FastMath.exp(real);
935         final SinCos sc      = FastMath.sinCos(imaginary);
936         return createComplex(expReal * sc.cos(), expReal * sc.sin());
937     }
938 
939     /** {@inheritDoc}
940      * @since 1.7
941      */
942     @Override
943     public Complex expm1() {
944         if (isNaN) {
945             return NaN;
946         }
947 
948         final double expm1Real = FastMath.expm1(real);
949         final SinCos sc        = FastMath.sinCos(imaginary);
950         return createComplex(expm1Real * sc.cos(), expm1Real * sc.sin());
951     }
952 
953     /**
954      * Compute the
955      * <a href="http://mathworld.wolfram.com/NaturalLogarithm.html" TARGET="_top">
956      * natural logarithm</a> of this complex number.
957      * Implements the formula:
958      * <pre>
959      *  <code>
960      *   log(a + bi) = ln(|a + bi|) + arg(a + bi)i
961      *  </code>
962      * </pre>
963      * where ln on the right hand side is {@link FastMath#log(double)},
964      * {@code |a + bi|} is the modulus, {@link Complex#abs},  and
965      * {@code arg(a + bi) = }{@link FastMath#atan2}(b, a).
966      * <p>
967      * Returns {@link Complex#NaN} if either real or imaginary part of the
968      * input argument is {@code NaN}.
969      * </p>
970      * Infinite (or critical) values in real or imaginary parts of the input may
971      * result in infinite or NaN values returned in parts of the result.
972      * <pre>
973      *  Examples:
974      *  <code>
975      *   log(1 &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;/2)i
976      *   log(INFINITY + i) = INFINITY + 0i
977      *   log(-INFINITY + i) = INFINITY + &pi;i
978      *   log(INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;/4)i
979      *   log(-INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (3&pi;/4)i
980      *   log(0 + 0i) = -INFINITY + 0i
981      *  </code>
982      * </pre>
983      *
984      * @return the value <code>ln &nbsp; this</code>, the natural logarithm
985      * of {@code this}.
986      */
987     @Override
988     public Complex log() {
989         if (isNaN) {
990             return NaN;
991         }
992 
993         return createComplex(FastMath.log(FastMath.hypot(real, imaginary)),
994                              FastMath.atan2(imaginary, real));
995     }
996 
997     /** {@inheritDoc}
998      * @since 1.7
999      */
1000     @Override
1001     public Complex log1p() {
1002         return add(1.0).log();
1003     }
1004 
1005     /** {@inheritDoc}
1006      * @since 1.7
1007      */
1008     @Override
1009     public Complex log10() {
1010         return log().divide(LOG10);
1011     }
1012 
1013     /**
1014      * Returns of value of this complex number raised to the power of {@code x}.
1015      * <p>
1016      * If {@code x} is a real number whose real part has an integer value, returns {@link #pow(int)},
1017      * if both {@code this} and {@code x} are real and {@link FastMath#pow(double, double)}
1018      * with the corresponding real arguments would return a finite number (neither NaN
1019      * nor infinite), then returns the same value converted to {@code Complex},
1020      * with the same special cases.
1021      * In all other cases real cases, implements y<sup>x</sup> = exp(x&middot;log(y)).
1022      * </p>
1023      *
1024      * @param  x exponent to which this {@code Complex} is to be raised.
1025      * @return <code> this<sup>x</sup></code>.
1026      * @throws NullArgumentException if x is {@code null}.
1027      */
1028     @Override
1029     public Complex pow(Complex x)
1030         throws NullArgumentException {
1031 
1032         MathUtils.checkNotNull(x);
1033 
1034         if (x.imaginary == 0.0) {
1035             final int nx = (int) FastMath.rint(x.real);
1036             if (x.real == nx) {
1037                 // integer power
1038                 return pow(nx);
1039             } else if (this.imaginary == 0.0) {
1040                 // check real implementation that handles a bunch of special cases
1041                 final double realPow = FastMath.pow(this.real, x.real);
1042                 if (Double.isFinite(realPow)) {
1043                     return createComplex(realPow, 0);
1044                 }
1045             }
1046         }
1047 
1048         // generic implementation
1049         return this.log().multiply(x).exp();
1050 
1051     }
1052 
1053 
1054     /**
1055      * Returns of value of this complex number raised to the power of {@code x}.
1056      * <p>
1057      * If {@code x} has an integer value, returns {@link #pow(int)},
1058      * if {@code this} is real and {@link FastMath#pow(double, double)}
1059      * with the corresponding real arguments would return a finite number (neither NaN
1060      * nor infinite), then returns the same value converted to {@code Complex},
1061      * with the same special cases.
1062      * In all other cases real cases, implements y<sup>x</sup> = exp(x&middot;log(y)).
1063      * </p>
1064      *
1065      * @param  x exponent to which this {@code Complex} is to be raised.
1066      * @return <code> this<sup>x</sup></code>.
1067      */
1068     @Override
1069     public Complex pow(double x) {
1070 
1071         final int nx = (int) FastMath.rint(x);
1072         if (x == nx) {
1073             // integer power
1074             return pow(nx);
1075         } else if (this.imaginary == 0.0) {
1076             // check real implementation that handles a bunch of special cases
1077             final double realPow = FastMath.pow(this.real, x);
1078             if (Double.isFinite(realPow)) {
1079                 return createComplex(realPow, 0);
1080             }
1081         }
1082 
1083         // generic implementation
1084         return this.log().multiply(x).exp();
1085 
1086     }
1087 
1088      /** {@inheritDoc}
1089       * @since 1.7
1090       */
1091     @Override
1092     public Complex pow(final int n) {
1093 
1094         Complex result = ONE;
1095         final boolean invert;
1096         int p = n;
1097         if (p < 0) {
1098             invert = true;
1099             p = -p;
1100         } else {
1101             invert = false;
1102         }
1103 
1104         // Exponentiate by successive squaring
1105         Complex square = this;
1106         while (p > 0) {
1107             if ((p & 0x1) > 0) {
1108                 result = result.multiply(square);
1109             }
1110             square = square.multiply(square);
1111             p = p >> 1;
1112         }
1113 
1114         return invert ? result.reciprocal() : result;
1115 
1116     }
1117 
1118      /**
1119       * Compute the
1120      * <a href="http://mathworld.wolfram.com/Sine.html" TARGET="_top">
1121      * sine</a>
1122      * of this complex number.
1123      * Implements the formula:
1124      * <pre>
1125      *  <code>
1126      *   sin(a + bi) = sin(a)cosh(b) + cos(a)sinh(b)i
1127      *  </code>
1128      * </pre>
1129      * where the (real) functions on the right-hand side are
1130      * {@link FastMath#sin}, {@link FastMath#cos},
1131      * {@link FastMath#cosh} and {@link FastMath#sinh}.
1132      * <p>
1133      * Returns {@link Complex#NaN} if either real or imaginary part of the
1134      * input argument is {@code NaN}.
1135      * </p><p>
1136      * Infinite values in real or imaginary parts of the input may result in
1137      * infinite or {@code NaN} values returned in parts of the result.
1138      * <pre>
1139      *  Examples:
1140      *  <code>
1141      *   sin(1 &plusmn; INFINITY i) = 1 &plusmn; INFINITY i
1142      *   sin(&plusmn;INFINITY + i) = NaN + NaN i
1143      *   sin(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
1144      *  </code>
1145      * </pre>
1146      *
1147      * @return the sine of this complex number.
1148      */
1149     @Override
1150     public Complex sin() {
1151         if (isNaN) {
1152             return NaN;
1153         }
1154 
1155         final SinCos   scr  = FastMath.sinCos(real);
1156         final SinhCosh schi = FastMath.sinhCosh(imaginary);
1157         return createComplex(scr.sin() * schi.cosh(), scr.cos() * schi.sinh());
1158 
1159     }
1160 
1161     /** {@inheritDoc}
1162      */
1163     @Override
1164     public FieldSinCos<Complex> sinCos() {
1165         if (isNaN) {
1166             return new FieldSinCos<>(NaN, NaN);
1167         }
1168 
1169         final SinCos scr = FastMath.sinCos(real);
1170         final SinhCosh schi = FastMath.sinhCosh(imaginary);
1171         return new FieldSinCos<>(createComplex(scr.sin() * schi.cosh(),  scr.cos() * schi.sinh()),
1172                                  createComplex(scr.cos() * schi.cosh(), -scr.sin() * schi.sinh()));
1173     }
1174 
1175     /** {@inheritDoc}
1176      * @since 1.7
1177      */
1178     @Override
1179     public Complex atan2(Complex x) {
1180 
1181         // compute r = sqrt(x^2+y^2)
1182         final Complex r = x.square().add(multiply(this)).sqrt();
1183 
1184         if (FastMath.copySign(1.0, x.real) >= 0) {
1185             // compute atan2(y, x) = 2 atan(y / (r + x))
1186             return divide(r.add(x)).atan().multiply(2);
1187         } else {
1188             // compute atan2(y, x) = +/- pi - 2 atan(y / (r - x))
1189             return divide(r.subtract(x)).atan().multiply(-2).add(FastMath.PI);
1190         }
1191     }
1192 
1193     /** {@inheritDoc}
1194      * <p>
1195      * Branch cuts are on the real axis, below +1.
1196      * </p>
1197      * @since 1.7
1198      */
1199     @Override
1200     public Complex acosh() {
1201         final Complex sqrtPlus  = add(1).sqrt();
1202         final Complex sqrtMinus = subtract(1).sqrt();
1203         return add(sqrtPlus.multiply(sqrtMinus)).log();
1204     }
1205 
1206     /** {@inheritDoc}
1207      * <p>
1208      * Branch cuts are on the imaginary axis, above +i and below -i.
1209      * </p>
1210      * @since 1.7
1211      */
1212     @Override
1213     public Complex asinh() {
1214         return add(multiply(this).add(1.0).sqrt()).log();
1215     }
1216 
1217     /** {@inheritDoc}
1218      * <p>
1219      * Branch cuts are on the real axis, above +1 and below -1.
1220      * </p>
1221      * @since 1.7
1222      */
1223     @Override
1224     public Complex atanh() {
1225         final Complex logPlus  = add(1).log();
1226         final Complex logMinus = createComplex(1 - real, -imaginary).log();
1227         return logPlus.subtract(logMinus).multiply(0.5);
1228     }
1229 
1230     /**
1231      * Compute the
1232      * <a href="http://mathworld.wolfram.com/HyperbolicSine.html" TARGET="_top">
1233      * hyperbolic sine</a> of this complex number.
1234      * Implements the formula:
1235      * <pre>
1236      *  <code>
1237      *   sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i
1238      *  </code>
1239      * </pre>
1240      * where the (real) functions on the right-hand side are
1241      * {@link FastMath#sin}, {@link FastMath#cos},
1242      * {@link FastMath#cosh} and {@link FastMath#sinh}.
1243      * <p>
1244      * Returns {@link Complex#NaN} if either real or imaginary part of the
1245      * input argument is {@code NaN}.
1246      * </p><p>
1247      * Infinite values in real or imaginary parts of the input may result in
1248      * infinite or NaN values returned in parts of the result.
1249      * <pre>
1250      *  Examples:
1251      *  <code>
1252      *   sinh(1 &plusmn; INFINITY i) = NaN + NaN i
1253      *   sinh(&plusmn;INFINITY + i) = &plusmn; INFINITY + INFINITY i
1254      *   sinh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
1255      *  </code>
1256      * </pre>
1257      *
1258      * @return the hyperbolic sine of {@code this}.
1259      */
1260     @Override
1261     public Complex sinh() {
1262         if (isNaN) {
1263             return NaN;
1264         }
1265 
1266         final SinhCosh schr = FastMath.sinhCosh(real);
1267         final SinCos   sci  = FastMath.sinCos(imaginary);
1268         return createComplex(schr.sinh() * sci.cos(), schr.cosh() * sci.sin());
1269     }
1270 
1271     /** {@inheritDoc}
1272      */
1273     @Override
1274     public FieldSinhCosh<Complex> sinhCosh() {
1275         if (isNaN) {
1276             return new FieldSinhCosh<>(NaN, NaN);
1277         }
1278 
1279         final SinhCosh schr = FastMath.sinhCosh(real);
1280         final SinCos   sci  = FastMath.sinCos(imaginary);
1281         return new FieldSinhCosh<>(createComplex(schr.sinh() * sci.cos(), schr.cosh() * sci.sin()),
1282                                    createComplex(schr.cosh() * sci.cos(), schr.sinh() * sci.sin()));
1283     }
1284 
1285     /**
1286      * Compute the
1287      * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
1288      * square root</a> of this complex number.
1289      * Implements the following algorithm to compute {@code sqrt(a + bi)}:
1290      * <ol><li>Let {@code t = sqrt((|a| + |a + bi|) / 2)}</li>
1291      * <li><pre>if {@code  a ≥ 0} return {@code t + (b/2t)i}
1292      *  else return {@code |b|/2t + sign(b)t i }</pre></li>
1293      * </ol>
1294      * where <ul>
1295      * <li>{@code |a| = }{@link FastMath#abs(double) abs(a)}</li>
1296      * <li>{@code |a + bi| = }{@link FastMath#hypot(double, double) hypot(a, b)}</li>
1297      * <li>{@code sign(b) = }{@link FastMath#copySign(double, double) copySign(1, b)}
1298      * </ul>
1299      * The real part is therefore always nonnegative.
1300      * <p>
1301      * Returns {@link Complex#NaN} if either real or imaginary part of the
1302      * input argument is {@code NaN}.
1303      * </p>
1304      * <p>
1305      * Infinite values in real or imaginary parts of the input may result in
1306      * infinite or NaN values returned in parts of the result.
1307      * </p>
1308      * <pre>
1309      *  Examples:
1310      *  <code>
1311      *   sqrt(1 ± ∞ i) = ∞ + NaN i
1312      *   sqrt(∞ + i) = ∞ + 0i
1313      *   sqrt(-∞ + i) = 0 + ∞ i
1314      *   sqrt(∞ ± ∞ i) = ∞ + NaN i
1315      *   sqrt(-∞ ± ∞ i) = NaN ± ∞ i
1316      *  </code>
1317      * </pre>
1318      *
1319      * @return the square root of {@code this} with nonnegative real part.
1320      */
1321     @Override
1322     public Complex sqrt() {
1323         if (isNaN) {
1324             return NaN;
1325         }
1326 
1327         if (real == 0.0 && imaginary == 0.0) {
1328             return ZERO;
1329         }
1330 
1331         double t = FastMath.sqrt((FastMath.abs(real) + FastMath.hypot(real, imaginary)) * 0.5);
1332         if (FastMath.copySign(1, real) >= 0.0) {
1333             return createComplex(t, imaginary / (2.0 * t));
1334         } else {
1335             return createComplex(FastMath.abs(imaginary) / (2.0 * t),
1336                                  FastMath.copySign(t, imaginary));
1337         }
1338     }
1339 
1340     /**
1341      * Compute the
1342      * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
1343      * square root</a> of <code>1 - this<sup>2</sup></code> for this complex
1344      * number.
1345      * Computes the result directly as
1346      * {@code sqrt(ONE.subtract(z.square()))}.
1347      * <p>
1348      * Returns {@link Complex#NaN} if either real or imaginary part of the
1349      * input argument is {@code NaN}.
1350      * </p>
1351      * Infinite values in real or imaginary parts of the input may result in
1352      * infinite or NaN values returned in parts of the result.
1353      *
1354      * @return the square root of <code>1 - this<sup>2</sup></code>.
1355      */
1356     public Complex sqrt1z() {
1357         final Complex t2 = this.square();
1358         return createComplex(1 - t2.real, -t2.imaginary).sqrt();
1359     }
1360 
1361     /** {@inheritDoc}
1362      * <p>
1363      * This implementation compute the principal cube root by using a branch cut along real negative axis.
1364      * </p>
1365      * @since 1.7
1366      */
1367     @Override
1368     public Complex cbrt() {
1369         final double magnitude = FastMath.cbrt(norm());
1370         final SinCos sc        = FastMath.sinCos(getArgument() / 3);
1371         return createComplex(magnitude * sc.cos(), magnitude * sc.sin());
1372     }
1373 
1374     /** {@inheritDoc}
1375      * <p>
1376      * This implementation compute the principal n<sup>th</sup> root by using a branch cut along real negative axis.
1377      * </p>
1378      * @since 1.7
1379      */
1380     @Override
1381     public Complex rootN(int n) {
1382         final double magnitude = FastMath.pow(norm(), 1.0 / n);
1383         final SinCos sc        = FastMath.sinCos(getArgument() / n);
1384         return createComplex(magnitude * sc.cos(), magnitude * sc.sin());
1385     }
1386 
1387     /**
1388      * Compute the
1389      * <a href="http://mathworld.wolfram.com/Tangent.html" TARGET="_top">
1390      * tangent</a> of this complex number.
1391      * Implements the formula:
1392      * <pre>
1393      *  <code>
1394      *   tan(a + bi) = sin(2a)/(cos(2a)+cosh(2b)) + [sinh(2b)/(cos(2a)+cosh(2b))]i
1395      *  </code>
1396      * </pre>
1397      * where the (real) functions on the right-hand side are
1398      * {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and
1399      * {@link FastMath#sinh}.
1400      * <p>
1401      * Returns {@link Complex#NaN} if either real or imaginary part of the
1402      * input argument is {@code NaN}.
1403      * </p>
1404      * Infinite (or critical) values in real or imaginary parts of the input may
1405      * result in infinite or NaN values returned in parts of the result.
1406      * <pre>
1407      *  Examples:
1408      *  <code>
1409      *   tan(a &plusmn; INFINITY i) = 0 &plusmn; i
1410      *   tan(&plusmn;INFINITY + bi) = NaN + NaN i
1411      *   tan(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
1412      *   tan(&plusmn;&pi;/2 + 0 i) = &plusmn;INFINITY + NaN i
1413      *  </code>
1414      * </pre>
1415      *
1416      * @return the tangent of {@code this}.
1417      */
1418     @Override
1419     public Complex tan() {
1420         if (isNaN || Double.isInfinite(real)) {
1421             return NaN;
1422         }
1423         if (imaginary > 20.0) {
1424             return I;
1425         }
1426         if (imaginary < -20.0) {
1427             return MINUS_I;
1428         }
1429 
1430         final SinCos sc2r = FastMath.sinCos(2.0 * real);
1431         double imaginary2 = 2.0 * imaginary;
1432         double d = sc2r.cos() + FastMath.cosh(imaginary2);
1433 
1434         return createComplex(sc2r.sin() / d, FastMath.sinh(imaginary2) / d);
1435 
1436     }
1437 
1438     /**
1439      * Compute the
1440      * <a href="http://mathworld.wolfram.com/HyperbolicTangent.html" TARGET="_top">
1441      * hyperbolic tangent</a> of this complex number.
1442      * Implements the formula:
1443      * <pre>
1444      *  <code>
1445      *   tan(a + bi) = sinh(2a)/(cosh(2a)+cos(2b)) + [sin(2b)/(cosh(2a)+cos(2b))]i
1446      *  </code>
1447      * </pre>
1448      * where the (real) functions on the right-hand side are
1449      * {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and
1450      * {@link FastMath#sinh}.
1451      * <p>
1452      * Returns {@link Complex#NaN} if either real or imaginary part of the
1453      * input argument is {@code NaN}.
1454      * </p>
1455      * Infinite values in real or imaginary parts of the input may result in
1456      * infinite or NaN values returned in parts of the result.
1457      * <pre>
1458      *  Examples:
1459      *  <code>
1460      *   tanh(a &plusmn; INFINITY i) = NaN + NaN i
1461      *   tanh(&plusmn;INFINITY + bi) = &plusmn;1 + 0 i
1462      *   tanh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
1463      *   tanh(0 + (&pi;/2)i) = NaN + INFINITY i
1464      *  </code>
1465      * </pre>
1466      *
1467      * @return the hyperbolic tangent of {@code this}.
1468      */
1469     @Override
1470     public Complex tanh() {
1471         if (isNaN || Double.isInfinite(imaginary)) {
1472             return NaN;
1473         }
1474         if (real > 20.0) {
1475             return ONE;
1476         }
1477         if (real < -20.0) {
1478             return MINUS_ONE;
1479         }
1480         double real2 = 2.0 * real;
1481         final SinCos sc2i = FastMath.sinCos(2.0 * imaginary);
1482         double d = FastMath.cosh(real2) + sc2i.cos();
1483 
1484         return createComplex(FastMath.sinh(real2) / d, sc2i.sin() / d);
1485     }
1486 
1487 
1488 
1489     /**
1490      * Compute the argument of this complex number.
1491      * The argument is the angle phi between the positive real axis and
1492      * the point representing this number in the complex plane.
1493      * The value returned is between -PI (not inclusive)
1494      * and PI (inclusive), with negative values returned for numbers with
1495      * negative imaginary parts.
1496      * <p>
1497      * If either real or imaginary part (or both) is NaN, NaN is returned.
1498      * Infinite parts are handled as {@code Math.atan2} handles them,
1499      * essentially treating finite parts as zero in the presence of an
1500      * infinite coordinate and returning a multiple of pi/4 depending on
1501      * the signs of the infinite parts.
1502      * See the javadoc for {@code Math.atan2} for full details.
1503      *
1504      * @return the argument of {@code this}.
1505      */
1506     public double getArgument() {
1507         return FastMath.atan2(getImaginaryPart(), getRealPart());
1508     }
1509 
1510     /**
1511      * Computes the n-th roots of this complex number.
1512      * The nth roots are defined by the formula:
1513      * <pre>
1514      *  <code>
1515      *   z<sub>k</sub> = abs<sup>1/n</sup> (cos(phi + 2&pi;k/n) + i (sin(phi + 2&pi;k/n))
1516      *  </code>
1517      * </pre>
1518      * for <i>{@code k=0, 1, ..., n-1}</i>, where {@code abs} and {@code phi}
1519      * are respectively the {@link #abs() modulus} and
1520      * {@link #getArgument() argument} of this complex number.
1521      * <p>
1522      * If one or both parts of this complex number is NaN, a list with just
1523      * one element, {@link #NaN} is returned.
1524      * if neither part is NaN, but at least one part is infinite, the result
1525      * is a one-element list containing {@link #INF}.
1526      *
1527      * @param n Degree of root.
1528      * @return a List of all {@code n}-th roots of {@code this}.
1529      * @throws MathIllegalArgumentException if {@code n <= 0}.
1530      */
1531     public List<Complex> nthRoot(int n) throws MathIllegalArgumentException {
1532 
1533         if (n <= 0) {
1534             throw new MathIllegalArgumentException(LocalizedCoreFormats.CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N,
1535                                                    n);
1536         }
1537 
1538         final List<Complex> result = new ArrayList<>();
1539 
1540         if (isNaN) {
1541             result.add(NaN);
1542             return result;
1543         }
1544         if (isInfinite()) {
1545             result.add(INF);
1546             return result;
1547         }
1548 
1549         // nth root of abs -- faster / more accurate to use a solver here?
1550         final double nthRootOfAbs = FastMath.pow(FastMath.hypot(real, imaginary), 1.0 / n);
1551 
1552         // Compute nth roots of complex number with k = 0, 1, ... n-1
1553         final double nthPhi = getArgument() / n;
1554         final double slice = 2 * FastMath.PI / n;
1555         double innerPart = nthPhi;
1556         for (int k = 0; k < n ; k++) {
1557             // inner part
1558             final SinCos scInner = FastMath.sinCos(innerPart);
1559             final double realPart = nthRootOfAbs *  scInner.cos();
1560             final double imaginaryPart = nthRootOfAbs *  scInner.sin();
1561             result.add(createComplex(realPart, imaginaryPart));
1562             innerPart += slice;
1563         }
1564 
1565         return result;
1566     }
1567 
1568     /**
1569      * Create a complex number given the real and imaginary parts.
1570      *
1571      * @param realPart Real part.
1572      * @param imaginaryPart Imaginary part.
1573      * @return a new complex number instance.
1574      *
1575      * @see #valueOf(double, double)
1576      */
1577     protected Complex createComplex(double realPart,
1578                                     double imaginaryPart) {
1579         return new Complex(realPart, imaginaryPart);
1580     }
1581 
1582     /**
1583      * Create a complex number given the real and imaginary parts.
1584      *
1585      * @param realPart Real part.
1586      * @param imaginaryPart Imaginary part.
1587      * @return a Complex instance.
1588      */
1589     public static Complex valueOf(double realPart,
1590                                   double imaginaryPart) {
1591         if (Double.isNaN(realPart) ||
1592             Double.isNaN(imaginaryPart)) {
1593             return NaN;
1594         }
1595         return new Complex(realPart, imaginaryPart);
1596     }
1597 
1598     /**
1599      * Create a complex number given only the real part.
1600      *
1601      * @param realPart Real part.
1602      * @return a Complex instance.
1603      */
1604     public static Complex valueOf(double realPart) {
1605         if (Double.isNaN(realPart)) {
1606             return NaN;
1607         }
1608         return new Complex(realPart);
1609     }
1610 
1611     /** {@inheritDoc} */
1612     @Override
1613     public Complex newInstance(double realPart) {
1614         return valueOf(realPart);
1615     }
1616 
1617     /**
1618      * Resolve the transient fields in a deserialized Complex Object.
1619      * Subclasses will need to override {@link #createComplex} to
1620      * deserialize properly.
1621      *
1622      * @return A Complex instance with all fields resolved.
1623      */
1624     protected final Object readResolve() {
1625         return createComplex(real, imaginary);
1626     }
1627 
1628     /** {@inheritDoc} */
1629     @Override
1630     public ComplexField getField() {
1631         return ComplexField.getInstance();
1632     }
1633 
1634     /** {@inheritDoc} */
1635     @Override
1636     public String toString() {
1637         return "(" + real + ", " + imaginary + ")";
1638     }
1639 
1640     /** {@inheritDoc}
1641      * @since 1.7
1642      */
1643     @Override
1644     public Complex scalb(int n) {
1645         return createComplex(FastMath.scalb(real, n), FastMath.scalb(imaginary, n));
1646     }
1647 
1648     /** {@inheritDoc}
1649      */
1650     @Override
1651     public Complex ulp() {
1652         return createComplex(FastMath.ulp(real), FastMath.ulp(imaginary));
1653     }
1654 
1655     /** {@inheritDoc}
1656      * @since 1.7
1657      */
1658     @Override
1659     public Complex hypot(Complex y) {
1660         if (isInfinite() || y.isInfinite()) {
1661             return INF;
1662         } else if (isNaN() || y.isNaN()) {
1663             return NaN;
1664         } else {
1665             return square().add(y.square()).sqrt();
1666         }
1667     }
1668 
1669     /** {@inheritDoc}
1670      * @since 1.7
1671      */
1672     @Override
1673     public Complex linearCombination(final Complex[] a, final Complex[] b)
1674         throws MathIllegalArgumentException {
1675         final int n = 2 * a.length;
1676         final double[] realA      = new double[n];
1677         final double[] realB      = new double[n];
1678         final double[] imaginaryA = new double[n];
1679         final double[] imaginaryB = new double[n];
1680         for (int i = 0; i < a.length; ++i)  {
1681             final Complex ai = a[i];
1682             final Complex bi = b[i];
1683             realA[2 * i    ]      = +ai.real;
1684             realA[2 * i + 1]      = -ai.imaginary;
1685             realB[2 * i    ]      = +bi.real;
1686             realB[2 * i + 1]      = +bi.imaginary;
1687             imaginaryA[2 * i    ] = +ai.real;
1688             imaginaryA[2 * i + 1] = +ai.imaginary;
1689             imaginaryB[2 * i    ] = +bi.imaginary;
1690             imaginaryB[2 * i + 1] = +bi.real;
1691         }
1692         return createComplex(MathArrays.linearCombination(realA,  realB),
1693                              MathArrays.linearCombination(imaginaryA, imaginaryB));
1694     }
1695 
1696     /** {@inheritDoc}
1697      * @since 1.7
1698      */
1699     @Override
1700     public Complex linearCombination(final double[] a, final Complex[] b)
1701         throws MathIllegalArgumentException {
1702         final int n = a.length;
1703         final double[] realB      = new double[n];
1704         final double[] imaginaryB = new double[n];
1705         for (int i = 0; i < a.length; ++i)  {
1706             final Complex bi = b[i];
1707             realB[i]      = +bi.real;
1708             imaginaryB[i] = +bi.imaginary;
1709         }
1710         return createComplex(MathArrays.linearCombination(a,  realB),
1711                              MathArrays.linearCombination(a, imaginaryB));
1712     }
1713 
1714     /** {@inheritDoc}
1715      * @since 1.7
1716      */
1717     @Override
1718     public Complex linearCombination(final Complex a1, final Complex b1, final Complex a2, final Complex b2) {
1719         return createComplex(MathArrays.linearCombination(+a1.real, b1.real,
1720                                                           -a1.imaginary, b1.imaginary,
1721                                                           +a2.real, b2.real,
1722                                                           -a2.imaginary, b2.imaginary),
1723                              MathArrays.linearCombination(+a1.real, b1.imaginary,
1724                                                           +a1.imaginary, b1.real,
1725                                                           +a2.real, b2.imaginary,
1726                                                           +a2.imaginary, b2.real));
1727     }
1728 
1729     /** {@inheritDoc}
1730      * @since 1.7
1731      */
1732     @Override
1733     public Complex linearCombination(final double a1, final Complex b1, final double a2, final Complex b2) {
1734         return createComplex(MathArrays.linearCombination(a1, b1.real,
1735                                                           a2, b2.real),
1736                              MathArrays.linearCombination(a1, b1.imaginary,
1737                                                           a2, b2.imaginary));
1738     }
1739 
1740     /** {@inheritDoc}
1741      * @since 1.7
1742      */
1743     @Override
1744     public Complex linearCombination(final Complex a1, final Complex b1,
1745                                      final Complex a2, final Complex b2,
1746                                      final Complex a3, final Complex b3) {
1747         return linearCombination(new Complex[] { a1, a2, a3 },
1748                                  new Complex[] { b1, b2, b3 });
1749     }
1750 
1751     /** {@inheritDoc}
1752      * @since 1.7
1753      */
1754     @Override
1755     public Complex linearCombination(final double a1, final Complex b1,
1756                                      final double a2, final Complex b2,
1757                                      final double a3, final Complex b3) {
1758         return linearCombination(new double[]  { a1, a2, a3 },
1759                                  new Complex[] { b1, b2, b3 });
1760     }
1761 
1762     /** {@inheritDoc}
1763      * @since 1.7
1764      */
1765     @Override
1766     public Complex linearCombination(final Complex a1, final Complex b1,
1767                                      final Complex a2, final Complex b2,
1768                                      final Complex a3, final Complex b3,
1769                                      final Complex a4, final Complex b4) {
1770         return linearCombination(new Complex[] { a1, a2, a3, a4 },
1771                                  new Complex[] { b1, b2, b3, b4 });
1772     }
1773 
1774     /** {@inheritDoc}
1775      * @since 1.7
1776      */
1777     @Override
1778     public Complex linearCombination(final double a1, final Complex b1,
1779                                      final double a2, final Complex b2,
1780                                      final double a3, final Complex b3,
1781                                      final double a4, final Complex b4) {
1782         return linearCombination(new double[]  { a1, a2, a3, a4 },
1783                                  new Complex[] { b1, b2, b3, b4 });
1784     }
1785 
1786     /** {@inheritDoc} */
1787     @Override
1788     public Complex getPi() {
1789         return PI;
1790     }
1791 
1792     /** {@inheritDoc}
1793      * @since 1.7
1794      */
1795     @Override
1796     public Complex ceil() {
1797         return createComplex(FastMath.ceil(getRealPart()), FastMath.ceil(getImaginaryPart()));
1798     }
1799 
1800     /** {@inheritDoc}
1801      * @since 1.7
1802      */
1803     @Override
1804     public Complex floor() {
1805         return createComplex(FastMath.floor(getRealPart()), FastMath.floor(getImaginaryPart()));
1806     }
1807 
1808     /** {@inheritDoc}
1809      * @since 1.7
1810      */
1811     @Override
1812     public Complex rint() {
1813         return createComplex(FastMath.rint(getRealPart()), FastMath.rint(getImaginaryPart()));
1814     }
1815 
1816     /** {@inheritDoc}
1817      * <p>
1818      * for complex numbers, the integer n corresponding to {@code this.subtract(remainder(a)).divide(a)}
1819      * is a <a href="https://en.wikipedia.org/wiki/Gaussian_integer">Wikipedia - Gaussian integer</a>.
1820      * </p>
1821      * @since 1.7
1822      */
1823     @Override
1824     public Complex remainder(final double a) {
1825         return createComplex(FastMath.IEEEremainder(getRealPart(), a), FastMath.IEEEremainder(getImaginaryPart(), a));
1826     }
1827 
1828     /** {@inheritDoc}
1829      * <p>
1830      * for complex numbers, the integer n corresponding to {@code this.subtract(remainder(a)).divide(a)}
1831      * is a <a href="https://en.wikipedia.org/wiki/Gaussian_integer">Wikipedia - Gaussian integer</a>.
1832      * </p>
1833      * @since 1.7
1834      */
1835     @Override
1836     public Complex remainder(final Complex a) {
1837         final Complex complexQuotient = divide(a);
1838         final double  qRInt           = FastMath.rint(complexQuotient.real);
1839         final double  qIInt           = FastMath.rint(complexQuotient.imaginary);
1840         return createComplex(real - qRInt * a.real + qIInt * a.imaginary,
1841                              imaginary - qRInt * a.imaginary - qIInt * a.real);
1842     }
1843 
1844     /** {@inheritDoc}
1845      * @since 2.0
1846      */
1847     @Override
1848     public Complex sign() {
1849         if (isNaN() || isZero()) {
1850             return this;
1851         } else {
1852             return this.divide(FastMath.hypot(real, imaginary));
1853         }
1854     }
1855 
1856     /** {@inheritDoc}
1857      * <p>
1858      * The signs of real and imaginary parts are copied independently.
1859      * </p>
1860      * @since 1.7
1861      */
1862     @Override
1863     public Complex copySign(final Complex z) {
1864         return createComplex(FastMath.copySign(getRealPart(), z.getRealPart()),
1865                              FastMath.copySign(getImaginaryPart(), z.getImaginaryPart()));
1866     }
1867 
1868     /** {@inheritDoc}
1869      * @since 1.7
1870      */
1871     @Override
1872     public Complex copySign(double r) {
1873         return createComplex(FastMath.copySign(getRealPart(), r), FastMath.copySign(getImaginaryPart(), r));
1874     }
1875 
1876     /** {@inheritDoc} */
1877     @Override
1878     public Complex toDegrees() {
1879         return createComplex(FastMath.toDegrees(getRealPart()), FastMath.toDegrees(getImaginaryPart()));
1880     }
1881 
1882     /** {@inheritDoc} */
1883     @Override
1884     public Complex toRadians() {
1885         return createComplex(FastMath.toRadians(getRealPart()), FastMath.toRadians(getImaginaryPart()));
1886     }
1887 
1888     /** {@inheritDoc}
1889      * <p>
1890      * Comparison us performed using real ordering as the primary sort order and
1891      * imaginary ordering as the secondary sort order.
1892      * </p>
1893      * @since 3.0
1894      */
1895     @Override
1896     public int compareTo(final Complex o) {
1897         final int cR = Double.compare(getReal(), o.getReal());
1898         if (cR == 0) {
1899             return Double.compare(getImaginary(),o.getImaginary());
1900         } else {
1901             return cR;
1902         }
1903     }
1904 
1905 }