Complex.java

  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.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */

  21. package org.hipparchus.complex;

  22. import java.io.Serializable;
  23. import java.util.ArrayList;
  24. import java.util.List;

  25. import org.hipparchus.CalculusFieldElement;
  26. import org.hipparchus.exception.LocalizedCoreFormats;
  27. import org.hipparchus.exception.MathIllegalArgumentException;
  28. import org.hipparchus.exception.NullArgumentException;
  29. import org.hipparchus.util.FastMath;
  30. import org.hipparchus.util.FieldSinCos;
  31. import org.hipparchus.util.FieldSinhCosh;
  32. import org.hipparchus.util.MathArrays;
  33. import org.hipparchus.util.MathUtils;
  34. import org.hipparchus.util.Precision;
  35. import org.hipparchus.util.SinCos;
  36. import org.hipparchus.util.SinhCosh;

  37. /**
  38.  * Representation of a Complex number, i.e. a number which has both a
  39.  * real and imaginary part.
  40.  * <p>
  41.  * Implementations of arithmetic operations handle {@code NaN} and
  42.  * infinite values according to the rules for {@link java.lang.Double}, i.e.
  43.  * {@link #equals} is an equivalence relation for all instances that have
  44.  * a {@code NaN} in either real or imaginary part, e.g. the following are
  45.  * considered equal:
  46.  * <ul>
  47.  *  <li>{@code 1 + NaNi}</li>
  48.  *  <li>{@code NaN + i}</li>
  49.  *  <li>{@code NaN + NaNi}</li>
  50.  * </ul>
  51.  * <p>
  52.  * Note that this contradicts the IEEE-754 standard for floating
  53.  * point numbers (according to which the test {@code x == x} must fail if
  54.  * {@code x} is {@code NaN}). The method
  55.  * {@link org.hipparchus.util.Precision#equals(double,double,int)
  56.  * equals for primitive double} in {@link org.hipparchus.util.Precision}
  57.  * conforms with IEEE-754 while this class conforms with the standard behavior
  58.  * for Java object types.
  59.  */
  60. public class Complex implements CalculusFieldElement<Complex>, Comparable<Complex>, Serializable  {
  61.     /** The square root of -1. A number representing "0.0 + 1.0i". */
  62.     public static final Complex I = new Complex(0.0, 1.0);
  63.     /** The square root of -1. A number representing "0.0 - 1.0i".
  64.      * @since 1.7
  65.      */
  66.     public static final Complex MINUS_I = new Complex(0.0, -1.0);
  67.     // CHECKSTYLE: stop ConstantName
  68.     /** A complex number representing "NaN + NaNi". */
  69.     public static final Complex NaN = new Complex(Double.NaN, Double.NaN);
  70.     // CHECKSTYLE: resume ConstantName
  71.     /** A complex number representing "+INF + INFi" */
  72.     public static final Complex INF = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
  73.     /** A complex number representing "1.0 + 0.0i". */
  74.     public static final Complex ONE = new Complex(1.0, 0.0);
  75.     /** A complex number representing "-1.0 + 0.0i".
  76.      * @since 1.7
  77.      */
  78.     public static final Complex MINUS_ONE = new Complex(-1.0, 0.0);
  79.     /** A complex number representing "0.0 + 0.0i". */
  80.     public static final Complex ZERO = new Complex(0.0, 0.0);
  81.     /** A complex number representing "π + 0.0i". */
  82.     public static final Complex PI   = new Complex(FastMath.PI, 0.0);

  83.     /** A real number representing log(10). */
  84.     private static final double LOG10 = 2.302585092994045684;

  85.     /** Serializable version identifier */
  86.     private static final long serialVersionUID = 20160305L;

  87.     /** The imaginary part. */
  88.     private final double imaginary;
  89.     /** The real part. */
  90.     private final double real;
  91.     /** Record whether this complex number is equal to NaN. */
  92.     private final transient boolean isNaN;
  93.     /** Record whether this complex number is infinite. */
  94.     private final transient boolean isInfinite;

  95.     /**
  96.      * Create a complex number given only the real part.
  97.      *
  98.      * @param real Real part.
  99.      */
  100.     public Complex(double real) {
  101.         this(real, 0.0);
  102.     }

  103.     /**
  104.      * Create a complex number given the real and imaginary parts.
  105.      *
  106.      * @param real Real part.
  107.      * @param imaginary Imaginary part.
  108.      */
  109.     public Complex(double real, double imaginary) {
  110.         this.real = real;
  111.         this.imaginary = imaginary;

  112.         isNaN = Double.isNaN(real) || Double.isNaN(imaginary);
  113.         isInfinite = !isNaN &&
  114.             (Double.isInfinite(real) || Double.isInfinite(imaginary));
  115.     }

  116.     /**
  117.      * Return the absolute value of this complex number.
  118.      * Returns {@code NaN} if either real or imaginary part is {@code NaN}
  119.      * and {@code Double.POSITIVE_INFINITY} if neither part is {@code NaN},
  120.      * but at least one part is infinite.
  121.      *
  122.      * @return the norm.
  123.      * @since 2.0
  124.      */
  125.     @Override
  126.     public Complex abs() {
  127.         // we check NaN here because FastMath.hypot checks it after infinity
  128.         return isNaN ? NaN : createComplex(FastMath.hypot(real, imaginary), 0.0);
  129.     }

  130.     /** {@inheritDoc} */
  131.     @Override
  132.     public double norm() {
  133.         // we check NaN here because FastMath.hypot checks it after infinity
  134.         return isNaN ? Double.NaN : FastMath.hypot(real, imaginary);
  135.     }

  136.     /**
  137.      * Returns a {@code Complex} whose value is
  138.      * {@code (this + addend)}.
  139.      * Uses the definitional formula
  140.      * <p>
  141.      *   {@code (a + bi) + (c + di) = (a+c) + (b+d)i}
  142.      * </p>
  143.      * If either {@code this} or {@code addend} has a {@code NaN} value in
  144.      * either part, {@link #NaN} is returned; otherwise {@code Infinite}
  145.      * and {@code NaN} values are returned in the parts of the result
  146.      * according to the rules for {@link java.lang.Double} arithmetic.
  147.      *
  148.      * @param  addend Value to be added to this {@code Complex}.
  149.      * @return {@code this + addend}.
  150.      * @throws NullArgumentException if {@code addend} is {@code null}.
  151.      */
  152.     @Override
  153.     public Complex add(Complex addend) throws NullArgumentException {
  154.         MathUtils.checkNotNull(addend);
  155.         if (isNaN || addend.isNaN) {
  156.             return NaN;
  157.         }

  158.         return createComplex(real + addend.getRealPart(),
  159.                              imaginary + addend.getImaginaryPart());
  160.     }

  161.     /**
  162.      * Returns a {@code Complex} whose value is {@code (this + addend)},
  163.      * with {@code addend} interpreted as a real number.
  164.      *
  165.      * @param addend Value to be added to this {@code Complex}.
  166.      * @return {@code this + addend}.
  167.      * @see #add(Complex)
  168.      */
  169.     @Override
  170.     public Complex add(double addend) {
  171.         if (isNaN || Double.isNaN(addend)) {
  172.             return NaN;
  173.         }

  174.         return createComplex(real + addend, imaginary);
  175.     }

  176.      /**
  177.      * Returns the conjugate of this complex number.
  178.      * The conjugate of {@code a + bi} is {@code a - bi}.
  179.      * <p>
  180.      * {@link #NaN} is returned if either the real or imaginary
  181.      * part of this Complex number equals {@code Double.NaN}.
  182.      * </p><p>
  183.      * If the imaginary part is infinite, and the real part is not
  184.      * {@code NaN}, the returned value has infinite imaginary part
  185.      * of the opposite sign, e.g. the conjugate of
  186.      * {@code 1 + POSITIVE_INFINITY i} is {@code 1 - NEGATIVE_INFINITY i}.
  187.      * </p>
  188.      * @return the conjugate of this Complex object.
  189.      */
  190.     public Complex conjugate() {
  191.         if (isNaN) {
  192.             return NaN;
  193.         }

  194.         return createComplex(real, -imaginary);
  195.     }

  196.     /**
  197.      * Returns a {@code Complex} whose value is
  198.      * {@code (this / divisor)}.
  199.      * Implements the definitional formula
  200.      * <pre>
  201.      *  <code>
  202.      *    a + bi          ac + bd + (bc - ad)i
  203.      *    ----------- = -------------------------
  204.      *    c + di         c<sup>2</sup> + d<sup>2</sup>
  205.      *  </code>
  206.      * </pre>
  207.      * but uses
  208.      * <a href="http://doi.acm.org/10.1145/1039813.1039814">
  209.      * prescaling of operands</a> to limit the effects of overflows and
  210.      * underflows in the computation.
  211.      * <p>
  212.      * {@code Infinite} and {@code NaN} values are handled according to the
  213.      * following rules, applied in the order presented:
  214.      * <ul>
  215.      *  <li>If either {@code this} or {@code divisor} has a {@code NaN} value
  216.      *   in either part, {@link #NaN} is returned.
  217.      *  </li>
  218.      *  <li>If {@code divisor} equals {@link #ZERO}, {@link #NaN} is returned.
  219.      *  </li>
  220.      *  <li>If {@code this} and {@code divisor} are both infinite,
  221.      *   {@link #NaN} is returned.
  222.      *  </li>
  223.      *  <li>If {@code this} is finite (i.e., has no {@code Infinite} or
  224.      *   {@code NaN} parts) and {@code divisor} is infinite (one or both parts
  225.      *   infinite), {@link #ZERO} is returned.
  226.      *  </li>
  227.      *  <li>If {@code this} is infinite and {@code divisor} is finite,
  228.      *   {@code NaN} values are returned in the parts of the result if the
  229.      *   {@link java.lang.Double} rules applied to the definitional formula
  230.      *   force {@code NaN} results.
  231.      *  </li>
  232.      * </ul>
  233.      *
  234.      * @param divisor Value by which this {@code Complex} is to be divided.
  235.      * @return {@code this / divisor}.
  236.      * @throws NullArgumentException if {@code divisor} is {@code null}.
  237.      */
  238.     @Override
  239.     public Complex divide(Complex divisor)
  240.         throws NullArgumentException {
  241.         MathUtils.checkNotNull(divisor);
  242.         if (isNaN || divisor.isNaN) {
  243.             return NaN;
  244.         }

  245.         final double c = divisor.getRealPart();
  246.         final double d = divisor.getImaginaryPart();
  247.         if (c == 0.0 && d == 0.0) {
  248.             return NaN;
  249.         }

  250.         if (divisor.isInfinite() && !isInfinite()) {
  251.             return ZERO;
  252.         }

  253.         if (FastMath.abs(c) < FastMath.abs(d)) {
  254.             double q = c / d;
  255.             double denominator = c * q + d;
  256.             return createComplex((real * q + imaginary) / denominator,
  257.                                  (imaginary * q - real) / denominator);
  258.         } else {
  259.             double q = d / c;
  260.             double denominator = d * q + c;
  261.             return createComplex((imaginary * q + real) / denominator,
  262.                                  (imaginary - real * q) / denominator);
  263.         }
  264.     }

  265.     /**
  266.      * Returns a {@code Complex} whose value is {@code (this / divisor)},
  267.      * with {@code divisor} interpreted as a real number.
  268.      *
  269.      * @param  divisor Value by which this {@code Complex} is to be divided.
  270.      * @return {@code this / divisor}.
  271.      * @see #divide(Complex)
  272.      */
  273.     @Override
  274.     public Complex divide(double divisor) {
  275.         if (isNaN || Double.isNaN(divisor)) {
  276.             return NaN;
  277.         }
  278.         if (divisor == 0d) {
  279.             return NaN;
  280.         }
  281.         if (Double.isInfinite(divisor)) {
  282.             return !isInfinite() ? ZERO : NaN;
  283.         }
  284.         return createComplex(real / divisor,
  285.                              imaginary  / divisor);
  286.     }

  287.     /** {@inheritDoc} */
  288.     @Override
  289.     public Complex reciprocal() {
  290.         if (isNaN) {
  291.             return NaN;
  292.         }

  293.         if (real == 0.0 && imaginary == 0.0) {
  294.             return INF;
  295.         }

  296.         if (isInfinite) {
  297.             return ZERO;
  298.         }

  299.         if (FastMath.abs(real) < FastMath.abs(imaginary)) {
  300.             double q = real / imaginary;
  301.             double scale = 1. / (real * q + imaginary);
  302.             return createComplex(scale * q, -scale);
  303.         } else {
  304.             double q = imaginary / real;
  305.             double scale = 1. / (imaginary * q + real);
  306.             return createComplex(scale, -scale * q);
  307.         }
  308.     }

  309.     /**
  310.      * Test for equality with another object.
  311.      * If both the real and imaginary parts of two complex numbers
  312.      * are exactly the same, and neither is {@code Double.NaN}, the two
  313.      * Complex objects are considered to be equal.
  314.      * The behavior is the same as for JDK's {@link Double#equals(Object)
  315.      * Double}:
  316.      * <ul>
  317.      *  <li>All {@code NaN} values are considered to be equal,
  318.      *   i.e, if either (or both) real and imaginary parts of the complex
  319.      *   number are equal to {@code Double.NaN}, the complex number is equal
  320.      *   to {@code NaN}.
  321.      *  </li>
  322.      *  <li>
  323.      *   Instances constructed with different representations of zero (i.e.
  324.      *   either "0" or "-0") are <em>not</em> considered to be equal.
  325.      *  </li>
  326.      * </ul>
  327.      *
  328.      * @param other Object to test for equality with this instance.
  329.      * @return {@code true} if the objects are equal, {@code false} if object
  330.      * is {@code null}, not an instance of {@code Complex}, or not equal to
  331.      * this instance.
  332.      */
  333.     @Override
  334.     public boolean equals(Object other) {
  335.         if (this == other) {
  336.             return true;
  337.         }
  338.         if (other instanceof Complex){
  339.             Complex c = (Complex) other;
  340.             if (c.isNaN) {
  341.                 return isNaN;
  342.             } else {
  343.                 return MathUtils.equals(real, c.real) &&
  344.                        MathUtils.equals(imaginary, c.imaginary);
  345.             }
  346.         }
  347.         return false;
  348.     }

  349.     /**
  350.      * Test for the floating-point equality between Complex objects.
  351.      * It returns {@code true} if both arguments are equal or within the
  352.      * range of allowed error (inclusive).
  353.      *
  354.      * @param x First value (cannot be {@code null}).
  355.      * @param y Second value (cannot be {@code null}).
  356.      * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
  357.      * values between the real (resp. imaginary) parts of {@code x} and
  358.      * {@code y}.
  359.      * @return {@code true} if there are fewer than {@code maxUlps} floating
  360.      * point values between the real (resp. imaginary) parts of {@code x}
  361.      * and {@code y}.
  362.      *
  363.      * @see Precision#equals(double,double,int)
  364.      */
  365.     public static boolean equals(Complex x, Complex y, int maxUlps) {
  366.         return Precision.equals(x.real, y.real, maxUlps) &&
  367.                Precision.equals(x.imaginary, y.imaginary, maxUlps);
  368.     }

  369.     /**
  370.      * Returns {@code true} iff the values are equal as defined by
  371.      * {@link #equals(Complex,Complex,int) equals(x, y, 1)}.
  372.      *
  373.      * @param x First value (cannot be {@code null}).
  374.      * @param y Second value (cannot be {@code null}).
  375.      * @return {@code true} if the values are equal.
  376.      */
  377.     public static boolean equals(Complex x, Complex y) {
  378.         return equals(x, y, 1);
  379.     }

  380.     /**
  381.      * Returns {@code true} if, both for the real part and for the imaginary
  382.      * part, there is no double value strictly between the arguments or the
  383.      * difference between them is within the range of allowed error
  384.      * (inclusive).  Returns {@code false} if either of the arguments is NaN.
  385.      *
  386.      * @param x First value (cannot be {@code null}).
  387.      * @param y Second value (cannot be {@code null}).
  388.      * @param eps Amount of allowed absolute error.
  389.      * @return {@code true} if the values are two adjacent floating point
  390.      * numbers or they are within range of each other.
  391.      *
  392.      * @see Precision#equals(double,double,double)
  393.      */
  394.     public static boolean equals(Complex x, Complex y, double eps) {
  395.         return Precision.equals(x.real, y.real, eps) &&
  396.                Precision.equals(x.imaginary, y.imaginary, eps);
  397.     }

  398.     /**
  399.      * Returns {@code true} if, both for the real part and for the imaginary
  400.      * part, there is no double value strictly between the arguments or the
  401.      * relative difference between them is smaller or equal to the given
  402.      * tolerance. Returns {@code false} if either of the arguments is NaN.
  403.      *
  404.      * @param x First value (cannot be {@code null}).
  405.      * @param y Second value (cannot be {@code null}).
  406.      * @param eps Amount of allowed relative error.
  407.      * @return {@code true} if the values are two adjacent floating point
  408.      * numbers or they are within range of each other.
  409.      *
  410.      * @see Precision#equalsWithRelativeTolerance(double,double,double)
  411.      */
  412.     public static boolean equalsWithRelativeTolerance(Complex x,
  413.                                                       Complex y,
  414.                                                       double eps) {
  415.         return Precision.equalsWithRelativeTolerance(x.real, y.real, eps) &&
  416.                Precision.equalsWithRelativeTolerance(x.imaginary, y.imaginary, eps);
  417.     }

  418.     /**
  419.      * Get a hashCode for the complex number.
  420.      * Any {@code Double.NaN} value in real or imaginary part produces
  421.      * the same hash code {@code 7}.
  422.      *
  423.      * @return a hash code value for this object.
  424.      */
  425.     @Override
  426.     public int hashCode() {
  427.         if (isNaN) {
  428.             return 7;
  429.         }
  430.         return 37 * (17 * MathUtils.hash(imaginary) +
  431.             MathUtils.hash(real));
  432.     }

  433.     /** {@inheritDoc}
  434.      * <p>
  435.      * This implementation considers +0.0 and -0.0 to be equal for both
  436.      * real and imaginary components.
  437.      * </p>
  438.      * @since 1.8
  439.      */
  440.     @Override
  441.     public boolean isZero() {
  442.         return real == 0.0 && imaginary == 0.0;
  443.     }

  444.     /**
  445.      * Access the imaginary part.
  446.      *
  447.      * @return the imaginary part.
  448.      */
  449.     public double getImaginary() {
  450.         return imaginary;
  451.     }

  452.     /**
  453.      * Access the imaginary part.
  454.      *
  455.      * @return the imaginary part.
  456.      * @since 2.0
  457.      */
  458.     public double getImaginaryPart() {
  459.         return imaginary;
  460.     }

  461.     /**
  462.      * Access the real part.
  463.      *
  464.      * @return the real part.
  465.      */
  466.     @Override
  467.     public double getReal() {
  468.         return real;
  469.     }

  470.     /** {@inheritDoc} */
  471.     @Override
  472.     public Complex getAddendum() {
  473.         return new Complex(0, imaginary);
  474.     }

  475.     /**
  476.      * Access the real part.
  477.      *
  478.      * @return the real part.
  479.      * @since 2.0
  480.      */
  481.     public double getRealPart() {
  482.         return real;
  483.     }

  484.     /**
  485.      * Checks whether either or both parts of this complex number is
  486.      * {@code NaN}.
  487.      *
  488.      * @return true if either or both parts of this complex number is
  489.      * {@code NaN}; false otherwise.
  490.      */
  491.     @Override
  492.     public boolean isNaN() {
  493.         return isNaN;
  494.     }

  495.     /** Check whether the instance is real (i.e. imaginary part is zero).
  496.      * @return true if imaginary part is zero
  497.      * @since 1.7
  498.      */
  499.     public boolean isReal() {
  500.         return imaginary == 0.0;
  501.     }

  502.     /** Check whether the instance is an integer (i.e. imaginary part is zero and real part has no fractional part).
  503.      * @return true if imaginary part is zero and real part has no fractional part
  504.      * @since 1.7
  505.      */
  506.     public boolean isMathematicalInteger() {
  507.         return isReal() && Precision.isMathematicalInteger(real);
  508.     }

  509.     /**
  510.      * Checks whether either the real or imaginary part of this complex number
  511.      * takes an infinite value (either {@code Double.POSITIVE_INFINITY} or
  512.      * {@code Double.NEGATIVE_INFINITY}) and neither part
  513.      * is {@code NaN}.
  514.      *
  515.      * @return true if one or both parts of this complex number are infinite
  516.      * and neither part is {@code NaN}.
  517.      */
  518.     @Override
  519.     public boolean isInfinite() {
  520.         return isInfinite;
  521.     }

  522.     /**
  523.      * Returns a {@code Complex} whose value is {@code this * factor}.
  524.      * Implements preliminary checks for {@code NaN} and infinity followed by
  525.      * the definitional formula:
  526.      * <p>
  527.      *   {@code (a + bi)(c + di) = (ac - bd) + (ad + bc)i}
  528.      * </p>
  529.      * Returns {@link #NaN} if either {@code this} or {@code factor} has one or
  530.      * more {@code NaN} parts.
  531.      * <p>
  532.      * Returns {@link #INF} if neither {@code this} nor {@code factor} has one
  533.      * or more {@code NaN} parts and if either {@code this} or {@code factor}
  534.      * has one or more infinite parts (same result is returned regardless of
  535.      * the sign of the components).
  536.      * </p><p>
  537.      * Returns finite values in components of the result per the definitional
  538.      * formula in all remaining cases.</p>
  539.      *
  540.      * @param  factor value to be multiplied by this {@code Complex}.
  541.      * @return {@code this * factor}.
  542.      * @throws NullArgumentException if {@code factor} is {@code null}.
  543.      */
  544.     @Override
  545.     public Complex multiply(Complex factor)
  546.         throws NullArgumentException {
  547.         MathUtils.checkNotNull(factor);
  548.         if (isNaN || factor.isNaN) {
  549.             return NaN;
  550.         }
  551.         if (Double.isInfinite(real) ||
  552.             Double.isInfinite(imaginary) ||
  553.             Double.isInfinite(factor.real) ||
  554.             Double.isInfinite(factor.imaginary)) {
  555.             // we don't use isInfinite() to avoid testing for NaN again
  556.             return INF;
  557.         }
  558.         return createComplex(MathArrays.linearCombination(real, factor.real, -imaginary, factor.imaginary),
  559.                              MathArrays.linearCombination(real, factor.imaginary, imaginary, factor.real));
  560.     }

  561.     /**
  562.      * Returns a {@code Complex} whose value is {@code this * factor}, with {@code factor}
  563.      * interpreted as a integer number.
  564.      *
  565.      * @param  factor value to be multiplied by this {@code Complex}.
  566.      * @return {@code this * factor}.
  567.      * @see #multiply(Complex)
  568.      */
  569.     @Override
  570.     public Complex multiply(final int factor) {
  571.         if (isNaN) {
  572.             return NaN;
  573.         }
  574.         if (Double.isInfinite(real) ||
  575.             Double.isInfinite(imaginary)) {
  576.             return INF;
  577.         }
  578.         return createComplex(real * factor, imaginary * factor);
  579.     }

  580.     /**
  581.      * Returns a {@code Complex} whose value is {@code this * factor}, with {@code factor}
  582.      * interpreted as a real number.
  583.      *
  584.      * @param  factor value to be multiplied by this {@code Complex}.
  585.      * @return {@code this * factor}.
  586.      * @see #multiply(Complex)
  587.      */
  588.     @Override
  589.     public Complex multiply(double factor) {
  590.         if (isNaN || Double.isNaN(factor)) {
  591.             return NaN;
  592.         }
  593.         if (Double.isInfinite(real) ||
  594.             Double.isInfinite(imaginary) ||
  595.             Double.isInfinite(factor)) {
  596.             // we don't use isInfinite() to avoid testing for NaN again
  597.             return INF;
  598.         }
  599.         return createComplex(real * factor, imaginary * factor);
  600.     }

  601.     /** Compute this * i.
  602.      * @return this * i
  603.      * @since 2.0
  604.      */
  605.     public Complex multiplyPlusI() {
  606.         return createComplex(-imaginary, real);
  607.     }

  608.     /** Compute this *- -i.
  609.      * @return this * i
  610.      * @since 2.0
  611.      */
  612.     public Complex multiplyMinusI() {
  613.         return createComplex(imaginary, -real);
  614.     }

  615.     /** {@inheritDoc} */
  616.     @Override
  617.     public Complex square() {
  618.         return multiply(this);
  619.     }

  620.     /**
  621.      * Returns a {@code Complex} whose value is {@code (-this)}.
  622.      * Returns {@code NaN} if either real or imaginary
  623.      * part of this Complex number is {@code Double.NaN}.
  624.      *
  625.      * @return {@code -this}.
  626.      */
  627.     @Override
  628.     public Complex negate() {
  629.         if (isNaN) {
  630.             return NaN;
  631.         }

  632.         return createComplex(-real, -imaginary);
  633.     }

  634.     /**
  635.      * Returns a {@code Complex} whose value is
  636.      * {@code (this - subtrahend)}.
  637.      * Uses the definitional formula
  638.      * <p>
  639.      *  {@code (a + bi) - (c + di) = (a-c) + (b-d)i}
  640.      * </p>
  641.      * If either {@code this} or {@code subtrahend} has a {@code NaN]} value in either part,
  642.      * {@link #NaN} is returned; otherwise infinite and {@code NaN} values are
  643.      * returned in the parts of the result according to the rules for
  644.      * {@link java.lang.Double} arithmetic.
  645.      *
  646.      * @param  subtrahend value to be subtracted from this {@code Complex}.
  647.      * @return {@code this - subtrahend}.
  648.      * @throws NullArgumentException if {@code subtrahend} is {@code null}.
  649.      */
  650.     @Override
  651.     public Complex subtract(Complex subtrahend)
  652.         throws NullArgumentException {
  653.         MathUtils.checkNotNull(subtrahend);
  654.         if (isNaN || subtrahend.isNaN) {
  655.             return NaN;
  656.         }

  657.         return createComplex(real - subtrahend.getRealPart(),
  658.                              imaginary - subtrahend.getImaginaryPart());
  659.     }

  660.     /**
  661.      * Returns a {@code Complex} whose value is
  662.      * {@code (this - subtrahend)}.
  663.      *
  664.      * @param  subtrahend value to be subtracted from this {@code Complex}.
  665.      * @return {@code this - subtrahend}.
  666.      * @see #subtract(Complex)
  667.      */
  668.     @Override
  669.     public Complex subtract(double subtrahend) {
  670.         if (isNaN || Double.isNaN(subtrahend)) {
  671.             return NaN;
  672.         }
  673.         return createComplex(real - subtrahend, imaginary);
  674.     }

  675.     /**
  676.      * Compute the
  677.      * <a href="http://mathworld.wolfram.com/InverseCosine.html" TARGET="_top">
  678.      * inverse cosine</a> of this complex number.
  679.      * Implements the formula:
  680.      * <p>
  681.      *  {@code acos(z) = -i (log(z + i (sqrt(1 - z<sup>2</sup>))))}
  682.      * </p>
  683.      * Returns {@link Complex#NaN} if either real or imaginary part of the
  684.      * input argument is {@code NaN} or infinite.
  685.      *
  686.      * @return the inverse cosine of this complex number.
  687.      */
  688.     @Override
  689.     public Complex acos() {
  690.         if (isNaN) {
  691.             return NaN;
  692.         }

  693.         return this.add(this.sqrt1z().multiplyPlusI()).log().multiplyMinusI();
  694.     }

  695.     /**
  696.      * Compute the
  697.      * <a href="http://mathworld.wolfram.com/InverseSine.html" TARGET="_top">
  698.      * inverse sine</a> of this complex number.
  699.      * Implements the formula:
  700.      * <p>
  701.      *  {@code asin(z) = -i (log(sqrt(1 - z<sup>2</sup>) + iz))}
  702.      * </p><p>
  703.      * Returns {@link Complex#NaN} if either real or imaginary part of the
  704.      * input argument is {@code NaN} or infinite.</p>
  705.      *
  706.      * @return the inverse sine of this complex number.
  707.      */
  708.     @Override
  709.     public Complex asin() {
  710.         if (isNaN) {
  711.             return NaN;
  712.         }

  713.         return sqrt1z().add(this.multiplyPlusI()).log().multiplyMinusI();
  714.     }

  715.     /**
  716.      * Compute the
  717.      * <a href="http://mathworld.wolfram.com/InverseTangent.html" TARGET="_top">
  718.      * inverse tangent</a> of this complex number.
  719.      * Implements the formula:
  720.      * <p>
  721.      * {@code atan(z) = (i/2) log((1 - iz)/(1 + iz))}
  722.      * </p><p>
  723.      * Returns {@link Complex#NaN} if either real or imaginary part of the
  724.      * input argument is {@code NaN} or infinite.</p>
  725.      *
  726.      * @return the inverse tangent of this complex number
  727.      */
  728.     @Override
  729.     public Complex atan() {
  730.         if (isNaN) {
  731.             return NaN;
  732.         }

  733.         if (real == 0.0) {

  734.             // singularity at ±i
  735.             if (imaginary * imaginary - 1.0 == 0.0) {
  736.                 return NaN;
  737.             }

  738.             // branch cut on imaginary axis
  739.             final Complex tmp = createComplex((1 + imaginary) / (1 - imaginary), 0.0).log().multiplyPlusI().multiply(0.5);
  740.             return createComplex(FastMath.copySign(tmp.real, real), tmp.imaginary);

  741.         } else if (imaginary == 0.0) {
  742.             // taking care to preserve the sign of the zero imaginary part
  743.             return createComplex(FastMath.atan(real), imaginary);
  744.         } else {
  745.             // regular formula
  746.             final Complex n = createComplex(1 + imaginary, -real);
  747.             final Complex d = createComplex(1 - imaginary,  real);
  748.             return n.divide(d).log().multiplyPlusI().multiply(0.5);
  749.         }

  750.     }

  751.     /**
  752.      * Compute the
  753.      * <a href="http://mathworld.wolfram.com/Cosine.html" TARGET="_top">
  754.      * cosine</a> of this complex number.
  755.      * Implements the formula:
  756.      * <p>
  757.      *  {@code cos(a + bi) = cos(a)cosh(b) - sin(a)sinh(b)i}
  758.      * </p><p>
  759.      * where the (real) functions on the right-hand side are
  760.      * {@link FastMath#sin}, {@link FastMath#cos},
  761.      * {@link FastMath#cosh} and {@link FastMath#sinh}.
  762.      * </p><p>
  763.      * Returns {@link Complex#NaN} if either real or imaginary part of the
  764.      * input argument is {@code NaN}.
  765.      * </p><p>
  766.      * Infinite values in real or imaginary parts of the input may result in
  767.      * infinite or NaN values returned in parts of the result.</p>
  768.      * <pre>
  769.      *  Examples:
  770.      *  <code>
  771.      *   cos(1 &plusmn; INFINITY i) = 1 ∓ INFINITY i
  772.      *   cos(&plusmn;INFINITY + i) = NaN + NaN i
  773.      *   cos(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
  774.      *  </code>
  775.      * </pre>
  776.      *
  777.      * @return the cosine of this complex number.
  778.      */
  779.     @Override
  780.     public Complex cos() {
  781.         if (isNaN) {
  782.             return NaN;
  783.         }

  784.         final SinCos   scr  = FastMath.sinCos(real);
  785.         final SinhCosh schi = FastMath.sinhCosh(imaginary);
  786.         return createComplex(scr.cos() * schi.cosh(), -scr.sin() * schi.sinh());
  787.     }

  788.     /**
  789.      * Compute the
  790.      * <a href="http://mathworld.wolfram.com/HyperbolicCosine.html" TARGET="_top">
  791.      * hyperbolic cosine</a> of this complex number.
  792.      * Implements the formula:
  793.      * <pre>
  794.      *  <code>
  795.      *   cosh(a + bi) = cosh(a)cos(b) + sinh(a)sin(b)i
  796.      *  </code>
  797.      * </pre>
  798.      * where the (real) functions on the right-hand side are
  799.      * {@link FastMath#sin}, {@link FastMath#cos},
  800.      * {@link FastMath#cosh} and {@link FastMath#sinh}.
  801.      * <p>
  802.      * Returns {@link Complex#NaN} if either real or imaginary part of the
  803.      * input argument is {@code NaN}.
  804.      * </p>
  805.      * Infinite values in real or imaginary parts of the input may result in
  806.      * infinite or NaN values returned in parts of the result.
  807.      * <pre>
  808.      *  Examples:
  809.      *  <code>
  810.      *   cosh(1 &plusmn; INFINITY i) = NaN + NaN i
  811.      *   cosh(&plusmn;INFINITY + i) = INFINITY &plusmn; INFINITY i
  812.      *   cosh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
  813.      *  </code>
  814.      * </pre>
  815.      *
  816.      * @return the hyperbolic cosine of this complex number.
  817.      */
  818.     @Override
  819.     public Complex cosh() {
  820.         if (isNaN) {
  821.             return NaN;
  822.         }

  823.         final SinhCosh schr = FastMath.sinhCosh(real);
  824.         final SinCos   sci  = FastMath.sinCos(imaginary);
  825.         return createComplex(schr.cosh() * sci.cos(), schr.sinh() * sci.sin());
  826.     }

  827.     /**
  828.      * Compute the
  829.      * <a href="http://mathworld.wolfram.com/ExponentialFunction.html" TARGET="_top">
  830.      * exponential function</a> of this complex number.
  831.      * Implements the formula:
  832.      * <pre>
  833.      *  <code>
  834.      *   exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i
  835.      *  </code>
  836.      * </pre>
  837.      * where the (real) functions on the right-hand side are
  838.      * {@link FastMath#exp(double)} p}, {@link FastMath#cos(double)}, and
  839.      * {@link FastMath#sin(double)}.
  840.      * <p>
  841.      * Returns {@link Complex#NaN} if either real or imaginary part of the
  842.      * input argument is {@code NaN}.
  843.      * </p>
  844.      * Infinite values in real or imaginary parts of the input may result in
  845.      * infinite or NaN values returned in parts of the result.
  846.      * <pre>
  847.      *  Examples:
  848.      *  <code>
  849.      *   exp(1 &plusmn; INFINITY i) = NaN + NaN i
  850.      *   exp(INFINITY + i) = INFINITY + INFINITY i
  851.      *   exp(-INFINITY + i) = 0 + 0i
  852.      *   exp(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
  853.      *  </code>
  854.      * </pre>
  855.      *
  856.      * @return <code><i>e</i><sup>this</sup></code>.
  857.      */
  858.     @Override
  859.     public Complex exp() {
  860.         if (isNaN) {
  861.             return NaN;
  862.         }

  863.         final double expReal = FastMath.exp(real);
  864.         final SinCos sc      = FastMath.sinCos(imaginary);
  865.         return createComplex(expReal * sc.cos(), expReal * sc.sin());
  866.     }

  867.     /** {@inheritDoc}
  868.      * @since 1.7
  869.      */
  870.     @Override
  871.     public Complex expm1() {
  872.         if (isNaN) {
  873.             return NaN;
  874.         }

  875.         final double expm1Real = FastMath.expm1(real);
  876.         final SinCos sc        = FastMath.sinCos(imaginary);
  877.         return createComplex(expm1Real * sc.cos(), expm1Real * sc.sin());
  878.     }

  879.     /**
  880.      * Compute the
  881.      * <a href="http://mathworld.wolfram.com/NaturalLogarithm.html" TARGET="_top">
  882.      * natural logarithm</a> of this complex number.
  883.      * Implements the formula:
  884.      * <pre>
  885.      *  <code>
  886.      *   log(a + bi) = ln(|a + bi|) + arg(a + bi)i
  887.      *  </code>
  888.      * </pre>
  889.      * where ln on the right hand side is {@link FastMath#log(double)},
  890.      * {@code |a + bi|} is the modulus, {@link Complex#abs},  and
  891.      * {@code arg(a + bi) = }{@link FastMath#atan2}(b, a).
  892.      * <p>
  893.      * Returns {@link Complex#NaN} if either real or imaginary part of the
  894.      * input argument is {@code NaN}.
  895.      * </p>
  896.      * Infinite (or critical) values in real or imaginary parts of the input may
  897.      * result in infinite or NaN values returned in parts of the result.
  898.      * <pre>
  899.      *  Examples:
  900.      *  <code>
  901.      *   log(1 &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;/2)i
  902.      *   log(INFINITY + i) = INFINITY + 0i
  903.      *   log(-INFINITY + i) = INFINITY + &pi;i
  904.      *   log(INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;/4)i
  905.      *   log(-INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (3&pi;/4)i
  906.      *   log(0 + 0i) = -INFINITY + 0i
  907.      *  </code>
  908.      * </pre>
  909.      *
  910.      * @return the value <code>ln &nbsp; this</code>, the natural logarithm
  911.      * of {@code this}.
  912.      */
  913.     @Override
  914.     public Complex log() {
  915.         if (isNaN) {
  916.             return NaN;
  917.         }

  918.         return createComplex(FastMath.log(FastMath.hypot(real, imaginary)),
  919.                              FastMath.atan2(imaginary, real));
  920.     }

  921.     /** {@inheritDoc}
  922.      * @since 1.7
  923.      */
  924.     @Override
  925.     public Complex log1p() {
  926.         return add(1.0).log();
  927.     }

  928.     /** {@inheritDoc}
  929.      * @since 1.7
  930.      */
  931.     @Override
  932.     public Complex log10() {
  933.         return log().divide(LOG10);
  934.     }

  935.     /**
  936.      * Returns of value of this complex number raised to the power of {@code x}.
  937.      * <p>
  938.      * If {@code x} is a real number whose real part has an integer value, returns {@link #pow(int)},
  939.      * if both {@code this} and {@code x} are real and {@link FastMath#pow(double, double)}
  940.      * with the corresponding real arguments would return a finite number (neither NaN
  941.      * nor infinite), then returns the same value converted to {@code Complex},
  942.      * with the same special cases.
  943.      * In all other cases real cases, implements y<sup>x</sup> = exp(x&middot;log(y)).
  944.      * </p>
  945.      *
  946.      * @param  x exponent to which this {@code Complex} is to be raised.
  947.      * @return <code> this<sup>x</sup></code>.
  948.      * @throws NullArgumentException if x is {@code null}.
  949.      */
  950.     @Override
  951.     public Complex pow(Complex x)
  952.         throws NullArgumentException {

  953.         MathUtils.checkNotNull(x);

  954.         if (x.imaginary == 0.0) {
  955.             final int nx = (int) FastMath.rint(x.real);
  956.             if (x.real == nx) {
  957.                 // integer power
  958.                 return pow(nx);
  959.             } else if (this.imaginary == 0.0) {
  960.                 // check real implementation that handles a bunch of special cases
  961.                 final double realPow = FastMath.pow(this.real, x.real);
  962.                 if (Double.isFinite(realPow)) {
  963.                     return createComplex(realPow, 0);
  964.                 }
  965.             }
  966.         }

  967.         // generic implementation
  968.         return this.log().multiply(x).exp();

  969.     }


  970.     /**
  971.      * Returns of value of this complex number raised to the power of {@code x}.
  972.      * <p>
  973.      * If {@code x} has an integer value, returns {@link #pow(int)},
  974.      * if {@code this} is real and {@link FastMath#pow(double, double)}
  975.      * with the corresponding real arguments would return a finite number (neither NaN
  976.      * nor infinite), then returns the same value converted to {@code Complex},
  977.      * with the same special cases.
  978.      * In all other cases real cases, implements y<sup>x</sup> = exp(x&middot;log(y)).
  979.      * </p>
  980.      *
  981.      * @param  x exponent to which this {@code Complex} is to be raised.
  982.      * @return <code> this<sup>x</sup></code>.
  983.      */
  984.     @Override
  985.     public Complex pow(double x) {

  986.         final int nx = (int) FastMath.rint(x);
  987.         if (x == nx) {
  988.             // integer power
  989.             return pow(nx);
  990.         } else if (this.imaginary == 0.0) {
  991.             // check real implementation that handles a bunch of special cases
  992.             final double realPow = FastMath.pow(this.real, x);
  993.             if (Double.isFinite(realPow)) {
  994.                 return createComplex(realPow, 0);
  995.             }
  996.         }

  997.         // generic implementation
  998.         return this.log().multiply(x).exp();

  999.     }

  1000.      /** {@inheritDoc}
  1001.       * @since 1.7
  1002.       */
  1003.     @Override
  1004.     public Complex pow(final int n) {

  1005.         Complex result = ONE;
  1006.         final boolean invert;
  1007.         int p = n;
  1008.         if (p < 0) {
  1009.             invert = true;
  1010.             p = -p;
  1011.         } else {
  1012.             invert = false;
  1013.         }

  1014.         // Exponentiate by successive squaring
  1015.         Complex square = this;
  1016.         while (p > 0) {
  1017.             if ((p & 0x1) > 0) {
  1018.                 result = result.multiply(square);
  1019.             }
  1020.             square = square.multiply(square);
  1021.             p = p >> 1;
  1022.         }

  1023.         return invert ? result.reciprocal() : result;

  1024.     }

  1025.      /**
  1026.       * Compute the
  1027.      * <a href="http://mathworld.wolfram.com/Sine.html" TARGET="_top">
  1028.      * sine</a>
  1029.      * of this complex number.
  1030.      * Implements the formula:
  1031.      * <pre>
  1032.      *  <code>
  1033.      *   sin(a + bi) = sin(a)cosh(b) + cos(a)sinh(b)i
  1034.      *  </code>
  1035.      * </pre>
  1036.      * where the (real) functions on the right-hand side are
  1037.      * {@link FastMath#sin}, {@link FastMath#cos},
  1038.      * {@link FastMath#cosh} and {@link FastMath#sinh}.
  1039.      * <p>
  1040.      * Returns {@link Complex#NaN} if either real or imaginary part of the
  1041.      * input argument is {@code NaN}.
  1042.      * </p><p>
  1043.      * Infinite values in real or imaginary parts of the input may result in
  1044.      * infinite or {@code NaN} values returned in parts of the result.
  1045.      * <pre>
  1046.      *  Examples:
  1047.      *  <code>
  1048.      *   sin(1 &plusmn; INFINITY i) = 1 &plusmn; INFINITY i
  1049.      *   sin(&plusmn;INFINITY + i) = NaN + NaN i
  1050.      *   sin(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
  1051.      *  </code>
  1052.      * </pre>
  1053.      *
  1054.      * @return the sine of this complex number.
  1055.      */
  1056.     @Override
  1057.     public Complex sin() {
  1058.         if (isNaN) {
  1059.             return NaN;
  1060.         }

  1061.         final SinCos   scr  = FastMath.sinCos(real);
  1062.         final SinhCosh schi = FastMath.sinhCosh(imaginary);
  1063.         return createComplex(scr.sin() * schi.cosh(), scr.cos() * schi.sinh());

  1064.     }

  1065.     /** {@inheritDoc}
  1066.      */
  1067.     @Override
  1068.     public FieldSinCos<Complex> sinCos() {
  1069.         if (isNaN) {
  1070.             return new FieldSinCos<>(NaN, NaN);
  1071.         }

  1072.         final SinCos scr = FastMath.sinCos(real);
  1073.         final SinhCosh schi = FastMath.sinhCosh(imaginary);
  1074.         return new FieldSinCos<>(createComplex(scr.sin() * schi.cosh(),  scr.cos() * schi.sinh()),
  1075.                                  createComplex(scr.cos() * schi.cosh(), -scr.sin() * schi.sinh()));
  1076.     }

  1077.     /** {@inheritDoc}
  1078.      * @since 1.7
  1079.      */
  1080.     @Override
  1081.     public Complex atan2(Complex x) {

  1082.         // compute r = sqrt(x^2+y^2)
  1083.         final Complex r = x.square().add(multiply(this)).sqrt();

  1084.         if (FastMath.copySign(1.0, x.real) >= 0) {
  1085.             // compute atan2(y, x) = 2 atan(y / (r + x))
  1086.             return divide(r.add(x)).atan().multiply(2);
  1087.         } else {
  1088.             // compute atan2(y, x) = +/- pi - 2 atan(y / (r - x))
  1089.             return divide(r.subtract(x)).atan().multiply(-2).add(FastMath.PI);
  1090.         }
  1091.     }

  1092.     /** {@inheritDoc}
  1093.      * <p>
  1094.      * Branch cuts are on the real axis, below +1.
  1095.      * </p>
  1096.      * @since 1.7
  1097.      */
  1098.     @Override
  1099.     public Complex acosh() {
  1100.         final Complex sqrtPlus  = add(1).sqrt();
  1101.         final Complex sqrtMinus = subtract(1).sqrt();
  1102.         return add(sqrtPlus.multiply(sqrtMinus)).log();
  1103.     }

  1104.     /** {@inheritDoc}
  1105.      * <p>
  1106.      * Branch cuts are on the imaginary axis, above +i and below -i.
  1107.      * </p>
  1108.      * @since 1.7
  1109.      */
  1110.     @Override
  1111.     public Complex asinh() {
  1112.         return add(multiply(this).add(1.0).sqrt()).log();
  1113.     }

  1114.     /** {@inheritDoc}
  1115.      * <p>
  1116.      * Branch cuts are on the real axis, above +1 and below -1.
  1117.      * </p>
  1118.      * @since 1.7
  1119.      */
  1120.     @Override
  1121.     public Complex atanh() {
  1122.         final Complex logPlus  = add(1).log();
  1123.         final Complex logMinus = createComplex(1 - real, -imaginary).log();
  1124.         return logPlus.subtract(logMinus).multiply(0.5);
  1125.     }

  1126.     /**
  1127.      * Compute the
  1128.      * <a href="http://mathworld.wolfram.com/HyperbolicSine.html" TARGET="_top">
  1129.      * hyperbolic sine</a> of this complex number.
  1130.      * Implements the formula:
  1131.      * <pre>
  1132.      *  <code>
  1133.      *   sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i
  1134.      *  </code>
  1135.      * </pre>
  1136.      * where the (real) functions on the right-hand side are
  1137.      * {@link FastMath#sin}, {@link FastMath#cos},
  1138.      * {@link FastMath#cosh} and {@link FastMath#sinh}.
  1139.      * <p>
  1140.      * Returns {@link Complex#NaN} if either real or imaginary part of the
  1141.      * input argument is {@code NaN}.
  1142.      * </p><p>
  1143.      * Infinite values in real or imaginary parts of the input may result in
  1144.      * infinite or NaN values returned in parts of the result.
  1145.      * <pre>
  1146.      *  Examples:
  1147.      *  <code>
  1148.      *   sinh(1 &plusmn; INFINITY i) = NaN + NaN i
  1149.      *   sinh(&plusmn;INFINITY + i) = &plusmn; INFINITY + INFINITY i
  1150.      *   sinh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
  1151.      *  </code>
  1152.      * </pre>
  1153.      *
  1154.      * @return the hyperbolic sine of {@code this}.
  1155.      */
  1156.     @Override
  1157.     public Complex sinh() {
  1158.         if (isNaN) {
  1159.             return NaN;
  1160.         }

  1161.         final SinhCosh schr = FastMath.sinhCosh(real);
  1162.         final SinCos   sci  = FastMath.sinCos(imaginary);
  1163.         return createComplex(schr.sinh() * sci.cos(), schr.cosh() * sci.sin());
  1164.     }

  1165.     /** {@inheritDoc}
  1166.      */
  1167.     @Override
  1168.     public FieldSinhCosh<Complex> sinhCosh() {
  1169.         if (isNaN) {
  1170.             return new FieldSinhCosh<>(NaN, NaN);
  1171.         }

  1172.         final SinhCosh schr = FastMath.sinhCosh(real);
  1173.         final SinCos   sci  = FastMath.sinCos(imaginary);
  1174.         return new FieldSinhCosh<>(createComplex(schr.sinh() * sci.cos(), schr.cosh() * sci.sin()),
  1175.                                    createComplex(schr.cosh() * sci.cos(), schr.sinh() * sci.sin()));
  1176.     }

  1177.     /**
  1178.      * Compute the
  1179.      * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
  1180.      * square root</a> of this complex number.
  1181.      * Implements the following algorithm to compute {@code sqrt(a + bi)}:
  1182.      * <ol><li>Let {@code t = sqrt((|a| + |a + bi|) / 2)}</li>
  1183.      * <li><pre>if {@code  a ≥ 0} return {@code t + (b/2t)i}
  1184.      *  else return {@code |b|/2t + sign(b)t i }</pre></li>
  1185.      * </ol>
  1186.      * where <ul>
  1187.      * <li>{@code |a| = }{@link FastMath#abs(double) abs(a)}</li>
  1188.      * <li>{@code |a + bi| = }{@link FastMath#hypot(double, double) hypot(a, b)}</li>
  1189.      * <li>{@code sign(b) = }{@link FastMath#copySign(double, double) copySign(1, b)}
  1190.      * </ul>
  1191.      * The real part is therefore always nonnegative.
  1192.      * <p>
  1193.      * Returns {@link Complex#NaN} if either real or imaginary part of the
  1194.      * input argument is {@code NaN}.
  1195.      * </p>
  1196.      * <p>
  1197.      * Infinite values in real or imaginary parts of the input may result in
  1198.      * infinite or NaN values returned in parts of the result.
  1199.      * </p>
  1200.      * <pre>
  1201.      *  Examples:
  1202.      *  <code>
  1203.      *   sqrt(1 ± ∞ i) = ∞ + NaN i
  1204.      *   sqrt(∞ + i) = ∞ + 0i
  1205.      *   sqrt(-∞ + i) = 0 + ∞ i
  1206.      *   sqrt(∞ ± ∞ i) = ∞ + NaN i
  1207.      *   sqrt(-∞ ± ∞ i) = NaN ± ∞ i
  1208.      *  </code>
  1209.      * </pre>
  1210.      *
  1211.      * @return the square root of {@code this} with nonnegative real part.
  1212.      */
  1213.     @Override
  1214.     public Complex sqrt() {
  1215.         if (isNaN) {
  1216.             return NaN;
  1217.         }

  1218.         if (real == 0.0 && imaginary == 0.0) {
  1219.             return ZERO;
  1220.         }

  1221.         double t = FastMath.sqrt((FastMath.abs(real) + FastMath.hypot(real, imaginary)) * 0.5);
  1222.         if (FastMath.copySign(1, real) >= 0.0) {
  1223.             return createComplex(t, imaginary / (2.0 * t));
  1224.         } else {
  1225.             return createComplex(FastMath.abs(imaginary) / (2.0 * t),
  1226.                                  FastMath.copySign(t, imaginary));
  1227.         }
  1228.     }

  1229.     /**
  1230.      * Compute the
  1231.      * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
  1232.      * square root</a> of <code>1 - this<sup>2</sup></code> for this complex
  1233.      * number.
  1234.      * Computes the result directly as
  1235.      * {@code sqrt(ONE.subtract(z.square()))}.
  1236.      * <p>
  1237.      * Returns {@link Complex#NaN} if either real or imaginary part of the
  1238.      * input argument is {@code NaN}.
  1239.      * </p>
  1240.      * Infinite values in real or imaginary parts of the input may result in
  1241.      * infinite or NaN values returned in parts of the result.
  1242.      *
  1243.      * @return the square root of <code>1 - this<sup>2</sup></code>.
  1244.      */
  1245.     public Complex sqrt1z() {
  1246.         final Complex t2 = this.square();
  1247.         return createComplex(1 - t2.real, -t2.imaginary).sqrt();
  1248.     }

  1249.     /** {@inheritDoc}
  1250.      * <p>
  1251.      * This implementation compute the principal cube root by using a branch cut along real negative axis.
  1252.      * </p>
  1253.      * @since 1.7
  1254.      */
  1255.     @Override
  1256.     public Complex cbrt() {
  1257.         final double magnitude = FastMath.cbrt(norm());
  1258.         final SinCos sc        = FastMath.sinCos(getArgument() / 3);
  1259.         return createComplex(magnitude * sc.cos(), magnitude * sc.sin());
  1260.     }

  1261.     /** {@inheritDoc}
  1262.      * <p>
  1263.      * This implementation compute the principal n<sup>th</sup> root by using a branch cut along real negative axis.
  1264.      * </p>
  1265.      * @since 1.7
  1266.      */
  1267.     @Override
  1268.     public Complex rootN(int n) {
  1269.         final double magnitude = FastMath.pow(norm(), 1.0 / n);
  1270.         final SinCos sc        = FastMath.sinCos(getArgument() / n);
  1271.         return createComplex(magnitude * sc.cos(), magnitude * sc.sin());
  1272.     }

  1273.     /**
  1274.      * Compute the
  1275.      * <a href="http://mathworld.wolfram.com/Tangent.html" TARGET="_top">
  1276.      * tangent</a> of this complex number.
  1277.      * Implements the formula:
  1278.      * <pre>
  1279.      *  <code>
  1280.      *   tan(a + bi) = sin(2a)/(cos(2a)+cosh(2b)) + [sinh(2b)/(cos(2a)+cosh(2b))]i
  1281.      *  </code>
  1282.      * </pre>
  1283.      * where the (real) functions on the right-hand side are
  1284.      * {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and
  1285.      * {@link FastMath#sinh}.
  1286.      * <p>
  1287.      * Returns {@link Complex#NaN} if either real or imaginary part of the
  1288.      * input argument is {@code NaN}.
  1289.      * </p>
  1290.      * Infinite (or critical) values in real or imaginary parts of the input may
  1291.      * result in infinite or NaN values returned in parts of the result.
  1292.      * <pre>
  1293.      *  Examples:
  1294.      *  <code>
  1295.      *   tan(a &plusmn; INFINITY i) = 0 &plusmn; i
  1296.      *   tan(&plusmn;INFINITY + bi) = NaN + NaN i
  1297.      *   tan(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
  1298.      *   tan(&plusmn;&pi;/2 + 0 i) = &plusmn;INFINITY + NaN i
  1299.      *  </code>
  1300.      * </pre>
  1301.      *
  1302.      * @return the tangent of {@code this}.
  1303.      */
  1304.     @Override
  1305.     public Complex tan() {
  1306.         if (isNaN || Double.isInfinite(real)) {
  1307.             return NaN;
  1308.         }
  1309.         if (imaginary > 20.0) {
  1310.             return I;
  1311.         }
  1312.         if (imaginary < -20.0) {
  1313.             return MINUS_I;
  1314.         }

  1315.         final SinCos sc2r = FastMath.sinCos(2.0 * real);
  1316.         double imaginary2 = 2.0 * imaginary;
  1317.         double d = sc2r.cos() + FastMath.cosh(imaginary2);

  1318.         return createComplex(sc2r.sin() / d, FastMath.sinh(imaginary2) / d);

  1319.     }

  1320.     /**
  1321.      * Compute the
  1322.      * <a href="http://mathworld.wolfram.com/HyperbolicTangent.html" TARGET="_top">
  1323.      * hyperbolic tangent</a> of this complex number.
  1324.      * Implements the formula:
  1325.      * <pre>
  1326.      *  <code>
  1327.      *   tan(a + bi) = sinh(2a)/(cosh(2a)+cos(2b)) + [sin(2b)/(cosh(2a)+cos(2b))]i
  1328.      *  </code>
  1329.      * </pre>
  1330.      * where the (real) functions on the right-hand side are
  1331.      * {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and
  1332.      * {@link FastMath#sinh}.
  1333.      * <p>
  1334.      * Returns {@link Complex#NaN} if either real or imaginary part of the
  1335.      * input argument is {@code NaN}.
  1336.      * </p>
  1337.      * Infinite values in real or imaginary parts of the input may result in
  1338.      * infinite or NaN values returned in parts of the result.
  1339.      * <pre>
  1340.      *  Examples:
  1341.      *  <code>
  1342.      *   tanh(a &plusmn; INFINITY i) = NaN + NaN i
  1343.      *   tanh(&plusmn;INFINITY + bi) = &plusmn;1 + 0 i
  1344.      *   tanh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
  1345.      *   tanh(0 + (&pi;/2)i) = NaN + INFINITY i
  1346.      *  </code>
  1347.      * </pre>
  1348.      *
  1349.      * @return the hyperbolic tangent of {@code this}.
  1350.      */
  1351.     @Override
  1352.     public Complex tanh() {
  1353.         if (isNaN || Double.isInfinite(imaginary)) {
  1354.             return NaN;
  1355.         }
  1356.         if (real > 20.0) {
  1357.             return ONE;
  1358.         }
  1359.         if (real < -20.0) {
  1360.             return MINUS_ONE;
  1361.         }
  1362.         double real2 = 2.0 * real;
  1363.         final SinCos sc2i = FastMath.sinCos(2.0 * imaginary);
  1364.         double d = FastMath.cosh(real2) + sc2i.cos();

  1365.         return createComplex(FastMath.sinh(real2) / d, sc2i.sin() / d);
  1366.     }



  1367.     /**
  1368.      * Compute the argument of this complex number.
  1369.      * The argument is the angle phi between the positive real axis and
  1370.      * the point representing this number in the complex plane.
  1371.      * The value returned is between -PI (not inclusive)
  1372.      * and PI (inclusive), with negative values returned for numbers with
  1373.      * negative imaginary parts.
  1374.      * <p>
  1375.      * If either real or imaginary part (or both) is NaN, NaN is returned.
  1376.      * Infinite parts are handled as {@code Math.atan2} handles them,
  1377.      * essentially treating finite parts as zero in the presence of an
  1378.      * infinite coordinate and returning a multiple of pi/4 depending on
  1379.      * the signs of the infinite parts.
  1380.      * See the javadoc for {@code Math.atan2} for full details.
  1381.      *
  1382.      * @return the argument of {@code this}.
  1383.      */
  1384.     public double getArgument() {
  1385.         return FastMath.atan2(getImaginaryPart(), getRealPart());
  1386.     }

  1387.     /**
  1388.      * Computes the n-th roots of this complex number.
  1389.      * The nth roots are defined by the formula:
  1390.      * <pre>
  1391.      *  <code>
  1392.      *   z<sub>k</sub> = abs<sup>1/n</sup> (cos(phi + 2&pi;k/n) + i (sin(phi + 2&pi;k/n))
  1393.      *  </code>
  1394.      * </pre>
  1395.      * for <i>{@code k=0, 1, ..., n-1}</i>, where {@code abs} and {@code phi}
  1396.      * are respectively the {@link #abs() modulus} and
  1397.      * {@link #getArgument() argument} of this complex number.
  1398.      * <p>
  1399.      * If one or both parts of this complex number is NaN, a list with just
  1400.      * one element, {@link #NaN} is returned.
  1401.      * if neither part is NaN, but at least one part is infinite, the result
  1402.      * is a one-element list containing {@link #INF}.
  1403.      *
  1404.      * @param n Degree of root.
  1405.      * @return a List of all {@code n}-th roots of {@code this}.
  1406.      * @throws MathIllegalArgumentException if {@code n <= 0}.
  1407.      */
  1408.     public List<Complex> nthRoot(int n) throws MathIllegalArgumentException {

  1409.         if (n <= 0) {
  1410.             throw new MathIllegalArgumentException(LocalizedCoreFormats.CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N,
  1411.                                                    n);
  1412.         }

  1413.         final List<Complex> result = new ArrayList<>();

  1414.         if (isNaN) {
  1415.             result.add(NaN);
  1416.             return result;
  1417.         }
  1418.         if (isInfinite()) {
  1419.             result.add(INF);
  1420.             return result;
  1421.         }

  1422.         // nth root of abs -- faster / more accurate to use a solver here?
  1423.         final double nthRootOfAbs = FastMath.pow(FastMath.hypot(real, imaginary), 1.0 / n);

  1424.         // Compute nth roots of complex number with k = 0, 1, ... n-1
  1425.         final double nthPhi = getArgument() / n;
  1426.         final double slice = 2 * FastMath.PI / n;
  1427.         double innerPart = nthPhi;
  1428.         for (int k = 0; k < n ; k++) {
  1429.             // inner part
  1430.             final SinCos scInner = FastMath.sinCos(innerPart);
  1431.             final double realPart = nthRootOfAbs *  scInner.cos();
  1432.             final double imaginaryPart = nthRootOfAbs *  scInner.sin();
  1433.             result.add(createComplex(realPart, imaginaryPart));
  1434.             innerPart += slice;
  1435.         }

  1436.         return result;
  1437.     }

  1438.     /**
  1439.      * Create a complex number given the real and imaginary parts.
  1440.      *
  1441.      * @param realPart Real part.
  1442.      * @param imaginaryPart Imaginary part.
  1443.      * @return a new complex number instance.
  1444.      *
  1445.      * @see #valueOf(double, double)
  1446.      */
  1447.     protected Complex createComplex(double realPart,
  1448.                                     double imaginaryPart) {
  1449.         return new Complex(realPart, imaginaryPart);
  1450.     }

  1451.     /**
  1452.      * Create a complex number given the real and imaginary parts.
  1453.      *
  1454.      * @param realPart Real part.
  1455.      * @param imaginaryPart Imaginary part.
  1456.      * @return a Complex instance.
  1457.      */
  1458.     public static Complex valueOf(double realPart,
  1459.                                   double imaginaryPart) {
  1460.         if (Double.isNaN(realPart) ||
  1461.             Double.isNaN(imaginaryPart)) {
  1462.             return NaN;
  1463.         }
  1464.         return new Complex(realPart, imaginaryPart);
  1465.     }

  1466.     /**
  1467.      * Create a complex number given only the real part.
  1468.      *
  1469.      * @param realPart Real part.
  1470.      * @return a Complex instance.
  1471.      */
  1472.     public static Complex valueOf(double realPart) {
  1473.         if (Double.isNaN(realPart)) {
  1474.             return NaN;
  1475.         }
  1476.         return new Complex(realPart);
  1477.     }

  1478.     /** {@inheritDoc} */
  1479.     @Override
  1480.     public Complex newInstance(double realPart) {
  1481.         return valueOf(realPart);
  1482.     }

  1483.     /**
  1484.      * Resolve the transient fields in a deserialized Complex Object.
  1485.      * Subclasses will need to override {@link #createComplex} to
  1486.      * deserialize properly.
  1487.      *
  1488.      * @return A Complex instance with all fields resolved.
  1489.      */
  1490.     protected final Object readResolve() {
  1491.         return createComplex(real, imaginary);
  1492.     }

  1493.     /** {@inheritDoc} */
  1494.     @Override
  1495.     public ComplexField getField() {
  1496.         return ComplexField.getInstance();
  1497.     }

  1498.     /** {@inheritDoc} */
  1499.     @Override
  1500.     public String toString() {
  1501.         return "(" + real + ", " + imaginary + ")";
  1502.     }

  1503.     /** {@inheritDoc}
  1504.      * @since 1.7
  1505.      */
  1506.     @Override
  1507.     public Complex scalb(int n) {
  1508.         return createComplex(FastMath.scalb(real, n), FastMath.scalb(imaginary, n));
  1509.     }

  1510.     /** {@inheritDoc}
  1511.      */
  1512.     @Override
  1513.     public Complex ulp() {
  1514.         return createComplex(FastMath.ulp(real), FastMath.ulp(imaginary));
  1515.     }

  1516.     /** {@inheritDoc}
  1517.      * @since 1.7
  1518.      */
  1519.     @Override
  1520.     public Complex hypot(Complex y) {
  1521.         if (isInfinite() || y.isInfinite()) {
  1522.             return INF;
  1523.         } else if (isNaN() || y.isNaN()) {
  1524.             return NaN;
  1525.         } else {
  1526.             return square().add(y.square()).sqrt();
  1527.         }
  1528.     }

  1529.     /** {@inheritDoc}
  1530.      * @since 1.7
  1531.      */
  1532.     @Override
  1533.     public Complex linearCombination(final Complex[] a, final Complex[] b)
  1534.         throws MathIllegalArgumentException {
  1535.         final int n = 2 * a.length;
  1536.         final double[] realA      = new double[n];
  1537.         final double[] realB      = new double[n];
  1538.         final double[] imaginaryA = new double[n];
  1539.         final double[] imaginaryB = new double[n];
  1540.         for (int i = 0; i < a.length; ++i)  {
  1541.             final Complex ai = a[i];
  1542.             final Complex bi = b[i];
  1543.             realA[2 * i    ]      = +ai.real;
  1544.             realA[2 * i + 1]      = -ai.imaginary;
  1545.             realB[2 * i    ]      = +bi.real;
  1546.             realB[2 * i + 1]      = +bi.imaginary;
  1547.             imaginaryA[2 * i    ] = +ai.real;
  1548.             imaginaryA[2 * i + 1] = +ai.imaginary;
  1549.             imaginaryB[2 * i    ] = +bi.imaginary;
  1550.             imaginaryB[2 * i + 1] = +bi.real;
  1551.         }
  1552.         return createComplex(MathArrays.linearCombination(realA,  realB),
  1553.                              MathArrays.linearCombination(imaginaryA, imaginaryB));
  1554.     }

  1555.     /** {@inheritDoc}
  1556.      * @since 1.7
  1557.      */
  1558.     @Override
  1559.     public Complex linearCombination(final double[] a, final Complex[] b)
  1560.         throws MathIllegalArgumentException {
  1561.         final int n = a.length;
  1562.         final double[] realB      = new double[n];
  1563.         final double[] imaginaryB = new double[n];
  1564.         for (int i = 0; i < a.length; ++i)  {
  1565.             final Complex bi = b[i];
  1566.             realB[i]      = +bi.real;
  1567.             imaginaryB[i] = +bi.imaginary;
  1568.         }
  1569.         return createComplex(MathArrays.linearCombination(a,  realB),
  1570.                              MathArrays.linearCombination(a, imaginaryB));
  1571.     }

  1572.     /** {@inheritDoc}
  1573.      * @since 1.7
  1574.      */
  1575.     @Override
  1576.     public Complex linearCombination(final Complex a1, final Complex b1, final Complex a2, final Complex b2) {
  1577.         return createComplex(MathArrays.linearCombination(+a1.real, b1.real,
  1578.                                                           -a1.imaginary, b1.imaginary,
  1579.                                                           +a2.real, b2.real,
  1580.                                                           -a2.imaginary, b2.imaginary),
  1581.                              MathArrays.linearCombination(+a1.real, b1.imaginary,
  1582.                                                           +a1.imaginary, b1.real,
  1583.                                                           +a2.real, b2.imaginary,
  1584.                                                           +a2.imaginary, b2.real));
  1585.     }

  1586.     /** {@inheritDoc}
  1587.      * @since 1.7
  1588.      */
  1589.     @Override
  1590.     public Complex linearCombination(final double a1, final Complex b1, final double a2, final Complex b2) {
  1591.         return createComplex(MathArrays.linearCombination(a1, b1.real,
  1592.                                                           a2, b2.real),
  1593.                              MathArrays.linearCombination(a1, b1.imaginary,
  1594.                                                           a2, b2.imaginary));
  1595.     }

  1596.     /** {@inheritDoc}
  1597.      * @since 1.7
  1598.      */
  1599.     @Override
  1600.     public Complex linearCombination(final Complex a1, final Complex b1,
  1601.                                      final Complex a2, final Complex b2,
  1602.                                      final Complex a3, final Complex b3) {
  1603.         return linearCombination(new Complex[] { a1, a2, a3 },
  1604.                                  new Complex[] { b1, b2, b3 });
  1605.     }

  1606.     /** {@inheritDoc}
  1607.      * @since 1.7
  1608.      */
  1609.     @Override
  1610.     public Complex linearCombination(final double a1, final Complex b1,
  1611.                                      final double a2, final Complex b2,
  1612.                                      final double a3, final Complex b3) {
  1613.         return linearCombination(new double[]  { a1, a2, a3 },
  1614.                                  new Complex[] { b1, b2, b3 });
  1615.     }

  1616.     /** {@inheritDoc}
  1617.      * @since 1.7
  1618.      */
  1619.     @Override
  1620.     public Complex linearCombination(final Complex a1, final Complex b1,
  1621.                                      final Complex a2, final Complex b2,
  1622.                                      final Complex a3, final Complex b3,
  1623.                                      final Complex a4, final Complex b4) {
  1624.         return linearCombination(new Complex[] { a1, a2, a3, a4 },
  1625.                                  new Complex[] { b1, b2, b3, b4 });
  1626.     }

  1627.     /** {@inheritDoc}
  1628.      * @since 1.7
  1629.      */
  1630.     @Override
  1631.     public Complex linearCombination(final double a1, final Complex b1,
  1632.                                      final double a2, final Complex b2,
  1633.                                      final double a3, final Complex b3,
  1634.                                      final double a4, final Complex b4) {
  1635.         return linearCombination(new double[]  { a1, a2, a3, a4 },
  1636.                                  new Complex[] { b1, b2, b3, b4 });
  1637.     }

  1638.     /** {@inheritDoc} */
  1639.     @Override
  1640.     public Complex getPi() {
  1641.         return PI;
  1642.     }

  1643.     /** {@inheritDoc}
  1644.      * @since 1.7
  1645.      */
  1646.     @Override
  1647.     public Complex ceil() {
  1648.         return createComplex(FastMath.ceil(getRealPart()), FastMath.ceil(getImaginaryPart()));
  1649.     }

  1650.     /** {@inheritDoc}
  1651.      * @since 1.7
  1652.      */
  1653.     @Override
  1654.     public Complex floor() {
  1655.         return createComplex(FastMath.floor(getRealPart()), FastMath.floor(getImaginaryPart()));
  1656.     }

  1657.     /** {@inheritDoc}
  1658.      * @since 1.7
  1659.      */
  1660.     @Override
  1661.     public Complex rint() {
  1662.         return createComplex(FastMath.rint(getRealPart()), FastMath.rint(getImaginaryPart()));
  1663.     }

  1664.     /** {@inheritDoc}
  1665.      * <p>
  1666.      * for complex numbers, the integer n corresponding to {@code this.subtract(remainder(a)).divide(a)}
  1667.      * is a <a href="https://en.wikipedia.org/wiki/Gaussian_integer">Wikipedia - Gaussian integer</a>.
  1668.      * </p>
  1669.      * @since 1.7
  1670.      */
  1671.     @Override
  1672.     public Complex remainder(final double a) {
  1673.         return createComplex(FastMath.IEEEremainder(getRealPart(), a), FastMath.IEEEremainder(getImaginaryPart(), a));
  1674.     }

  1675.     /** {@inheritDoc}
  1676.      * <p>
  1677.      * for complex numbers, the integer n corresponding to {@code this.subtract(remainder(a)).divide(a)}
  1678.      * is a <a href="https://en.wikipedia.org/wiki/Gaussian_integer">Wikipedia - Gaussian integer</a>.
  1679.      * </p>
  1680.      * @since 1.7
  1681.      */
  1682.     @Override
  1683.     public Complex remainder(final Complex a) {
  1684.         final Complex complexQuotient = divide(a);
  1685.         final double  qRInt           = FastMath.rint(complexQuotient.real);
  1686.         final double  qIInt           = FastMath.rint(complexQuotient.imaginary);
  1687.         return createComplex(real - qRInt * a.real + qIInt * a.imaginary,
  1688.                              imaginary - qRInt * a.imaginary - qIInt * a.real);
  1689.     }

  1690.     /** {@inheritDoc}
  1691.      * @since 2.0
  1692.      */
  1693.     @Override
  1694.     public Complex sign() {
  1695.         if (isNaN() || isZero()) {
  1696.             return this;
  1697.         } else {
  1698.             return this.divide(FastMath.hypot(real, imaginary));
  1699.         }
  1700.     }

  1701.     /** {@inheritDoc}
  1702.      * <p>
  1703.      * The signs of real and imaginary parts are copied independently.
  1704.      * </p>
  1705.      * @since 1.7
  1706.      */
  1707.     @Override
  1708.     public Complex copySign(final Complex z) {
  1709.         return createComplex(FastMath.copySign(getRealPart(), z.getRealPart()),
  1710.                              FastMath.copySign(getImaginaryPart(), z.getImaginaryPart()));
  1711.     }

  1712.     /** {@inheritDoc}
  1713.      * @since 1.7
  1714.      */
  1715.     @Override
  1716.     public Complex copySign(double r) {
  1717.         return createComplex(FastMath.copySign(getRealPart(), r), FastMath.copySign(getImaginaryPart(), r));
  1718.     }

  1719.     /** {@inheritDoc} */
  1720.     @Override
  1721.     public Complex toDegrees() {
  1722.         return createComplex(FastMath.toDegrees(getRealPart()), FastMath.toDegrees(getImaginaryPart()));
  1723.     }

  1724.     /** {@inheritDoc} */
  1725.     @Override
  1726.     public Complex toRadians() {
  1727.         return createComplex(FastMath.toRadians(getRealPart()), FastMath.toRadians(getImaginaryPart()));
  1728.     }

  1729.     /** {@inheritDoc}
  1730.      * <p>
  1731.      * Comparison us performed using real ordering as the primary sort order and
  1732.      * imaginary ordering as the secondary sort order.
  1733.      * </p>
  1734.      * @since 3.0
  1735.      */
  1736.     @Override
  1737.     public int compareTo(final Complex o) {
  1738.         final int cR = Double.compare(getReal(), o.getReal());
  1739.         if (cR == 0) {
  1740.             return Double.compare(getImaginary(),o.getImaginary());
  1741.         } else {
  1742.             return cR;
  1743.         }
  1744.     }

  1745. }