001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.commons.math3.complex; 019 020 import java.io.Serializable; 021 import java.util.ArrayList; 022 import java.util.List; 023 024 import org.apache.commons.math3.FieldElement; 025 import org.apache.commons.math3.exception.NotPositiveException; 026 import org.apache.commons.math3.exception.NullArgumentException; 027 import org.apache.commons.math3.exception.util.LocalizedFormats; 028 import org.apache.commons.math3.util.FastMath; 029 import org.apache.commons.math3.util.MathUtils; 030 031 /** 032 * Representation of a Complex number, i.e. a number which has both a 033 * real and imaginary part. 034 * <br/> 035 * Implementations of arithmetic operations handle {@code NaN} and 036 * infinite values according to the rules for {@link java.lang.Double}, i.e. 037 * {@link #equals} is an equivalence relation for all instances that have 038 * a {@code NaN} in either real or imaginary part, e.g. the following are 039 * considered equal: 040 * <ul> 041 * <li>{@code 1 + NaNi}</li> 042 * <li>{@code NaN + i}</li> 043 * <li>{@code NaN + NaNi}</li> 044 * </ul> 045 * Note that this is in contradiction with the IEEE-754 standard for floating 046 * point numbers (according to which the test {@code x == x} must fail if 047 * {@code x} is {@code NaN}). The method 048 * {@link org.apache.commons.math3.util.Precision#equals(double,double,int) 049 * equals for primitive double} in {@link org.apache.commons.math3.util.Precision} 050 * conforms with IEEE-754 while this class conforms with the standard behavior 051 * for Java object types. 052 * <br/> 053 * Implements Serializable since 2.0 054 * 055 * @version $Id: Complex.java 1416643 2012-12-03 19:37:14Z tn $ 056 */ 057 public class Complex implements FieldElement<Complex>, Serializable { 058 /** The square root of -1. A number representing "0.0 + 1.0i" */ 059 public static final Complex I = new Complex(0.0, 1.0); 060 // CHECKSTYLE: stop ConstantName 061 /** A complex number representing "NaN + NaNi" */ 062 public static final Complex NaN = new Complex(Double.NaN, Double.NaN); 063 // CHECKSTYLE: resume ConstantName 064 /** A complex number representing "+INF + INFi" */ 065 public static final Complex INF = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); 066 /** A complex number representing "1.0 + 0.0i" */ 067 public static final Complex ONE = new Complex(1.0, 0.0); 068 /** A complex number representing "0.0 + 0.0i" */ 069 public static final Complex ZERO = new Complex(0.0, 0.0); 070 071 /** Serializable version identifier */ 072 private static final long serialVersionUID = -6195664516687396620L; 073 074 /** The imaginary part. */ 075 private final double imaginary; 076 /** The real part. */ 077 private final double real; 078 /** Record whether this complex number is equal to NaN. */ 079 private final transient boolean isNaN; 080 /** Record whether this complex number is infinite. */ 081 private final transient boolean isInfinite; 082 083 /** 084 * Create a complex number given only the real part. 085 * 086 * @param real Real part. 087 */ 088 public Complex(double real) { 089 this(real, 0.0); 090 } 091 092 /** 093 * Create a complex number given the real and imaginary parts. 094 * 095 * @param real Real part. 096 * @param imaginary Imaginary part. 097 */ 098 public Complex(double real, double imaginary) { 099 this.real = real; 100 this.imaginary = imaginary; 101 102 isNaN = Double.isNaN(real) || Double.isNaN(imaginary); 103 isInfinite = !isNaN && 104 (Double.isInfinite(real) || Double.isInfinite(imaginary)); 105 } 106 107 /** 108 * Return the absolute value of this complex number. 109 * Returns {@code NaN} if either real or imaginary part is {@code NaN} 110 * and {@code Double.POSITIVE_INFINITY} if neither part is {@code NaN}, 111 * but at least one part is infinite. 112 * 113 * @return the absolute value. 114 */ 115 public double abs() { 116 if (isNaN) { 117 return Double.NaN; 118 } 119 if (isInfinite()) { 120 return Double.POSITIVE_INFINITY; 121 } 122 if (FastMath.abs(real) < FastMath.abs(imaginary)) { 123 if (imaginary == 0.0) { 124 return FastMath.abs(real); 125 } 126 double q = real / imaginary; 127 return FastMath.abs(imaginary) * FastMath.sqrt(1 + q * q); 128 } else { 129 if (real == 0.0) { 130 return FastMath.abs(imaginary); 131 } 132 double q = imaginary / real; 133 return FastMath.abs(real) * FastMath.sqrt(1 + q * q); 134 } 135 } 136 137 /** 138 * Returns a {@code Complex} whose value is 139 * {@code (this + addend)}. 140 * Uses the definitional formula 141 * <pre> 142 * <code> 143 * (a + bi) + (c + di) = (a+c) + (b+d)i 144 * </code> 145 * </pre> 146 * <br/> 147 * If either {@code this} or {@code addend} has a {@code NaN} value in 148 * either part, {@link #NaN} is returned; otherwise {@code Infinite} 149 * and {@code NaN} values are returned in the parts of the result 150 * according to the rules for {@link java.lang.Double} arithmetic. 151 * 152 * @param addend Value to be added to this {@code Complex}. 153 * @return {@code this + addend}. 154 * @throws NullArgumentException if {@code addend} is {@code null}. 155 */ 156 public Complex add(Complex addend) throws NullArgumentException { 157 MathUtils.checkNotNull(addend); 158 if (isNaN || addend.isNaN) { 159 return NaN; 160 } 161 162 return createComplex(real + addend.getReal(), 163 imaginary + addend.getImaginary()); 164 } 165 166 /** 167 * Returns a {@code Complex} whose value is {@code (this + addend)}, 168 * with {@code addend} interpreted as a real number. 169 * 170 * @param addend Value to be added to this {@code Complex}. 171 * @return {@code this + addend}. 172 * @see #add(Complex) 173 */ 174 public Complex add(double addend) { 175 if (isNaN || Double.isNaN(addend)) { 176 return NaN; 177 } 178 179 return createComplex(real + addend, imaginary); 180 } 181 182 /** 183 * Return the conjugate of this complex number. 184 * The conjugate of {@code a + bi} is {@code a - bi}. 185 * <br/> 186 * {@link #NaN} is returned if either the real or imaginary 187 * part of this Complex number equals {@code Double.NaN}. 188 * <br/> 189 * If the imaginary part is infinite, and the real part is not 190 * {@code NaN}, the returned value has infinite imaginary part 191 * of the opposite sign, e.g. the conjugate of 192 * {@code 1 + POSITIVE_INFINITY i} is {@code 1 - NEGATIVE_INFINITY i}. 193 * 194 * @return the conjugate of this Complex object. 195 */ 196 public Complex conjugate() { 197 if (isNaN) { 198 return NaN; 199 } 200 201 return createComplex(real, -imaginary); 202 } 203 204 /** 205 * Returns a {@code Complex} whose value is 206 * {@code (this / divisor)}. 207 * Implements the definitional formula 208 * <pre> 209 * <code> 210 * a + bi ac + bd + (bc - ad)i 211 * ----------- = ------------------------- 212 * c + di c<sup>2</sup> + d<sup>2</sup> 213 * </code> 214 * </pre> 215 * but uses 216 * <a href="http://doi.acm.org/10.1145/1039813.1039814"> 217 * prescaling of operands</a> to limit the effects of overflows and 218 * underflows in the computation. 219 * <br/> 220 * {@code Infinite} and {@code NaN} values are handled according to the 221 * following rules, applied in the order presented: 222 * <ul> 223 * <li>If either {@code this} or {@code divisor} has a {@code NaN} value 224 * in either part, {@link #NaN} is returned. 225 * </li> 226 * <li>If {@code divisor} equals {@link #ZERO}, {@link #NaN} is returned. 227 * </li> 228 * <li>If {@code this} and {@code divisor} are both infinite, 229 * {@link #NaN} is returned. 230 * </li> 231 * <li>If {@code this} is finite (i.e., has no {@code Infinite} or 232 * {@code NaN} parts) and {@code divisor} is infinite (one or both parts 233 * infinite), {@link #ZERO} is returned. 234 * </li> 235 * <li>If {@code this} is infinite and {@code divisor} is finite, 236 * {@code NaN} values are returned in the parts of the result if the 237 * {@link java.lang.Double} rules applied to the definitional formula 238 * force {@code NaN} results. 239 * </li> 240 * </ul> 241 * 242 * @param divisor Value by which this {@code Complex} is to be divided. 243 * @return {@code this / divisor}. 244 * @throws NullArgumentException if {@code divisor} is {@code null}. 245 */ 246 public Complex divide(Complex divisor) 247 throws NullArgumentException { 248 MathUtils.checkNotNull(divisor); 249 if (isNaN || divisor.isNaN) { 250 return NaN; 251 } 252 253 final double c = divisor.getReal(); 254 final double d = divisor.getImaginary(); 255 if (c == 0.0 && d == 0.0) { 256 return NaN; 257 } 258 259 if (divisor.isInfinite() && !isInfinite()) { 260 return ZERO; 261 } 262 263 if (FastMath.abs(c) < FastMath.abs(d)) { 264 double q = c / d; 265 double denominator = c * q + d; 266 return createComplex((real * q + imaginary) / denominator, 267 (imaginary * q - real) / denominator); 268 } else { 269 double q = d / c; 270 double denominator = d * q + c; 271 return createComplex((imaginary * q + real) / denominator, 272 (imaginary - real * q) / denominator); 273 } 274 } 275 276 /** 277 * Returns a {@code Complex} whose value is {@code (this / divisor)}, 278 * with {@code divisor} interpreted as a real number. 279 * 280 * @param divisor Value by which this {@code Complex} is to be divided. 281 * @return {@code this / divisor}. 282 * @see #divide(Complex) 283 */ 284 public Complex divide(double divisor) { 285 if (isNaN || Double.isNaN(divisor)) { 286 return NaN; 287 } 288 if (divisor == 0d) { 289 return NaN; 290 } 291 if (Double.isInfinite(divisor)) { 292 return !isInfinite() ? ZERO : NaN; 293 } 294 return createComplex(real / divisor, 295 imaginary / divisor); 296 } 297 298 /** {@inheritDoc} */ 299 public Complex reciprocal() { 300 if (isNaN) { 301 return NaN; 302 } 303 304 if (real == 0.0 && imaginary == 0.0) { 305 return NaN; 306 } 307 308 if (isInfinite) { 309 return ZERO; 310 } 311 312 if (FastMath.abs(real) < FastMath.abs(imaginary)) { 313 double q = real / imaginary; 314 double scale = 1. / (real * q + imaginary); 315 return createComplex(scale * q, -scale); 316 } else { 317 double q = imaginary / real; 318 double scale = 1. / (imaginary * q + real); 319 return createComplex(scale, -scale * q); 320 } 321 } 322 323 /** 324 * Test for the equality of two Complex objects. 325 * If both the real and imaginary parts of two complex numbers 326 * are exactly the same, and neither is {@code Double.NaN}, the two 327 * Complex objects are considered to be equal. 328 * All {@code NaN} values are considered to be equal - i.e, if either 329 * (or both) real and imaginary parts of the complex number are equal 330 * to {@code Double.NaN}, the complex number is equal to 331 * {@code NaN}. 332 * 333 * @param other Object to test for equality to this 334 * @return true if two Complex objects are equal, false if object is 335 * {@code null}, not an instance of Complex, or not equal to this Complex 336 * instance. 337 */ 338 @Override 339 public boolean equals(Object other) { 340 if (this == other) { 341 return true; 342 } 343 if (other instanceof Complex){ 344 Complex c = (Complex)other; 345 if (c.isNaN) { 346 return isNaN; 347 } else { 348 return (real == c.real) && (imaginary == c.imaginary); 349 } 350 } 351 return false; 352 } 353 354 /** 355 * Get a hashCode for the complex number. 356 * Any {@code Double.NaN} value in real or imaginary part produces 357 * the same hash code {@code 7}. 358 * 359 * @return a hash code value for this object. 360 */ 361 @Override 362 public int hashCode() { 363 if (isNaN) { 364 return 7; 365 } 366 return 37 * (17 * MathUtils.hash(imaginary) + 367 MathUtils.hash(real)); 368 } 369 370 /** 371 * Access the imaginary part. 372 * 373 * @return the imaginary part. 374 */ 375 public double getImaginary() { 376 return imaginary; 377 } 378 379 /** 380 * Access the real part. 381 * 382 * @return the real part. 383 */ 384 public double getReal() { 385 return real; 386 } 387 388 /** 389 * Checks whether either or both parts of this complex number is 390 * {@code NaN}. 391 * 392 * @return true if either or both parts of this complex number is 393 * {@code NaN}; false otherwise. 394 */ 395 public boolean isNaN() { 396 return isNaN; 397 } 398 399 /** 400 * Checks whether either the real or imaginary part of this complex number 401 * takes an infinite value (either {@code Double.POSITIVE_INFINITY} or 402 * {@code Double.NEGATIVE_INFINITY}) and neither part 403 * is {@code NaN}. 404 * 405 * @return true if one or both parts of this complex number are infinite 406 * and neither part is {@code NaN}. 407 */ 408 public boolean isInfinite() { 409 return isInfinite; 410 } 411 412 /** 413 * Returns a {@code Complex} whose value is {@code this * factor}. 414 * Implements preliminary checks for {@code NaN} and infinity followed by 415 * the definitional formula: 416 * <pre> 417 * <code> 418 * (a + bi)(c + di) = (ac - bd) + (ad + bc)i 419 * </code> 420 * </pre> 421 * Returns {@link #NaN} if either {@code this} or {@code factor} has one or 422 * more {@code NaN} parts. 423 * <br/> 424 * Returns {@link #INF} if neither {@code this} nor {@code factor} has one 425 * or more {@code NaN} parts and if either {@code this} or {@code factor} 426 * has one or more infinite parts (same result is returned regardless of 427 * the sign of the components). 428 * <br/> 429 * Returns finite values in components of the result per the definitional 430 * formula in all remaining cases. 431 * 432 * @param factor value to be multiplied by this {@code Complex}. 433 * @return {@code this * factor}. 434 * @throws NullArgumentException if {@code factor} is {@code null}. 435 */ 436 public Complex multiply(Complex factor) 437 throws NullArgumentException { 438 MathUtils.checkNotNull(factor); 439 if (isNaN || factor.isNaN) { 440 return NaN; 441 } 442 if (Double.isInfinite(real) || 443 Double.isInfinite(imaginary) || 444 Double.isInfinite(factor.real) || 445 Double.isInfinite(factor.imaginary)) { 446 // we don't use isInfinite() to avoid testing for NaN again 447 return INF; 448 } 449 return createComplex(real * factor.real - imaginary * factor.imaginary, 450 real * factor.imaginary + imaginary * factor.real); 451 } 452 453 /** 454 * Returns a {@code Complex} whose value is {@code this * factor}, with {@code factor} 455 * interpreted as a integer number. 456 * 457 * @param factor value to be multiplied by this {@code Complex}. 458 * @return {@code this * factor}. 459 * @see #multiply(Complex) 460 */ 461 public Complex multiply(final int factor) { 462 if (isNaN) { 463 return NaN; 464 } 465 if (Double.isInfinite(real) || 466 Double.isInfinite(imaginary)) { 467 return INF; 468 } 469 return createComplex(real * factor, imaginary * factor); 470 } 471 472 /** 473 * Returns a {@code Complex} whose value is {@code this * factor}, with {@code factor} 474 * interpreted as a real number. 475 * 476 * @param factor value to be multiplied by this {@code Complex}. 477 * @return {@code this * factor}. 478 * @see #multiply(Complex) 479 */ 480 public Complex multiply(double factor) { 481 if (isNaN || Double.isNaN(factor)) { 482 return NaN; 483 } 484 if (Double.isInfinite(real) || 485 Double.isInfinite(imaginary) || 486 Double.isInfinite(factor)) { 487 // we don't use isInfinite() to avoid testing for NaN again 488 return INF; 489 } 490 return createComplex(real * factor, imaginary * factor); 491 } 492 493 /** 494 * Returns a {@code Complex} whose value is {@code (-this)}. 495 * Returns {@code NaN} if either real or imaginary 496 * part of this Complex number equals {@code Double.NaN}. 497 * 498 * @return {@code -this}. 499 */ 500 public Complex negate() { 501 if (isNaN) { 502 return NaN; 503 } 504 505 return createComplex(-real, -imaginary); 506 } 507 508 /** 509 * Returns a {@code Complex} whose value is 510 * {@code (this - subtrahend)}. 511 * Uses the definitional formula 512 * <pre> 513 * <code> 514 * (a + bi) - (c + di) = (a-c) + (b-d)i 515 * </code> 516 * </pre> 517 * If either {@code this} or {@code subtrahend} has a {@code NaN]} value in either part, 518 * {@link #NaN} is returned; otherwise infinite and {@code NaN} values are 519 * returned in the parts of the result according to the rules for 520 * {@link java.lang.Double} arithmetic. 521 * 522 * @param subtrahend value to be subtracted from this {@code Complex}. 523 * @return {@code this - subtrahend}. 524 * @throws NullArgumentException if {@code subtrahend} is {@code null}. 525 */ 526 public Complex subtract(Complex subtrahend) 527 throws NullArgumentException { 528 MathUtils.checkNotNull(subtrahend); 529 if (isNaN || subtrahend.isNaN) { 530 return NaN; 531 } 532 533 return createComplex(real - subtrahend.getReal(), 534 imaginary - subtrahend.getImaginary()); 535 } 536 537 /** 538 * Returns a {@code Complex} whose value is 539 * {@code (this - subtrahend)}. 540 * 541 * @param subtrahend value to be subtracted from this {@code Complex}. 542 * @return {@code this - subtrahend}. 543 * @see #subtract(Complex) 544 */ 545 public Complex subtract(double subtrahend) { 546 if (isNaN || Double.isNaN(subtrahend)) { 547 return NaN; 548 } 549 return createComplex(real - subtrahend, imaginary); 550 } 551 552 /** 553 * Compute the 554 * <a href="http://mathworld.wolfram.com/InverseCosine.html" TARGET="_top"> 555 * inverse cosine</a> of this complex number. 556 * Implements the formula: 557 * <pre> 558 * <code> 559 * acos(z) = -i (log(z + i (sqrt(1 - z<sup>2</sup>)))) 560 * </code> 561 * </pre> 562 * Returns {@link Complex#NaN} if either real or imaginary part of the 563 * input argument is {@code NaN} or infinite. 564 * 565 * @return the inverse cosine of this complex number. 566 * @since 1.2 567 */ 568 public Complex acos() { 569 if (isNaN) { 570 return NaN; 571 } 572 573 return this.add(this.sqrt1z().multiply(I)).log().multiply(I.negate()); 574 } 575 576 /** 577 * Compute the 578 * <a href="http://mathworld.wolfram.com/InverseSine.html" TARGET="_top"> 579 * inverse sine</a> of this complex number. 580 * Implements the formula: 581 * <pre> 582 * <code> 583 * asin(z) = -i (log(sqrt(1 - z<sup>2</sup>) + iz)) 584 * </code> 585 * </pre> 586 * Returns {@link Complex#NaN} if either real or imaginary part of the 587 * input argument is {@code NaN} or infinite. 588 * 589 * @return the inverse sine of this complex number. 590 * @since 1.2 591 */ 592 public Complex asin() { 593 if (isNaN) { 594 return NaN; 595 } 596 597 return sqrt1z().add(this.multiply(I)).log().multiply(I.negate()); 598 } 599 600 /** 601 * Compute the 602 * <a href="http://mathworld.wolfram.com/InverseTangent.html" TARGET="_top"> 603 * inverse tangent</a> of this complex number. 604 * Implements the formula: 605 * <pre> 606 * <code> 607 * atan(z) = (i/2) log((i + z)/(i - z)) 608 * </code> 609 * </pre> 610 * Returns {@link Complex#NaN} if either real or imaginary part of the 611 * input argument is {@code NaN} or infinite. 612 * 613 * @return the inverse tangent of this complex number 614 * @since 1.2 615 */ 616 public Complex atan() { 617 if (isNaN) { 618 return NaN; 619 } 620 621 return this.add(I).divide(I.subtract(this)).log() 622 .multiply(I.divide(createComplex(2.0, 0.0))); 623 } 624 625 /** 626 * Compute the 627 * <a href="http://mathworld.wolfram.com/Cosine.html" TARGET="_top"> 628 * cosine</a> 629 * of this complex number. 630 * Implements the formula: 631 * <pre> 632 * <code> 633 * cos(a + bi) = cos(a)cosh(b) - sin(a)sinh(b)i 634 * </code> 635 * </pre> 636 * where the (real) functions on the right-hand side are 637 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 638 * {@link FastMath#cosh} and {@link FastMath#sinh}. 639 * <br/> 640 * Returns {@link Complex#NaN} if either real or imaginary part of the 641 * input argument is {@code NaN}. 642 * <br/> 643 * Infinite values in real or imaginary parts of the input may result in 644 * infinite or NaN values returned in parts of the result. 645 * <pre> 646 * Examples: 647 * <code> 648 * cos(1 ± INFINITY i) = 1 ∓ INFINITY i 649 * cos(±INFINITY + i) = NaN + NaN i 650 * cos(±INFINITY ± INFINITY i) = NaN + NaN i 651 * </code> 652 * </pre> 653 * 654 * @return the cosine of this complex number. 655 * @since 1.2 656 */ 657 public Complex cos() { 658 if (isNaN) { 659 return NaN; 660 } 661 662 return createComplex(FastMath.cos(real) * FastMath.cosh(imaginary), 663 -FastMath.sin(real) * FastMath.sinh(imaginary)); 664 } 665 666 /** 667 * Compute the 668 * <a href="http://mathworld.wolfram.com/HyperbolicCosine.html" TARGET="_top"> 669 * hyperbolic cosine</a> of this complex number. 670 * Implements the formula: 671 * <pre> 672 * <code> 673 * cosh(a + bi) = cosh(a)cos(b) + sinh(a)sin(b)i} 674 * </code> 675 * </pre> 676 * where the (real) functions on the right-hand side are 677 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 678 * {@link FastMath#cosh} and {@link FastMath#sinh}. 679 * <br/> 680 * Returns {@link Complex#NaN} if either real or imaginary part of the 681 * input argument is {@code NaN}. 682 * <br/> 683 * Infinite values in real or imaginary parts of the input may result in 684 * infinite or NaN values returned in parts of the result. 685 * <pre> 686 * Examples: 687 * <code> 688 * cosh(1 ± INFINITY i) = NaN + NaN i 689 * cosh(±INFINITY + i) = INFINITY ± INFINITY i 690 * cosh(±INFINITY ± INFINITY i) = NaN + NaN i 691 * </code> 692 * </pre> 693 * 694 * @return the hyperbolic cosine of this complex number. 695 * @since 1.2 696 */ 697 public Complex cosh() { 698 if (isNaN) { 699 return NaN; 700 } 701 702 return createComplex(FastMath.cosh(real) * FastMath.cos(imaginary), 703 FastMath.sinh(real) * FastMath.sin(imaginary)); 704 } 705 706 /** 707 * Compute the 708 * <a href="http://mathworld.wolfram.com/ExponentialFunction.html" TARGET="_top"> 709 * exponential function</a> of this complex number. 710 * Implements the formula: 711 * <pre> 712 * <code> 713 * exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i 714 * </code> 715 * </pre> 716 * where the (real) functions on the right-hand side are 717 * {@link java.lang.Math#exp}, {@link java.lang.Math#cos}, and 718 * {@link java.lang.Math#sin}. 719 * <br/> 720 * Returns {@link Complex#NaN} if either real or imaginary part of the 721 * input argument is {@code NaN}. 722 * <br/> 723 * Infinite values in real or imaginary parts of the input may result in 724 * infinite or NaN values returned in parts of the result. 725 * <pre> 726 * Examples: 727 * <code> 728 * exp(1 ± INFINITY i) = NaN + NaN i 729 * exp(INFINITY + i) = INFINITY + INFINITY i 730 * exp(-INFINITY + i) = 0 + 0i 731 * exp(±INFINITY ± INFINITY i) = NaN + NaN i 732 * </code> 733 * </pre> 734 * 735 * @return <code><i>e</i><sup>this</sup></code>. 736 * @since 1.2 737 */ 738 public Complex exp() { 739 if (isNaN) { 740 return NaN; 741 } 742 743 double expReal = FastMath.exp(real); 744 return createComplex(expReal * FastMath.cos(imaginary), 745 expReal * FastMath.sin(imaginary)); 746 } 747 748 /** 749 * Compute the 750 * <a href="http://mathworld.wolfram.com/NaturalLogarithm.html" TARGET="_top"> 751 * natural logarithm</a> of this complex number. 752 * Implements the formula: 753 * <pre> 754 * <code> 755 * log(a + bi) = ln(|a + bi|) + arg(a + bi)i 756 * </code> 757 * </pre> 758 * where ln on the right hand side is {@link java.lang.Math#log}, 759 * {@code |a + bi|} is the modulus, {@link Complex#abs}, and 760 * {@code arg(a + bi) = }{@link java.lang.Math#atan2}(b, a). 761 * <br/> 762 * Returns {@link Complex#NaN} if either real or imaginary part of the 763 * input argument is {@code NaN}. 764 * <br/> 765 * Infinite (or critical) values in real or imaginary parts of the input may 766 * result in infinite or NaN values returned in parts of the result. 767 * <pre> 768 * Examples: 769 * <code> 770 * log(1 ± INFINITY i) = INFINITY ± (π/2)i 771 * log(INFINITY + i) = INFINITY + 0i 772 * log(-INFINITY + i) = INFINITY + πi 773 * log(INFINITY ± INFINITY i) = INFINITY ± (π/4)i 774 * log(-INFINITY ± INFINITY i) = INFINITY ± (3π/4)i 775 * log(0 + 0i) = -INFINITY + 0i 776 * </code> 777 * </pre> 778 * 779 * @return the value <code>ln this</code>, the natural logarithm 780 * of {@code this}. 781 * @since 1.2 782 */ 783 public Complex log() { 784 if (isNaN) { 785 return NaN; 786 } 787 788 return createComplex(FastMath.log(abs()), 789 FastMath.atan2(imaginary, real)); 790 } 791 792 /** 793 * Returns of value of this complex number raised to the power of {@code x}. 794 * Implements the formula: 795 * <pre> 796 * <code> 797 * y<sup>x</sup> = exp(x·log(y)) 798 * </code> 799 * </pre> 800 * where {@code exp} and {@code log} are {@link #exp} and 801 * {@link #log}, respectively. 802 * <br/> 803 * Returns {@link Complex#NaN} if either real or imaginary part of the 804 * input argument is {@code NaN} or infinite, or if {@code y} 805 * equals {@link Complex#ZERO}. 806 * 807 * @param x exponent to which this {@code Complex} is to be raised. 808 * @return <code> this<sup>{@code x}</sup></code>. 809 * @throws NullArgumentException if x is {@code null}. 810 * @since 1.2 811 */ 812 public Complex pow(Complex x) 813 throws NullArgumentException { 814 MathUtils.checkNotNull(x); 815 return this.log().multiply(x).exp(); 816 } 817 818 /** 819 * Returns of value of this complex number raised to the power of {@code x}. 820 * 821 * @param x exponent to which this {@code Complex} is to be raised. 822 * @return <code>this<sup>x</sup></code>. 823 * @see #pow(Complex) 824 */ 825 public Complex pow(double x) { 826 return this.log().multiply(x).exp(); 827 } 828 829 /** 830 * Compute the 831 * <a href="http://mathworld.wolfram.com/Sine.html" TARGET="_top"> 832 * sine</a> 833 * of this complex number. 834 * Implements the formula: 835 * <pre> 836 * <code> 837 * sin(a + bi) = sin(a)cosh(b) - cos(a)sinh(b)i 838 * </code> 839 * </pre> 840 * where the (real) functions on the right-hand side are 841 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 842 * {@link FastMath#cosh} and {@link FastMath#sinh}. 843 * <br/> 844 * Returns {@link Complex#NaN} if either real or imaginary part of the 845 * input argument is {@code NaN}. 846 * <br/> 847 * Infinite values in real or imaginary parts of the input may result in 848 * infinite or {@code NaN} values returned in parts of the result. 849 * <pre> 850 * Examples: 851 * <code> 852 * sin(1 ± INFINITY i) = 1 ± INFINITY i 853 * sin(±INFINITY + i) = NaN + NaN i 854 * sin(±INFINITY ± INFINITY i) = NaN + NaN i 855 * </code> 856 * </pre> 857 * 858 * @return the sine of this complex number. 859 * @since 1.2 860 */ 861 public Complex sin() { 862 if (isNaN) { 863 return NaN; 864 } 865 866 return createComplex(FastMath.sin(real) * FastMath.cosh(imaginary), 867 FastMath.cos(real) * FastMath.sinh(imaginary)); 868 } 869 870 /** 871 * Compute the 872 * <a href="http://mathworld.wolfram.com/HyperbolicSine.html" TARGET="_top"> 873 * hyperbolic sine</a> of this complex number. 874 * Implements the formula: 875 * <pre> 876 * <code> 877 * sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i 878 * </code> 879 * </pre> 880 * where the (real) functions on the right-hand side are 881 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 882 * {@link FastMath#cosh} and {@link FastMath#sinh}. 883 * <br/> 884 * Returns {@link Complex#NaN} if either real or imaginary part of the 885 * input argument is {@code NaN}. 886 * <br/> 887 * Infinite values in real or imaginary parts of the input may result in 888 * infinite or NaN values returned in parts of the result. 889 * <pre> 890 * Examples: 891 * <code> 892 * sinh(1 ± INFINITY i) = NaN + NaN i 893 * sinh(±INFINITY + i) = ± INFINITY + INFINITY i 894 * sinh(±INFINITY ± INFINITY i) = NaN + NaN i 895 * </code> 896 * </pre> 897 * 898 * @return the hyperbolic sine of {@code this}. 899 * @since 1.2 900 */ 901 public Complex sinh() { 902 if (isNaN) { 903 return NaN; 904 } 905 906 return createComplex(FastMath.sinh(real) * FastMath.cos(imaginary), 907 FastMath.cosh(real) * FastMath.sin(imaginary)); 908 } 909 910 /** 911 * Compute the 912 * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top"> 913 * square root</a> of this complex number. 914 * Implements the following algorithm to compute {@code sqrt(a + bi)}: 915 * <ol><li>Let {@code t = sqrt((|a| + |a + bi|) / 2)}</li> 916 * <li><pre>if {@code a ≥ 0} return {@code t + (b/2t)i} 917 * else return {@code |b|/2t + sign(b)t i }</pre></li> 918 * </ol> 919 * where <ul> 920 * <li>{@code |a| = }{@link Math#abs}(a)</li> 921 * <li>{@code |a + bi| = }{@link Complex#abs}(a + bi)</li> 922 * <li>{@code sign(b) = }{@link FastMath#copySign(double,double) copySign(1d, b)} 923 * </ul> 924 * <br/> 925 * Returns {@link Complex#NaN} if either real or imaginary part of the 926 * input argument is {@code NaN}. 927 * <br/> 928 * Infinite values in real or imaginary parts of the input may result in 929 * infinite or NaN values returned in parts of the result. 930 * <pre> 931 * Examples: 932 * <code> 933 * sqrt(1 ± INFINITY i) = INFINITY + NaN i 934 * sqrt(INFINITY + i) = INFINITY + 0i 935 * sqrt(-INFINITY + i) = 0 + INFINITY i 936 * sqrt(INFINITY ± INFINITY i) = INFINITY + NaN i 937 * sqrt(-INFINITY ± INFINITY i) = NaN ± INFINITY i 938 * </code> 939 * </pre> 940 * 941 * @return the square root of {@code this}. 942 * @since 1.2 943 */ 944 public Complex sqrt() { 945 if (isNaN) { 946 return NaN; 947 } 948 949 if (real == 0.0 && imaginary == 0.0) { 950 return createComplex(0.0, 0.0); 951 } 952 953 double t = FastMath.sqrt((FastMath.abs(real) + abs()) / 2.0); 954 if (real >= 0.0) { 955 return createComplex(t, imaginary / (2.0 * t)); 956 } else { 957 return createComplex(FastMath.abs(imaginary) / (2.0 * t), 958 FastMath.copySign(1d, imaginary) * t); 959 } 960 } 961 962 /** 963 * Compute the 964 * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top"> 965 * square root</a> of <code>1 - this<sup>2</sup></code> for this complex 966 * number. 967 * Computes the result directly as 968 * {@code sqrt(ONE.subtract(z.multiply(z)))}. 969 * <br/> 970 * Returns {@link Complex#NaN} if either real or imaginary part of the 971 * input argument is {@code NaN}. 972 * <br/> 973 * Infinite values in real or imaginary parts of the input may result in 974 * infinite or NaN values returned in parts of the result. 975 * 976 * @return the square root of <code>1 - this<sup>2</sup></code>. 977 * @since 1.2 978 */ 979 public Complex sqrt1z() { 980 return createComplex(1.0, 0.0).subtract(this.multiply(this)).sqrt(); 981 } 982 983 /** 984 * Compute the 985 * <a href="http://mathworld.wolfram.com/Tangent.html" TARGET="_top"> 986 * tangent</a> of this complex number. 987 * Implements the formula: 988 * <pre> 989 * <code> 990 * tan(a + bi) = sin(2a)/(cos(2a)+cosh(2b)) + [sinh(2b)/(cos(2a)+cosh(2b))]i 991 * </code> 992 * </pre> 993 * where the (real) functions on the right-hand side are 994 * {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and 995 * {@link FastMath#sinh}. 996 * <br/> 997 * Returns {@link Complex#NaN} if either real or imaginary part of the 998 * input argument is {@code NaN}. 999 * <br/> 1000 * Infinite (or critical) values in real or imaginary parts of the input may 1001 * result in infinite or NaN values returned in parts of the result. 1002 * <pre> 1003 * Examples: 1004 * <code> 1005 * tan(a ± INFINITY i) = 0 ± i 1006 * tan(±INFINITY + bi) = NaN + NaN i 1007 * tan(±INFINITY ± INFINITY i) = NaN + NaN i 1008 * tan(±π/2 + 0 i) = ±INFINITY + NaN i 1009 * </code> 1010 * </pre> 1011 * 1012 * @return the tangent of {@code this}. 1013 * @since 1.2 1014 */ 1015 public Complex tan() { 1016 if (isNaN || Double.isInfinite(real)) { 1017 return NaN; 1018 } 1019 if (imaginary > 20.0) { 1020 return createComplex(0.0, 1.0); 1021 } 1022 if (imaginary < -20.0) { 1023 return createComplex(0.0, -1.0); 1024 } 1025 1026 double real2 = 2.0 * real; 1027 double imaginary2 = 2.0 * imaginary; 1028 double d = FastMath.cos(real2) + FastMath.cosh(imaginary2); 1029 1030 return createComplex(FastMath.sin(real2) / d, 1031 FastMath.sinh(imaginary2) / d); 1032 } 1033 1034 /** 1035 * Compute the 1036 * <a href="http://mathworld.wolfram.com/HyperbolicTangent.html" TARGET="_top"> 1037 * hyperbolic tangent</a> of this complex number. 1038 * Implements the formula: 1039 * <pre> 1040 * <code> 1041 * tan(a + bi) = sinh(2a)/(cosh(2a)+cos(2b)) + [sin(2b)/(cosh(2a)+cos(2b))]i 1042 * </code> 1043 * </pre> 1044 * where the (real) functions on the right-hand side are 1045 * {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and 1046 * {@link FastMath#sinh}. 1047 * <br/> 1048 * Returns {@link Complex#NaN} if either real or imaginary part of the 1049 * input argument is {@code NaN}. 1050 * <br/> 1051 * Infinite values in real or imaginary parts of the input may result in 1052 * infinite or NaN values returned in parts of the result. 1053 * <pre> 1054 * Examples: 1055 * <code> 1056 * tanh(a ± INFINITY i) = NaN + NaN i 1057 * tanh(±INFINITY + bi) = ±1 + 0 i 1058 * tanh(±INFINITY ± INFINITY i) = NaN + NaN i 1059 * tanh(0 + (π/2)i) = NaN + INFINITY i 1060 * </code> 1061 * </pre> 1062 * 1063 * @return the hyperbolic tangent of {@code this}. 1064 * @since 1.2 1065 */ 1066 public Complex tanh() { 1067 if (isNaN || Double.isInfinite(imaginary)) { 1068 return NaN; 1069 } 1070 if (real > 20.0) { 1071 return createComplex(1.0, 0.0); 1072 } 1073 if (real < -20.0) { 1074 return createComplex(-1.0, 0.0); 1075 } 1076 double real2 = 2.0 * real; 1077 double imaginary2 = 2.0 * imaginary; 1078 double d = FastMath.cosh(real2) + FastMath.cos(imaginary2); 1079 1080 return createComplex(FastMath.sinh(real2) / d, 1081 FastMath.sin(imaginary2) / d); 1082 } 1083 1084 1085 1086 /** 1087 * Compute the argument of this complex number. 1088 * The argument is the angle phi between the positive real axis and 1089 * the point representing this number in the complex plane. 1090 * The value returned is between -PI (not inclusive) 1091 * and PI (inclusive), with negative values returned for numbers with 1092 * negative imaginary parts. 1093 * <br/> 1094 * If either real or imaginary part (or both) is NaN, NaN is returned. 1095 * Infinite parts are handled as {@code Math.atan2} handles them, 1096 * essentially treating finite parts as zero in the presence of an 1097 * infinite coordinate and returning a multiple of pi/4 depending on 1098 * the signs of the infinite parts. 1099 * See the javadoc for {@code Math.atan2} for full details. 1100 * 1101 * @return the argument of {@code this}. 1102 */ 1103 public double getArgument() { 1104 return FastMath.atan2(getImaginary(), getReal()); 1105 } 1106 1107 /** 1108 * Computes the n-th roots of this complex number. 1109 * The nth roots are defined by the formula: 1110 * <pre> 1111 * <code> 1112 * z<sub>k</sub> = abs<sup>1/n</sup> (cos(phi + 2πk/n) + i (sin(phi + 2πk/n)) 1113 * </code> 1114 * </pre> 1115 * for <i>{@code k=0, 1, ..., n-1}</i>, where {@code abs} and {@code phi} 1116 * are respectively the {@link #abs() modulus} and 1117 * {@link #getArgument() argument} of this complex number. 1118 * <br/> 1119 * If one or both parts of this complex number is NaN, a list with just 1120 * one element, {@link #NaN} is returned. 1121 * if neither part is NaN, but at least one part is infinite, the result 1122 * is a one-element list containing {@link #INF}. 1123 * 1124 * @param n Degree of root. 1125 * @return a List<Complex> of all {@code n}-th roots of {@code this}. 1126 * @throws NotPositiveException if {@code n <= 0}. 1127 * @since 2.0 1128 */ 1129 public List<Complex> nthRoot(int n) throws NotPositiveException { 1130 1131 if (n <= 0) { 1132 throw new NotPositiveException(LocalizedFormats.CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N, 1133 n); 1134 } 1135 1136 final List<Complex> result = new ArrayList<Complex>(); 1137 1138 if (isNaN) { 1139 result.add(NaN); 1140 return result; 1141 } 1142 if (isInfinite()) { 1143 result.add(INF); 1144 return result; 1145 } 1146 1147 // nth root of abs -- faster / more accurate to use a solver here? 1148 final double nthRootOfAbs = FastMath.pow(abs(), 1.0 / n); 1149 1150 // Compute nth roots of complex number with k = 0, 1, ... n-1 1151 final double nthPhi = getArgument() / n; 1152 final double slice = 2 * FastMath.PI / n; 1153 double innerPart = nthPhi; 1154 for (int k = 0; k < n ; k++) { 1155 // inner part 1156 final double realPart = nthRootOfAbs * FastMath.cos(innerPart); 1157 final double imaginaryPart = nthRootOfAbs * FastMath.sin(innerPart); 1158 result.add(createComplex(realPart, imaginaryPart)); 1159 innerPart += slice; 1160 } 1161 1162 return result; 1163 } 1164 1165 /** 1166 * Create a complex number given the real and imaginary parts. 1167 * 1168 * @param realPart Real part. 1169 * @param imaginaryPart Imaginary part. 1170 * @return a new complex number instance. 1171 * @since 1.2 1172 * @see #valueOf(double, double) 1173 */ 1174 protected Complex createComplex(double realPart, 1175 double imaginaryPart) { 1176 return new Complex(realPart, imaginaryPart); 1177 } 1178 1179 /** 1180 * Create a complex number given the real and imaginary parts. 1181 * 1182 * @param realPart Real part. 1183 * @param imaginaryPart Imaginary part. 1184 * @return a Complex instance. 1185 */ 1186 public static Complex valueOf(double realPart, 1187 double imaginaryPart) { 1188 if (Double.isNaN(realPart) || 1189 Double.isNaN(imaginaryPart)) { 1190 return NaN; 1191 } 1192 return new Complex(realPart, imaginaryPart); 1193 } 1194 1195 /** 1196 * Create a complex number given only the real part. 1197 * 1198 * @param realPart Real part. 1199 * @return a Complex instance. 1200 */ 1201 public static Complex valueOf(double realPart) { 1202 if (Double.isNaN(realPart)) { 1203 return NaN; 1204 } 1205 return new Complex(realPart); 1206 } 1207 1208 /** 1209 * Resolve the transient fields in a deserialized Complex Object. 1210 * Subclasses will need to override {@link #createComplex} to 1211 * deserialize properly. 1212 * 1213 * @return A Complex instance with all fields resolved. 1214 * @since 2.0 1215 */ 1216 protected final Object readResolve() { 1217 return createComplex(real, imaginary); 1218 } 1219 1220 /** {@inheritDoc} */ 1221 public ComplexField getField() { 1222 return ComplexField.getInstance(); 1223 } 1224 1225 /** {@inheritDoc} */ 1226 @Override 1227 public String toString() { 1228 return "(" + real + ", " + imaginary + ")"; 1229 } 1230 1231 }