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