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     /**
510      * Access the real part.
511      *
512      * @return the real part.
513      * @since 2.0
514      */
515     public double getRealPart() {
516         return real;
517     }
518 
519     /**
520      * Checks whether either or both parts of this complex number is
521      * {@code NaN}.
522      *
523      * @return true if either or both parts of this complex number is
524      * {@code NaN}; false otherwise.
525      */
526     @Override
527     public boolean isNaN() {
528         return isNaN;
529     }
530 
531     /** Check whether the instance is real (i.e. imaginary part is zero).
532      * @return true if imaginary part is zero
533      * @since 1.7
534      */
535     public boolean isReal() {
536         return imaginary == 0.0;
537     }
538 
539     /** Check whether the instance is an integer (i.e. imaginary part is zero and real part has no fractional part).
540      * @return true if imaginary part is zero and real part has no fractional part
541      * @since 1.7
542      */
543     public boolean isMathematicalInteger() {
544         return isReal() && Precision.isMathematicalInteger(real);
545     }
546 
547     /**
548      * Checks whether either the real or imaginary part of this complex number
549      * takes an infinite value (either {@code Double.POSITIVE_INFINITY} or
550      * {@code Double.NEGATIVE_INFINITY}) and neither part
551      * is {@code NaN}.
552      *
553      * @return true if one or both parts of this complex number are infinite
554      * and neither part is {@code NaN}.
555      */
556     @Override
557     public boolean isInfinite() {
558         return isInfinite;
559     }
560 
561     /**
562      * Returns a {@code Complex} whose value is {@code this * factor}.
563      * Implements preliminary checks for {@code NaN} and infinity followed by
564      * the definitional formula:
565      * <p>
566      *   {@code (a + bi)(c + di) = (ac - bd) + (ad + bc)i}
567      * </p>
568      * Returns {@link #NaN} if either {@code this} or {@code factor} has one or
569      * more {@code NaN} parts.
570      * <p>
571      * Returns {@link #INF} if neither {@code this} nor {@code factor} has one
572      * or more {@code NaN} parts and if either {@code this} or {@code factor}
573      * has one or more infinite parts (same result is returned regardless of
574      * the sign of the components).
575      * </p><p>
576      * Returns finite values in components of the result per the definitional
577      * formula in all remaining cases.</p>
578      *
579      * @param  factor value to be multiplied by this {@code Complex}.
580      * @return {@code this * factor}.
581      * @throws NullArgumentException if {@code factor} is {@code null}.
582      */
583     @Override
584     public Complex multiply(Complex factor)
585         throws NullArgumentException {
586         MathUtils.checkNotNull(factor);
587         if (isNaN || factor.isNaN) {
588             return NaN;
589         }
590         if (Double.isInfinite(real) ||
591             Double.isInfinite(imaginary) ||
592             Double.isInfinite(factor.real) ||
593             Double.isInfinite(factor.imaginary)) {
594             // we don't use isInfinite() to avoid testing for NaN again
595             return INF;
596         }
597         return createComplex(MathArrays.linearCombination(real, factor.real, -imaginary, factor.imaginary),
598                              MathArrays.linearCombination(real, factor.imaginary, imaginary, factor.real));
599     }
600 
601     /**
602      * Returns a {@code Complex} whose value is {@code this * factor}, with {@code factor}
603      * interpreted as a integer number.
604      *
605      * @param  factor value to be multiplied by this {@code Complex}.
606      * @return {@code this * factor}.
607      * @see #multiply(Complex)
608      */
609     @Override
610     public Complex multiply(final int factor) {
611         if (isNaN) {
612             return NaN;
613         }
614         if (Double.isInfinite(real) ||
615             Double.isInfinite(imaginary)) {
616             return INF;
617         }
618         return createComplex(real * factor, imaginary * factor);
619     }
620 
621     /**
622      * Returns a {@code Complex} whose value is {@code this * factor}, with {@code factor}
623      * interpreted as a real number.
624      *
625      * @param  factor value to be multiplied by this {@code Complex}.
626      * @return {@code this * factor}.
627      * @see #multiply(Complex)
628      */
629     @Override
630     public Complex multiply(double factor) {
631         if (isNaN || Double.isNaN(factor)) {
632             return NaN;
633         }
634         if (Double.isInfinite(real) ||
635             Double.isInfinite(imaginary) ||
636             Double.isInfinite(factor)) {
637             // we don't use isInfinite() to avoid testing for NaN again
638             return INF;
639         }
640         return createComplex(real * factor, imaginary * factor);
641     }
642 
643     /** Compute this * i.
644      * @return this * i
645      * @since 2.0
646      */
647     public Complex multiplyPlusI() {
648         return createComplex(-imaginary, real);
649     }
650 
651     /** Compute this *- -i.
652      * @return this * i
653      * @since 2.0
654      */
655     public Complex multiplyMinusI() {
656         return createComplex(imaginary, -real);
657     }
658 
659     /** {@inheritDoc} */
660     @Override
661     public Complex square() {
662         return multiply(this);
663     }
664 
665     /**
666      * Returns a {@code Complex} whose value is {@code (-this)}.
667      * Returns {@code NaN} if either real or imaginary
668      * part of this Complex number is {@code Double.NaN}.
669      *
670      * @return {@code -this}.
671      */
672     @Override
673     public Complex negate() {
674         if (isNaN) {
675             return NaN;
676         }
677 
678         return createComplex(-real, -imaginary);
679     }
680 
681     /**
682      * Returns a {@code Complex} whose value is
683      * {@code (this - subtrahend)}.
684      * Uses the definitional formula
685      * <p>
686      *  {@code (a + bi) - (c + di) = (a-c) + (b-d)i}
687      * </p>
688      * If either {@code this} or {@code subtrahend} has a {@code NaN]} value in either part,
689      * {@link #NaN} is returned; otherwise infinite and {@code NaN} values are
690      * returned in the parts of the result according to the rules for
691      * {@link java.lang.Double} arithmetic.
692      *
693      * @param  subtrahend value to be subtracted from this {@code Complex}.
694      * @return {@code this - subtrahend}.
695      * @throws NullArgumentException if {@code subtrahend} is {@code null}.
696      */
697     @Override
698     public Complex subtract(Complex subtrahend)
699         throws NullArgumentException {
700         MathUtils.checkNotNull(subtrahend);
701         if (isNaN || subtrahend.isNaN) {
702             return NaN;
703         }
704 
705         return createComplex(real - subtrahend.getRealPart(),
706                              imaginary - subtrahend.getImaginaryPart());
707     }
708 
709     /**
710      * Returns a {@code Complex} whose value is
711      * {@code (this - subtrahend)}.
712      *
713      * @param  subtrahend value to be subtracted from this {@code Complex}.
714      * @return {@code this - subtrahend}.
715      * @see #subtract(Complex)
716      */
717     @Override
718     public Complex subtract(double subtrahend) {
719         if (isNaN || Double.isNaN(subtrahend)) {
720             return NaN;
721         }
722         return createComplex(real - subtrahend, imaginary);
723     }
724 
725     /**
726      * Compute the
727      * <a href="http://mathworld.wolfram.com/InverseCosine.html" TARGET="_top">
728      * inverse cosine</a> of this complex number.
729      * Implements the formula:
730      * <p>
731      *  {@code acos(z) = -i (log(z + i (sqrt(1 - z<sup>2</sup>))))}
732      * </p>
733      * Returns {@link Complex#NaN} if either real or imaginary part of the
734      * input argument is {@code NaN} or infinite.
735      *
736      * @return the inverse cosine of this complex number.
737      */
738     @Override
739     public Complex acos() {
740         if (isNaN) {
741             return NaN;
742         }
743 
744         return this.add(this.sqrt1z().multiplyPlusI()).log().multiplyMinusI();
745     }
746 
747     /**
748      * Compute the
749      * <a href="http://mathworld.wolfram.com/InverseSine.html" TARGET="_top">
750      * inverse sine</a> of this complex number.
751      * Implements the formula:
752      * <p>
753      *  {@code asin(z) = -i (log(sqrt(1 - z<sup>2</sup>) + iz))}
754      * </p><p>
755      * Returns {@link Complex#NaN} if either real or imaginary part of the
756      * input argument is {@code NaN} or infinite.</p>
757      *
758      * @return the inverse sine of this complex number.
759      */
760     @Override
761     public Complex asin() {
762         if (isNaN) {
763             return NaN;
764         }
765 
766         return sqrt1z().add(this.multiplyPlusI()).log().multiplyMinusI();
767     }
768 
769     /**
770      * Compute the
771      * <a href="http://mathworld.wolfram.com/InverseTangent.html" TARGET="_top">
772      * inverse tangent</a> of this complex number.
773      * Implements the formula:
774      * <p>
775      * {@code atan(z) = (i/2) log((1 - iz)/(1 + iz))}
776      * </p><p>
777      * Returns {@link Complex#NaN} if either real or imaginary part of the
778      * input argument is {@code NaN} or infinite.</p>
779      *
780      * @return the inverse tangent of this complex number
781      */
782     @Override
783     public Complex atan() {
784         if (isNaN) {
785             return NaN;
786         }
787 
788         if (real == 0.0) {
789 
790             // singularity at ±i
791             if (imaginary * imaginary - 1.0 == 0.0) {
792                 return NaN;
793             }
794 
795             // branch cut on imaginary axis
796             final Complex tmp = createComplex((1 + imaginary) / (1 - imaginary), 0.0).log().multiplyPlusI().multiply(0.5);
797             return createComplex(FastMath.copySign(tmp.real, real), tmp.imaginary);
798 
799         } else {
800             // regular formula
801             final Complex n = createComplex(1 + imaginary, -real);
802             final Complex d = createComplex(1 - imaginary,  real);
803             return n.divide(d).log().multiplyPlusI().multiply(0.5);
804         }
805 
806     }
807 
808     /**
809      * Compute the
810      * <a href="http://mathworld.wolfram.com/Cosine.html" TARGET="_top">
811      * cosine</a> of this complex number.
812      * Implements the formula:
813      * <p>
814      *  {@code cos(a + bi) = cos(a)cosh(b) - sin(a)sinh(b)i}
815      * </p><p>
816      * where the (real) functions on the right-hand side are
817      * {@link FastMath#sin}, {@link FastMath#cos},
818      * {@link FastMath#cosh} and {@link FastMath#sinh}.
819      * </p><p>
820      * Returns {@link Complex#NaN} if either real or imaginary part of the
821      * input argument is {@code NaN}.
822      * </p><p>
823      * Infinite values in real or imaginary parts of the input may result in
824      * infinite or NaN values returned in parts of the result.</p>
825      * <pre>
826      *  Examples:
827      *  <code>
828      *   cos(1 &plusmn; INFINITY i) = 1 \u2213 INFINITY i
829      *   cos(&plusmn;INFINITY + i) = NaN + NaN i
830      *   cos(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
831      *  </code>
832      * </pre>
833      *
834      * @return the cosine of this complex number.
835      */
836     @Override
837     public Complex cos() {
838         if (isNaN) {
839             return NaN;
840         }
841 
842         final SinCos   scr  = FastMath.sinCos(real);
843         final SinhCosh schi = FastMath.sinhCosh(imaginary);
844         return createComplex(scr.cos() * schi.cosh(), -scr.sin() * schi.sinh());
845     }
846 
847     /**
848      * Compute the
849      * <a href="http://mathworld.wolfram.com/HyperbolicCosine.html" TARGET="_top">
850      * hyperbolic cosine</a> of this complex number.
851      * Implements the formula:
852      * <pre>
853      *  <code>
854      *   cosh(a + bi) = cosh(a)cos(b) + sinh(a)sin(b)i
855      *  </code>
856      * </pre>
857      * where the (real) functions on the right-hand side are
858      * {@link FastMath#sin}, {@link FastMath#cos},
859      * {@link FastMath#cosh} and {@link FastMath#sinh}.
860      * <p>
861      * Returns {@link Complex#NaN} if either real or imaginary part of the
862      * input argument is {@code NaN}.
863      * </p>
864      * Infinite values in real or imaginary parts of the input may result in
865      * infinite or NaN values returned in parts of the result.
866      * <pre>
867      *  Examples:
868      *  <code>
869      *   cosh(1 &plusmn; INFINITY i) = NaN + NaN i
870      *   cosh(&plusmn;INFINITY + i) = INFINITY &plusmn; INFINITY i
871      *   cosh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
872      *  </code>
873      * </pre>
874      *
875      * @return the hyperbolic cosine of this complex number.
876      */
877     @Override
878     public Complex cosh() {
879         if (isNaN) {
880             return NaN;
881         }
882 
883         final SinhCosh schr = FastMath.sinhCosh(real);
884         final SinCos   sci  = FastMath.sinCos(imaginary);
885         return createComplex(schr.cosh() * sci.cos(), schr.sinh() * sci.sin());
886     }
887 
888     /**
889      * Compute the
890      * <a href="http://mathworld.wolfram.com/ExponentialFunction.html" TARGET="_top">
891      * exponential function</a> of this complex number.
892      * Implements the formula:
893      * <pre>
894      *  <code>
895      *   exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i
896      *  </code>
897      * </pre>
898      * where the (real) functions on the right-hand side are
899      * {@link FastMath#exp(double)} p}, {@link FastMath#cos(double)}, and
900      * {@link FastMath#sin(double)}.
901      * <p>
902      * Returns {@link Complex#NaN} if either real or imaginary part of the
903      * input argument is {@code NaN}.
904      * </p>
905      * Infinite values in real or imaginary parts of the input may result in
906      * infinite or NaN values returned in parts of the result.
907      * <pre>
908      *  Examples:
909      *  <code>
910      *   exp(1 &plusmn; INFINITY i) = NaN + NaN i
911      *   exp(INFINITY + i) = INFINITY + INFINITY i
912      *   exp(-INFINITY + i) = 0 + 0i
913      *   exp(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
914      *  </code>
915      * </pre>
916      *
917      * @return <code><i>e</i><sup>this</sup></code>.
918      */
919     @Override
920     public Complex exp() {
921         if (isNaN) {
922             return NaN;
923         }
924 
925         final double expReal = FastMath.exp(real);
926         final SinCos sc      = FastMath.sinCos(imaginary);
927         return createComplex(expReal * sc.cos(), expReal * sc.sin());
928     }
929 
930     /** {@inheritDoc}
931      * @since 1.7
932      */
933     @Override
934     public Complex expm1() {
935         if (isNaN) {
936             return NaN;
937         }
938 
939         final double expm1Real = FastMath.expm1(real);
940         final SinCos sc        = FastMath.sinCos(imaginary);
941         return createComplex(expm1Real * sc.cos(), expm1Real * sc.sin());
942     }
943 
944     /**
945      * Compute the
946      * <a href="http://mathworld.wolfram.com/NaturalLogarithm.html" TARGET="_top">
947      * natural logarithm</a> of this complex number.
948      * Implements the formula:
949      * <pre>
950      *  <code>
951      *   log(a + bi) = ln(|a + bi|) + arg(a + bi)i
952      *  </code>
953      * </pre>
954      * where ln on the right hand side is {@link FastMath#log(double)},
955      * {@code |a + bi|} is the modulus, {@link Complex#abs},  and
956      * {@code arg(a + bi) = }{@link FastMath#atan2}(b, a).
957      * <p>
958      * Returns {@link Complex#NaN} if either real or imaginary part of the
959      * input argument is {@code NaN}.
960      * </p>
961      * Infinite (or critical) values in real or imaginary parts of the input may
962      * result in infinite or NaN values returned in parts of the result.
963      * <pre>
964      *  Examples:
965      *  <code>
966      *   log(1 &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;/2)i
967      *   log(INFINITY + i) = INFINITY + 0i
968      *   log(-INFINITY + i) = INFINITY + &pi;i
969      *   log(INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;/4)i
970      *   log(-INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (3&pi;/4)i
971      *   log(0 + 0i) = -INFINITY + 0i
972      *  </code>
973      * </pre>
974      *
975      * @return the value <code>ln &nbsp; this</code>, the natural logarithm
976      * of {@code this}.
977      */
978     @Override
979     public Complex log() {
980         if (isNaN) {
981             return NaN;
982         }
983 
984         return createComplex(FastMath.log(FastMath.hypot(real, imaginary)),
985                              FastMath.atan2(imaginary, real));
986     }
987 
988     /** {@inheritDoc}
989      * @since 1.7
990      */
991     @Override
992     public Complex log1p() {
993         return add(1.0).log();
994     }
995 
996     /** {@inheritDoc}
997      * @since 1.7
998      */
999     @Override
1000     public Complex log10() {
1001         return log().divide(LOG10);
1002     }
1003 
1004     /**
1005      * Returns of value of this complex number raised to the power of {@code x}.
1006      * <p>
1007      * If {@code x} is a real number whose real part has an integer value, returns {@link #pow(int)},
1008      * if both {@code this} and {@code x} are real and {@link FastMath#pow(double, double)}
1009      * with the corresponding real arguments would return a finite number (neither NaN
1010      * nor infinite), then returns the same value converted to {@code Complex},
1011      * with the same special cases.
1012      * In all other cases real cases, implements y<sup>x</sup> = exp(x&middot;log(y)).
1013      * </p>
1014      *
1015      * @param  x exponent to which this {@code Complex} is to be raised.
1016      * @return <code> this<sup>x</sup></code>.
1017      * @throws NullArgumentException if x is {@code null}.
1018      */
1019     @Override
1020     public Complex pow(Complex x)
1021         throws NullArgumentException {
1022 
1023         MathUtils.checkNotNull(x);
1024 
1025         if (x.imaginary == 0.0) {
1026             final int nx = (int) FastMath.rint(x.real);
1027             if (x.real == nx) {
1028                 // integer power
1029                 return pow(nx);
1030             } else if (this.imaginary == 0.0) {
1031                 // check real implementation that handles a bunch of special cases
1032                 final double realPow = FastMath.pow(this.real, x.real);
1033                 if (Double.isFinite(realPow)) {
1034                     return createComplex(realPow, 0);
1035                 }
1036             }
1037         }
1038 
1039         // generic implementation
1040         return this.log().multiply(x).exp();
1041 
1042     }
1043 
1044 
1045     /**
1046      * Returns of value of this complex number raised to the power of {@code x}.
1047      * <p>
1048      * If {@code x} has an integer value, returns {@link #pow(int)},
1049      * if {@code this} is real and {@link FastMath#pow(double, double)}
1050      * with the corresponding real arguments would return a finite number (neither NaN
1051      * nor infinite), then returns the same value converted to {@code Complex},
1052      * with the same special cases.
1053      * In all other cases real cases, implements y<sup>x</sup> = exp(x&middot;log(y)).
1054      * </p>
1055      *
1056      * @param  x exponent to which this {@code Complex} is to be raised.
1057      * @return <code> this<sup>x</sup></code>.
1058      */
1059     @Override
1060     public Complex pow(double x) {
1061 
1062         final int nx = (int) FastMath.rint(x);
1063         if (x == nx) {
1064             // integer power
1065             return pow(nx);
1066         } else if (this.imaginary == 0.0) {
1067             // check real implementation that handles a bunch of special cases
1068             final double realPow = FastMath.pow(this.real, x);
1069             if (Double.isFinite(realPow)) {
1070                 return createComplex(realPow, 0);
1071             }
1072         }
1073 
1074         // generic implementation
1075         return this.log().multiply(x).exp();
1076 
1077     }
1078 
1079      /** {@inheritDoc}
1080       * @since 1.7
1081       */
1082     @Override
1083     public Complex pow(final int n) {
1084 
1085         Complex result = ONE;
1086         final boolean invert;
1087         int p = n;
1088         if (p < 0) {
1089             invert = true;
1090             p = -p;
1091         } else {
1092             invert = false;
1093         }
1094 
1095         // Exponentiate by successive squaring
1096         Complex square = this;
1097         while (p > 0) {
1098             if ((p & 0x1) > 0) {
1099                 result = result.multiply(square);
1100             }
1101             square = square.multiply(square);
1102             p = p >> 1;
1103         }
1104 
1105         return invert ? result.reciprocal() : result;
1106 
1107     }
1108 
1109      /**
1110       * Compute the
1111      * <a href="http://mathworld.wolfram.com/Sine.html" TARGET="_top">
1112      * sine</a>
1113      * of this complex number.
1114      * Implements the formula:
1115      * <pre>
1116      *  <code>
1117      *   sin(a + bi) = sin(a)cosh(b) + cos(a)sinh(b)i
1118      *  </code>
1119      * </pre>
1120      * where the (real) functions on the right-hand side are
1121      * {@link FastMath#sin}, {@link FastMath#cos},
1122      * {@link FastMath#cosh} and {@link FastMath#sinh}.
1123      * <p>
1124      * Returns {@link Complex#NaN} if either real or imaginary part of the
1125      * input argument is {@code NaN}.
1126      * </p><p>
1127      * Infinite values in real or imaginary parts of the input may result in
1128      * infinite or {@code NaN} values returned in parts of the result.
1129      * <pre>
1130      *  Examples:
1131      *  <code>
1132      *   sin(1 &plusmn; INFINITY i) = 1 &plusmn; INFINITY i
1133      *   sin(&plusmn;INFINITY + i) = NaN + NaN i
1134      *   sin(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
1135      *  </code>
1136      * </pre>
1137      *
1138      * @return the sine of this complex number.
1139      */
1140     @Override
1141     public Complex sin() {
1142         if (isNaN) {
1143             return NaN;
1144         }
1145 
1146         final SinCos   scr  = FastMath.sinCos(real);
1147         final SinhCosh schi = FastMath.sinhCosh(imaginary);
1148         return createComplex(scr.sin() * schi.cosh(), scr.cos() * schi.sinh());
1149 
1150     }
1151 
1152     /** {@inheritDoc}
1153      */
1154     @Override
1155     public FieldSinCos<Complex> sinCos() {
1156         if (isNaN) {
1157             return new FieldSinCos<>(NaN, NaN);
1158         }
1159 
1160         final SinCos scr = FastMath.sinCos(real);
1161         final SinhCosh schi = FastMath.sinhCosh(imaginary);
1162         return new FieldSinCos<>(createComplex(scr.sin() * schi.cosh(),  scr.cos() * schi.sinh()),
1163                                  createComplex(scr.cos() * schi.cosh(), -scr.sin() * schi.sinh()));
1164     }
1165 
1166     /** {@inheritDoc}
1167      * @since 1.7
1168      */
1169     @Override
1170     public Complex atan2(Complex x) {
1171 
1172         // compute r = sqrt(x^2+y^2)
1173         final Complex r = x.square().add(multiply(this)).sqrt();
1174 
1175         if (FastMath.copySign(1.0, x.real) >= 0) {
1176             // compute atan2(y, x) = 2 atan(y / (r + x))
1177             return divide(r.add(x)).atan().multiply(2);
1178         } else {
1179             // compute atan2(y, x) = +/- pi - 2 atan(y / (r - x))
1180             return divide(r.subtract(x)).atan().multiply(-2).add(FastMath.PI);
1181         }
1182     }
1183 
1184     /** {@inheritDoc}
1185      * <p>
1186      * Branch cuts are on the real axis, below +1.
1187      * </p>
1188      * @since 1.7
1189      */
1190     @Override
1191     public Complex acosh() {
1192         final Complex sqrtPlus  = add(1).sqrt();
1193         final Complex sqrtMinus = subtract(1).sqrt();
1194         return add(sqrtPlus.multiply(sqrtMinus)).log();
1195     }
1196 
1197     /** {@inheritDoc}
1198      * <p>
1199      * Branch cuts are on the imaginary axis, above +i and below -i.
1200      * </p>
1201      * @since 1.7
1202      */
1203     @Override
1204     public Complex asinh() {
1205         return add(multiply(this).add(1.0).sqrt()).log();
1206     }
1207 
1208     /** {@inheritDoc}
1209      * <p>
1210      * Branch cuts are on the real axis, above +1 and below -1.
1211      * </p>
1212      * @since 1.7
1213      */
1214     @Override
1215     public Complex atanh() {
1216         final Complex logPlus  = add(1).log();
1217         final Complex logMinus = createComplex(1 - real, -imaginary).log();
1218         return logPlus.subtract(logMinus).multiply(0.5);
1219     }
1220 
1221     /**
1222      * Compute the
1223      * <a href="http://mathworld.wolfram.com/HyperbolicSine.html" TARGET="_top">
1224      * hyperbolic sine</a> of this complex number.
1225      * Implements the formula:
1226      * <pre>
1227      *  <code>
1228      *   sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i
1229      *  </code>
1230      * </pre>
1231      * where the (real) functions on the right-hand side are
1232      * {@link FastMath#sin}, {@link FastMath#cos},
1233      * {@link FastMath#cosh} and {@link FastMath#sinh}.
1234      * <p>
1235      * Returns {@link Complex#NaN} if either real or imaginary part of the
1236      * input argument is {@code NaN}.
1237      * </p><p>
1238      * Infinite values in real or imaginary parts of the input may result in
1239      * infinite or NaN values returned in parts of the result.
1240      * <pre>
1241      *  Examples:
1242      *  <code>
1243      *   sinh(1 &plusmn; INFINITY i) = NaN + NaN i
1244      *   sinh(&plusmn;INFINITY + i) = &plusmn; INFINITY + INFINITY i
1245      *   sinh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
1246      *  </code>
1247      * </pre>
1248      *
1249      * @return the hyperbolic sine of {@code this}.
1250      */
1251     @Override
1252     public Complex sinh() {
1253         if (isNaN) {
1254             return NaN;
1255         }
1256 
1257         final SinhCosh schr = FastMath.sinhCosh(real);
1258         final SinCos   sci  = FastMath.sinCos(imaginary);
1259         return createComplex(schr.sinh() * sci.cos(), schr.cosh() * sci.sin());
1260     }
1261 
1262     /** {@inheritDoc}
1263      */
1264     @Override
1265     public FieldSinhCosh<Complex> sinhCosh() {
1266         if (isNaN) {
1267             return new FieldSinhCosh<>(NaN, NaN);
1268         }
1269 
1270         final SinhCosh schr = FastMath.sinhCosh(real);
1271         final SinCos   sci  = FastMath.sinCos(imaginary);
1272         return new FieldSinhCosh<>(createComplex(schr.sinh() * sci.cos(), schr.cosh() * sci.sin()),
1273                                    createComplex(schr.cosh() * sci.cos(), schr.sinh() * sci.sin()));
1274     }
1275 
1276     /**
1277      * Compute the
1278      * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
1279      * square root</a> of this complex number.
1280      * Implements the following algorithm to compute {@code sqrt(a + bi)}:
1281      * <ol><li>Let {@code t = sqrt((|a| + |a + bi|) / 2)}</li>
1282      * <li><pre>if {@code  a ≥ 0} return {@code t + (b/2t)i}
1283      *  else return {@code |b|/2t + sign(b)t i }</pre></li>
1284      * </ol>
1285      * where <ul>
1286      * <li>{@code |a| = }{@link FastMath#abs(double) abs(a)}</li>
1287      * <li>{@code |a + bi| = }{@link FastMath#hypot(double, double) hypot(a, b)}</li>
1288      * <li>{@code sign(b) = }{@link FastMath#copySign(double, double) copySign(1, b)}
1289      * </ul>
1290      * The real part is therefore always nonnegative.
1291      * <p>
1292      * Returns {@link Complex#NaN} if either real or imaginary part of the
1293      * input argument is {@code NaN}.
1294      * </p>
1295      * <p>
1296      * Infinite values in real or imaginary parts of the input may result in
1297      * infinite or NaN values returned in parts of the result.
1298      * </p>
1299      * <pre>
1300      *  Examples:
1301      *  <code>
1302      *   sqrt(1 ± ∞ i) = ∞ + NaN i
1303      *   sqrt(∞ + i) = ∞ + 0i
1304      *   sqrt(-∞ + i) = 0 + ∞ i
1305      *   sqrt(∞ ± ∞ i) = ∞ + NaN i
1306      *   sqrt(-∞ ± ∞ i) = NaN ± ∞ i
1307      *  </code>
1308      * </pre>
1309      *
1310      * @return the square root of {@code this} with nonnegative real part.
1311      */
1312     @Override
1313     public Complex sqrt() {
1314         if (isNaN) {
1315             return NaN;
1316         }
1317 
1318         if (real == 0.0 && imaginary == 0.0) {
1319             return ZERO;
1320         }
1321 
1322         double t = FastMath.sqrt((FastMath.abs(real) + FastMath.hypot(real, imaginary)) * 0.5);
1323         if (FastMath.copySign(1, real) >= 0.0) {
1324             return createComplex(t, imaginary / (2.0 * t));
1325         } else {
1326             return createComplex(FastMath.abs(imaginary) / (2.0 * t),
1327                                  FastMath.copySign(t, imaginary));
1328         }
1329     }
1330 
1331     /**
1332      * Compute the
1333      * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
1334      * square root</a> of <code>1 - this<sup>2</sup></code> for this complex
1335      * number.
1336      * Computes the result directly as
1337      * {@code sqrt(ONE.subtract(z.square()))}.
1338      * <p>
1339      * Returns {@link Complex#NaN} if either real or imaginary part of the
1340      * input argument is {@code NaN}.
1341      * </p>
1342      * Infinite values in real or imaginary parts of the input may result in
1343      * infinite or NaN values returned in parts of the result.
1344      *
1345      * @return the square root of <code>1 - this<sup>2</sup></code>.
1346      */
1347     public Complex sqrt1z() {
1348         final Complex t2 = this.square();
1349         return createComplex(1 - t2.real, -t2.imaginary).sqrt();
1350     }
1351 
1352     /** {@inheritDoc}
1353      * <p>
1354      * This implementation compute the principal cube root by using a branch cut along real negative axis.
1355      * </p>
1356      * @since 1.7
1357      */
1358     @Override
1359     public Complex cbrt() {
1360         final double magnitude = FastMath.cbrt(norm());
1361         final SinCos sc        = FastMath.sinCos(getArgument() / 3);
1362         return createComplex(magnitude * sc.cos(), magnitude * sc.sin());
1363     }
1364 
1365     /** {@inheritDoc}
1366      * <p>
1367      * This implementation compute the principal n<sup>th</sup> root by using a branch cut along real negative axis.
1368      * </p>
1369      * @since 1.7
1370      */
1371     @Override
1372     public Complex rootN(int n) {
1373         final double magnitude = FastMath.pow(norm(), 1.0 / n);
1374         final SinCos sc        = FastMath.sinCos(getArgument() / n);
1375         return createComplex(magnitude * sc.cos(), magnitude * sc.sin());
1376     }
1377 
1378     /**
1379      * Compute the
1380      * <a href="http://mathworld.wolfram.com/Tangent.html" TARGET="_top">
1381      * tangent</a> of this complex number.
1382      * Implements the formula:
1383      * <pre>
1384      *  <code>
1385      *   tan(a + bi) = sin(2a)/(cos(2a)+cosh(2b)) + [sinh(2b)/(cos(2a)+cosh(2b))]i
1386      *  </code>
1387      * </pre>
1388      * where the (real) functions on the right-hand side are
1389      * {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and
1390      * {@link FastMath#sinh}.
1391      * <p>
1392      * Returns {@link Complex#NaN} if either real or imaginary part of the
1393      * input argument is {@code NaN}.
1394      * </p>
1395      * Infinite (or critical) values in real or imaginary parts of the input may
1396      * result in infinite or NaN values returned in parts of the result.
1397      * <pre>
1398      *  Examples:
1399      *  <code>
1400      *   tan(a &plusmn; INFINITY i) = 0 &plusmn; i
1401      *   tan(&plusmn;INFINITY + bi) = NaN + NaN i
1402      *   tan(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
1403      *   tan(&plusmn;&pi;/2 + 0 i) = &plusmn;INFINITY + NaN i
1404      *  </code>
1405      * </pre>
1406      *
1407      * @return the tangent of {@code this}.
1408      */
1409     @Override
1410     public Complex tan() {
1411         if (isNaN || Double.isInfinite(real)) {
1412             return NaN;
1413         }
1414         if (imaginary > 20.0) {
1415             return I;
1416         }
1417         if (imaginary < -20.0) {
1418             return MINUS_I;
1419         }
1420 
1421         final SinCos sc2r = FastMath.sinCos(2.0 * real);
1422         double imaginary2 = 2.0 * imaginary;
1423         double d = sc2r.cos() + FastMath.cosh(imaginary2);
1424 
1425         return createComplex(sc2r.sin() / d, FastMath.sinh(imaginary2) / d);
1426 
1427     }
1428 
1429     /**
1430      * Compute the
1431      * <a href="http://mathworld.wolfram.com/HyperbolicTangent.html" TARGET="_top">
1432      * hyperbolic tangent</a> of this complex number.
1433      * Implements the formula:
1434      * <pre>
1435      *  <code>
1436      *   tan(a + bi) = sinh(2a)/(cosh(2a)+cos(2b)) + [sin(2b)/(cosh(2a)+cos(2b))]i
1437      *  </code>
1438      * </pre>
1439      * where the (real) functions on the right-hand side are
1440      * {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and
1441      * {@link FastMath#sinh}.
1442      * <p>
1443      * Returns {@link Complex#NaN} if either real or imaginary part of the
1444      * input argument is {@code NaN}.
1445      * </p>
1446      * Infinite values in real or imaginary parts of the input may result in
1447      * infinite or NaN values returned in parts of the result.
1448      * <pre>
1449      *  Examples:
1450      *  <code>
1451      *   tanh(a &plusmn; INFINITY i) = NaN + NaN i
1452      *   tanh(&plusmn;INFINITY + bi) = &plusmn;1 + 0 i
1453      *   tanh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
1454      *   tanh(0 + (&pi;/2)i) = NaN + INFINITY i
1455      *  </code>
1456      * </pre>
1457      *
1458      * @return the hyperbolic tangent of {@code this}.
1459      */
1460     @Override
1461     public Complex tanh() {
1462         if (isNaN || Double.isInfinite(imaginary)) {
1463             return NaN;
1464         }
1465         if (real > 20.0) {
1466             return ONE;
1467         }
1468         if (real < -20.0) {
1469             return MINUS_ONE;
1470         }
1471         double real2 = 2.0 * real;
1472         final SinCos sc2i = FastMath.sinCos(2.0 * imaginary);
1473         double d = FastMath.cosh(real2) + sc2i.cos();
1474 
1475         return createComplex(FastMath.sinh(real2) / d, sc2i.sin() / d);
1476     }
1477 
1478 
1479 
1480     /**
1481      * Compute the argument of this complex number.
1482      * The argument is the angle phi between the positive real axis and
1483      * the point representing this number in the complex plane.
1484      * The value returned is between -PI (not inclusive)
1485      * and PI (inclusive), with negative values returned for numbers with
1486      * negative imaginary parts.
1487      * <p>
1488      * If either real or imaginary part (or both) is NaN, NaN is returned.
1489      * Infinite parts are handled as {@code Math.atan2} handles them,
1490      * essentially treating finite parts as zero in the presence of an
1491      * infinite coordinate and returning a multiple of pi/4 depending on
1492      * the signs of the infinite parts.
1493      * See the javadoc for {@code Math.atan2} for full details.
1494      *
1495      * @return the argument of {@code this}.
1496      */
1497     public double getArgument() {
1498         return FastMath.atan2(getImaginaryPart(), getRealPart());
1499     }
1500 
1501     /**
1502      * Computes the n-th roots of this complex number.
1503      * The nth roots are defined by the formula:
1504      * <pre>
1505      *  <code>
1506      *   z<sub>k</sub> = abs<sup>1/n</sup> (cos(phi + 2&pi;k/n) + i (sin(phi + 2&pi;k/n))
1507      *  </code>
1508      * </pre>
1509      * for <i>{@code k=0, 1, ..., n-1}</i>, where {@code abs} and {@code phi}
1510      * are respectively the {@link #abs() modulus} and
1511      * {@link #getArgument() argument} of this complex number.
1512      * <p>
1513      * If one or both parts of this complex number is NaN, a list with just
1514      * one element, {@link #NaN} is returned.
1515      * if neither part is NaN, but at least one part is infinite, the result
1516      * is a one-element list containing {@link #INF}.
1517      *
1518      * @param n Degree of root.
1519      * @return a List of all {@code n}-th roots of {@code this}.
1520      * @throws MathIllegalArgumentException if {@code n <= 0}.
1521      */
1522     public List<Complex> nthRoot(int n) throws MathIllegalArgumentException {
1523 
1524         if (n <= 0) {
1525             throw new MathIllegalArgumentException(LocalizedCoreFormats.CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N,
1526                                                    n);
1527         }
1528 
1529         final List<Complex> result = new ArrayList<>();
1530 
1531         if (isNaN) {
1532             result.add(NaN);
1533             return result;
1534         }
1535         if (isInfinite()) {
1536             result.add(INF);
1537             return result;
1538         }
1539 
1540         // nth root of abs -- faster / more accurate to use a solver here?
1541         final double nthRootOfAbs = FastMath.pow(FastMath.hypot(real, imaginary), 1.0 / n);
1542 
1543         // Compute nth roots of complex number with k = 0, 1, ... n-1
1544         final double nthPhi = getArgument() / n;
1545         final double slice = 2 * FastMath.PI / n;
1546         double innerPart = nthPhi;
1547         for (int k = 0; k < n ; k++) {
1548             // inner part
1549             final SinCos scInner = FastMath.sinCos(innerPart);
1550             final double realPart = nthRootOfAbs *  scInner.cos();
1551             final double imaginaryPart = nthRootOfAbs *  scInner.sin();
1552             result.add(createComplex(realPart, imaginaryPart));
1553             innerPart += slice;
1554         }
1555 
1556         return result;
1557     }
1558 
1559     /**
1560      * Create a complex number given the real and imaginary parts.
1561      *
1562      * @param realPart Real part.
1563      * @param imaginaryPart Imaginary part.
1564      * @return a new complex number instance.
1565      *
1566      * @see #valueOf(double, double)
1567      */
1568     protected Complex createComplex(double realPart,
1569                                     double imaginaryPart) {
1570         return new Complex(realPart, imaginaryPart);
1571     }
1572 
1573     /**
1574      * Create a complex number given the real and imaginary parts.
1575      *
1576      * @param realPart Real part.
1577      * @param imaginaryPart Imaginary part.
1578      * @return a Complex instance.
1579      */
1580     public static Complex valueOf(double realPart,
1581                                   double imaginaryPart) {
1582         if (Double.isNaN(realPart) ||
1583             Double.isNaN(imaginaryPart)) {
1584             return NaN;
1585         }
1586         return new Complex(realPart, imaginaryPart);
1587     }
1588 
1589     /**
1590      * Create a complex number given only the real part.
1591      *
1592      * @param realPart Real part.
1593      * @return a Complex instance.
1594      */
1595     public static Complex valueOf(double realPart) {
1596         if (Double.isNaN(realPart)) {
1597             return NaN;
1598         }
1599         return new Complex(realPart);
1600     }
1601 
1602     /** {@inheritDoc} */
1603     @Override
1604     public Complex newInstance(double realPart) {
1605         return valueOf(realPart);
1606     }
1607 
1608     /**
1609      * Resolve the transient fields in a deserialized Complex Object.
1610      * Subclasses will need to override {@link #createComplex} to
1611      * deserialize properly.
1612      *
1613      * @return A Complex instance with all fields resolved.
1614      */
1615     protected final Object readResolve() {
1616         return createComplex(real, imaginary);
1617     }
1618 
1619     /** {@inheritDoc} */
1620     @Override
1621     public ComplexField getField() {
1622         return ComplexField.getInstance();
1623     }
1624 
1625     /** {@inheritDoc} */
1626     @Override
1627     public String toString() {
1628         return "(" + real + ", " + imaginary + ")";
1629     }
1630 
1631     /** {@inheritDoc}
1632      * @since 1.7
1633      */
1634     @Override
1635     public Complex scalb(int n) {
1636         return createComplex(FastMath.scalb(real, n), FastMath.scalb(imaginary, n));
1637     }
1638 
1639     /** {@inheritDoc}
1640      */
1641     @Override
1642     public Complex ulp() {
1643         return createComplex(FastMath.ulp(real), FastMath.ulp(imaginary));
1644     }
1645 
1646     /** {@inheritDoc}
1647      * @since 1.7
1648      */
1649     @Override
1650     public Complex hypot(Complex y) {
1651         if (isInfinite() || y.isInfinite()) {
1652             return INF;
1653         } else if (isNaN() || y.isNaN()) {
1654             return NaN;
1655         } else {
1656             return square().add(y.square()).sqrt();
1657         }
1658     }
1659 
1660     /** {@inheritDoc}
1661      * @since 1.7
1662      */
1663     @Override
1664     public Complex linearCombination(final Complex[] a, final Complex[] b)
1665         throws MathIllegalArgumentException {
1666         final int n = 2 * a.length;
1667         final double[] realA      = new double[n];
1668         final double[] realB      = new double[n];
1669         final double[] imaginaryA = new double[n];
1670         final double[] imaginaryB = new double[n];
1671         for (int i = 0; i < a.length; ++i)  {
1672             final Complex ai = a[i];
1673             final Complex bi = b[i];
1674             realA[2 * i    ]      = +ai.real;
1675             realA[2 * i + 1]      = -ai.imaginary;
1676             realB[2 * i    ]      = +bi.real;
1677             realB[2 * i + 1]      = +bi.imaginary;
1678             imaginaryA[2 * i    ] = +ai.real;
1679             imaginaryA[2 * i + 1] = +ai.imaginary;
1680             imaginaryB[2 * i    ] = +bi.imaginary;
1681             imaginaryB[2 * i + 1] = +bi.real;
1682         }
1683         return createComplex(MathArrays.linearCombination(realA,  realB),
1684                              MathArrays.linearCombination(imaginaryA, imaginaryB));
1685     }
1686 
1687     /** {@inheritDoc}
1688      * @since 1.7
1689      */
1690     @Override
1691     public Complex linearCombination(final double[] a, final Complex[] b)
1692         throws MathIllegalArgumentException {
1693         final int n = a.length;
1694         final double[] realB      = new double[n];
1695         final double[] imaginaryB = new double[n];
1696         for (int i = 0; i < a.length; ++i)  {
1697             final Complex bi = b[i];
1698             realB[i]      = +bi.real;
1699             imaginaryB[i] = +bi.imaginary;
1700         }
1701         return createComplex(MathArrays.linearCombination(a,  realB),
1702                              MathArrays.linearCombination(a, imaginaryB));
1703     }
1704 
1705     /** {@inheritDoc}
1706      * @since 1.7
1707      */
1708     @Override
1709     public Complex linearCombination(final Complex a1, final Complex b1, final Complex a2, final Complex b2) {
1710         return createComplex(MathArrays.linearCombination(+a1.real, b1.real,
1711                                                           -a1.imaginary, b1.imaginary,
1712                                                           +a2.real, b2.real,
1713                                                           -a2.imaginary, b2.imaginary),
1714                              MathArrays.linearCombination(+a1.real, b1.imaginary,
1715                                                           +a1.imaginary, b1.real,
1716                                                           +a2.real, b2.imaginary,
1717                                                           +a2.imaginary, b2.real));
1718     }
1719 
1720     /** {@inheritDoc}
1721      * @since 1.7
1722      */
1723     @Override
1724     public Complex linearCombination(final double a1, final Complex b1, final double a2, final Complex b2) {
1725         return createComplex(MathArrays.linearCombination(a1, b1.real,
1726                                                           a2, b2.real),
1727                              MathArrays.linearCombination(a1, b1.imaginary,
1728                                                           a2, b2.imaginary));
1729     }
1730 
1731     /** {@inheritDoc}
1732      * @since 1.7
1733      */
1734     @Override
1735     public Complex linearCombination(final Complex a1, final Complex b1,
1736                                      final Complex a2, final Complex b2,
1737                                      final Complex a3, final Complex b3) {
1738         return linearCombination(new Complex[] { a1, a2, a3 },
1739                                  new Complex[] { b1, b2, b3 });
1740     }
1741 
1742     /** {@inheritDoc}
1743      * @since 1.7
1744      */
1745     @Override
1746     public Complex linearCombination(final double a1, final Complex b1,
1747                                      final double a2, final Complex b2,
1748                                      final double a3, final Complex b3) {
1749         return linearCombination(new double[]  { a1, a2, a3 },
1750                                  new Complex[] { b1, b2, b3 });
1751     }
1752 
1753     /** {@inheritDoc}
1754      * @since 1.7
1755      */
1756     @Override
1757     public Complex linearCombination(final Complex a1, final Complex b1,
1758                                      final Complex a2, final Complex b2,
1759                                      final Complex a3, final Complex b3,
1760                                      final Complex a4, final Complex b4) {
1761         return linearCombination(new Complex[] { a1, a2, a3, a4 },
1762                                  new Complex[] { b1, b2, b3, b4 });
1763     }
1764 
1765     /** {@inheritDoc}
1766      * @since 1.7
1767      */
1768     @Override
1769     public Complex linearCombination(final double a1, final Complex b1,
1770                                      final double a2, final Complex b2,
1771                                      final double a3, final Complex b3,
1772                                      final double a4, final Complex b4) {
1773         return linearCombination(new double[]  { a1, a2, a3, a4 },
1774                                  new Complex[] { b1, b2, b3, b4 });
1775     }
1776 
1777     /** {@inheritDoc} */
1778     @Override
1779     public Complex getPi() {
1780         return PI;
1781     }
1782 
1783     /** {@inheritDoc}
1784      * @since 1.7
1785      */
1786     @Override
1787     public Complex ceil() {
1788         return createComplex(FastMath.ceil(getRealPart()), FastMath.ceil(getImaginaryPart()));
1789     }
1790 
1791     /** {@inheritDoc}
1792      * @since 1.7
1793      */
1794     @Override
1795     public Complex floor() {
1796         return createComplex(FastMath.floor(getRealPart()), FastMath.floor(getImaginaryPart()));
1797     }
1798 
1799     /** {@inheritDoc}
1800      * @since 1.7
1801      */
1802     @Override
1803     public Complex rint() {
1804         return createComplex(FastMath.rint(getRealPart()), FastMath.rint(getImaginaryPart()));
1805     }
1806 
1807     /** {@inheritDoc}
1808      * <p>
1809      * for complex numbers, the integer n corresponding to {@code this.subtract(remainder(a)).divide(a)}
1810      * is a <a href="https://en.wikipedia.org/wiki/Gaussian_integer">Wikipedia - Gaussian integer</a>.
1811      * </p>
1812      * @since 1.7
1813      */
1814     @Override
1815     public Complex remainder(final double a) {
1816         return createComplex(FastMath.IEEEremainder(getRealPart(), a), FastMath.IEEEremainder(getImaginaryPart(), a));
1817     }
1818 
1819     /** {@inheritDoc}
1820      * <p>
1821      * for complex numbers, the integer n corresponding to {@code this.subtract(remainder(a)).divide(a)}
1822      * is a <a href="https://en.wikipedia.org/wiki/Gaussian_integer">Wikipedia - Gaussian integer</a>.
1823      * </p>
1824      * @since 1.7
1825      */
1826     @Override
1827     public Complex remainder(final Complex a) {
1828         final Complex complexQuotient = divide(a);
1829         final double  qRInt           = FastMath.rint(complexQuotient.real);
1830         final double  qIInt           = FastMath.rint(complexQuotient.imaginary);
1831         return createComplex(real - qRInt * a.real + qIInt * a.imaginary,
1832                              imaginary - qRInt * a.imaginary - qIInt * a.real);
1833     }
1834 
1835     /** {@inheritDoc}
1836      * @since 2.0
1837      */
1838     @Override
1839     public Complex sign() {
1840         if (isNaN() || isZero()) {
1841             return this;
1842         } else {
1843             return this.divide(FastMath.hypot(real, imaginary));
1844         }
1845     }
1846 
1847     /** {@inheritDoc}
1848      * <p>
1849      * The signs of real and imaginary parts are copied independently.
1850      * </p>
1851      * @since 1.7
1852      */
1853     @Override
1854     public Complex copySign(final Complex z) {
1855         return createComplex(FastMath.copySign(getRealPart(), z.getRealPart()),
1856                              FastMath.copySign(getImaginaryPart(), z.getImaginaryPart()));
1857     }
1858 
1859     /** {@inheritDoc}
1860      * @since 1.7
1861      */
1862     @Override
1863     public Complex copySign(double r) {
1864         return createComplex(FastMath.copySign(getRealPart(), r), FastMath.copySign(getImaginaryPart(), r));
1865     }
1866 
1867     /** {@inheritDoc} */
1868     @Override
1869     public Complex toDegrees() {
1870         return createComplex(FastMath.toDegrees(getRealPart()), FastMath.toDegrees(getImaginaryPart()));
1871     }
1872 
1873     /** {@inheritDoc} */
1874     @Override
1875     public Complex toRadians() {
1876         return createComplex(FastMath.toRadians(getRealPart()), FastMath.toRadians(getImaginaryPart()));
1877     }
1878 
1879     /** {@inheritDoc}
1880      * <p>
1881      * Comparison us performed using real ordering as the primary sort order and
1882      * imaginary ordering as the secondary sort order.
1883      * </p>
1884      * @since 3.0
1885      */
1886     @Override
1887     public int compareTo(final Complex o) {
1888         final int cR = Double.compare(getReal(), o.getReal());
1889         if (cR == 0) {
1890             return Double.compare(getImaginary(),o.getImaginary());
1891         } else {
1892             return cR;
1893         }
1894     }
1895 
1896 }