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 }