View Javadoc

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 org.apache.commons.math.util.MathUtils;
21  
22  /**
23   * Static implementations of common 
24   * {@link org.apache.commons.math.complex.Complex}-valued functions.  Included
25   * are trigonometric, exponential, log, power and square root functions.
26   *<p>
27   * Reference:
28   * <ul>
29   * <li><a href="http://myweb.lmu.edu/dmsmith/ZMLIB.pdf">
30   * Multiple Precision Complex Arithmetic and Functions</a></li>
31   * </ul>
32   * See individual method javadocs for the computational formulas used.
33   * In general, NaN values in either real or imaginary parts of input arguments
34   * result in {@link Complex#NaN} returned.  Otherwise, infinite or NaN values
35   * are returned as they arise in computing the real functions specified in the
36   * computational formulas.  Null arguments result in NullPointerExceptions.
37   *
38   * @version $Revision: 615734 $ $Date: 2008-01-27 23:10:03 -0700 (Sun, 27 Jan 2008) $
39   */
40  public class ComplexUtils {
41      
42      /**
43       * Default constructor.
44       */
45      private ComplexUtils() {
46          super();
47      }
48      
49      /**
50       * Compute the 
51       * <a href="http://mathworld.wolfram.com/InverseCosine.html" TARGET="_top">
52       * inverse cosine</a> for the given complex argument.
53       * <p>
54       * Implements the formula: <pre>
55       * <code> acos(z) = -i (log(z + i (sqrt(1 - z<sup>2</sup>))))</code></pre>
56       * <p>
57       * Returns {@link Complex#NaN} if either real or imaginary part of the 
58       * input argument is <code>NaN</code> or infinite.
59       * 
60       * @param z the value whose inverse cosine is to be returned
61       * @return the inverse cosine of <code>z</code>
62       * @throws NullPointerException if <code>z</code> is null
63       * @deprecated use Complex.acos()
64       */
65      public static Complex acos(Complex z) {
66          return z.acos();
67      }
68      
69      /**
70       * Compute the 
71       * <a href="http://mathworld.wolfram.com/InverseSine.html" TARGET="_top">
72       * inverse sine</a> for the given complex argument.
73       * <p>
74       * Implements the formula: <pre>
75       * <code> asin(z) = -i (log(sqrt(1 - z<sup>2</sup>) + iz)) </code></pre>
76       * <p>
77       * Returns {@link Complex#NaN} if either real or imaginary part of the 
78       * input argument is <code>NaN</code> or infinite.
79       * 
80       * @param z the value whose inverse sine is to be returned.
81       * @return the inverse sine of <code>z</code>.
82       * @throws NullPointerException if <code>z</code> is null
83       * @deprecated use Complex.asin()
84       */
85      public static Complex asin(Complex z) {
86          return z.asin();
87      }
88      
89      /**
90       * Compute the 
91       * <a href="http://mathworld.wolfram.com/InverseTangent.html" TARGET="_top">
92       * inverse tangent</a> for the given complex argument.
93       * <p>
94       * Implements the formula: <pre>
95       * <code> atan(z) = (i/2) log((i + z)/(i - z)) </code></pre>
96       * <p>
97       * Returns {@link Complex#NaN} if either real or imaginary part of the 
98       * input argument is <code>NaN</code> or infinite. 
99       * 
100      * @param z the value whose inverse tangent is to be returned
101      * @return the inverse tangent of <code>z</code>
102      * @throws NullPointerException if <code>z</code> is null
103      * @deprecated use Complex.atan()
104      */
105     public static Complex atan(Complex z) {
106         return z.atan();
107     }
108     
109     /**
110      * Compute the 
111      * <a href="http://mathworld.wolfram.com/Cosine.html" TARGET="_top">
112      * cosine</a>
113      * for the given complex argument.
114      * <p>
115      * Implements the formula: <pre>
116      * <code> cos(a + bi) = cos(a)cosh(b) - sin(a)sinh(b)i</code></pre>
117      * where the (real) functions on the right-hand side are
118      * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 
119      * {@link MathUtils#cosh} and {@link MathUtils#sinh}.
120      * <p>
121      * Returns {@link Complex#NaN} if either real or imaginary part of the 
122      * input argument is <code>NaN</code>.
123      * <p>
124      * Infinite values in real or imaginary parts of the input may result in
125      * infinite or NaN values returned in parts of the result.<pre>
126      * Examples: 
127      * <code>
128      * cos(1 &plusmn; INFINITY i) = 1 &#x2213; INFINITY i
129      * cos(&plusmn;INFINITY + i) = NaN + NaN i
130      * cos(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i</code></pre>
131      * 
132      * @param z the value whose cosine is to be returned
133      * @return the cosine of <code>z</code>
134      * @throws NullPointerException if <code>z</code> is null
135      * @deprecated use Complex.cos()
136      */
137     public static Complex cos(Complex z) {
138         return z.cos();
139     }
140     
141     /**
142      * Compute the 
143      * <a href="http://mathworld.wolfram.com/HyperbolicCosine.html" TARGET="_top">
144      * hyperbolic cosine</a> for the given complex argument.
145      * <p>
146      * Implements the formula: <pre>
147      * <code> cosh(a + bi) = cosh(a)cos(b) + sinh(a)sin(b)i</code></pre>
148      * where the (real) functions on the right-hand side are
149      * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 
150      * {@link MathUtils#cosh} and {@link MathUtils#sinh}.
151      * <p>
152      * Returns {@link Complex#NaN} if either real or imaginary part of the 
153      * input argument is <code>NaN</code>.
154      * <p>
155      * Infinite values in real or imaginary parts of the input may result in
156      * infinite or NaN values returned in parts of the result.<pre>
157      * Examples: 
158      * <code>
159      * cosh(1 &plusmn; INFINITY i) = NaN + NaN i
160      * cosh(&plusmn;INFINITY + i) = INFINITY &plusmn; INFINITY i
161      * cosh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i</code></pre>
162      * <p>
163      * Throws <code>NullPointerException</code> if z is null.
164      * 
165      * @param z the value whose hyperbolic cosine is to be returned.
166      * @return the hyperbolic cosine of <code>z</code>.
167      * @deprecated use Complex.cosh()
168      */
169     public static Complex cosh(Complex z) {
170         return z.cosh();
171     }
172     
173     /**
174      * Compute the
175      * <a href="http://mathworld.wolfram.com/ExponentialFunction.html" TARGET="_top">
176      * exponential function</a> for the given complex argument.
177      * <p>
178      * Implements the formula: <pre>
179      * <code> exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i</code></pre>
180      * where the (real) functions on the right-hand side are
181      * {@link java.lang.Math#exp}, {@link java.lang.Math#cos}, and
182      * {@link java.lang.Math#sin}.
183      * <p>
184      * Returns {@link Complex#NaN} if either real or imaginary part of the 
185      * input argument is <code>NaN</code>.
186      * <p>
187      * Infinite values in real or imaginary parts of the input may result in
188      * infinite or NaN values returned in parts of the result.<pre>
189      * Examples: 
190      * <code>
191      * exp(1 &plusmn; INFINITY i) = NaN + NaN i
192      * exp(INFINITY + i) = INFINITY + INFINITY i
193      * exp(-INFINITY + i) = 0 + 0i
194      * exp(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i</code></pre>
195      * <p>
196      * Throws <code>NullPointerException</code> if z is null.
197      * 
198      * @param z the value
199      * @return <i>e</i><sup><code>z</code></sup>
200      * @deprecated use Complex.exp()
201      */
202     public static Complex exp(Complex z) {
203         return z.exp();
204     }
205     
206     /**
207      * Compute the 
208      * <a href="http://mathworld.wolfram.com/NaturalLogarithm.html" TARGET="_top">
209      * natural logarithm</a> for the given complex argument.
210      * <p>
211      * Implements the formula: <pre>
212      * <code> log(a + bi) = ln(|a + bi|) + arg(a + bi)i</code></pre>
213      * where ln on the right hand side is {@link java.lang.Math#log},
214      * <code>|a + bi|</code> is the modulus, {@link Complex#abs},  and
215      * <code>arg(a + bi) = {@link java.lang.Math#atan2}(b, a)</code>
216      * <p>
217      * Returns {@link Complex#NaN} if either real or imaginary part of the 
218      * input argument is <code>NaN</code>.
219      * <p>
220      * Infinite (or critical) values in real or imaginary parts of the input may
221      * result in infinite or NaN values returned in parts of the result.<pre>
222      * Examples: 
223      * <code>
224      * log(1 &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;/2)i
225      * log(INFINITY + i) = INFINITY + 0i
226      * log(-INFINITY + i) = INFINITY + &pi;i
227      * log(INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;/4)i
228      * log(-INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (3&pi;/4)i
229      * log(0 + 0i) = -INFINITY + 0i
230      * </code></pre>
231      * Throws <code>NullPointerException</code> if z is null.
232      * 
233      * @param z the value.
234      * @return ln <code>z</code>.
235      * @deprecated use Complex.log()
236      */
237     public static Complex log(Complex z) {
238         return z.log();
239     }
240     
241     /**
242      * Creates a complex number from the given polar representation.
243      * <p>
244      * The value returned is <code>r&middot;e<sup>i&middot;theta</sup></code>,
245      * computed as <code>r&middot;cos(theta) + r&middot;sin(theta)i</code></p>
246      * <p>
247      * If either <code>r</code> or <code>theta</code> is NaN, or 
248      * <code>theta</code> is infinite, {@link Complex#NaN} is returned.</p>
249      * <p>
250      * If <code>r</code> is infinite and <code>theta</code> is finite, 
251      * infinite or NaN values may be returned in parts of the result, following
252      * the rules for double arithmetic.<pre>
253      * Examples: 
254      * <code>
255      * polar2Complex(INFINITY, &pi;/4) = INFINITY + INFINITY i
256      * polar2Complex(INFINITY, 0) = INFINITY + NaN i
257      * polar2Complex(INFINITY, -&pi;/4) = INFINITY - INFINITY i
258      * polar2Complex(INFINITY, 5&pi;/4) = -INFINITY - INFINITY i </code></pre></p>
259      * 
260      * @param r the modulus of the complex number to create
261      * @param theta  the argument of the complex number to create
262      * @return <code>r&middot;e<sup>i&middot;theta</sup></code>
263      * @throws IllegalArgumentException  if r is negative
264      * @since 1.1
265      */
266     public static Complex polar2Complex(double r, double theta) {
267         if (r < 0) {
268             throw new IllegalArgumentException
269                 ("Complex modulus must not be negative");
270         }
271         return new Complex(r * Math.cos(theta), r * Math.sin(theta));
272     }
273     
274     /**
275      * Returns of value of <code>y</code> raised to the power of <code>x</code>.
276      * <p>
277      * Implements the formula: <pre>
278      * <code> y<sup>x</sup> = exp(x&middot;log(y))</code></pre> 
279      * where <code>exp</code> and <code>log</code> are {@link #exp} and
280      * {@link #log}, respectively.
281      * <p>
282      * Returns {@link Complex#NaN} if either real or imaginary part of the 
283      * input argument is <code>NaN</code> or infinite, or if <code>y</code>
284      * equals {@link Complex#ZERO}.
285      * 
286      * @param y the base.
287      * @param x the exponent.
288      * @return <code>y</code><sup><code>x</code></sup>
289      * @throws NullPointerException if either x or y is null
290      * @deprecated use Complex.pow(x)
291      */
292     public static Complex pow(Complex y, Complex x) {
293         return y.pow(x);
294     }
295     
296     /**
297      * Compute the 
298      * <a href="http://mathworld.wolfram.com/Sine.html" TARGET="_top">
299      * sine</a>
300      * for the given complex argument.
301      * <p>
302       * Implements the formula: <pre>
303      * <code> sin(a + bi) = sin(a)cosh(b) - cos(a)sinh(b)i</code></pre>
304      * where the (real) functions on the right-hand side are
305      * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 
306      * {@link MathUtils#cosh} and {@link MathUtils#sinh}.
307      * <p>
308      * Returns {@link Complex#NaN} if either real or imaginary part of the 
309      * input argument is <code>NaN</code>.
310      * <p>
311      * Infinite values in real or imaginary parts of the input may result in
312      * infinite or NaN values returned in parts of the result.<pre>
313      * Examples: 
314      * <code>
315      * sin(1 &plusmn; INFINITY i) = 1 &plusmn; INFINITY i
316      * sin(&plusmn;INFINITY + i) = NaN + NaN i
317      * sin(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i</code></pre>
318      * 
319      * Throws <code>NullPointerException</code> if z is null. 
320      * 
321      * @param z the value whose sine is to be returned.
322      * @return the sine of <code>z</code>.
323      * @deprecated use Complex.sin()
324      */
325     public static Complex sin(Complex z) {
326         return z.sin();
327     }
328     
329     /**
330      * Compute the 
331      * <a href="http://mathworld.wolfram.com/HyperbolicSine.html" TARGET="_top">
332      * hyperbolic sine</a> for the given complex argument.
333      * <p>
334      * Implements the formula: <pre>
335      * <code> sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i</code></pre>
336      * where the (real) functions on the right-hand side are
337      * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 
338      * {@link MathUtils#cosh} and {@link MathUtils#sinh}.
339      * <p>
340      * Returns {@link Complex#NaN} if either real or imaginary part of the 
341      * input argument is <code>NaN</code>.
342      * <p>
343      * Infinite values in real or imaginary parts of the input may result in
344      * infinite or NaN values returned in parts of the result.<pre>
345      * Examples: 
346      * <code>
347      * sinh(1 &plusmn; INFINITY i) = NaN + NaN i
348      * sinh(&plusmn;INFINITY + i) = &plusmn; INFINITY + INFINITY i
349      * sinh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i</code></pre
350      * 
351      * @param z the value whose hyperbolic sine is to be returned
352      * @return the hyperbolic sine of <code>z</code>
353      * @throws NullPointerException if <code>z</code> is null
354      * @deprecated use Complex.sinh()
355      */
356     public static Complex sinh(Complex z) {
357         return z.sinh();
358     }
359     
360     /**
361      * Compute the 
362      * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
363      * square root</a> for the given complex argument.
364      * <p>
365      * Implements the following algorithm to compute <code>sqrt(a + bi)</code>: 
366      * <ol><li>Let <code>t = sqrt((|a| + |a + bi|) / 2)</code></li>
367      * <li><pre>if <code> a &#8805; 0</code> return <code>t + (b/2t)i</code>
368      *  else return <code>|b|/2t + sign(b)t i </code></pre></li>
369      * </ol>
370      * where <ul>
371      * <li><code>|a| = {@link Math#abs}(a)</code></li>
372      * <li><code>|a + bi| = {@link Complex#abs}(a + bi) </code></li>
373      * <li><code>sign(b) =  {@link MathUtils#indicator}(b) </code>
374      * </ul>
375      * <p>
376      * Returns {@link Complex#NaN} if either real or imaginary part of the 
377      * input argument is <code>NaN</code>.
378      * <p>
379      * Infinite values in real or imaginary parts of the input may result in
380      * infinite or NaN values returned in parts of the result.<pre>
381      * Examples: 
382      * <code>
383      * sqrt(1 &plusmn; INFINITY i) = INFINITY + NaN i
384      * sqrt(INFINITY + i) = INFINITY + 0i
385      * sqrt(-INFINITY + i) = 0 + INFINITY i
386      * sqrt(INFINITY &plusmn; INFINITY i) = INFINITY + NaN i
387      * sqrt(-INFINITY &plusmn; INFINITY i) = NaN &plusmn; INFINITY i
388      * </code></pre>
389      * 
390      * @param z the value whose square root is to be returned
391      * @return the square root of <code>z</code>
392      * @throws NullPointerException if <code>z</code> is null
393      * @deprecated use Complex.sqrt()
394      */
395     public static Complex sqrt(Complex z) {
396         return z.sqrt();
397     }
398     
399     /**
400      * Compute the 
401      * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
402      * square root</a> of 1 - <code>z</code><sup>2</sup> for the given complex
403      * argument.
404      * <p>
405      * Computes the result directly as 
406      * <code>sqrt(Complex.ONE.subtract(z.multiply(z)))</code>.
407      * <p>
408      * Returns {@link Complex#NaN} if either real or imaginary part of the 
409      * input argument is <code>NaN</code>.
410      * <p>
411      * Infinite values in real or imaginary parts of the input may result in
412      * infinite or NaN values returned in parts of the result. 
413      * 
414      * @param z the value
415      * @return the square root of 1 - <code>z</code><sup>2</sup>
416      * @throws NullPointerException if <code>z</code> is null
417      * @deprecated use Complex.sqrt1z()
418      */
419     public static Complex sqrt1z(Complex z) {
420         return z.sqrt1z();
421     }
422     
423     /**
424      * Compute the 
425      * <a href="http://mathworld.wolfram.com/Tangent.html" TARGET="_top">
426      * tangent</a> for the given complex argument.
427      * <p>
428      * Implements the formula: <pre>
429      * <code>tan(a + bi) = sin(2a)/(cos(2a)+cosh(2b)) + [sinh(2b)/(cos(2a)+cosh(2b))]i</code></pre>
430      * where the (real) functions on the right-hand side are
431      * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 
432      * {@link MathUtils#cosh} and {@link MathUtils#sinh}.
433      * <p>
434      * Returns {@link Complex#NaN} if either real or imaginary part of the 
435      * input argument is <code>NaN</code>.
436      * <p>
437      * Infinite (or critical) values in real or imaginary parts of the input may
438      * result in infinite or NaN values returned in parts of the result.<pre>
439      * Examples: 
440      * <code>
441      * tan(1 &plusmn; INFINITY i) = 0 + NaN i
442      * tan(&plusmn;INFINITY + i) = NaN + NaN i
443      * tan(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
444      * tan(&plusmn;&pi;/2 + 0 i) = &plusmn;INFINITY + NaN i</code></pre>
445      * 
446      * @param z the value whose tangent is to be returned
447      * @return the tangent of <code>z</code>
448      * @throws NullPointerException if <code>z</code> is null
449      * @deprecated use Complex.tan()
450      */
451     public static Complex tan(Complex z) {
452         return z.tan();
453     }
454     
455     /**
456      * Compute the
457      * <a href="http://mathworld.wolfram.com/HyperbolicTangent.html" TARGET="_top">
458      * hyperbolic tangent</a> for the given complex argument.
459     * <p>
460      * Implements the formula: <pre>
461      * <code>tan(a + bi) = sinh(2a)/(cosh(2a)+cos(2b)) + [sin(2b)/(cosh(2a)+cos(2b))]i</code></pre>
462      * where the (real) functions on the right-hand side are
463      * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, 
464      * {@link MathUtils#cosh} and {@link MathUtils#sinh}.
465      * <p>
466      * Returns {@link Complex#NaN} if either real or imaginary part of the 
467      * input argument is <code>NaN</code>.
468      * <p>
469      * Infinite values in real or imaginary parts of the input may result in
470      * infinite or NaN values returned in parts of the result.<pre>
471      * Examples: 
472      * <code>
473      * tanh(1 &plusmn; INFINITY i) = NaN + NaN i
474      * tanh(&plusmn;INFINITY + i) = NaN + 0 i
475      * tanh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
476      * tanh(0 + (&pi;/2)i) = NaN + INFINITY i</code></pre>
477      *
478      * @param z the value whose hyperbolic tangent is to be returned
479      * @return the hyperbolic tangent of <code>z</code>
480      * @throws NullPointerException if <code>z</code> is null
481      * @deprecated use Complex.tanh()
482      */
483     public static Complex tanh(Complex z) {
484         return z.tanh();
485     }
486 }