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 * http://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 package org.apache.commons.math.complex; 19 20 import java.io.Serializable; 21 import java.util.ArrayList; 22 import java.util.List; 23 24 import org.apache.commons.math.FieldElement; 25 import org.apache.commons.math.MathRuntimeException; 26 import org.apache.commons.math.exception.util.LocalizedFormats; 27 import org.apache.commons.math.util.MathUtils; 28 import org.apache.commons.math.util.FastMath; 29 30 /** 31 * Representation of a Complex number - a number which has both a 32 * real and imaginary part. 33 * <p> 34 * Implementations of arithmetic operations handle <code>NaN</code> and 35 * infinite values according to the rules for {@link java.lang.Double} 36 * arithmetic, applying definitional formulas and returning <code>NaN</code> or 37 * infinite values in real or imaginary parts as these arise in computation. 38 * See individual method javadocs for details.</p> 39 * <p> 40 * {@link #equals} identifies all values with <code>NaN</code> in either real 41 * or imaginary part - e.g., <pre> 42 * <code>1 + NaNi == NaN + i == NaN + NaNi.</code></pre></p> 43 * 44 * implements Serializable since 2.0 45 * 46 * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $ 47 */ 48 public class Complex implements FieldElement<Complex>, Serializable { 49 50 /** The square root of -1. A number representing "0.0 + 1.0i" */ 51 public static final Complex I = new Complex(0.0, 1.0); 52 53 // CHECKSTYLE: stop ConstantName 54 /** A complex number representing "NaN + NaNi" */ 55 public static final Complex NaN = new Complex(Double.NaN, Double.NaN); 56 // CHECKSTYLE: resume ConstantName 57 58 /** A complex number representing "+INF + INFi" */ 59 public static final Complex INF = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); 60 61 /** A complex number representing "1.0 + 0.0i" */ 62 public static final Complex ONE = new Complex(1.0, 0.0); 63 64 /** A complex number representing "0.0 + 0.0i" */ 65 public static final Complex ZERO = new Complex(0.0, 0.0); 66 67 /** Serializable version identifier */ 68 private static final long serialVersionUID = -6195664516687396620L; 69 70 /** The imaginary part. */ 71 private final double imaginary; 72 73 /** The real part. */ 74 private final double real; 75 76 /** Record whether this complex number is equal to NaN. */ 77 private final transient boolean isNaN; 78 79 /** Record whether this complex number is infinite. */ 80 private final transient boolean isInfinite; 81 82 /** 83 * Create a complex number given the real and imaginary parts. 84 * 85 * @param real the real part 86 * @param imaginary the imaginary part 87 */ Complex(double real, double imaginary)88 public Complex(double real, double imaginary) { 89 super(); 90 this.real = real; 91 this.imaginary = imaginary; 92 93 isNaN = Double.isNaN(real) || Double.isNaN(imaginary); 94 isInfinite = !isNaN && 95 (Double.isInfinite(real) || Double.isInfinite(imaginary)); 96 } 97 98 /** 99 * Return the absolute value of this complex number. 100 * <p> 101 * Returns <code>NaN</code> if either real or imaginary part is 102 * <code>NaN</code> and <code>Double.POSITIVE_INFINITY</code> if 103 * neither part is <code>NaN</code>, but at least one part takes an infinite 104 * value.</p> 105 * 106 * @return the absolute value 107 */ abs()108 public double abs() { 109 if (isNaN()) { 110 return Double.NaN; 111 } 112 113 if (isInfinite()) { 114 return Double.POSITIVE_INFINITY; 115 } 116 117 if (FastMath.abs(real) < FastMath.abs(imaginary)) { 118 if (imaginary == 0.0) { 119 return FastMath.abs(real); 120 } 121 double q = real / imaginary; 122 return FastMath.abs(imaginary) * FastMath.sqrt(1 + q * q); 123 } else { 124 if (real == 0.0) { 125 return FastMath.abs(imaginary); 126 } 127 double q = imaginary / real; 128 return FastMath.abs(real) * FastMath.sqrt(1 + q * q); 129 } 130 } 131 132 /** 133 * Return the sum of this complex number and the given complex number. 134 * <p> 135 * Uses the definitional formula 136 * <pre> 137 * (a + bi) + (c + di) = (a+c) + (b+d)i 138 * </pre></p> 139 * <p> 140 * If either this or <code>rhs</code> has a NaN value in either part, 141 * {@link #NaN} is returned; otherwise Inifinite and NaN values are 142 * returned in the parts of the result according to the rules for 143 * {@link java.lang.Double} arithmetic.</p> 144 * 145 * @param rhs the other complex number 146 * @return the complex number sum 147 * @throws NullPointerException if <code>rhs</code> is null 148 */ add(Complex rhs)149 public Complex add(Complex rhs) { 150 return createComplex(real + rhs.getReal(), 151 imaginary + rhs.getImaginary()); 152 } 153 154 /** 155 * Return the conjugate of this complex number. The conjugate of 156 * "A + Bi" is "A - Bi". 157 * <p> 158 * {@link #NaN} is returned if either the real or imaginary 159 * part of this Complex number equals <code>Double.NaN</code>.</p> 160 * <p> 161 * If the imaginary part is infinite, and the real part is not NaN, 162 * the returned value has infinite imaginary part of the opposite 163 * sign - e.g. the conjugate of <code>1 + POSITIVE_INFINITY i</code> 164 * is <code>1 - NEGATIVE_INFINITY i</code></p> 165 * 166 * @return the conjugate of this Complex object 167 */ conjugate()168 public Complex conjugate() { 169 if (isNaN()) { 170 return NaN; 171 } 172 return createComplex(real, -imaginary); 173 } 174 175 /** 176 * Return the quotient of this complex number and the given complex number. 177 * <p> 178 * Implements the definitional formula 179 * <pre><code> 180 * a + bi ac + bd + (bc - ad)i 181 * ----------- = ------------------------- 182 * c + di c<sup>2</sup> + d<sup>2</sup> 183 * </code></pre> 184 * but uses 185 * <a href="http://doi.acm.org/10.1145/1039813.1039814"> 186 * prescaling of operands</a> to limit the effects of overflows and 187 * underflows in the computation.</p> 188 * <p> 189 * Infinite and NaN values are handled / returned according to the 190 * following rules, applied in the order presented: 191 * <ul> 192 * <li>If either this or <code>rhs</code> has a NaN value in either part, 193 * {@link #NaN} is returned.</li> 194 * <li>If <code>rhs</code> equals {@link #ZERO}, {@link #NaN} is returned. 195 * </li> 196 * <li>If this and <code>rhs</code> are both infinite, 197 * {@link #NaN} is returned.</li> 198 * <li>If this is finite (i.e., has no infinite or NaN parts) and 199 * <code>rhs</code> is infinite (one or both parts infinite), 200 * {@link #ZERO} is returned.</li> 201 * <li>If this is infinite and <code>rhs</code> is finite, NaN values are 202 * returned in the parts of the result if the {@link java.lang.Double} 203 * rules applied to the definitional formula force NaN results.</li> 204 * </ul></p> 205 * 206 * @param rhs the other complex number 207 * @return the complex number quotient 208 * @throws NullPointerException if <code>rhs</code> is null 209 */ divide(Complex rhs)210 public Complex divide(Complex rhs) { 211 if (isNaN() || rhs.isNaN()) { 212 return NaN; 213 } 214 215 double c = rhs.getReal(); 216 double d = rhs.getImaginary(); 217 if (c == 0.0 && d == 0.0) { 218 return NaN; 219 } 220 221 if (rhs.isInfinite() && !isInfinite()) { 222 return ZERO; 223 } 224 225 if (FastMath.abs(c) < FastMath.abs(d)) { 226 double q = c / d; 227 double denominator = c * q + d; 228 return createComplex((real * q + imaginary) / denominator, 229 (imaginary * q - real) / denominator); 230 } else { 231 double q = d / c; 232 double denominator = d * q + c; 233 return createComplex((imaginary * q + real) / denominator, 234 (imaginary - real * q) / denominator); 235 } 236 } 237 238 /** 239 * Test for the equality of two Complex objects. 240 * <p> 241 * If both the real and imaginary parts of two Complex numbers 242 * are exactly the same, and neither is <code>Double.NaN</code>, the two 243 * Complex objects are considered to be equal.</p> 244 * <p> 245 * All <code>NaN</code> values are considered to be equal - i.e, if either 246 * (or both) real and imaginary parts of the complex number are equal 247 * to <code>Double.NaN</code>, the complex number is equal to 248 * <code>Complex.NaN</code>.</p> 249 * 250 * @param other Object to test for equality to this 251 * @return true if two Complex objects are equal, false if 252 * object is null, not an instance of Complex, or 253 * not equal to this Complex instance 254 * 255 */ 256 @Override equals(Object other)257 public boolean equals(Object other) { 258 if (this == other) { 259 return true; 260 } 261 if (other instanceof Complex){ 262 Complex rhs = (Complex)other; 263 if (rhs.isNaN()) { 264 return this.isNaN(); 265 } else { 266 return (real == rhs.real) && (imaginary == rhs.imaginary); 267 } 268 } 269 return false; 270 } 271 272 /** 273 * Get a hashCode for the complex number. 274 * <p> 275 * All NaN values have the same hash code.</p> 276 * 277 * @return a hash code value for this object 278 */ 279 @Override hashCode()280 public int hashCode() { 281 if (isNaN()) { 282 return 7; 283 } 284 return 37 * (17 * MathUtils.hash(imaginary) + 285 MathUtils.hash(real)); 286 } 287 288 /** 289 * Access the imaginary part. 290 * 291 * @return the imaginary part 292 */ getImaginary()293 public double getImaginary() { 294 return imaginary; 295 } 296 297 /** 298 * Access the real part. 299 * 300 * @return the real part 301 */ getReal()302 public double getReal() { 303 return real; 304 } 305 306 /** 307 * Returns true if either or both parts of this complex number is NaN; 308 * false otherwise 309 * 310 * @return true if either or both parts of this complex number is NaN; 311 * false otherwise 312 */ isNaN()313 public boolean isNaN() { 314 return isNaN; 315 } 316 317 /** 318 * Returns true if either the real or imaginary part of this complex number 319 * takes an infinite value (either <code>Double.POSITIVE_INFINITY</code> or 320 * <code>Double.NEGATIVE_INFINITY</code>) and neither part 321 * is <code>NaN</code>. 322 * 323 * @return true if one or both parts of this complex number are infinite 324 * and neither part is <code>NaN</code> 325 */ isInfinite()326 public boolean isInfinite() { 327 return isInfinite; 328 } 329 330 /** 331 * Return the product of this complex number and the given complex number. 332 * <p> 333 * Implements preliminary checks for NaN and infinity followed by 334 * the definitional formula: 335 * <pre><code> 336 * (a + bi)(c + di) = (ac - bd) + (ad + bc)i 337 * </code></pre> 338 * </p> 339 * <p> 340 * Returns {@link #NaN} if either this or <code>rhs</code> has one or more 341 * NaN parts. 342 * </p> 343 * Returns {@link #INF} if neither this nor <code>rhs</code> has one or more 344 * NaN parts and if either this or <code>rhs</code> has one or more 345 * infinite parts (same result is returned regardless of the sign of the 346 * components). 347 * </p> 348 * <p> 349 * Returns finite values in components of the result per the 350 * definitional formula in all remaining cases. 351 * </p> 352 * 353 * @param rhs the other complex number 354 * @return the complex number product 355 * @throws NullPointerException if <code>rhs</code> is null 356 */ multiply(Complex rhs)357 public Complex multiply(Complex rhs) { 358 if (isNaN() || rhs.isNaN()) { 359 return NaN; 360 } 361 if (Double.isInfinite(real) || Double.isInfinite(imaginary) || 362 Double.isInfinite(rhs.real)|| Double.isInfinite(rhs.imaginary)) { 363 // we don't use Complex.isInfinite() to avoid testing for NaN again 364 return INF; 365 } 366 return createComplex(real * rhs.real - imaginary * rhs.imaginary, 367 real * rhs.imaginary + imaginary * rhs.real); 368 } 369 370 /** 371 * Return the product of this complex number and the given scalar number. 372 * <p> 373 * Implements preliminary checks for NaN and infinity followed by 374 * the definitional formula: 375 * <pre><code> 376 * c(a + bi) = (ca) + (cb)i 377 * </code></pre> 378 * </p> 379 * <p> 380 * Returns {@link #NaN} if either this or <code>rhs</code> has one or more 381 * NaN parts. 382 * </p> 383 * Returns {@link #INF} if neither this nor <code>rhs</code> has one or more 384 * NaN parts and if either this or <code>rhs</code> has one or more 385 * infinite parts (same result is returned regardless of the sign of the 386 * components). 387 * </p> 388 * <p> 389 * Returns finite values in components of the result per the 390 * definitional formula in all remaining cases. 391 * </p> 392 * 393 * @param rhs the scalar number 394 * @return the complex number product 395 */ multiply(double rhs)396 public Complex multiply(double rhs) { 397 if (isNaN() || Double.isNaN(rhs)) { 398 return NaN; 399 } 400 if (Double.isInfinite(real) || Double.isInfinite(imaginary) || 401 Double.isInfinite(rhs)) { 402 // we don't use Complex.isInfinite() to avoid testing for NaN again 403 return INF; 404 } 405 return createComplex(real * rhs, imaginary * rhs); 406 } 407 408 /** 409 * Return the additive inverse of this complex number. 410 * <p> 411 * Returns <code>Complex.NaN</code> if either real or imaginary 412 * part of this Complex number equals <code>Double.NaN</code>.</p> 413 * 414 * @return the negation of this complex number 415 */ negate()416 public Complex negate() { 417 if (isNaN()) { 418 return NaN; 419 } 420 421 return createComplex(-real, -imaginary); 422 } 423 424 /** 425 * Return the difference between this complex number and the given complex 426 * number. 427 * <p> 428 * Uses the definitional formula 429 * <pre> 430 * (a + bi) - (c + di) = (a-c) + (b-d)i 431 * </pre></p> 432 * <p> 433 * If either this or <code>rhs</code> has a NaN value in either part, 434 * {@link #NaN} is returned; otherwise inifinite and NaN values are 435 * returned in the parts of the result according to the rules for 436 * {@link java.lang.Double} arithmetic. </p> 437 * 438 * @param rhs the other complex number 439 * @return the complex number difference 440 * @throws NullPointerException if <code>rhs</code> is null 441 */ subtract(Complex rhs)442 public Complex subtract(Complex rhs) { 443 if (isNaN() || rhs.isNaN()) { 444 return NaN; 445 } 446 447 return createComplex(real - rhs.getReal(), 448 imaginary - rhs.getImaginary()); 449 } 450 451 /** 452 * Compute the 453 * <a href="http://mathworld.wolfram.com/InverseCosine.html" TARGET="_top"> 454 * inverse cosine</a> of this complex number. 455 * <p> 456 * Implements the formula: <pre> 457 * <code> acos(z) = -i (log(z + i (sqrt(1 - z<sup>2</sup>))))</code></pre></p> 458 * <p> 459 * Returns {@link Complex#NaN} if either real or imaginary part of the 460 * input argument is <code>NaN</code> or infinite.</p> 461 * 462 * @return the inverse cosine of this complex number 463 * @since 1.2 464 */ acos()465 public Complex acos() { 466 if (isNaN()) { 467 return Complex.NaN; 468 } 469 470 return this.add(this.sqrt1z().multiply(Complex.I)).log() 471 .multiply(Complex.I.negate()); 472 } 473 474 /** 475 * Compute the 476 * <a href="http://mathworld.wolfram.com/InverseSine.html" TARGET="_top"> 477 * inverse sine</a> of this complex number. 478 * <p> 479 * Implements the formula: <pre> 480 * <code> asin(z) = -i (log(sqrt(1 - z<sup>2</sup>) + iz)) </code></pre></p> 481 * <p> 482 * Returns {@link Complex#NaN} if either real or imaginary part of the 483 * input argument is <code>NaN</code> or infinite.</p> 484 * 485 * @return the inverse sine of this complex number. 486 * @since 1.2 487 */ asin()488 public Complex asin() { 489 if (isNaN()) { 490 return Complex.NaN; 491 } 492 493 return sqrt1z().add(this.multiply(Complex.I)).log() 494 .multiply(Complex.I.negate()); 495 } 496 497 /** 498 * Compute the 499 * <a href="http://mathworld.wolfram.com/InverseTangent.html" TARGET="_top"> 500 * inverse tangent</a> of this complex number. 501 * <p> 502 * Implements the formula: <pre> 503 * <code> atan(z) = (i/2) log((i + z)/(i - z)) </code></pre></p> 504 * <p> 505 * Returns {@link Complex#NaN} if either real or imaginary part of the 506 * input argument is <code>NaN</code> or infinite.</p> 507 * 508 * @return the inverse tangent of this complex number 509 * @since 1.2 510 */ atan()511 public Complex atan() { 512 if (isNaN()) { 513 return Complex.NaN; 514 } 515 516 return this.add(Complex.I).divide(Complex.I.subtract(this)).log() 517 .multiply(Complex.I.divide(createComplex(2.0, 0.0))); 518 } 519 520 /** 521 * Compute the 522 * <a href="http://mathworld.wolfram.com/Cosine.html" TARGET="_top"> 523 * cosine</a> 524 * of this complex number. 525 * <p> 526 * Implements the formula: <pre> 527 * <code> cos(a + bi) = cos(a)cosh(b) - sin(a)sinh(b)i</code></pre> 528 * where the (real) functions on the right-hand side are 529 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 530 * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p> 531 * <p> 532 * Returns {@link Complex#NaN} if either real or imaginary part of the 533 * input argument is <code>NaN</code>.</p> 534 * <p> 535 * Infinite values in real or imaginary parts of the input may result in 536 * infinite or NaN values returned in parts of the result.<pre> 537 * Examples: 538 * <code> 539 * cos(1 ± INFINITY i) = 1 ∓ INFINITY i 540 * cos(±INFINITY + i) = NaN + NaN i 541 * cos(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre></p> 542 * 543 * @return the cosine of this complex number 544 * @since 1.2 545 */ cos()546 public Complex cos() { 547 if (isNaN()) { 548 return Complex.NaN; 549 } 550 551 return createComplex(FastMath.cos(real) * MathUtils.cosh(imaginary), 552 -FastMath.sin(real) * MathUtils.sinh(imaginary)); 553 } 554 555 /** 556 * Compute the 557 * <a href="http://mathworld.wolfram.com/HyperbolicCosine.html" TARGET="_top"> 558 * hyperbolic cosine</a> of this complex number. 559 * <p> 560 * Implements the formula: <pre> 561 * <code> cosh(a + bi) = cosh(a)cos(b) + sinh(a)sin(b)i</code></pre> 562 * where the (real) functions on the right-hand side are 563 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 564 * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p> 565 * <p> 566 * Returns {@link Complex#NaN} if either real or imaginary part of the 567 * input argument is <code>NaN</code>.</p> 568 * <p> 569 * Infinite values in real or imaginary parts of the input may result in 570 * infinite or NaN values returned in parts of the result.<pre> 571 * Examples: 572 * <code> 573 * cosh(1 ± INFINITY i) = NaN + NaN i 574 * cosh(±INFINITY + i) = INFINITY ± INFINITY i 575 * cosh(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre></p> 576 * 577 * @return the hyperbolic cosine of this complex number. 578 * @since 1.2 579 */ cosh()580 public Complex cosh() { 581 if (isNaN()) { 582 return Complex.NaN; 583 } 584 585 return createComplex(MathUtils.cosh(real) * FastMath.cos(imaginary), 586 MathUtils.sinh(real) * FastMath.sin(imaginary)); 587 } 588 589 /** 590 * Compute the 591 * <a href="http://mathworld.wolfram.com/ExponentialFunction.html" TARGET="_top"> 592 * exponential function</a> of this complex number. 593 * <p> 594 * Implements the formula: <pre> 595 * <code> exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i</code></pre> 596 * where the (real) functions on the right-hand side are 597 * {@link java.lang.Math#exp}, {@link java.lang.Math#cos}, and 598 * {@link java.lang.Math#sin}.</p> 599 * <p> 600 * Returns {@link Complex#NaN} if either real or imaginary part of the 601 * input argument is <code>NaN</code>.</p> 602 * <p> 603 * Infinite values in real or imaginary parts of the input may result in 604 * infinite or NaN values returned in parts of the result.<pre> 605 * Examples: 606 * <code> 607 * exp(1 ± INFINITY i) = NaN + NaN i 608 * exp(INFINITY + i) = INFINITY + INFINITY i 609 * exp(-INFINITY + i) = 0 + 0i 610 * exp(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre></p> 611 * 612 * @return <i>e</i><sup><code>this</code></sup> 613 * @since 1.2 614 */ exp()615 public Complex exp() { 616 if (isNaN()) { 617 return Complex.NaN; 618 } 619 620 double expReal = FastMath.exp(real); 621 return createComplex(expReal * FastMath.cos(imaginary), expReal * FastMath.sin(imaginary)); 622 } 623 624 /** 625 * Compute the 626 * <a href="http://mathworld.wolfram.com/NaturalLogarithm.html" TARGET="_top"> 627 * natural logarithm</a> of this complex number. 628 * <p> 629 * Implements the formula: <pre> 630 * <code> log(a + bi) = ln(|a + bi|) + arg(a + bi)i</code></pre> 631 * where ln on the right hand side is {@link java.lang.Math#log}, 632 * <code>|a + bi|</code> is the modulus, {@link Complex#abs}, and 633 * <code>arg(a + bi) = {@link java.lang.Math#atan2}(b, a)</code></p> 634 * <p> 635 * Returns {@link Complex#NaN} if either real or imaginary part of the 636 * input argument is <code>NaN</code>.</p> 637 * <p> 638 * Infinite (or critical) values in real or imaginary parts of the input may 639 * result in infinite or NaN values returned in parts of the result.<pre> 640 * Examples: 641 * <code> 642 * log(1 ± INFINITY i) = INFINITY ± (π/2)i 643 * log(INFINITY + i) = INFINITY + 0i 644 * log(-INFINITY + i) = INFINITY + πi 645 * log(INFINITY ± INFINITY i) = INFINITY ± (π/4)i 646 * log(-INFINITY ± INFINITY i) = INFINITY ± (3π/4)i 647 * log(0 + 0i) = -INFINITY + 0i 648 * </code></pre></p> 649 * 650 * @return ln of this complex number. 651 * @since 1.2 652 */ log()653 public Complex log() { 654 if (isNaN()) { 655 return Complex.NaN; 656 } 657 658 return createComplex(FastMath.log(abs()), 659 FastMath.atan2(imaginary, real)); 660 } 661 662 /** 663 * Returns of value of this complex number raised to the power of <code>x</code>. 664 * <p> 665 * Implements the formula: <pre> 666 * <code> y<sup>x</sup> = exp(x·log(y))</code></pre> 667 * where <code>exp</code> and <code>log</code> are {@link #exp} and 668 * {@link #log}, respectively.</p> 669 * <p> 670 * Returns {@link Complex#NaN} if either real or imaginary part of the 671 * input argument is <code>NaN</code> or infinite, or if <code>y</code> 672 * equals {@link Complex#ZERO}.</p> 673 * 674 * @param x the exponent. 675 * @return <code>this</code><sup><code>x</code></sup> 676 * @throws NullPointerException if x is null 677 * @since 1.2 678 */ pow(Complex x)679 public Complex pow(Complex x) { 680 if (x == null) { 681 throw new NullPointerException(); 682 } 683 return this.log().multiply(x).exp(); 684 } 685 686 /** 687 * Compute the 688 * <a href="http://mathworld.wolfram.com/Sine.html" TARGET="_top"> 689 * sine</a> 690 * of this complex number. 691 * <p> 692 * Implements the formula: <pre> 693 * <code> sin(a + bi) = sin(a)cosh(b) - cos(a)sinh(b)i</code></pre> 694 * where the (real) functions on the right-hand side are 695 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 696 * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p> 697 * <p> 698 * Returns {@link Complex#NaN} if either real or imaginary part of the 699 * input argument is <code>NaN</code>.</p> 700 * <p> 701 * Infinite values in real or imaginary parts of the input may result in 702 * infinite or NaN values returned in parts of the result.<pre> 703 * Examples: 704 * <code> 705 * sin(1 ± INFINITY i) = 1 ± INFINITY i 706 * sin(±INFINITY + i) = NaN + NaN i 707 * sin(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre></p> 708 * 709 * @return the sine of this complex number. 710 * @since 1.2 711 */ sin()712 public Complex sin() { 713 if (isNaN()) { 714 return Complex.NaN; 715 } 716 717 return createComplex(FastMath.sin(real) * MathUtils.cosh(imaginary), 718 FastMath.cos(real) * MathUtils.sinh(imaginary)); 719 } 720 721 /** 722 * Compute the 723 * <a href="http://mathworld.wolfram.com/HyperbolicSine.html" TARGET="_top"> 724 * hyperbolic sine</a> of this complex number. 725 * <p> 726 * Implements the formula: <pre> 727 * <code> sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i</code></pre> 728 * where the (real) functions on the right-hand side are 729 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 730 * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p> 731 * <p> 732 * Returns {@link Complex#NaN} if either real or imaginary part of the 733 * input argument is <code>NaN</code>.</p> 734 * <p> 735 * Infinite values in real or imaginary parts of the input may result in 736 * infinite or NaN values returned in parts of the result.<pre> 737 * Examples: 738 * <code> 739 * sinh(1 ± INFINITY i) = NaN + NaN i 740 * sinh(±INFINITY + i) = ± INFINITY + INFINITY i 741 * sinh(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre></p> 742 * 743 * @return the hyperbolic sine of this complex number 744 * @since 1.2 745 */ sinh()746 public Complex sinh() { 747 if (isNaN()) { 748 return Complex.NaN; 749 } 750 751 return createComplex(MathUtils.sinh(real) * FastMath.cos(imaginary), 752 MathUtils.cosh(real) * FastMath.sin(imaginary)); 753 } 754 755 /** 756 * Compute the 757 * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top"> 758 * square root</a> of this complex number. 759 * <p> 760 * Implements the following algorithm to compute <code>sqrt(a + bi)</code>: 761 * <ol><li>Let <code>t = sqrt((|a| + |a + bi|) / 2)</code></li> 762 * <li><pre>if <code> a ≥ 0</code> return <code>t + (b/2t)i</code> 763 * else return <code>|b|/2t + sign(b)t i </code></pre></li> 764 * </ol> 765 * where <ul> 766 * <li><code>|a| = {@link Math#abs}(a)</code></li> 767 * <li><code>|a + bi| = {@link Complex#abs}(a + bi) </code></li> 768 * <li><code>sign(b) = {@link MathUtils#indicator}(b) </code> 769 * </ul></p> 770 * <p> 771 * Returns {@link Complex#NaN} if either real or imaginary part of the 772 * input argument is <code>NaN</code>.</p> 773 * <p> 774 * Infinite values in real or imaginary parts of the input may result in 775 * infinite or NaN values returned in parts of the result.<pre> 776 * Examples: 777 * <code> 778 * sqrt(1 ± INFINITY i) = INFINITY + NaN i 779 * sqrt(INFINITY + i) = INFINITY + 0i 780 * sqrt(-INFINITY + i) = 0 + INFINITY i 781 * sqrt(INFINITY ± INFINITY i) = INFINITY + NaN i 782 * sqrt(-INFINITY ± INFINITY i) = NaN ± INFINITY i 783 * </code></pre></p> 784 * 785 * @return the square root of this complex number 786 * @since 1.2 787 */ sqrt()788 public Complex sqrt() { 789 if (isNaN()) { 790 return Complex.NaN; 791 } 792 793 if (real == 0.0 && imaginary == 0.0) { 794 return createComplex(0.0, 0.0); 795 } 796 797 double t = FastMath.sqrt((FastMath.abs(real) + abs()) / 2.0); 798 if (real >= 0.0) { 799 return createComplex(t, imaginary / (2.0 * t)); 800 } else { 801 return createComplex(FastMath.abs(imaginary) / (2.0 * t), 802 MathUtils.indicator(imaginary) * t); 803 } 804 } 805 806 /** 807 * Compute the 808 * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top"> 809 * square root</a> of 1 - <code>this</code><sup>2</sup> for this complex 810 * number. 811 * <p> 812 * Computes the result directly as 813 * <code>sqrt(Complex.ONE.subtract(z.multiply(z)))</code>.</p> 814 * <p> 815 * Returns {@link Complex#NaN} if either real or imaginary part of the 816 * input argument is <code>NaN</code>.</p> 817 * <p> 818 * Infinite values in real or imaginary parts of the input may result in 819 * infinite or NaN values returned in parts of the result.</p> 820 * 821 * @return the square root of 1 - <code>this</code><sup>2</sup> 822 * @since 1.2 823 */ sqrt1z()824 public Complex sqrt1z() { 825 return createComplex(1.0, 0.0).subtract(this.multiply(this)).sqrt(); 826 } 827 828 /** 829 * Compute the 830 * <a href="http://mathworld.wolfram.com/Tangent.html" TARGET="_top"> 831 * tangent</a> of this complex number. 832 * <p> 833 * Implements the formula: <pre> 834 * <code>tan(a + bi) = sin(2a)/(cos(2a)+cosh(2b)) + [sinh(2b)/(cos(2a)+cosh(2b))]i</code></pre> 835 * where the (real) functions on the right-hand side are 836 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 837 * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p> 838 * <p> 839 * Returns {@link Complex#NaN} if either real or imaginary part of the 840 * input argument is <code>NaN</code>.</p> 841 * <p> 842 * Infinite (or critical) values in real or imaginary parts of the input may 843 * result in infinite or NaN values returned in parts of the result.<pre> 844 * Examples: 845 * <code> 846 * tan(1 ± INFINITY i) = 0 + NaN i 847 * tan(±INFINITY + i) = NaN + NaN i 848 * tan(±INFINITY ± INFINITY i) = NaN + NaN i 849 * tan(±π/2 + 0 i) = ±INFINITY + NaN i</code></pre></p> 850 * 851 * @return the tangent of this complex number 852 * @since 1.2 853 */ tan()854 public Complex tan() { 855 if (isNaN()) { 856 return Complex.NaN; 857 } 858 859 double real2 = 2.0 * real; 860 double imaginary2 = 2.0 * imaginary; 861 double d = FastMath.cos(real2) + MathUtils.cosh(imaginary2); 862 863 return createComplex(FastMath.sin(real2) / d, MathUtils.sinh(imaginary2) / d); 864 } 865 866 /** 867 * Compute the 868 * <a href="http://mathworld.wolfram.com/HyperbolicTangent.html" TARGET="_top"> 869 * hyperbolic tangent</a> of this complex number. 870 * <p> 871 * Implements the formula: <pre> 872 * <code>tan(a + bi) = sinh(2a)/(cosh(2a)+cos(2b)) + [sin(2b)/(cosh(2a)+cos(2b))]i</code></pre> 873 * where the (real) functions on the right-hand side are 874 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 875 * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p> 876 * <p> 877 * Returns {@link Complex#NaN} if either real or imaginary part of the 878 * input argument is <code>NaN</code>.</p> 879 * <p> 880 * Infinite values in real or imaginary parts of the input may result in 881 * infinite or NaN values returned in parts of the result.<pre> 882 * Examples: 883 * <code> 884 * tanh(1 ± INFINITY i) = NaN + NaN i 885 * tanh(±INFINITY + i) = NaN + 0 i 886 * tanh(±INFINITY ± INFINITY i) = NaN + NaN i 887 * tanh(0 + (π/2)i) = NaN + INFINITY i</code></pre></p> 888 * 889 * @return the hyperbolic tangent of this complex number 890 * @since 1.2 891 */ tanh()892 public Complex tanh() { 893 if (isNaN()) { 894 return Complex.NaN; 895 } 896 897 double real2 = 2.0 * real; 898 double imaginary2 = 2.0 * imaginary; 899 double d = MathUtils.cosh(real2) + FastMath.cos(imaginary2); 900 901 return createComplex(MathUtils.sinh(real2) / d, FastMath.sin(imaginary2) / d); 902 } 903 904 905 906 /** 907 * <p>Compute the argument of this complex number. 908 * </p> 909 * <p>The argument is the angle phi between the positive real axis and the point 910 * representing this number in the complex plane. The value returned is between -PI (not inclusive) 911 * and PI (inclusive), with negative values returned for numbers with negative imaginary parts. 912 * </p> 913 * <p>If either real or imaginary part (or both) is NaN, NaN is returned. Infinite parts are handled 914 * as java.Math.atan2 handles them, essentially treating finite parts as zero in the presence of 915 * an infinite coordinate and returning a multiple of pi/4 depending on the signs of the infinite 916 * parts. See the javadoc for java.Math.atan2 for full details.</p> 917 * 918 * @return the argument of this complex number 919 */ getArgument()920 public double getArgument() { 921 return FastMath.atan2(getImaginary(), getReal()); 922 } 923 924 /** 925 * <p>Computes the n-th roots of this complex number. 926 * </p> 927 * <p>The nth roots are defined by the formula: <pre> 928 * <code> z<sub>k</sub> = abs<sup> 1/n</sup> (cos(phi + 2πk/n) + i (sin(phi + 2πk/n))</code></pre> 929 * for <i><code>k=0, 1, ..., n-1</code></i>, where <code>abs</code> and <code>phi</code> are 930 * respectively the {@link #abs() modulus} and {@link #getArgument() argument} of this complex number. 931 * </p> 932 * <p>If one or both parts of this complex number is NaN, a list with just one element, 933 * {@link #NaN} is returned.</p> 934 * <p>if neither part is NaN, but at least one part is infinite, the result is a one-element 935 * list containing {@link #INF}.</p> 936 * 937 * @param n degree of root 938 * @return List<Complex> all nth roots of this complex number 939 * @throws IllegalArgumentException if parameter n is less than or equal to 0 940 * @since 2.0 941 */ nthRoot(int n)942 public List<Complex> nthRoot(int n) throws IllegalArgumentException { 943 944 if (n <= 0) { 945 throw MathRuntimeException.createIllegalArgumentException( 946 LocalizedFormats.CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N, 947 n); 948 } 949 950 List<Complex> result = new ArrayList<Complex>(); 951 952 if (isNaN()) { 953 result.add(Complex.NaN); 954 return result; 955 } 956 957 if (isInfinite()) { 958 result.add(Complex.INF); 959 return result; 960 } 961 962 // nth root of abs -- faster / more accurate to use a solver here? 963 final double nthRootOfAbs = FastMath.pow(abs(), 1.0 / n); 964 965 // Compute nth roots of complex number with k = 0, 1, ... n-1 966 final double nthPhi = getArgument()/n; 967 final double slice = 2 * FastMath.PI / n; 968 double innerPart = nthPhi; 969 for (int k = 0; k < n ; k++) { 970 // inner part 971 final double realPart = nthRootOfAbs * FastMath.cos(innerPart); 972 final double imaginaryPart = nthRootOfAbs * FastMath.sin(innerPart); 973 result.add(createComplex(realPart, imaginaryPart)); 974 innerPart += slice; 975 } 976 977 return result; 978 } 979 980 /** 981 * Create a complex number given the real and imaginary parts. 982 * 983 * @param realPart the real part 984 * @param imaginaryPart the imaginary part 985 * @return a new complex number instance 986 * @since 1.2 987 */ createComplex(double realPart, double imaginaryPart)988 protected Complex createComplex(double realPart, double imaginaryPart) { 989 return new Complex(realPart, imaginaryPart); 990 } 991 992 /** 993 * <p>Resolve the transient fields in a deserialized Complex Object.</p> 994 * <p>Subclasses will need to override {@link #createComplex} to deserialize properly</p> 995 * @return A Complex instance with all fields resolved. 996 * @since 2.0 997 */ readResolve()998 protected final Object readResolve() { 999 return createComplex(real, imaginary); 1000 } 1001 1002 /** {@inheritDoc} */ getField()1003 public ComplexField getField() { 1004 return ComplexField.getInstance(); 1005 } 1006 1007 } 1008