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