You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ps...@apache.org on 2005/11/23 18:44:04 UTC
svn commit: r348502 - in /jakarta/commons/proper/math/branches/MATH_1_1: ./
src/java/org/apache/commons/math/complex/ src/test/org/apache/commons/math/
src/test/org/apache/commons/math/complex/ xdocs/ xdocs/userguide/
Author: psteitz
Date: Wed Nov 23 09:43:57 2005
New Revision: 348502
URL: http://svn.apache.org/viewcvs?rev=348502&view=rev
Log:
* Added polar2Complex method to ComplexUtils to create Complex numbers from
polar representations.
* Improved documentation and test cases related to handling of infinite and NaN
values in Complex, ComplexUtils classes. BZ #37086.
Modified:
jakarta/commons/proper/math/branches/MATH_1_1/project.xml
jakarta/commons/proper/math/branches/MATH_1_1/src/java/org/apache/commons/math/complex/Complex.java
jakarta/commons/proper/math/branches/MATH_1_1/src/java/org/apache/commons/math/complex/ComplexUtils.java
jakarta/commons/proper/math/branches/MATH_1_1/src/test/org/apache/commons/math/TestUtils.java
jakarta/commons/proper/math/branches/MATH_1_1/src/test/org/apache/commons/math/complex/ComplexUtilsTest.java
jakarta/commons/proper/math/branches/MATH_1_1/xdocs/changes.xml
jakarta/commons/proper/math/branches/MATH_1_1/xdocs/userguide/complex.xml
Modified: jakarta/commons/proper/math/branches/MATH_1_1/project.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/branches/MATH_1_1/project.xml?rev=348502&r1=348501&r2=348502&view=diff
==============================================================================
--- jakarta/commons/proper/math/branches/MATH_1_1/project.xml (original)
+++ jakarta/commons/proper/math/branches/MATH_1_1/project.xml Wed Nov 23 09:43:57 2005
@@ -205,8 +205,8 @@
<reports>
<report>maven-changes-plugin</report>
<report>maven-checkstyle-plugin</report>
- <report>maven-clover-plugin</report>
<!--
+ <report>maven-clover-plugin</report>
<report>maven-changelog-plugin</report>
<report>maven-developer-activity-plugin</report>
<report>maven-file-activity-plugin</report>
Modified: jakarta/commons/proper/math/branches/MATH_1_1/src/java/org/apache/commons/math/complex/Complex.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/branches/MATH_1_1/src/java/org/apache/commons/math/complex/Complex.java?rev=348502&r1=348501&r2=348502&view=diff
==============================================================================
--- jakarta/commons/proper/math/branches/MATH_1_1/src/java/org/apache/commons/math/complex/Complex.java (original)
+++ jakarta/commons/proper/math/branches/MATH_1_1/src/java/org/apache/commons/math/complex/Complex.java Wed Nov 23 09:43:57 2005
@@ -23,11 +23,11 @@
* Representation of a Complex number - a number which has both a
* real and imaginary part.
* <p>
- * Implementation of arithmetic operations handles <code>NaN</code> and
+ * Implementations of arithmetic operations handle <code>NaN</code> and
* infinite values according to the rules for {@link java.lang.Double}
* arithmetic, applying definitional formulas and returning <code>NaN</code> or
* infinite values in real or imaginary parts as these arise in computation.
- * See the javadoc for individual methods for details.
+ * See individual method javadocs for details.
* <p>
* {@link #equals} identifies all values with <code>NaN</code> in either real
* or imaginary part - e.g., <pre>
@@ -76,7 +76,7 @@
* <p>
* Returns <code>NaN</code> if either real or imaginary part is
* <code>NaN</code> and <code>Double.POSITIVE_INFINITY</code> if
- * neither part is <code>NaN</code>, but at least on part takes an infinite
+ * neither part is <code>NaN</code>, but at least one part takes an infinite
* value.
*
* @return the absolute value.
@@ -110,11 +110,15 @@
* <p>
* Uses the definitional formula
* <pre>
- * (a + bi) + (c + di) = (a+c) + (b + d)i
+ * (a + bi) + (c + di) = (a+c) + (b+d)i
* </pre>
* <p>
- * Inifinite and NaN values are returned in the parts according to the
- * rules for {@link java.lang.Double} arithmetic.
+ * If either this or <code>rhs</code> has a NaN value in either part,
+ * {@link #NaN} is returned; otherwise Inifinite and NaN values are
+ * returned in the parts of the result according to the rules for
+ * {@link java.lang.Double} arithmetic.
+ * <p>
+ * Throws <code>NullPointerException</code> if <code>rhs</code> is null.
*
* @param rhs the other complex number.
* @return the complex number sum.
@@ -128,13 +132,13 @@
* Return the conjugate of this complex number. The conjugate of
* "A + Bi" is "A - Bi".
* <p>
- * Complex.NaN is returned if either the real or imaginary
- * part of this Complex number equals Double.NaN.
+ * {@link #NaN} is returned if either the real or imaginary
+ * part of this Complex number equals <code>Double.NaN</code>.
* <p>
* If the imaginary part is infinite, and the real part is not NaN,
* the returned value has infinite imaginary part of the opposite
* sign - e.g. the conjugate of <code>1 + POSITIVE_INFINITY i</code>
- * is <code>1 + NEGATIVE_INFINITY i</code>
+ * is <code>1 - NEGATIVE_INFINITY i</code>
*
* @return the conjugate of this Complex object
*/
@@ -152,7 +156,7 @@
* <pre><code>
* a + bi ac + bd + (bc - ad)i
* ----------- = -------------------------
- * c + di c*c + d*d
+ * c + di c<sup>2</sup> + d<sup>2</sup>
* </code></pre>
* but uses
* <a href="http://doi.acm.org/10.1145/1039813.1039814">
@@ -172,9 +176,10 @@
* <code>rhs</code> is infinite (one or both parts infinite),
* {@link #ZERO} is returned.</li>
* <li>If this is infinite and <code>rhs</code> is finite, NaN values are
- * returned in parts if the {@link java.lang.Double} rules applied to the
- * definitional formula force NaN results.</li>
+ * returned in the parts of the result if the {@link java.lang.Double}
+ * rules applied to the definitional formula force NaN results.</li>
* </ul>
+ * Throws <code>NullPointerException</code> if <code>rhs</code> is null.
*
* @param rhs the other complex number
* @return the complex number quotient
@@ -222,7 +227,7 @@
* <p>
* All <code>NaN</code> values are considered to be equal - i.e, if either
* (or both) real and imaginary parts of the complex number are equal
- * to Double.NaN, the complex number is equal to
+ * to <code>Double.NaN</code>, the complex number is equal to
* <code>Complex.NaN</code>.
*
* @param other Object to test for equality to this
@@ -336,6 +341,8 @@
* (-INF + -INFi)(1 + NaNi) = NaN + NaNi
* </code></pre>
*
+ * Throws <code>NullPointerException</code> if <code>rhs</code> is null.
+ *
* @param rhs the other complex number.
* @return the complex number product.
*/
@@ -349,6 +356,9 @@
/**
* Return the additive inverse of this complex number.
+ * <p>
+ * Returns <code>Complex.NaN</code> if either real or imaginary
+ * part of this Complex number equals <code>Double.NaN</code>.
*
* @return the negation of this complex number.
*/
@@ -363,7 +373,19 @@
/**
* Return the difference between this complex number and the given complex
* number.
- *
+ * <p>
+ * Uses the definitional formula
+ * <pre>
+ * (a + bi) - (c + di) = (a-c) + (b-d)i
+ * </pre>
+ * <p>
+ * If either this or <code>rhs</code> has a NaN value in either part,
+ * {@link #NaN} is returned; otherwise inifinite and NaN values are
+ * returned in the parts of the result according to the rules for
+ * {@link java.lang.Double} arithmetic.
+ * <p>
+ * Throws <code>NullPointerException</code> if <code>rhs</code> is null.
+ *
* @param rhs the other complex number.
* @return the complex number difference.
*/
Modified: jakarta/commons/proper/math/branches/MATH_1_1/src/java/org/apache/commons/math/complex/ComplexUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/branches/MATH_1_1/src/java/org/apache/commons/math/complex/ComplexUtils.java?rev=348502&r1=348501&r2=348502&view=diff
==============================================================================
--- jakarta/commons/proper/math/branches/MATH_1_1/src/java/org/apache/commons/math/complex/ComplexUtils.java (original)
+++ jakarta/commons/proper/math/branches/MATH_1_1/src/java/org/apache/commons/math/complex/ComplexUtils.java Wed Nov 23 09:43:57 2005
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2004 The Apache Software Foundation.
+ * Copyright 2003-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,14 +19,20 @@
import org.apache.commons.math.util.MathUtils;
/**
- * Implementations of various transcendental functions for
- * {@link org.apache.commons.math.complex.Complex} arguments.
- *
+ * 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$
*/
@@ -42,6 +48,15 @@
/**
* Compute the <a href="http://mathworld.wolfram.com/InverseCosine.html">
* 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.
+ * <p>
+ * Throws <code>NullPointerException</code> if z is null.
+ *
* @param z the value whose inverse cosine is to be returned.
* @return the inverse cosine of <code>z</code>.
*/
@@ -57,6 +72,15 @@
/**
* Compute the <a href="http://mathworld.wolfram.com/InverseSine.html">
* 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.
+ * <p>
+ * Throws <code>NullPointerException</code> if z is null.
+ *
* @param z the value whose inverse sine is to be returned.
* @return the inverse sine of <code>z</code>.
*/
@@ -72,6 +96,15 @@
/**
* Compute the <a href="http://mathworld.wolfram.com/InverseTangent.html">
* 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.
+ * <p>
+ * Throws <code>NullPointerException</code> if z is null.
+ *
* @param z the value whose inverse tangent is to be returned.
* @return the inverse tangent of <code>z</code>.
*/
@@ -80,7 +113,6 @@
return Complex.NaN;
}
-
return Complex.I.multiply(
log(Complex.I.add(z).divide(Complex.I.subtract(z))))
.divide(new Complex(2.0, 0.0));
@@ -89,6 +121,26 @@
/**
* Compute the <a href="http://mathworld.wolfram.com/Cosine.html">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>
+ *
+ * Throws <code>NullPointerException</code> if z is null.
+ *
* @param z the value whose cosine is to be returned.
* @return the cosine of <code>z</code>.
*/
@@ -107,6 +159,26 @@
/**
* Compute the <a href="http://mathworld.wolfram.com/HyperbolicCosine.html">
* 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>.
*/
@@ -126,6 +198,27 @@
* Compute the
* <a href="http://mathworld.wolfram.com/ExponentialFunction.html">
* 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>.
*/
@@ -136,14 +229,34 @@
double b = z.getImaginary();
double expA = Math.exp(z.getReal());
- double sinB = Math.sin(b);
- double cosB = Math.cos(b);
- return new Complex(expA * cosB, expA * sinB);
+ return new Complex(expA * Math.cos(b), expA * Math.sin(b));
}
/**
* Compute the <a href="http://mathworld.wolfram.com/NaturalLogarithm.html">
* 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 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
+ * </code></pre>
+ * Throws <code>NullPointerException</code> if z is null.
+ *
* @param z the value.
* @return ln <code>z</code>.
*/
@@ -156,12 +269,56 @@
Math.atan2(z.getImaginary(), z.getReal()));
}
+ /**
+ * 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>
+ * If either <code>r</code> or <code>theta</code> is NaN, or
+ * <code>theta</code> is infinite, {@link Complex#NaN} is returned.
+ * <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>
+ *
+ * Throws <code>IllegalArgumentException</code> if <code>r < 0</code>
+ *
+ * @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
+ */
+ 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.
+ * <p>
+ * Throws <code>NullPointerException</code> if either x or y is null.
+ *
* @param y the base.
* @param x the exponent.
- * @return <code>y</code><sup><code>z</code></sup>.
+ * @return <code>y</code><sup><code>x</code></sup>
*/
public static Complex pow(Complex y, Complex x) {
return exp(x.multiply(log(y)));
@@ -170,6 +327,26 @@
/**
* Compute the <a href="http://mathworld.wolfram.com/Sine.html">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>.
*/
@@ -188,6 +365,26 @@
/**
* Compute the <a href="http://mathworld.wolfram.com/HyperbolicSine.html">
* 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>
+ * <p>
+ * Throws <code>NullPointerException</code> if z is null.
+ *
* @param z the value whose hyperbolic sine is to be returned.
* @return the hyperbolic sine of <code>z</code>.
*/
@@ -204,8 +401,36 @@
}
/**
- * Compute the <a href="http://mathworld.wolfram.com/SquareRoot.html">squre
+ * Compute the <a href="http://mathworld.wolfram.com/SquareRoot.html">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>
+ *
+ * Throws <code>NullPointerException</code> if z is null.
+ *
* @param z the value whose square root is to be returned.
* @return the square root of <code>z</code>.
*/
@@ -221,14 +446,26 @@
if (a >= 0.0) {
return new Complex(t, b / (2.0 * t));
} else {
- return new Complex(Math.abs(z.getImaginary()) / (2.0 * t),
+ return new Complex(Math.abs(b) / (2.0 * t),
MathUtils.indicator(b) * t);
}
}
/**
- * Compute the <a href="http://mathworld.wolfram.com/SquareRoot.html">squre
- * root of 1 - <code>z</code><sup>2</sup> for the given complex argument.
+ * Compute the <a href="http://mathworld.wolfram.com/SquareRoot.html">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.
+ * <p>
+ * Throws <code>NullPointerException</code> if z is null.
+ *
* @param z the value.
* @return the square root of 1 - <code>z</code><sup>2</sup>.
*/
@@ -239,6 +476,26 @@
/**
* Compute the <a href="http://mathworld.wolfram.com/Tangent.html">
* 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 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</code></pre>
+ *
+ * Throws <code>NullPointerException</code> if z is null.
+ *
* @param z the value whose tangent is to be returned.
* @return the tangent of <code>z</code>.
*/
@@ -258,6 +515,26 @@
* Compute the
* <a href="http://mathworld.wolfram.com/HyperbolicTangent.html">
* 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>
+ * tan(1 ± INFINITY i) = NaN + NaN i
+ * tan(±INFINITY + i) = NaN + 0 i
+ * tan(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre>
+ *
+ * Throws <code>NullPointerException</code> if z is null.
+ *
* @param z the value whose hyperbolic tangent is to be returned.
* @return the hyperbolic tangent of <code>z</code>.
*/
Modified: jakarta/commons/proper/math/branches/MATH_1_1/src/test/org/apache/commons/math/TestUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/branches/MATH_1_1/src/test/org/apache/commons/math/TestUtils.java?rev=348502&r1=348501&r2=348502&view=diff
==============================================================================
--- jakarta/commons/proper/math/branches/MATH_1_1/src/test/org/apache/commons/math/TestUtils.java (original)
+++ jakarta/commons/proper/math/branches/MATH_1_1/src/test/org/apache/commons/math/TestUtils.java Wed Nov 23 09:43:57 2005
@@ -42,6 +42,10 @@
assertEquals(null, expected, actual, delta);
}
+ /**
+ * Verifies that expected and actual are within delta, or are both NaN or
+ * infinities of the same sign.
+ */
public static void assertEquals(String msg, double expected, double actual, double delta) {
// check for NaN
if(Double.isNaN(expected)){
@@ -52,8 +56,26 @@
}
}
+ /*
+ * Verifies that the two arguments are exactly the same, either
+ * both NaN or infinities of same sign, or identical floating point values.
+ */
+ public static void assertSame(double expected, double actual) {
+ assertEquals(expected, actual, 0);
+ }
+
+ /**
+ * Verifies that real and imaginary parts of the two complex arguments
+ * are exactly the same. Also ensures that NaN / infinite components match.
+ */
+ public static void assertSame(Complex expected, Complex actual) {
+ assertSame(expected.getReal(), actual.getReal());
+ assertSame(expected.getImaginary(), actual.getImaginary());
+ }
+
/**
- *
+ * Verifies that real and imaginary parts of the two complex arguments
+ * differ by at most delta. Also ensures that NaN / infinite components match.
*/
public static void assertEquals(Complex expected, Complex actual, double delta) {
assertEquals(expected.getReal(), actual.getReal(), delta);
Modified: jakarta/commons/proper/math/branches/MATH_1_1/src/test/org/apache/commons/math/complex/ComplexUtilsTest.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/branches/MATH_1_1/src/test/org/apache/commons/math/complex/ComplexUtilsTest.java?rev=348502&r1=348501&r2=348502&view=diff
==============================================================================
--- jakarta/commons/proper/math/branches/MATH_1_1/src/test/org/apache/commons/math/complex/ComplexUtilsTest.java (original)
+++ jakarta/commons/proper/math/branches/MATH_1_1/src/test/org/apache/commons/math/complex/ComplexUtilsTest.java Wed Nov 23 09:43:57 2005
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2004 The Apache Software Foundation.
+ * Copyright 2003-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,16 +25,63 @@
*/
public class ComplexUtilsTest extends TestCase {
+ private double inf = Double.POSITIVE_INFINITY;
+ private double negInf = Double.NEGATIVE_INFINITY;
+ private double nan = Double.NaN;
+ private double pi = Math.PI;
+
+ private Complex oneInf = new Complex(1, inf);
+ private Complex oneNegInf = new Complex(1, negInf);
+ private Complex infOne = new Complex(inf, 1);
+ private Complex negInfOne = new Complex(negInf, 1);
+ private Complex negInfInf = new Complex(negInf, inf);
+ private Complex infNegInf = new Complex(inf, negInf);
+ private Complex infInf = new Complex(inf, inf);
+ private Complex negInfNegInf = new Complex(negInf, negInf);
+ private Complex oneNaN = new Complex(1, nan);
+ private Complex infNaN = new Complex(inf, nan);
+ private Complex negInfNaN = new Complex(negInf, nan);
+ private Complex nanInf = new Complex(nan, inf);
+ private Complex nanNegInf = new Complex(nan, negInf);
+ private Complex zeroNaN = new Complex(0, nan);
+ private Complex nanZero = new Complex(nan, 0);
+ private Complex infZero = new Complex(inf, 0);
+ private Complex zeroInf = new Complex(0, inf);
+
+ private ComplexFormat fmt = new ComplexFormat();
+
public void testAcos() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(0.936812, -2.30551);
TestUtils.assertEquals(expected, ComplexUtils.acos(z), 1.0e-5);
+ TestUtils.assertEquals(new Complex(Math.acos(0), 0),
+ ComplexUtils.acos(Complex.ZERO), 1.0e-12);
+ }
+
+ public void testAcosInf() {
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.acos(oneInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.acos(oneNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.acos(infOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.acos(negInfOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.acos(infInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.acos(infNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.acos(negInfInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.acos(negInfNegInf));
}
public void testAcosNaN() {
assertTrue(ComplexUtils.acos(Complex.NaN).isNaN());
}
+ public void testAcosNull() {
+ try {
+ Complex z = ComplexUtils.acos(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+ }
+
public void testAsin() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(0.633984, 2.30551);
@@ -45,14 +92,55 @@
assertTrue(ComplexUtils.asin(Complex.NaN).isNaN());
}
+ public void testAsinInf() {
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.asin(oneInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.asin(oneNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.asin(infOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.asin(negInfOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.asin(infInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.asin(infNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.asin(negInfInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.asin(negInfNegInf));
+ }
+
+ public void testAsinNull() {
+ try {
+ Complex z = ComplexUtils.asin(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+ }
+
public void testAtan() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(1.44831, 0.158997);
TestUtils.assertEquals(expected, ComplexUtils.atan(z), 1.0e-5);
}
+ public void testAtanInf() {
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.atan(oneInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.atan(oneNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.atan(infOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.atan(negInfOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.atan(infInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.atan(infNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.atan(negInfInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.atan(negInfNegInf));
+ }
+
public void testAtanNaN() {
assertTrue(ComplexUtils.atan(Complex.NaN).isNaN());
+ assertTrue(ComplexUtils.atan(Complex.I).isNaN());
+ }
+
+ public void testAtanNull() {
+ try {
+ Complex z = ComplexUtils.atan(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
}
public void testCos() {
@@ -61,6 +149,30 @@
TestUtils.assertEquals(expected, ComplexUtils.cos(z), 1.0e-5);
}
+ public void testCosNaN() {
+ assertTrue(ComplexUtils.cos(Complex.NaN).isNaN());
+ }
+
+ public void testCosInf() {
+ TestUtils.assertSame(infNegInf, ComplexUtils.cos(oneInf));
+ TestUtils.assertSame(infInf, ComplexUtils.cos(oneNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.cos(infOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.cos(negInfOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.cos(infInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.cos(infNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.cos(negInfInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.cos(negInfNegInf));
+ }
+
+ public void testCosNull() {
+ try {
+ Complex z = ComplexUtils.cos(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+ }
+
public void testCosh() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(-6.58066, -7.58155);
@@ -71,8 +183,24 @@
assertTrue(ComplexUtils.cosh(Complex.NaN).isNaN());
}
- public void testCosNaN() {
- assertTrue(ComplexUtils.cos(Complex.NaN).isNaN());
+ public void testCoshInf() {
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.cosh(oneInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.cosh(oneNegInf));
+ TestUtils.assertSame(infInf, ComplexUtils.cosh(infOne));
+ TestUtils.assertSame(infNegInf, ComplexUtils.cosh(negInfOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.cosh(infInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.cosh(infNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.cosh(negInfInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.cosh(negInfNegInf));
+ }
+
+ public void testCoshNull() {
+ try {
+ Complex z = ComplexUtils.cosh(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
}
public void testExp() {
@@ -85,6 +213,26 @@
assertTrue(ComplexUtils.exp(Complex.NaN).isNaN());
}
+ public void testExpInf() {
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.exp(oneInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.exp(oneNegInf));
+ TestUtils.assertSame(infInf, ComplexUtils.exp(infOne));
+ TestUtils.assertSame(Complex.ZERO, ComplexUtils.exp(negInfOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.exp(infInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.exp(infNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.exp(negInfInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.exp(negInfNegInf));
+ }
+
+ public void testExpNull() {
+ try {
+ Complex z = ComplexUtils.exp(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+ }
+
public void testLog() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(1.60944, 0.927295);
@@ -95,6 +243,97 @@
assertTrue(ComplexUtils.log(Complex.NaN).isNaN());
}
+ public void testLogInf() {
+ TestUtils.assertEquals(new Complex(inf, pi / 2),
+ ComplexUtils.log(oneInf), 10e-12);
+ TestUtils.assertEquals(new Complex(inf, -pi / 2),
+ ComplexUtils.log(oneNegInf), 10e-12);
+ TestUtils.assertEquals(infZero, ComplexUtils.log(infOne), 10e-12);
+ TestUtils.assertEquals(new Complex(inf, pi),
+ ComplexUtils.log(negInfOne), 10e-12);
+ TestUtils.assertEquals(new Complex(inf, pi / 4),
+ ComplexUtils.log(infInf), 10e-12);
+ TestUtils.assertEquals(new Complex(inf, -pi / 4),
+ ComplexUtils.log(infNegInf), 10e-12);
+ TestUtils.assertEquals(new Complex(inf, 3d * pi / 4),
+ ComplexUtils.log(negInfInf), 10e-12);
+ TestUtils.assertEquals(new Complex(inf, - 3d * pi / 4),
+ ComplexUtils.log(negInfNegInf), 10e-12);
+ }
+
+ public void testlogNull() {
+ try {
+ Complex z = ComplexUtils.log(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+ }
+
+ public void testPolar2Complex() {
+ TestUtils.assertEquals(Complex.ONE,
+ ComplexUtils.polar2Complex(1, 0), 10e-12);
+ TestUtils.assertEquals(Complex.ZERO,
+ ComplexUtils.polar2Complex(0, 1), 10e-12);
+ TestUtils.assertEquals(Complex.ZERO,
+ ComplexUtils.polar2Complex(0, -1), 10e-12);
+ TestUtils.assertEquals(Complex.I,
+ ComplexUtils.polar2Complex(1, pi/2), 10e-12);
+ TestUtils.assertEquals(Complex.I.negate(),
+ ComplexUtils.polar2Complex(1, -pi/2), 10e-12);
+ double r = 0;
+ for (int i = 0; i < 5; i++) {
+ r += i;
+ double theta = 0;
+ for (int j =0; j < 20; j++) {
+ theta += pi / 6;
+ TestUtils.assertEquals(altPolar(r, theta),
+ ComplexUtils.polar2Complex(r, theta), 10e-12);
+ }
+ theta = -2 * pi;
+ for (int j =0; j < 20; j++) {
+ theta -= pi / 6;
+ TestUtils.assertEquals(altPolar(r, theta),
+ ComplexUtils.polar2Complex(r, theta), 10e-12);
+ }
+ }
+ }
+
+ protected Complex altPolar(double r, double theta) {
+ return ComplexUtils.exp(Complex.I.multiply
+ (new Complex(theta, 0))).multiply(new Complex(r, 0));
+ }
+
+ public void testPolar2ComplexIllegalModulus() {
+ try {
+ Complex z = ComplexUtils.polar2Complex(-1, 0);
+ fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ }
+
+ public void testPolar2ComplexNaN() {
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(nan, 1));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(1, nan));
+ TestUtils.assertSame(Complex.NaN,
+ ComplexUtils.polar2Complex(nan, nan));
+ }
+
+ public void testPolar2ComplexInf() {
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(1, inf));
+ TestUtils.assertSame(Complex.NaN,
+ ComplexUtils.polar2Complex(1, negInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(inf, inf));
+ TestUtils.assertSame(Complex.NaN,
+ ComplexUtils.polar2Complex(inf, negInf));
+ TestUtils.assertSame(infInf, ComplexUtils.polar2Complex(inf, pi/4));
+ TestUtils.assertSame(infNaN, ComplexUtils.polar2Complex(inf, 0));
+ TestUtils.assertSame(infNegInf, ComplexUtils.polar2Complex(inf, -pi/4));
+ TestUtils.assertSame(negInfInf, ComplexUtils.polar2Complex(inf, 3*pi/4));
+ TestUtils.assertSame(negInfNegInf, ComplexUtils.polar2Complex(inf, 5*pi/4));
+ }
+
public void testPow() {
Complex x = new Complex(3, 4);
Complex y = new Complex(5, 6);
@@ -112,12 +351,76 @@
assertTrue(ComplexUtils.pow(x, Complex.NaN).isNaN());
}
+ public void testPowInf() {
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(Complex.ONE, oneInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(Complex.ONE, oneNegInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(Complex.ONE, infOne));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(Complex.ONE, infInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(Complex.ONE, infNegInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(Complex.ONE, negInfInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(Complex.ONE, negInfNegInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(infOne, Complex.ONE));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(negInfOne, Complex.ONE));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(infInf, Complex.ONE));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(infNegInf, Complex.ONE));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(negInfInf, Complex.ONE));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(negInfNegInf, Complex.ONE));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(negInfNegInf, infNegInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(negInfNegInf, negInfNegInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(negInfNegInf, infInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(infInf, infNegInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(infInf, negInfNegInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(infInf, infInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(infNegInf, infNegInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(infNegInf, negInfNegInf));
+ TestUtils.assertSame(Complex.NaN,ComplexUtils.pow(infNegInf, infInf));
+ }
+
+ public void testpowNull() {
+ try {
+ Complex z = ComplexUtils.pow(null, Complex.ONE);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+ try {
+ Complex z = ComplexUtils.pow(Complex.ONE, null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+ }
+
public void testSin() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(3.853738, -27.01681);
TestUtils.assertEquals(expected, ComplexUtils.sin(z), 1.0e-5);
}
+ public void testSinInf() {
+ TestUtils.assertSame(infInf, ComplexUtils.sin(oneInf));
+ TestUtils.assertSame(infNegInf, ComplexUtils.sin(oneNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.sin(infOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.sin(negInfOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.sin(infInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.sin(infNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.sin(negInfInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.sin(negInfNegInf));
+ }
+
+ public void testSinNaN() {
+ assertTrue(ComplexUtils.sin(Complex.NaN).isNaN());
+ }
+
+ public void testSinNull() {
+ try {
+ Complex z = ComplexUtils.sin(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+ }
+
public void testSinh() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(-6.54812, -7.61923);
@@ -128,8 +431,24 @@
assertTrue(ComplexUtils.sinh(Complex.NaN).isNaN());
}
- public void testSinNaN() {
- assertTrue(ComplexUtils.sin(Complex.NaN).isNaN());
+ public void testSinhInf() {
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.sinh(oneInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.sinh(oneNegInf));
+ TestUtils.assertSame(infInf, ComplexUtils.sinh(infOne));
+ TestUtils.assertSame(negInfInf, ComplexUtils.sinh(negInfOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.sinh(infInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.sinh(infNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.sinh(negInfInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.sinh(negInfNegInf));
+ }
+
+ public void testsinhNull() {
+ try {
+ Complex z = ComplexUtils.sinh(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
}
public void testSqrtRealPositive() {
@@ -161,6 +480,44 @@
Complex expected = new Complex(1.0, -2.0);
TestUtils.assertEquals(expected, ComplexUtils.sqrt(z), 1.0e-5);
}
+
+ public void testSqrtPolar() {
+ double r = 1;
+ for (int i = 0; i < 5; i++) {
+ r += i;
+ double theta = 0;
+ for (int j =0; j < 11; j++) {
+ theta += pi /12;
+ Complex z = ComplexUtils.polar2Complex(r, theta);
+ Complex sqrtz = ComplexUtils.polar2Complex(Math.sqrt(r), theta / 2);
+ TestUtils.assertEquals(sqrtz, ComplexUtils.sqrt(z), 10e-12);
+ }
+ }
+ }
+
+ public void testSqrtNaN() {
+ assertTrue(ComplexUtils.sqrt(Complex.NaN).isNaN());
+ }
+
+ public void testSqrtInf() {
+ TestUtils.assertSame(infNaN, ComplexUtils.sqrt(oneInf));
+ TestUtils.assertSame(infNaN, ComplexUtils.sqrt(oneNegInf));
+ TestUtils.assertSame(infZero, ComplexUtils.sqrt(infOne));
+ TestUtils.assertSame(zeroInf, ComplexUtils.sqrt(negInfOne));
+ TestUtils.assertSame(infNaN, ComplexUtils.sqrt(infInf));
+ TestUtils.assertSame(infNaN, ComplexUtils.sqrt(infNegInf));
+ TestUtils.assertSame(nanInf, ComplexUtils.sqrt(negInfInf));
+ TestUtils.assertSame(nanNegInf, ComplexUtils.sqrt(negInfNegInf));
+ }
+
+ public void testSqrtNull() {
+ try {
+ Complex z = ComplexUtils.sqrt(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+ }
public void testSqrt1z() {
Complex z = new Complex(3, 4);
@@ -172,8 +529,13 @@
assertTrue(ComplexUtils.sqrt1z(Complex.NaN).isNaN());
}
- public void testSqrtNaN() {
- assertTrue(ComplexUtils.sqrt(Complex.NaN).isNaN());
+ public void testSqrt1zNull() {
+ try {
+ Complex z = ComplexUtils.sqrt1z(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
}
public void testTan() {
@@ -182,6 +544,30 @@
TestUtils.assertEquals(expected, ComplexUtils.tan(z), 1.0e-5);
}
+ public void testTanNaN() {
+ assertTrue(ComplexUtils.tan(Complex.NaN).isNaN());
+ }
+
+ public void testTanInf() {
+ TestUtils.assertSame(zeroNaN, ComplexUtils.tan(oneInf));
+ TestUtils.assertSame(zeroNaN, ComplexUtils.tan(oneNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.tan(infOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.tan(negInfOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.tan(infInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.tan(infNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.tan(negInfInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.tan(negInfNegInf));
+ }
+
+ public void testTanNull() {
+ try {
+ Complex z = ComplexUtils.tan(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+ }
+
public void testTanh() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(1.00071, 0.00490826);
@@ -192,7 +578,23 @@
assertTrue(ComplexUtils.tanh(Complex.NaN).isNaN());
}
- public void testTanNaN() {
- assertTrue(ComplexUtils.tan(Complex.NaN).isNaN());
+ public void testTanhInf() {
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.tanh(oneInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.tanh(oneNegInf));
+ TestUtils.assertSame(nanZero, ComplexUtils.tanh(infOne));
+ TestUtils.assertSame(nanZero, ComplexUtils.tanh(negInfOne));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.tanh(infInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.tanh(infNegInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.tanh(negInfInf));
+ TestUtils.assertSame(Complex.NaN, ComplexUtils.tanh(negInfNegInf));
+ }
+
+ public void testTanhNull() {
+ try {
+ Complex z = ComplexUtils.tanh(null);
+ fail("Expecting NullPointerException");
+ } catch (NullPointerException ex) {
+ // expected
+ }
}
}
Modified: jakarta/commons/proper/math/branches/MATH_1_1/xdocs/changes.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/branches/MATH_1_1/xdocs/changes.xml?rev=348502&r1=348501&r2=348502&view=diff
==============================================================================
--- jakarta/commons/proper/math/branches/MATH_1_1/xdocs/changes.xml (original)
+++ jakarta/commons/proper/math/branches/MATH_1_1/xdocs/changes.xml Wed Nov 23 09:43:57 2005
@@ -38,13 +38,21 @@
Commons Math Release Notes</title>
</properties>
<body>
- <release version="1.1-RC3" date="TBD"
+ <release version="1.1-RC4" date="TBD"
description="This is a maintenance release containing bug fixes and enhancements.
All API changes are binary compatible with version 1.0. The enhancements
include some new probability distributions, a Fraction class, new matrix
and numerical utilities, and a PRNG pluggability framework making it
possible to replace the JDK-supplied random number generator in
commons-math (and elsewhere) with alternative PRNG implementations.">
+ <action dev="psteitz" type="update">
+ Added polar2Complex method to ComplexUtils to create Complex numbers
+ from polar representations.
+ </action>
+ <action dev="psteitz" type="fix" issue="37086">
+ Improved documentation and test cases related to handling of infinite
+ and NaN values in Complex, ComplexUtils classes.
+ </action>
<action dev="psteitz" type="fix" issue="37019" due-to="Mauro Talevi">
Fixed incorrect NaN handling in o.a.m.s.d.rank.Min, Max
</action>
Modified: jakarta/commons/proper/math/branches/MATH_1_1/xdocs/userguide/complex.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/branches/MATH_1_1/xdocs/userguide/complex.xml?rev=348502&r1=348501&r2=348502&view=diff
==============================================================================
--- jakarta/commons/proper/math/branches/MATH_1_1/xdocs/userguide/complex.xml (original)
+++ jakarta/commons/proper/math/branches/MATH_1_1/xdocs/userguide/complex.xml Wed Nov 23 09:43:57 2005
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!--
- Copyright 2003-2004 The Apache Software Foundation
+ Copyright 2003-2005 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
<!-- $Revision$ $Date$ -->
<document url="stat.html">
<properties>
- <title>The Commons Math User Guide - Statistics</title>
+ <title>The Commons Math User Guide - Complex Numbers</title>
</properties>
<body>
<section name="7 Complex Numbers">
@@ -37,6 +37,18 @@
org.apache.commons.math.complex.Complex</a> provides a complex number
type that forms the basis for the complex functionality found in
commons-math.
+ </p>
+ <p>
+ Complex functions and arithmetic operations are implemented in
+ commons-math by applying standard computational formulas and
+ following the rules for <code>java.lang.Double</code> arithmetic in
+ handling infinite and <code>NaN</code> values. No attempt is made
+ to comply with ANSII/IEC C99x Annex G or any other standard for
+ Complex arithmetic. See the class and method javadocs for the
+ <a href="../apidocs/org/apache/commons/math/complex/Complex.html">
+ Complex</a> and
+ <a href="../apidocs/org/apache/commons/math/complex/ComplexUtils.html">
+ ComplexUtils</a> classes for details on computing formulas.
</p>
<p>
To create a complex number, simply call the constructor passing in two
@@ -45,9 +57,14 @@
<source>Complex c = new Complex(1.0, 3.0); // 1 + 3i</source>
</p>
<p>
- The <code>Complex</code> class provides many unary and binary
+ Complex numbers may also be created from polar representations
+ using the <code>polar2Complex</code> method in
+ <code>ComplexUtils</code>.
+ </p>
+ <p>
+ The <code>Complex</code> class provides basic unary and binary
complex number operations. These operations provide the means to add,
- subtract, multiple and, divide complex numbers along with other
+ subtract, multiply and divide complex numbers along with other
complex number functions similar to the real number functions found in
<code>java.math.BigDecimal</code>:
<source>Complex lhs = new Complex(1.0, 3.0);
@@ -62,7 +79,7 @@
<subsection name="7.3 Complex Transcendental Functions" href="function">
<p>
<a href="../apidocs/org/apache/commons/math/complex/ComplexUtils.html">
- org.apache.commons.math.complex.ComplexMath</a> provides
+ org.apache.commons.math.complex.ComplexUtils</a> provides
implementations of serveral transcendental functions involving complex
number arguments. These operations provide the means to compute the
log, sine, tangent and, other complex values similar to the real
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org