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.math.complex;
019
020 import java.io.Serializable;
021 import java.util.ArrayList;
022 import java.util.List;
023
024 import org.apache.commons.math.FieldElement;
025 import org.apache.commons.math.exception.NullArgumentException;
026 import org.apache.commons.math.exception.NotPositiveException;
027 import org.apache.commons.math.exception.util.LocalizedFormats;
028 import org.apache.commons.math.util.MathUtils;
029 import org.apache.commons.math.util.FastMath;
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.math.util.Precision#equals(double,double,int)
049 * equals for primitive double} in {@link org.apache.commons.math.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 1183300 2011-10-14 11:04:17Z luc $
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()
574 .multiply(I.negate());
575 }
576
577 /**
578 * Compute the
579 * <a href="http://mathworld.wolfram.com/InverseSine.html" TARGET="_top">
580 * inverse sine</a> of this complex number.
581 * Implements the formula:
582 * <pre>
583 * <code>
584 * asin(z) = -i (log(sqrt(1 - z<sup>2</sup>) + iz))
585 * </code>
586 * </pre>
587 * Returns {@link Complex#NaN} if either real or imaginary part of the
588 * input argument is {@code NaN} or infinite.
589 *
590 * @return the inverse sine of this complex number.
591 * @since 1.2
592 */
593 public Complex asin() {
594 if (isNaN) {
595 return NaN;
596 }
597
598 return sqrt1z().add(this.multiply(I)).log()
599 .multiply(I.negate());
600 }
601
602 /**
603 * Compute the
604 * <a href="http://mathworld.wolfram.com/InverseTangent.html" TARGET="_top">
605 * inverse tangent</a> of this complex number.
606 * Implements the formula:
607 * <pre>
608 * <code>
609 * atan(z) = (i/2) log((i + z)/(i - z))
610 * </code>
611 * </pre>
612 * Returns {@link Complex#NaN} if either real or imaginary part of the
613 * input argument is {@code NaN} or infinite.
614 *
615 * @return the inverse tangent of this complex number
616 * @since 1.2
617 */
618 public Complex atan() {
619 if (isNaN) {
620 return NaN;
621 }
622
623 return this.add(I).divide(I.subtract(this)).log()
624 .multiply(I.divide(createComplex(2.0, 0.0)));
625 }
626
627 /**
628 * Compute the
629 * <a href="http://mathworld.wolfram.com/Cosine.html" TARGET="_top">
630 * cosine</a>
631 * of this complex number.
632 * Implements the formula:
633 * <pre>
634 * <code>
635 * cos(a + bi) = cos(a)cosh(b) - sin(a)sinh(b)i
636 * </code>
637 * </pre>
638 * where the (real) functions on the right-hand side are
639 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
640 * {@link FastMath#cosh} and {@link FastMath#sinh}.
641 * <br/>
642 * Returns {@link Complex#NaN} if either real or imaginary part of the
643 * input argument is {@code NaN}.
644 * <br/>
645 * Infinite values in real or imaginary parts of the input may result in
646 * infinite or NaN values returned in parts of the result.
647 * <pre>
648 * Examples:
649 * <code>
650 * cos(1 ± INFINITY i) = 1 ∓ INFINITY i
651 * cos(±INFINITY + i) = NaN + NaN i
652 * cos(±INFINITY ± INFINITY i) = NaN + NaN i
653 * </code>
654 * </pre>
655 *
656 * @return the cosine of this complex number.
657 * @since 1.2
658 */
659 public Complex cos() {
660 if (isNaN) {
661 return NaN;
662 }
663
664 return createComplex(FastMath.cos(real) * FastMath.cosh(imaginary),
665 -FastMath.sin(real) * FastMath.sinh(imaginary));
666 }
667
668 /**
669 * Compute the
670 * <a href="http://mathworld.wolfram.com/HyperbolicCosine.html" TARGET="_top">
671 * hyperbolic cosine</a> of this complex number.
672 * Implements the formula:
673 * <pre>
674 * <code>
675 * cosh(a + bi) = cosh(a)cos(b) + sinh(a)sin(b)i}
676 * </code>
677 * </pre>
678 * where the (real) functions on the right-hand side are
679 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
680 * {@link FastMath#cosh} and {@link FastMath#sinh}.
681 * <br/>
682 * Returns {@link Complex#NaN} if either real or imaginary part of the
683 * input argument is {@code NaN}.
684 * <br/>
685 * Infinite values in real or imaginary parts of the input may result in
686 * infinite or NaN values returned in parts of the result.
687 * <pre>
688 * Examples:
689 * <code>
690 * cosh(1 ± INFINITY i) = NaN + NaN i
691 * cosh(±INFINITY + i) = INFINITY ± INFINITY i
692 * cosh(±INFINITY ± INFINITY i) = NaN + NaN i
693 * </code>
694 * </pre>
695 *
696 * @return the hyperbolic cosine of this complex number.
697 * @since 1.2
698 */
699 public Complex cosh() {
700 if (isNaN) {
701 return NaN;
702 }
703
704 return createComplex(FastMath.cosh(real) * FastMath.cos(imaginary),
705 FastMath.sinh(real) * FastMath.sin(imaginary));
706 }
707
708 /**
709 * Compute the
710 * <a href="http://mathworld.wolfram.com/ExponentialFunction.html" TARGET="_top">
711 * exponential function</a> of this complex number.
712 * Implements the formula:
713 * <pre>
714 * <code>
715 * exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i
716 * </code>
717 * </pre>
718 * where the (real) functions on the right-hand side are
719 * {@link java.lang.Math#exp}, {@link java.lang.Math#cos}, and
720 * {@link java.lang.Math#sin}.
721 * <br/>
722 * Returns {@link Complex#NaN} if either real or imaginary part of the
723 * input argument is {@code NaN}.
724 * <br/>
725 * Infinite values in real or imaginary parts of the input may result in
726 * infinite or NaN values returned in parts of the result.
727 * <pre>
728 * Examples:
729 * <code>
730 * exp(1 ± INFINITY i) = NaN + NaN i
731 * exp(INFINITY + i) = INFINITY + INFINITY i
732 * exp(-INFINITY + i) = 0 + 0i
733 * exp(±INFINITY ± INFINITY i) = NaN + NaN i
734 * </code>
735 * </pre>
736 *
737 * @return <code><i>e</i><sup>this</sup></code>.
738 * @since 1.2
739 */
740 public Complex exp() {
741 if (isNaN) {
742 return NaN;
743 }
744
745 double expReal = FastMath.exp(real);
746 return createComplex(expReal * FastMath.cos(imaginary),
747 expReal * FastMath.sin(imaginary));
748 }
749
750 /**
751 * Compute the
752 * <a href="http://mathworld.wolfram.com/NaturalLogarithm.html" TARGET="_top">
753 * natural logarithm</a> of this complex number.
754 * Implements the formula:
755 * <pre>
756 * <code>
757 * log(a + bi) = ln(|a + bi|) + arg(a + bi)i
758 * </code>
759 * </pre>
760 * where ln on the right hand side is {@link java.lang.Math#log},
761 * {@code |a + bi|} is the modulus, {@link Complex#abs}, and
762 * {@code arg(a + bi) = }{@link java.lang.Math#atan2}(b, a).
763 * <br/>
764 * Returns {@link Complex#NaN} if either real or imaginary part of the
765 * input argument is {@code NaN}.
766 * <br/>
767 * Infinite (or critical) values in real or imaginary parts of the input may
768 * result in infinite or NaN values returned in parts of the result.
769 * <pre>
770 * Examples:
771 * <code>
772 * log(1 ± INFINITY i) = INFINITY ± (π/2)i
773 * log(INFINITY + i) = INFINITY + 0i
774 * log(-INFINITY + i) = INFINITY + πi
775 * log(INFINITY ± INFINITY i) = INFINITY ± (π/4)i
776 * log(-INFINITY ± INFINITY i) = INFINITY ± (3π/4)i
777 * log(0 + 0i) = -INFINITY + 0i
778 * </code>
779 * </pre>
780 *
781 * @return the value <code>ln this</code>, the natural logarithm
782 * of {@code this}.
783 * @since 1.2
784 */
785 public Complex log() {
786 if (isNaN) {
787 return NaN;
788 }
789
790 return createComplex(FastMath.log(abs()),
791 FastMath.atan2(imaginary, real));
792 }
793
794 /**
795 * Returns of value of this complex number raised to the power of {@code x}.
796 * Implements the formula:
797 * <pre>
798 * <code>
799 * y<sup>x</sup> = exp(x·log(y))
800 * </code>
801 * </pre>
802 * where {@code exp} and {@code log} are {@link #exp} and
803 * {@link #log}, respectively.
804 * <br/>
805 * Returns {@link Complex#NaN} if either real or imaginary part of the
806 * input argument is {@code NaN} or infinite, or if {@code y}
807 * equals {@link Complex#ZERO}.
808 *
809 * @param x exponent to which this {@code Complex} is to be raised.
810 * @return <code> this<sup>{@code x}</sup></code>.
811 * @throws NullArgumentException if x is {@code null}.
812 * @since 1.2
813 */
814 public Complex pow(Complex x)
815 throws NullArgumentException {
816 MathUtils.checkNotNull(x);
817 return this.log().multiply(x).exp();
818 }
819
820 /**
821 * Returns of value of this complex number raised to the power of {@code x}.
822 *
823 * @param x exponent to which this {@code Complex} is to be raised.
824 * @return <code>this<sup>x</sup></code>.
825 * @see #pow(Complex)
826 */
827 public Complex pow(double x) {
828 return this.log().multiply(x).exp();
829 }
830
831 /**
832 * Compute the
833 * <a href="http://mathworld.wolfram.com/Sine.html" TARGET="_top">
834 * sine</a>
835 * of this complex number.
836 * Implements the formula:
837 * <pre>
838 * <code>
839 * sin(a + bi) = sin(a)cosh(b) - cos(a)sinh(b)i
840 * </code>
841 * </pre>
842 * where the (real) functions on the right-hand side are
843 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
844 * {@link FastMath#cosh} and {@link FastMath#sinh}.
845 * <br/>
846 * Returns {@link Complex#NaN} if either real or imaginary part of the
847 * input argument is {@code NaN}.
848 * <br/>
849 * Infinite values in real or imaginary parts of the input may result in
850 * infinite or {@code NaN} values returned in parts of the result.
851 * <pre>
852 * Examples:
853 * <code>
854 * sin(1 ± INFINITY i) = 1 ± INFINITY i
855 * sin(±INFINITY + i) = NaN + NaN i
856 * sin(±INFINITY ± INFINITY i) = NaN + NaN i
857 * </code>
858 * </pre>
859 *
860 * @return the sine of this complex number.
861 * @since 1.2
862 */
863 public Complex sin() {
864 if (isNaN) {
865 return NaN;
866 }
867
868 return createComplex(FastMath.sin(real) * FastMath.cosh(imaginary),
869 FastMath.cos(real) * FastMath.sinh(imaginary));
870 }
871
872 /**
873 * Compute the
874 * <a href="http://mathworld.wolfram.com/HyperbolicSine.html" TARGET="_top">
875 * hyperbolic sine</a> of this complex number.
876 * Implements the formula:
877 * <pre>
878 * <code>
879 * sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i
880 * </code>
881 * </pre>
882 * where the (real) functions on the right-hand side are
883 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
884 * {@link FastMath#cosh} and {@link FastMath#sinh}.
885 * <br/>
886 * Returns {@link Complex#NaN} if either real or imaginary part of the
887 * input argument is {@code NaN}.
888 * <br/>
889 * Infinite values in real or imaginary parts of the input may result in
890 * infinite or NaN values returned in parts of the result.
891 * <pre>
892 * Examples:
893 * <code>
894 * sinh(1 ± INFINITY i) = NaN + NaN i
895 * sinh(±INFINITY + i) = ± INFINITY + INFINITY i
896 * sinh(±INFINITY ± INFINITY i) = NaN + NaN i
897 * </code>
898 * </pre>
899 *
900 * @return the hyperbolic sine of {@code this}.
901 * @since 1.2
902 */
903 public Complex sinh() {
904 if (isNaN) {
905 return NaN;
906 }
907
908 return createComplex(FastMath.sinh(real) * FastMath.cos(imaginary),
909 FastMath.cosh(real) * FastMath.sin(imaginary));
910 }
911
912 /**
913 * Compute the
914 * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
915 * square root</a> of this complex number.
916 * Implements the following algorithm to compute {@code sqrt(a + bi)}:
917 * <ol><li>Let {@code t = sqrt((|a| + |a + bi|) / 2)}</li>
918 * <li><pre>if {@code a ≥ 0} return {@code t + (b/2t)i}
919 * else return {@code |b|/2t + sign(b)t i }</pre></li>
920 * </ol>
921 * where <ul>
922 * <li>{@code |a| = }{@link Math#abs}(a)</li>
923 * <li>{@code |a + bi| = }{@link Complex#abs}(a + bi)</li>
924 * <li>{@code sign(b) = }{@link MathUtils#indicator}(b)
925 * </ul>
926 * <br/>
927 * Returns {@link Complex#NaN} if either real or imaginary part of the
928 * input argument is {@code NaN}.
929 * <br/>
930 * Infinite values in real or imaginary parts of the input may result in
931 * infinite or NaN values returned in parts of the result.
932 * <pre>
933 * Examples:
934 * <code>
935 * sqrt(1 ± INFINITY i) = INFINITY + NaN i
936 * sqrt(INFINITY + i) = INFINITY + 0i
937 * sqrt(-INFINITY + i) = 0 + INFINITY i
938 * sqrt(INFINITY ± INFINITY i) = INFINITY + NaN i
939 * sqrt(-INFINITY ± INFINITY i) = NaN ± INFINITY i
940 * </code>
941 * </pre>
942 *
943 * @return the square root of {@code this}.
944 * @since 1.2
945 */
946 public Complex sqrt() {
947 if (isNaN) {
948 return NaN;
949 }
950
951 if (real == 0.0 && imaginary == 0.0) {
952 return createComplex(0.0, 0.0);
953 }
954
955 double t = FastMath.sqrt((FastMath.abs(real) + abs()) / 2.0);
956 if (real >= 0.0) {
957 return createComplex(t, imaginary / (2.0 * t));
958 } else {
959 return createComplex(FastMath.abs(imaginary) / (2.0 * t),
960 MathUtils.indicator(imaginary) * t);
961 }
962 }
963
964 /**
965 * Compute the
966 * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
967 * square root</a> of <code>1 - this<sup>2</sup></code> for this complex
968 * number.
969 * Computes the result directly as
970 * {@code sqrt(ONE.subtract(z.multiply(z)))}.
971 * <br/>
972 * Returns {@link Complex#NaN} if either real or imaginary part of the
973 * input argument is {@code NaN}.
974 * <br/>
975 * Infinite values in real or imaginary parts of the input may result in
976 * infinite or NaN values returned in parts of the result.
977 *
978 * @return the square root of <code>1 - this<sup>2</sup></code>.
979 * @since 1.2
980 */
981 public Complex sqrt1z() {
982 return createComplex(1.0, 0.0).subtract(this.multiply(this)).sqrt();
983 }
984
985 /**
986 * Compute the
987 * <a href="http://mathworld.wolfram.com/Tangent.html" TARGET="_top">
988 * tangent</a> of this complex number.
989 * Implements the formula:
990 * <pre>
991 * <code>
992 * tan(a + bi) = sin(2a)/(cos(2a)+cosh(2b)) + [sinh(2b)/(cos(2a)+cosh(2b))]i
993 * </code>
994 * </pre>
995 * where the (real) functions on the right-hand side are
996 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
997 * {@link FastMath#cosh} and {@link FastMath#sinh}.
998 * <br/>
999 * Returns {@link Complex#NaN} if either real or imaginary part of the
1000 * input argument is {@code NaN}.
1001 * <br/>
1002 * Infinite (or critical) values in real or imaginary parts of the input may
1003 * result in infinite or NaN values returned in parts of the result.
1004 * <pre>
1005 * Examples:
1006 * <code>
1007 * tan(1 ± INFINITY i) = 0 + NaN i
1008 * tan(±INFINITY + i) = NaN + NaN i
1009 * tan(±INFINITY ± INFINITY i) = NaN + NaN i
1010 * tan(±π/2 + 0 i) = ±INFINITY + NaN i
1011 * </code>
1012 * </pre>
1013 *
1014 * @return the tangent of {@code this}.
1015 * @since 1.2
1016 */
1017 public Complex tan() {
1018 if (isNaN) {
1019 return NaN;
1020 }
1021
1022 double real2 = 2.0 * real;
1023 double imaginary2 = 2.0 * imaginary;
1024 double d = FastMath.cos(real2) + FastMath.cosh(imaginary2);
1025
1026 return createComplex(FastMath.sin(real2) / d,
1027 FastMath.sinh(imaginary2) / d);
1028 }
1029
1030 /**
1031 * Compute the
1032 * <a href="http://mathworld.wolfram.com/HyperbolicTangent.html" TARGET="_top">
1033 * hyperbolic tangent</a> of this complex number.
1034 * Implements the formula:
1035 * <pre>
1036 * <code>
1037 * tan(a + bi) = sinh(2a)/(cosh(2a)+cos(2b)) + [sin(2b)/(cosh(2a)+cos(2b))]i
1038 * </code>
1039 * </pre>
1040 * where the (real) functions on the right-hand side are
1041 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
1042 * {@link FastMath#cosh} and {@link FastMath#sinh}.
1043 * <br/>
1044 * Returns {@link Complex#NaN} if either real or imaginary part of the
1045 * input argument is {@code NaN}.
1046 * <br/>
1047 * Infinite values in real or imaginary parts of the input may result in
1048 * infinite or NaN values returned in parts of the result.
1049 * <pre>
1050 * Examples:
1051 * <code>
1052 * tanh(1 ± INFINITY i) = NaN + NaN i
1053 * tanh(±INFINITY + i) = NaN + 0 i
1054 * tanh(±INFINITY ± INFINITY i) = NaN + NaN i
1055 * tanh(0 + (π/2)i) = NaN + INFINITY i
1056 * </code>
1057 * </pre>
1058 *
1059 * @return the hyperbolic tangent of {@code this}.
1060 * @since 1.2
1061 */
1062 public Complex tanh() {
1063 if (isNaN) {
1064 return NaN;
1065 }
1066
1067 double real2 = 2.0 * real;
1068 double imaginary2 = 2.0 * imaginary;
1069 double d = FastMath.cosh(real2) + FastMath.cos(imaginary2);
1070
1071 return createComplex(FastMath.sinh(real2) / d,
1072 FastMath.sin(imaginary2) / d);
1073 }
1074
1075
1076
1077 /**
1078 * Compute the argument of this complex number.
1079 * The argument is the angle phi between the positive real axis and
1080 * the point representing this number in the complex plane.
1081 * The value returned is between -PI (not inclusive)
1082 * and PI (inclusive), with negative values returned for numbers with
1083 * negative imaginary parts.
1084 * <br/>
1085 * If either real or imaginary part (or both) is NaN, NaN is returned.
1086 * Infinite parts are handled as {@code Math.atan2} handles them,
1087 * essentially treating finite parts as zero in the presence of an
1088 * infinite coordinate and returning a multiple of pi/4 depending on
1089 * the signs of the infinite parts.
1090 * See the javadoc for {@code Math.atan2} for full details.
1091 *
1092 * @return the argument of {@code this}.
1093 */
1094 public double getArgument() {
1095 return FastMath.atan2(getImaginary(), getReal());
1096 }
1097
1098 /**
1099 * Computes the n-th roots of this complex number.
1100 * The nth roots are defined by the formula:
1101 * <pre>
1102 * <code>
1103 * z<sub>k</sub> = abs<sup>1/n</sup> (cos(phi + 2πk/n) + i (sin(phi + 2πk/n))
1104 * </code>
1105 * </pre>
1106 * for <i>{@code k=0, 1, ..., n-1}</i>, where {@code abs} and {@code phi}
1107 * are respectively the {@link #abs() modulus} and
1108 * {@link #getArgument() argument} of this complex number.
1109 * <br/>
1110 * If one or both parts of this complex number is NaN, a list with just
1111 * one element, {@link #NaN} is returned.
1112 * if neither part is NaN, but at least one part is infinite, the result
1113 * is a one-element list containing {@link #INF}.
1114 *
1115 * @param n Degree of root.
1116 * @return a List<Complex> of all {@code n}-th roots of {@code this}.
1117 * @throws NotPositiveException if {@code n <= 0}.
1118 * @since 2.0
1119 */
1120 public List<Complex> nthRoot(int n) {
1121
1122 if (n <= 0) {
1123 throw new NotPositiveException(LocalizedFormats.CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N,
1124 n);
1125 }
1126
1127 final List<Complex> result = new ArrayList<Complex>();
1128
1129 if (isNaN) {
1130 result.add(NaN);
1131 return result;
1132 }
1133 if (isInfinite()) {
1134 result.add(INF);
1135 return result;
1136 }
1137
1138 // nth root of abs -- faster / more accurate to use a solver here?
1139 final double nthRootOfAbs = FastMath.pow(abs(), 1.0 / n);
1140
1141 // Compute nth roots of complex number with k = 0, 1, ... n-1
1142 final double nthPhi = getArgument() / n;
1143 final double slice = 2 * FastMath.PI / n;
1144 double innerPart = nthPhi;
1145 for (int k = 0; k < n ; k++) {
1146 // inner part
1147 final double realPart = nthRootOfAbs * FastMath.cos(innerPart);
1148 final double imaginaryPart = nthRootOfAbs * FastMath.sin(innerPart);
1149 result.add(createComplex(realPart, imaginaryPart));
1150 innerPart += slice;
1151 }
1152
1153 return result;
1154 }
1155
1156 /**
1157 * Create a complex number given the real and imaginary parts.
1158 *
1159 * @param realPart Real part.
1160 * @param imaginaryPart Imaginary part.
1161 * @return a new complex number instance.
1162 * @since 1.2
1163 * @see #valueOf(double, double)
1164 */
1165 protected Complex createComplex(double realPart,
1166 double imaginaryPart) {
1167 return new Complex(realPart, imaginaryPart);
1168 }
1169
1170 /**
1171 * Create a complex number given the real and imaginary parts.
1172 *
1173 * @param realPart Real part.
1174 * @param imaginaryPart Imaginary part.
1175 * @return a Complex instance.
1176 */
1177 public static Complex valueOf(double realPart,
1178 double imaginaryPart) {
1179 if (Double.isNaN(realPart) ||
1180 Double.isNaN(imaginaryPart)) {
1181 return NaN;
1182 }
1183 return new Complex(realPart, imaginaryPart);
1184 }
1185
1186 /**
1187 * Create a complex number given only the real part.
1188 *
1189 * @param realPart Real part.
1190 * @return a Complex instance.
1191 */
1192 public static Complex valueOf(double realPart) {
1193 if (Double.isNaN(realPart)) {
1194 return NaN;
1195 }
1196 return new Complex(realPart);
1197 }
1198
1199 /**
1200 * Resolve the transient fields in a deserialized Complex Object.
1201 * Subclasses will need to override {@link #createComplex} to
1202 * deserialize properly.
1203 *
1204 * @return A Complex instance with all fields resolved.
1205 * @since 2.0
1206 */
1207 protected final Object readResolve() {
1208 return createComplex(real, imaginary);
1209 }
1210
1211 /** {@inheritDoc} */
1212 public ComplexField getField() {
1213 return ComplexField.getInstance();
1214 }
1215
1216 /** {@inheritDoc} */
1217 @Override
1218 public String toString() {
1219 return "(" + real + ", " + imaginary + ")";
1220 }
1221
1222 }