| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.commons.math.complex; |
| |
| import org.apache.commons.math.util.MathUtils; |
| |
| /** |
| * Static implementations of common |
| * {@link org.apache.commons.math.complex.Complex}-valued functions. Included |
| * are trigonometric, exponential, log, power and square root functions. |
| *<p> |
| * Reference: |
| * <ul> |
| * <li><a href="http://myweb.lmu.edu/dmsmith/ZMLIB.pdf"> |
| * Multiple Precision Complex Arithmetic and Functions</a></li> |
| * </ul> |
| * See individual method javadocs for the computational formulas used. |
| * In general, NaN values in either real or imaginary parts of input arguments |
| * result in {@link Complex#NaN} returned. Otherwise, infinite or NaN values |
| * are returned as they arise in computing the real functions specified in the |
| * computational formulas. Null arguments result in NullPointerExceptions. |
| * |
| * @version $Revision$ $Date$ |
| */ |
| public class ComplexUtils { |
| |
| /** |
| * Default constructor. |
| */ |
| private ComplexUtils() { |
| super(); |
| } |
| |
| /** |
| * Compute the |
| * <a href="http://mathworld.wolfram.com/InverseCosine.html" TARGET="_top"> |
| * inverse cosine</a> for the given complex argument. |
| * <p> |
| * Implements the formula: <pre> |
| * <code> acos(z) = -i (log(z + i (sqrt(1 - z<sup>2</sup>))))</code></pre> |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code> or infinite. |
| * |
| * @param z the value whose inverse cosine is to be returned |
| * @return the inverse cosine of <code>z</code> |
| * @throws NullPointerException if <code>z</code> is null |
| * @deprecated use Complex.acos() |
| */ |
| public static Complex acos(Complex z) { |
| return z.acos(); |
| } |
| |
| /** |
| * Compute the |
| * <a href="http://mathworld.wolfram.com/InverseSine.html" TARGET="_top"> |
| * inverse sine</a> for the given complex argument. |
| * <p> |
| * Implements the formula: <pre> |
| * <code> asin(z) = -i (log(sqrt(1 - z<sup>2</sup>) + iz)) </code></pre> |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code> or infinite. |
| * |
| * @param z the value whose inverse sine is to be returned. |
| * @return the inverse sine of <code>z</code>. |
| * @throws NullPointerException if <code>z</code> is null |
| * @deprecated use Complex.asin() |
| */ |
| public static Complex asin(Complex z) { |
| return z.asin(); |
| } |
| |
| /** |
| * Compute the |
| * <a href="http://mathworld.wolfram.com/InverseTangent.html" TARGET="_top"> |
| * inverse tangent</a> for the given complex argument. |
| * <p> |
| * Implements the formula: <pre> |
| * <code> atan(z) = (i/2) log((i + z)/(i - z)) </code></pre> |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code> or infinite. |
| * |
| * @param z the value whose inverse tangent is to be returned |
| * @return the inverse tangent of <code>z</code> |
| * @throws NullPointerException if <code>z</code> is null |
| * @deprecated use Complex.atan() |
| */ |
| public static Complex atan(Complex z) { |
| return z.atan(); |
| } |
| |
| /** |
| * Compute the |
| * <a href="http://mathworld.wolfram.com/Cosine.html" TARGET="_top"> |
| * cosine</a> |
| * for the given complex argument. |
| * <p> |
| * Implements the formula: <pre> |
| * <code> cos(a + bi) = cos(a)cosh(b) - sin(a)sinh(b)i</code></pre> |
| * where the (real) functions on the right-hand side are |
| * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, |
| * {@link MathUtils#cosh} and {@link MathUtils#sinh}. |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code>. |
| * <p> |
| * Infinite values in real or imaginary parts of the input may result in |
| * infinite or NaN values returned in parts of the result.<pre> |
| * Examples: |
| * <code> |
| * cos(1 ± INFINITY i) = 1 ∓ INFINITY i |
| * cos(±INFINITY + i) = NaN + NaN i |
| * cos(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre> |
| * |
| * @param z the value whose cosine is to be returned |
| * @return the cosine of <code>z</code> |
| * @throws NullPointerException if <code>z</code> is null |
| * @deprecated use Complex.cos() |
| */ |
| public static Complex cos(Complex z) { |
| return z.cos(); |
| } |
| |
| /** |
| * Compute the |
| * <a href="http://mathworld.wolfram.com/HyperbolicCosine.html" TARGET="_top"> |
| * hyperbolic cosine</a> for the given complex argument. |
| * <p> |
| * Implements the formula: <pre> |
| * <code> cosh(a + bi) = cosh(a)cos(b) + sinh(a)sin(b)i</code></pre> |
| * where the (real) functions on the right-hand side are |
| * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, |
| * {@link MathUtils#cosh} and {@link MathUtils#sinh}. |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code>. |
| * <p> |
| * Infinite values in real or imaginary parts of the input may result in |
| * infinite or NaN values returned in parts of the result.<pre> |
| * Examples: |
| * <code> |
| * cosh(1 ± INFINITY i) = NaN + NaN i |
| * cosh(±INFINITY + i) = INFINITY ± INFINITY i |
| * cosh(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre> |
| * <p> |
| * Throws <code>NullPointerException</code> if z is null. |
| * |
| * @param z the value whose hyperbolic cosine is to be returned. |
| * @return the hyperbolic cosine of <code>z</code>. |
| * @deprecated use Complex.cosh() |
| */ |
| public static Complex cosh(Complex z) { |
| return z.cosh(); |
| } |
| |
| /** |
| * Compute the |
| * <a href="http://mathworld.wolfram.com/ExponentialFunction.html" TARGET="_top"> |
| * exponential function</a> for the given complex argument. |
| * <p> |
| * Implements the formula: <pre> |
| * <code> exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i</code></pre> |
| * where the (real) functions on the right-hand side are |
| * {@link java.lang.Math#exp}, {@link java.lang.Math#cos}, and |
| * {@link java.lang.Math#sin}. |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code>. |
| * <p> |
| * Infinite values in real or imaginary parts of the input may result in |
| * infinite or NaN values returned in parts of the result.<pre> |
| * Examples: |
| * <code> |
| * exp(1 ± INFINITY i) = NaN + NaN i |
| * exp(INFINITY + i) = INFINITY + INFINITY i |
| * exp(-INFINITY + i) = 0 + 0i |
| * exp(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre> |
| * <p> |
| * Throws <code>NullPointerException</code> if z is null. |
| * |
| * @param z the value |
| * @return <i>e</i><sup><code>z</code></sup> |
| * @deprecated use Complex.exp() |
| */ |
| public static Complex exp(Complex z) { |
| return z.exp(); |
| } |
| |
| /** |
| * Compute the |
| * <a href="http://mathworld.wolfram.com/NaturalLogarithm.html" TARGET="_top"> |
| * natural logarithm</a> for the given complex argument. |
| * <p> |
| * Implements the formula: <pre> |
| * <code> log(a + bi) = ln(|a + bi|) + arg(a + bi)i</code></pre> |
| * where ln on the right hand side is {@link java.lang.Math#log}, |
| * <code>|a + bi|</code> is the modulus, {@link Complex#abs}, and |
| * <code>arg(a + bi) = {@link java.lang.Math#atan2}(b, a)</code> |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code>. |
| * <p> |
| * Infinite (or critical) values in real or imaginary parts of the input may |
| * result in infinite or NaN values returned in parts of the result.<pre> |
| * Examples: |
| * <code> |
| * log(1 ± INFINITY i) = INFINITY ± (π/2)i |
| * log(INFINITY + i) = INFINITY + 0i |
| * log(-INFINITY + i) = INFINITY + πi |
| * log(INFINITY ± INFINITY i) = INFINITY ± (π/4)i |
| * log(-INFINITY ± INFINITY i) = INFINITY ± (3π/4)i |
| * log(0 + 0i) = -INFINITY + 0i |
| * </code></pre> |
| * Throws <code>NullPointerException</code> if z is null. |
| * |
| * @param z the value. |
| * @return ln <code>z</code>. |
| * @deprecated use Complex.log() |
| */ |
| public static Complex log(Complex z) { |
| return z.log(); |
| } |
| |
| /** |
| * Creates a complex number from the given polar representation. |
| * <p> |
| * The value returned is <code>r·e<sup>i·theta</sup></code>, |
| * computed as <code>r·cos(theta) + r·sin(theta)i</code></p> |
| * <p> |
| * If either <code>r</code> or <code>theta</code> is NaN, or |
| * <code>theta</code> is infinite, {@link Complex#NaN} is returned.</p> |
| * <p> |
| * If <code>r</code> is infinite and <code>theta</code> is finite, |
| * infinite or NaN values may be returned in parts of the result, following |
| * the rules for double arithmetic.<pre> |
| * Examples: |
| * <code> |
| * polar2Complex(INFINITY, π/4) = INFINITY + INFINITY i |
| * polar2Complex(INFINITY, 0) = INFINITY + NaN i |
| * polar2Complex(INFINITY, -π/4) = INFINITY - INFINITY i |
| * polar2Complex(INFINITY, 5π/4) = -INFINITY - INFINITY i </code></pre></p> |
| * |
| * @param r the modulus of the complex number to create |
| * @param theta the argument of the complex number to create |
| * @return <code>r·e<sup>i·theta</sup></code> |
| * @throws IllegalArgumentException if r is negative |
| * @since 1.1 |
| */ |
| public static Complex polar2Complex(double r, double theta) { |
| if (r < 0) { |
| throw new IllegalArgumentException |
| ("Complex modulus must not be negative"); |
| } |
| return new Complex(r * Math.cos(theta), r * Math.sin(theta)); |
| } |
| |
| /** |
| * Returns of value of <code>y</code> raised to the power of <code>x</code>. |
| * <p> |
| * Implements the formula: <pre> |
| * <code> y<sup>x</sup> = exp(x·log(y))</code></pre> |
| * where <code>exp</code> and <code>log</code> are {@link #exp} and |
| * {@link #log}, respectively. |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code> or infinite, or if <code>y</code> |
| * equals {@link Complex#ZERO}. |
| * |
| * @param y the base. |
| * @param x the exponent. |
| * @return <code>y</code><sup><code>x</code></sup> |
| * @throws NullPointerException if either x or y is null |
| * @deprecated use Complex.pow(x) |
| */ |
| public static Complex pow(Complex y, Complex x) { |
| return y.pow(x); |
| } |
| |
| /** |
| * Compute the |
| * <a href="http://mathworld.wolfram.com/Sine.html" TARGET="_top"> |
| * sine</a> |
| * for the given complex argument. |
| * <p> |
| * Implements the formula: <pre> |
| * <code> sin(a + bi) = sin(a)cosh(b) - cos(a)sinh(b)i</code></pre> |
| * where the (real) functions on the right-hand side are |
| * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, |
| * {@link MathUtils#cosh} and {@link MathUtils#sinh}. |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code>. |
| * <p> |
| * Infinite values in real or imaginary parts of the input may result in |
| * infinite or NaN values returned in parts of the result.<pre> |
| * Examples: |
| * <code> |
| * sin(1 ± INFINITY i) = 1 ± INFINITY i |
| * sin(±INFINITY + i) = NaN + NaN i |
| * sin(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre> |
| * |
| * Throws <code>NullPointerException</code> if z is null. |
| * |
| * @param z the value whose sine is to be returned. |
| * @return the sine of <code>z</code>. |
| * @deprecated use Complex.sin() |
| */ |
| public static Complex sin(Complex z) { |
| return z.sin(); |
| } |
| |
| /** |
| * Compute the |
| * <a href="http://mathworld.wolfram.com/HyperbolicSine.html" TARGET="_top"> |
| * hyperbolic sine</a> for the given complex argument. |
| * <p> |
| * Implements the formula: <pre> |
| * <code> sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i</code></pre> |
| * where the (real) functions on the right-hand side are |
| * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, |
| * {@link MathUtils#cosh} and {@link MathUtils#sinh}. |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code>. |
| * <p> |
| * Infinite values in real or imaginary parts of the input may result in |
| * infinite or NaN values returned in parts of the result.<pre> |
| * Examples: |
| * <code> |
| * sinh(1 ± INFINITY i) = NaN + NaN i |
| * sinh(±INFINITY + i) = ± INFINITY + INFINITY i |
| * sinh(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre |
| * |
| * @param z the value whose hyperbolic sine is to be returned |
| * @return the hyperbolic sine of <code>z</code> |
| * @throws NullPointerException if <code>z</code> is null |
| * @deprecated use Complex.sinh() |
| */ |
| public static Complex sinh(Complex z) { |
| return z.sinh(); |
| } |
| |
| /** |
| * Compute the |
| * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top"> |
| * square root</a> for the given complex argument. |
| * <p> |
| * Implements the following algorithm to compute <code>sqrt(a + bi)</code>: |
| * <ol><li>Let <code>t = sqrt((|a| + |a + bi|) / 2)</code></li> |
| * <li><pre>if <code> a ≥ 0</code> return <code>t + (b/2t)i</code> |
| * else return <code>|b|/2t + sign(b)t i </code></pre></li> |
| * </ol> |
| * where <ul> |
| * <li><code>|a| = {@link Math#abs}(a)</code></li> |
| * <li><code>|a + bi| = {@link Complex#abs}(a + bi) </code></li> |
| * <li><code>sign(b) = {@link MathUtils#indicator}(b) </code> |
| * </ul> |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code>. |
| * <p> |
| * Infinite values in real or imaginary parts of the input may result in |
| * infinite or NaN values returned in parts of the result.<pre> |
| * Examples: |
| * <code> |
| * sqrt(1 ± INFINITY i) = INFINITY + NaN i |
| * sqrt(INFINITY + i) = INFINITY + 0i |
| * sqrt(-INFINITY + i) = 0 + INFINITY i |
| * sqrt(INFINITY ± INFINITY i) = INFINITY + NaN i |
| * sqrt(-INFINITY ± INFINITY i) = NaN ± INFINITY i |
| * </code></pre> |
| * |
| * @param z the value whose square root is to be returned |
| * @return the square root of <code>z</code> |
| * @throws NullPointerException if <code>z</code> is null |
| * @deprecated use Complex.sqrt() |
| */ |
| public static Complex sqrt(Complex z) { |
| return z.sqrt(); |
| } |
| |
| /** |
| * Compute the |
| * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top"> |
| * square root</a> of 1 - <code>z</code><sup>2</sup> for the given complex |
| * argument. |
| * <p> |
| * Computes the result directly as |
| * <code>sqrt(Complex.ONE.subtract(z.multiply(z)))</code>. |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code>. |
| * <p> |
| * Infinite values in real or imaginary parts of the input may result in |
| * infinite or NaN values returned in parts of the result. |
| * |
| * @param z the value |
| * @return the square root of 1 - <code>z</code><sup>2</sup> |
| * @throws NullPointerException if <code>z</code> is null |
| * @deprecated use Complex.sqrt1z() |
| */ |
| public static Complex sqrt1z(Complex z) { |
| return z.sqrt1z(); |
| } |
| |
| /** |
| * Compute the |
| * <a href="http://mathworld.wolfram.com/Tangent.html" TARGET="_top"> |
| * tangent</a> for the given complex argument. |
| * <p> |
| * Implements the formula: <pre> |
| * <code>tan(a + bi) = sin(2a)/(cos(2a)+cosh(2b)) + [sinh(2b)/(cos(2a)+cosh(2b))]i</code></pre> |
| * where the (real) functions on the right-hand side are |
| * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, |
| * {@link MathUtils#cosh} and {@link MathUtils#sinh}. |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code>. |
| * <p> |
| * Infinite (or critical) values in real or imaginary parts of the input may |
| * result in infinite or NaN values returned in parts of the result.<pre> |
| * Examples: |
| * <code> |
| * tan(1 ± INFINITY i) = 0 + NaN i |
| * tan(±INFINITY + i) = NaN + NaN i |
| * tan(±INFINITY ± INFINITY i) = NaN + NaN i |
| * tan(±π/2 + 0 i) = ±INFINITY + NaN i</code></pre> |
| * |
| * @param z the value whose tangent is to be returned |
| * @return the tangent of <code>z</code> |
| * @throws NullPointerException if <code>z</code> is null |
| * @deprecated use Complex.tan() |
| */ |
| public static Complex tan(Complex z) { |
| return z.tan(); |
| } |
| |
| /** |
| * Compute the |
| * <a href="http://mathworld.wolfram.com/HyperbolicTangent.html" TARGET="_top"> |
| * hyperbolic tangent</a> for the given complex argument. |
| * <p> |
| * Implements the formula: <pre> |
| * <code>tan(a + bi) = sinh(2a)/(cosh(2a)+cos(2b)) + [sin(2b)/(cosh(2a)+cos(2b))]i</code></pre> |
| * where the (real) functions on the right-hand side are |
| * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, |
| * {@link MathUtils#cosh} and {@link MathUtils#sinh}. |
| * <p> |
| * Returns {@link Complex#NaN} if either real or imaginary part of the |
| * input argument is <code>NaN</code>. |
| * <p> |
| * Infinite values in real or imaginary parts of the input may result in |
| * infinite or NaN values returned in parts of the result.<pre> |
| * Examples: |
| * <code> |
| * tanh(1 ± INFINITY i) = NaN + NaN i |
| * tanh(±INFINITY + i) = NaN + 0 i |
| * tanh(±INFINITY ± INFINITY i) = NaN + NaN i |
| * tanh(0 + (π/2)i) = NaN + INFINITY i</code></pre> |
| * |
| * @param z the value whose hyperbolic tangent is to be returned |
| * @return the hyperbolic tangent of <code>z</code> |
| * @throws NullPointerException if <code>z</code> is null |
| * @deprecated use Complex.tanh() |
| */ |
| public static Complex tanh(Complex z) { |
| return z.tanh(); |
| } |
| } |