You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ps...@apache.org on 2007/11/19 00:38:15 UTC
svn commit: r596159 - in /commons/proper/math/trunk:
src/java/org/apache/commons/math/complex/Complex.java
src/java/org/apache/commons/math/complex/ComplexUtils.java
src/test/org/apache/commons/math/complex/ComplexTest.java xdocs/changes.xml
Author: psteitz
Date: Sun Nov 18 15:38:05 2007
New Revision: 596159
URL: http://svn.apache.org/viewvc?rev=596159&view=rev
Log:
Merged most functions from ComplexUtils into Complex class, added
static factory method to Complex.
JIRA: MATH-171
Reported and patched by Niall Pemberton
Modified:
commons/proper/math/trunk/src/java/org/apache/commons/math/complex/Complex.java
commons/proper/math/trunk/src/java/org/apache/commons/math/complex/ComplexUtils.java
commons/proper/math/trunk/src/test/org/apache/commons/math/complex/ComplexTest.java
commons/proper/math/trunk/xdocs/changes.xml
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/complex/Complex.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/complex/Complex.java?rev=596159&r1=596158&r2=596159&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/complex/Complex.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/complex/Complex.java Sun Nov 18 15:38:05 2007
@@ -124,7 +124,7 @@
* @throws NullPointerException if <code>rhs</code> is null
*/
public Complex add(Complex rhs) {
- return new Complex(real + rhs.getReal(),
+ return createComplex(real + rhs.getReal(),
imaginary + rhs.getImaginary());
}
@@ -146,7 +146,7 @@
if (isNaN()) {
return NaN;
}
- return new Complex(real, -imaginary);
+ return createComplex(real, -imaginary);
}
/**
@@ -201,19 +201,19 @@
if (Math.abs(c) < Math.abs(d)) {
if (d == 0.0) {
- return new Complex(real/c, imaginary/c);
+ return createComplex(real/c, imaginary/c);
}
double q = c / d;
double denominator = c * q + d;
- return new Complex((real * q + imaginary) / denominator,
+ return createComplex((real * q + imaginary) / denominator,
(imaginary * q - real) / denominator);
} else {
if (c == 0.0) {
- return new Complex(imaginary/d, -real/c);
+ return createComplex(imaginary/d, -real/c);
}
double q = d / c;
double denominator = d * q + c;
- return new Complex((imaginary * q + real) / denominator,
+ return createComplex((imaginary * q + real) / denominator,
(imaginary - real * q) / denominator);
}
}
@@ -349,7 +349,7 @@
if (isNaN() || rhs.isNaN()) {
return NaN;
}
- return new Complex(real * rhs.real - imaginary * rhs.imaginary,
+ return createComplex(real * rhs.real - imaginary * rhs.imaginary,
real * rhs.imaginary + imaginary * rhs.real);
}
@@ -366,7 +366,7 @@
return NaN;
}
- return new Complex(-real, -imaginary);
+ return createComplex(-real, -imaginary);
}
/**
@@ -392,7 +392,472 @@
return NaN;
}
- return new Complex(real - rhs.getReal(),
+ return createComplex(real - rhs.getReal(),
imaginary - rhs.getImaginary());
+ }
+
+ /**
+ * Compute the
+ * <a href="http://mathworld.wolfram.com/InverseCosine.html" TARGET="_top">
+ * inverse cosine</a> of this complex number.
+ * <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.
+ *
+ * @return the inverse cosine of this complex number
+ * @since 1.2
+ */
+ public Complex acos() {
+ if (isNaN()) {
+ return Complex.NaN;
+ }
+
+ return this.add(this.sqrt1z().multiply(Complex.I)).log()
+ .multiply(Complex.I.negate());
+ }
+
+ /**
+ * Compute the
+ * <a href="http://mathworld.wolfram.com/InverseSine.html" TARGET="_top">
+ * inverse sine</a> of this complex number.
+ * <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.
+ *
+ * @return the inverse sine of this complex number.
+ * @since 1.2
+ */
+ public Complex asin() {
+ if (isNaN()) {
+ return Complex.NaN;
+ }
+
+ return sqrt1z().add(this.multiply(Complex.I)).log()
+ .multiply(Complex.I.negate());
+ }
+
+ /**
+ * Compute the
+ * <a href="http://mathworld.wolfram.com/InverseTangent.html" TARGET="_top">
+ * inverse tangent</a> of this complex number.
+ * <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.
+ *
+ * @return the inverse tangent of this complex number
+ * @since 1.2
+ */
+ public Complex atan() {
+ if (isNaN()) {
+ return Complex.NaN;
+ }
+
+ return this.add(Complex.I).divide(Complex.I.subtract(this)).log()
+ .multiply(Complex.I.divide(createComplex(2.0, 0.0)));
+ }
+
+ /**
+ * Compute the
+ * <a href="http://mathworld.wolfram.com/Cosine.html" TARGET="_top">
+ * cosine</a>
+ * of this complex number.
+ * <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>
+ *
+ * @return the cosine of this complex number
+ * @since 1.2
+ */
+ public Complex cos() {
+ if (isNaN()) {
+ return Complex.NaN;
+ }
+
+ return createComplex(Math.cos(real) * MathUtils.cosh(imaginary),
+ -Math.sin(real) * MathUtils.sinh(imaginary));
+ }
+
+ /**
+ * Compute the
+ * <a href="http://mathworld.wolfram.com/HyperbolicCosine.html" TARGET="_top">
+ * hyperbolic cosine</a> of this complex number.
+ * <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>
+ *
+ * @return the hyperbolic cosine of this complex number.
+ * @since 1.2
+ */
+ public Complex cosh() {
+ if (isNaN()) {
+ return Complex.NaN;
+ }
+
+ return createComplex(MathUtils.cosh(real) * Math.cos(imaginary),
+ MathUtils.sinh(real) * Math.sin(imaginary));
+ }
+
+ /**
+ * Compute the
+ * <a href="http://mathworld.wolfram.com/ExponentialFunction.html" TARGET="_top">
+ * exponential function</a> of this complex number.
+ * <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>
+ *
+ * @return <i>e</i><sup><code>this</code></sup>
+ * @since 1.2
+ */
+ public Complex exp() {
+ if (isNaN()) {
+ return Complex.NaN;
+ }
+
+ double expReal = Math.exp(real);
+ return createComplex(expReal * Math.cos(imaginary), expReal * Math.sin(imaginary));
+ }
+
+ /**
+ * Compute the
+ * <a href="http://mathworld.wolfram.com/NaturalLogarithm.html" TARGET="_top">
+ * natural logarithm</a> of this complex number.
+ * <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>
+ *
+ * @return ln of this complex number.
+ * @since 1.2
+ */
+ public Complex log() {
+ if (isNaN()) {
+ return Complex.NaN;
+ }
+
+ return createComplex(Math.log(abs()),
+ Math.atan2(imaginary, real));
+ }
+
+ /**
+ * Returns of value of this complex number 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 x the exponent.
+ * @return <code>this</code><sup><code>x</code></sup>
+ * @throws NullPointerException if x is null
+ * @since 1.2
+ */
+ public Complex pow(Complex x) {
+ if (x == null) {
+ throw new NullPointerException();
+ }
+ return this.log().multiply(x).exp();
+ }
+
+ /**
+ * Compute the
+ * <a href="http://mathworld.wolfram.com/Sine.html" TARGET="_top">
+ * sine</a>
+ * of this complex number.
+ * <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>
+ *
+ * @return the sine of this complex number.
+ * @since 1.2
+ */
+ public Complex sin() {
+ if (isNaN()) {
+ return Complex.NaN;
+ }
+
+ return createComplex(Math.sin(real) * MathUtils.cosh(imaginary),
+ Math.cos(real) * MathUtils.sinh(imaginary));
+ }
+
+ /**
+ * Compute the
+ * <a href="http://mathworld.wolfram.com/HyperbolicSine.html" TARGET="_top">
+ * hyperbolic sine</a> of this complex number.
+ * <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
+ *
+ * @return the hyperbolic sine of this complex number
+ * @since 1.2
+ */
+ public Complex sinh() {
+ if (isNaN()) {
+ return Complex.NaN;
+ }
+
+ return createComplex(MathUtils.sinh(real) * Math.cos(imaginary),
+ MathUtils.cosh(real) * Math.sin(imaginary));
+ }
+
+ /**
+ * Compute the
+ * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
+ * square root</a> of this complex number.
+ * <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>
+ *
+ * @return the square root of this complex number
+ * @since 1.2
+ */
+ public Complex sqrt() {
+ if (isNaN()) {
+ return Complex.NaN;
+ }
+
+ if (real == 0.0 && imaginary == 0.0) {
+ return createComplex(0.0, 0.0);
+ }
+
+ double t = Math.sqrt((Math.abs(real) + abs()) / 2.0);
+ if (real >= 0.0) {
+ return createComplex(t, imaginary / (2.0 * t));
+ } else {
+ return createComplex(Math.abs(imaginary) / (2.0 * t),
+ MathUtils.indicator(imaginary) * t);
+ }
+ }
+
+ /**
+ * Compute the
+ * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
+ * square root</a> of 1 - <code>this</code><sup>2</sup> for this complex
+ * number.
+ * <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.
+ *
+ * @return the square root of 1 - <code>this</code><sup>2</sup>
+ * @since 1.2
+ */
+ public Complex sqrt1z() {
+ return createComplex(1.0, 0.0).subtract(this.multiply(this)).sqrt();
+ }
+
+ /**
+ * Compute the
+ * <a href="http://mathworld.wolfram.com/Tangent.html" TARGET="_top">
+ * tangent</a> of this complex number.
+ * <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>
+ *
+ * @return the tangent of this complex number
+ * @since 1.2
+ */
+ public Complex tan() {
+ if (isNaN()) {
+ return Complex.NaN;
+ }
+
+ double real2 = 2.0 * real;
+ double imaginary2 = 2.0 * imaginary;
+ double d = Math.cos(real2) + MathUtils.cosh(imaginary2);
+
+ return createComplex(Math.sin(real2) / d, MathUtils.sinh(imaginary2) / d);
+ }
+
+ /**
+ * Compute the
+ * <a href="http://mathworld.wolfram.com/HyperbolicTangent.html" TARGET="_top">
+ * hyperbolic tangent</a> of this complex number.
+ * <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>
+ *
+ * @return the hyperbolic tangent of this complex number
+ * @since 1.2
+ */
+ public Complex tanh() {
+ if (isNaN()) {
+ return Complex.NaN;
+ }
+
+ double real2 = 2.0 * real;
+ double imaginary2 = 2.0 * imaginary;
+ double d = MathUtils.cosh(real2) + Math.cos(imaginary2);
+
+ return createComplex(MathUtils.sinh(real2) / d, Math.sin(imaginary2) / d);
+ }
+
+ /**
+ * Create a complex number given the real and imaginary parts.
+ *
+ * @param real the real part
+ * @param imaginary the imaginary part
+ * @return a new complex number instance
+ * @since 1.2
+ */
+ protected Complex createComplex(double real, double imaginary) {
+ return new Complex(real, imaginary);
}
}
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/complex/ComplexUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/complex/ComplexUtils.java?rev=596159&r1=596158&r2=596159&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/complex/ComplexUtils.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/complex/ComplexUtils.java Sun Nov 18 15:38:05 2007
@@ -60,14 +60,10 @@
* @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) {
- if (z.isNaN()) {
- return Complex.NaN;
- }
-
- return Complex.I.negate().multiply(log(z.add(
- Complex.I.multiply(sqrt1z(z)))));
+ return z.acos();
}
/**
@@ -84,14 +80,10 @@
* @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) {
- if (z.isNaN()) {
- return Complex.NaN;
- }
-
- return Complex.I.negate().multiply(log(sqrt1z(z).add(
- Complex.I.multiply(z))));
+ return z.asin();
}
/**
@@ -108,15 +100,10 @@
* @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) {
- if (z.isNaN()) {
- return Complex.NaN;
- }
-
- return Complex.I.multiply(
- log(Complex.I.add(z).divide(Complex.I.subtract(z))))
- .divide(new Complex(2.0, 0.0));
+ return z.atan();
}
/**
@@ -145,17 +132,10 @@
* @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) {
- if (z.isNaN()) {
- return Complex.NaN;
- }
-
- double a = z.getReal();
- double b = z.getImaginary();
-
- return new Complex(Math.cos(a) * MathUtils.cosh(b),
- -Math.sin(a) * MathUtils.sinh(b));
+ return z.cos();
}
/**
@@ -184,17 +164,10 @@
*
* @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) {
- if (z.isNaN()) {
- return Complex.NaN;
- }
-
- double a = z.getReal();
- double b = z.getImaginary();
-
- return new Complex(MathUtils.cosh(a) * Math.cos(b),
- MathUtils.sinh(a) * Math.sin(b));
+ return z.cosh();
}
/**
@@ -224,15 +197,10 @@
*
* @param z the value
* @return <i>e</i><sup><code>z</code></sup>
+ * @deprecated use Complex.exp()
*/
public static Complex exp(Complex z) {
- if (z.isNaN()) {
- return Complex.NaN;
- }
-
- double b = z.getImaginary();
- double expA = Math.exp(z.getReal());
- return new Complex(expA * Math.cos(b), expA * Math.sin(b));
+ return z.exp();
}
/**
@@ -264,14 +232,10 @@
*
* @param z the value.
* @return ln <code>z</code>.
+ * @deprecated use Complex.log()
*/
public static Complex log(Complex z) {
- if (z.isNaN()) {
- return Complex.NaN;
- }
-
- return new Complex(Math.log(z.abs()),
- Math.atan2(z.getImaginary(), z.getReal()));
+ return z.log();
}
/**
@@ -323,9 +287,10 @@
* @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 exp(x.multiply(log(y)));
+ return y.pow(x);
}
/**
@@ -355,17 +320,10 @@
*
* @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) {
- if (z.isNaN()) {
- return Complex.NaN;
- }
-
- double a = z.getReal();
- double b = z.getImaginary();
-
- return new Complex(Math.sin(a) * MathUtils.cosh(b),
- Math.cos(a) * MathUtils.sinh(b));
+ return z.sin();
}
/**
@@ -393,17 +351,10 @@
* @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) {
- if (z.isNaN()) {
- return Complex.NaN;
- }
-
- double a = z.getReal();
- double b = z.getImaginary();
-
- return new Complex(MathUtils.sinh(a) * Math.cos(b),
- MathUtils.cosh(a) * Math.sin(b));
+ return z.sinh();
}
/**
@@ -439,25 +390,10 @@
* @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) {
- if (z.isNaN()) {
- return Complex.NaN;
- }
-
- double a = z.getReal();
- double b = z.getImaginary();
- if (a == 0.0 && b == 0.0) {
- return new Complex(0.0, 0.0);
- }
-
- double t = Math.sqrt((Math.abs(a) + z.abs()) / 2.0);
- if (a >= 0.0) {
- return new Complex(t, b / (2.0 * t));
- } else {
- return new Complex(Math.abs(b) / (2.0 * t),
- MathUtils.indicator(b) * t);
- }
+ return z.sqrt();
}
/**
@@ -478,9 +414,10 @@
* @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 sqrt(Complex.ONE.subtract(z.multiply(z)));
+ return z.sqrt1z();
}
/**
@@ -509,17 +446,10 @@
* @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) {
- if (z.isNaN()) {
- return Complex.NaN;
- }
-
- double a2 = 2.0 * z.getReal();
- double b2 = 2.0 * z.getImaginary();
- double d = Math.cos(a2) + MathUtils.cosh(b2);
-
- return new Complex(Math.sin(a2) / d, MathUtils.sinh(b2) / d);
+ return z.tan();
}
/**
@@ -548,16 +478,9 @@
* @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) {
- if (z.isNaN()) {
- return Complex.NaN;
- }
-
- double a2 = 2.0 * z.getReal();
- double b2 = 2.0 * z.getImaginary();
- double d = MathUtils.cosh(a2) + Math.cos(b2);
-
- return new Complex(MathUtils.sinh(a2) / d, Math.sin(b2) / d);
+ return z.tanh();
}
}
Modified: commons/proper/math/trunk/src/test/org/apache/commons/math/complex/ComplexTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/complex/ComplexTest.java?rev=596159&r1=596158&r2=596159&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/org/apache/commons/math/complex/ComplexTest.java (original)
+++ commons/proper/math/trunk/src/test/org/apache/commons/math/complex/ComplexTest.java Sun Nov 18 15:38:05 2007
@@ -17,6 +17,8 @@
package org.apache.commons.math.complex;
+import org.apache.commons.math.TestUtils;
+
import junit.framework.TestCase;
/**
@@ -27,12 +29,25 @@
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 infZero = new Complex(inf, 0);
+ private Complex infNaN = new Complex(inf, nan);
+ private Complex infNegInf = new Complex(inf, neginf);
+ private Complex infInf = new Complex(inf, inf);
private Complex negInfInf = new Complex(neginf, inf);
+ private Complex negInfZero = new Complex(neginf, 0);
+ private Complex negInfOne = new Complex(neginf, 1);
+ private Complex negInfNaN = new Complex(neginf, nan);
private Complex negInfNegInf = new Complex(neginf, neginf);
private Complex oneNaN = new Complex(1, nan);
+ private Complex zeroInf = new Complex(0, inf);
+ private Complex zeroNaN = new Complex(0, nan);
+ private Complex nanInf = new Complex(nan, inf);
+ private Complex nanNegInf = new Complex(nan, neginf);
+ private Complex nanZero = new Complex(nan, 0);
public void testConstructor() {
Complex z = new Complex(3.0, 4.0);
@@ -274,5 +289,400 @@
Complex imaginaryNaN = new Complex(0.0, Double.NaN);
assertEquals(realNaN.hashCode(), imaginaryNaN.hashCode());
assertEquals(imaginaryNaN.hashCode(), Complex.NaN.hashCode());
+ }
+
+ public void testAcos() {
+ Complex z = new Complex(3, 4);
+ Complex expected = new Complex(0.936812, -2.30551);
+ TestUtils.assertEquals(expected, z.acos(), 1.0e-5);
+ TestUtils.assertEquals(new Complex(Math.acos(0), 0),
+ Complex.ZERO.acos(), 1.0e-12);
+ }
+
+ public void testAcosInf() {
+ TestUtils.assertSame(Complex.NaN, oneInf.acos());
+ TestUtils.assertSame(Complex.NaN, oneNegInf.acos());
+ TestUtils.assertSame(Complex.NaN, infOne.acos());
+ TestUtils.assertSame(Complex.NaN, negInfOne.acos());
+ TestUtils.assertSame(Complex.NaN, infInf.acos());
+ TestUtils.assertSame(Complex.NaN, infNegInf.acos());
+ TestUtils.assertSame(Complex.NaN, negInfInf.acos());
+ TestUtils.assertSame(Complex.NaN, negInfNegInf.acos());
+ }
+
+ public void testAcosNaN() {
+ assertTrue(Complex.NaN.acos().isNaN());
+ }
+
+ public void testAsin() {
+ Complex z = new Complex(3, 4);
+ Complex expected = new Complex(0.633984, 2.30551);
+ TestUtils.assertEquals(expected, z.asin(), 1.0e-5);
+ }
+
+ public void testAsinNaN() {
+ assertTrue(Complex.NaN.asin().isNaN());
+ }
+
+ public void testAsinInf() {
+ TestUtils.assertSame(Complex.NaN, oneInf.asin());
+ TestUtils.assertSame(Complex.NaN, oneNegInf.asin());
+ TestUtils.assertSame(Complex.NaN, infOne.asin());
+ TestUtils.assertSame(Complex.NaN, negInfOne.asin());
+ TestUtils.assertSame(Complex.NaN, infInf.asin());
+ TestUtils.assertSame(Complex.NaN, infNegInf.asin());
+ TestUtils.assertSame(Complex.NaN, negInfInf.asin());
+ TestUtils.assertSame(Complex.NaN, negInfNegInf.asin());
+ }
+
+
+ public void testAtan() {
+ Complex z = new Complex(3, 4);
+ Complex expected = new Complex(1.44831, 0.158997);
+ TestUtils.assertEquals(expected, z.atan(), 1.0e-5);
+ }
+
+ public void testAtanInf() {
+ TestUtils.assertSame(Complex.NaN, oneInf.atan());
+ TestUtils.assertSame(Complex.NaN, oneNegInf.atan());
+ TestUtils.assertSame(Complex.NaN, infOne.atan());
+ TestUtils.assertSame(Complex.NaN, negInfOne.atan());
+ TestUtils.assertSame(Complex.NaN, infInf.atan());
+ TestUtils.assertSame(Complex.NaN, infNegInf.atan());
+ TestUtils.assertSame(Complex.NaN, negInfInf.atan());
+ TestUtils.assertSame(Complex.NaN, negInfNegInf.atan());
+ }
+
+ public void testAtanNaN() {
+ assertTrue(Complex.NaN.atan().isNaN());
+ assertTrue(Complex.I.atan().isNaN());
+ }
+
+ public void testCos() {
+ Complex z = new Complex(3, 4);
+ Complex expected = new Complex(-27.03495, -3.851153);
+ TestUtils.assertEquals(expected, z.cos(), 1.0e-5);
+ }
+
+ public void testCosNaN() {
+ assertTrue(Complex.NaN.cos().isNaN());
+ }
+
+ public void testCosInf() {
+ TestUtils.assertSame(infNegInf, oneInf.cos());
+ TestUtils.assertSame(infInf, oneNegInf.cos());
+ TestUtils.assertSame(Complex.NaN, infOne.cos());
+ TestUtils.assertSame(Complex.NaN, negInfOne.cos());
+ TestUtils.assertSame(Complex.NaN, infInf.cos());
+ TestUtils.assertSame(Complex.NaN, infNegInf.cos());
+ TestUtils.assertSame(Complex.NaN, negInfInf.cos());
+ TestUtils.assertSame(Complex.NaN, negInfNegInf.cos());
+ }
+
+ public void testCosh() {
+ Complex z = new Complex(3, 4);
+ Complex expected = new Complex(-6.58066, -7.58155);
+ TestUtils.assertEquals(expected, z.cosh(), 1.0e-5);
+ }
+
+ public void testCoshNaN() {
+ assertTrue(Complex.NaN.cosh().isNaN());
+ }
+
+ public void testCoshInf() {
+ TestUtils.assertSame(Complex.NaN, oneInf.cosh());
+ TestUtils.assertSame(Complex.NaN, oneNegInf.cosh());
+ TestUtils.assertSame(infInf, infOne.cosh());
+ TestUtils.assertSame(infNegInf, negInfOne.cosh());
+ TestUtils.assertSame(Complex.NaN, infInf.cosh());
+ TestUtils.assertSame(Complex.NaN, infNegInf.cosh());
+ TestUtils.assertSame(Complex.NaN, negInfInf.cosh());
+ TestUtils.assertSame(Complex.NaN, negInfNegInf.cosh());
+ }
+
+ public void testExp() {
+ Complex z = new Complex(3, 4);
+ Complex expected = new Complex(-13.12878, -15.20078);
+ TestUtils.assertEquals(expected, z.exp(), 1.0e-5);
+ TestUtils.assertEquals(Complex.ONE,
+ Complex.ZERO.exp(), 10e-12);
+ Complex iPi = Complex.I.multiply(new Complex(pi,0));
+ TestUtils.assertEquals(Complex.ONE.negate(),
+ iPi.exp(), 10e-12);
+ }
+
+ public void testExpNaN() {
+ assertTrue(Complex.NaN.exp().isNaN());
+ }
+
+ public void testExpInf() {
+ TestUtils.assertSame(Complex.NaN, oneInf.exp());
+ TestUtils.assertSame(Complex.NaN, oneNegInf.exp());
+ TestUtils.assertSame(infInf, infOne.exp());
+ TestUtils.assertSame(Complex.ZERO, negInfOne.exp());
+ TestUtils.assertSame(Complex.NaN, infInf.exp());
+ TestUtils.assertSame(Complex.NaN, infNegInf.exp());
+ TestUtils.assertSame(Complex.NaN, negInfInf.exp());
+ TestUtils.assertSame(Complex.NaN, negInfNegInf.exp());
+ }
+
+ public void testLog() {
+ Complex z = new Complex(3, 4);
+ Complex expected = new Complex(1.60944, 0.927295);
+ TestUtils.assertEquals(expected, z.log(), 1.0e-5);
+ }
+
+ public void testLogNaN() {
+ assertTrue(Complex.NaN.log().isNaN());
+ }
+
+ public void testLogInf() {
+ TestUtils.assertEquals(new Complex(inf, pi / 2),
+ oneInf.log(), 10e-12);
+ TestUtils.assertEquals(new Complex(inf, -pi / 2),
+ oneNegInf.log(), 10e-12);
+ TestUtils.assertEquals(infZero, infOne.log(), 10e-12);
+ TestUtils.assertEquals(new Complex(inf, pi),
+ negInfOne.log(), 10e-12);
+ TestUtils.assertEquals(new Complex(inf, pi / 4),
+ infInf.log(), 10e-12);
+ TestUtils.assertEquals(new Complex(inf, -pi / 4),
+ infNegInf.log(), 10e-12);
+ TestUtils.assertEquals(new Complex(inf, 3d * pi / 4),
+ negInfInf.log(), 10e-12);
+ TestUtils.assertEquals(new Complex(inf, - 3d * pi / 4),
+ negInfNegInf.log(), 10e-12);
+ }
+
+ public void testLogZero() {
+ TestUtils.assertSame(negInfZero, Complex.ZERO.log());
+ }
+
+ public void testPow() {
+ Complex x = new Complex(3, 4);
+ Complex y = new Complex(5, 6);
+ Complex expected = new Complex(-1.860893, 11.83677);
+ TestUtils.assertEquals(expected, x.pow(y), 1.0e-5);
+ }
+
+ public void testPowNaNBase() {
+ Complex x = new Complex(3, 4);
+ assertTrue(Complex.NaN.pow(x).isNaN());
+ }
+
+ public void testPowNaNExponent() {
+ Complex x = new Complex(3, 4);
+ assertTrue(x.pow(Complex.NaN).isNaN());
+ }
+
+ public void testPowInf() {
+ TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(oneInf));
+ TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(oneNegInf));
+ TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(infOne));
+ TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(infInf));
+ TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(infNegInf));
+ TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(negInfInf));
+ TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(negInfNegInf));
+ TestUtils.assertSame(Complex.NaN,infOne.pow(Complex.ONE));
+ TestUtils.assertSame(Complex.NaN,negInfOne.pow(Complex.ONE));
+ TestUtils.assertSame(Complex.NaN,infInf.pow(Complex.ONE));
+ TestUtils.assertSame(Complex.NaN,infNegInf.pow(Complex.ONE));
+ TestUtils.assertSame(Complex.NaN,negInfInf.pow(Complex.ONE));
+ TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(Complex.ONE));
+ TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(infNegInf));
+ TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(negInfNegInf));
+ TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(infInf));
+ TestUtils.assertSame(Complex.NaN,infInf.pow(infNegInf));
+ TestUtils.assertSame(Complex.NaN,infInf.pow(negInfNegInf));
+ TestUtils.assertSame(Complex.NaN,infInf.pow(infInf));
+ TestUtils.assertSame(Complex.NaN,infNegInf.pow(infNegInf));
+ TestUtils.assertSame(Complex.NaN,infNegInf.pow(negInfNegInf));
+ TestUtils.assertSame(Complex.NaN,infNegInf.pow(infInf));
+ }
+
+ public void testPowZero() {
+ TestUtils.assertSame(Complex.NaN,
+ Complex.ZERO.pow(Complex.ONE));
+ TestUtils.assertSame(Complex.NaN,
+ Complex.ZERO.pow(Complex.ZERO));
+ TestUtils.assertSame(Complex.NaN,
+ Complex.ZERO.pow(Complex.I));
+ TestUtils.assertEquals(Complex.ONE,
+ Complex.ONE.pow(Complex.ZERO), 10e-12);
+ TestUtils.assertEquals(Complex.ONE,
+ Complex.I.pow(Complex.ZERO), 10e-12);
+ TestUtils.assertEquals(Complex.ONE,
+ new Complex(-1, 3).pow(Complex.ZERO), 10e-12);
+ }
+
+ public void testpowNull() {
+ try {
+ Complex.ONE.pow(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, z.sin(), 1.0e-5);
+ }
+
+ public void testSinInf() {
+ TestUtils.assertSame(infInf, oneInf.sin());
+ TestUtils.assertSame(infNegInf, oneNegInf.sin());
+ TestUtils.assertSame(Complex.NaN, infOne.sin());
+ TestUtils.assertSame(Complex.NaN, negInfOne.sin());
+ TestUtils.assertSame(Complex.NaN, infInf.sin());
+ TestUtils.assertSame(Complex.NaN, infNegInf.sin());
+ TestUtils.assertSame(Complex.NaN, negInfInf.sin());
+ TestUtils.assertSame(Complex.NaN, negInfNegInf.sin());
+ }
+
+ public void testSinNaN() {
+ assertTrue(Complex.NaN.sin().isNaN());
+ }
+
+ public void testSinh() {
+ Complex z = new Complex(3, 4);
+ Complex expected = new Complex(-6.54812, -7.61923);
+ TestUtils.assertEquals(expected, z.sinh(), 1.0e-5);
+ }
+
+ public void testSinhNaN() {
+ assertTrue(Complex.NaN.sinh().isNaN());
+ }
+
+ public void testSinhInf() {
+ TestUtils.assertSame(Complex.NaN, oneInf.sinh());
+ TestUtils.assertSame(Complex.NaN, oneNegInf.sinh());
+ TestUtils.assertSame(infInf, infOne.sinh());
+ TestUtils.assertSame(negInfInf, negInfOne.sinh());
+ TestUtils.assertSame(Complex.NaN, infInf.sinh());
+ TestUtils.assertSame(Complex.NaN, infNegInf.sinh());
+ TestUtils.assertSame(Complex.NaN, negInfInf.sinh());
+ TestUtils.assertSame(Complex.NaN, negInfNegInf.sinh());
+ }
+
+ public void testSqrtRealPositive() {
+ Complex z = new Complex(3, 4);
+ Complex expected = new Complex(2, 1);
+ TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5);
+ }
+
+ public void testSqrtRealZero() {
+ Complex z = new Complex(0.0, 4);
+ Complex expected = new Complex(1.41421, 1.41421);
+ TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5);
+ }
+
+ public void testSqrtRealNegative() {
+ Complex z = new Complex(-3.0, 4);
+ Complex expected = new Complex(1, 2);
+ TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5);
+ }
+
+ public void testSqrtImaginaryZero() {
+ Complex z = new Complex(-3.0, 0.0);
+ Complex expected = new Complex(0.0, 1.73205);
+ TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5);
+ }
+
+ public void testSqrtImaginaryNegative() {
+ Complex z = new Complex(-3.0, -4.0);
+ Complex expected = new Complex(1.0, -2.0);
+ TestUtils.assertEquals(expected, z.sqrt(), 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, z.sqrt(), 10e-12);
+ }
+ }
+ }
+
+ public void testSqrtNaN() {
+ assertTrue(Complex.NaN.sqrt().isNaN());
+ }
+
+ public void testSqrtInf() {
+ TestUtils.assertSame(infNaN, oneInf.sqrt());
+ TestUtils.assertSame(infNaN, oneNegInf.sqrt());
+ TestUtils.assertSame(infZero, infOne.sqrt());
+ TestUtils.assertSame(zeroInf, negInfOne.sqrt());
+ TestUtils.assertSame(infNaN, infInf.sqrt());
+ TestUtils.assertSame(infNaN, infNegInf.sqrt());
+ TestUtils.assertSame(nanInf, negInfInf.sqrt());
+ TestUtils.assertSame(nanNegInf, negInfNegInf.sqrt());
+ }
+
+ public void testSqrt1z() {
+ Complex z = new Complex(3, 4);
+ Complex expected = new Complex(4.08033, -2.94094);
+ TestUtils.assertEquals(expected, z.sqrt1z(), 1.0e-5);
+ }
+
+ public void testSqrt1zNaN() {
+ assertTrue(Complex.NaN.sqrt1z().isNaN());
+ }
+
+ public void testTan() {
+ Complex z = new Complex(3, 4);
+ Complex expected = new Complex(-0.000187346, 0.999356);
+ TestUtils.assertEquals(expected, z.tan(), 1.0e-5);
+ }
+
+ public void testTanNaN() {
+ assertTrue(Complex.NaN.tan().isNaN());
+ }
+
+ public void testTanInf() {
+ TestUtils.assertSame(zeroNaN, oneInf.tan());
+ TestUtils.assertSame(zeroNaN, oneNegInf.tan());
+ TestUtils.assertSame(Complex.NaN, infOne.tan());
+ TestUtils.assertSame(Complex.NaN, negInfOne.tan());
+ TestUtils.assertSame(Complex.NaN, infInf.tan());
+ TestUtils.assertSame(Complex.NaN, infNegInf.tan());
+ TestUtils.assertSame(Complex.NaN, negInfInf.tan());
+ TestUtils.assertSame(Complex.NaN, negInfNegInf.tan());
+ }
+
+ public void testTanCritical() {
+ TestUtils.assertSame(infNaN, new Complex(pi/2, 0).tan());
+ TestUtils.assertSame(negInfNaN, new Complex(-pi/2, 0).tan());
+ }
+
+ public void testTanh() {
+ Complex z = new Complex(3, 4);
+ Complex expected = new Complex(1.00071, 0.00490826);
+ TestUtils.assertEquals(expected, z.tanh(), 1.0e-5);
+ }
+
+ public void testTanhNaN() {
+ assertTrue(Complex.NaN.tanh().isNaN());
+ }
+
+ public void testTanhInf() {
+ TestUtils.assertSame(Complex.NaN, oneInf.tanh());
+ TestUtils.assertSame(Complex.NaN, oneNegInf.tanh());
+ TestUtils.assertSame(nanZero, infOne.tanh());
+ TestUtils.assertSame(nanZero, negInfOne.tanh());
+ TestUtils.assertSame(Complex.NaN, infInf.tanh());
+ TestUtils.assertSame(Complex.NaN, infNegInf.tanh());
+ TestUtils.assertSame(Complex.NaN, negInfInf.tanh());
+ TestUtils.assertSame(Complex.NaN, negInfNegInf.tanh());
+ }
+
+ public void testTanhCritical() {
+ TestUtils.assertSame(nanInf, new Complex(0, pi/2).tanh());
}
}
Modified: commons/proper/math/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/xdocs/changes.xml?rev=596159&r1=596158&r2=596159&view=diff
==============================================================================
--- commons/proper/math/trunk/xdocs/changes.xml (original)
+++ commons/proper/math/trunk/xdocs/changes.xml Sun Nov 18 15:38:05 2007
@@ -40,6 +40,10 @@
</properties>
<body>
<release version="1.2-SNAPSHOT" date="TBD">
+ <action dev="psteitz" type="update" issue="MATH-171" due-to="Niall Pemberton">
+ Merged most functions from ComplexUtils into Complex class, added
+ static factory method to Complex.
+ </action>
<action dev="luc" type="fix">
Fixed numerous warnings in test code.
</action>