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 }