Author: celestin
Date: Fri Jan 27 07:00:19 2012
New Revision: 1236548
URL: http://svn.apache.org/viewvc?rev=1236548&view=rev
Log:
Introduced tests to guard against overflow (MATH-722). Corrected Javadoc and
updated unit tests accordingly.
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math/complex/Complex.java
commons/proper/math/trunk/src/test/java/org/apache/commons/math/complex/ComplexTest.java
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math/complex/Complex.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/complex/Complex.java?rev=1236548&r1=1236547&r2=1236548&view=diff
==============================================================================
---
commons/proper/math/trunk/src/main/java/org/apache/commons/math/complex/Complex.java
(original)
+++
commons/proper/math/trunk/src/main/java/org/apache/commons/math/complex/Complex.java
Fri Jan 27 07:00:19 2012
@@ -993,8 +993,8 @@ public class Complex implements FieldEle
* </code>
* </pre>
* where the (real) functions on the right-hand side are
- * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
- * {@link FastMath#cosh} and {@link FastMath#sinh}.
+ * {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and
+ * {@link FastMath#sinh}.
* <br/>
* Returns {@link Complex#NaN} if either real or imaginary part of the
* input argument is {@code NaN}.
@@ -1004,8 +1004,8 @@ public class Complex implements FieldEle
* <pre>
* Examples:
* <code>
- * tan(1 ± INFINITY i) = 0 + NaN i
- * tan(±INFINITY + i) = NaN + NaN i
+ * tan(a ± INFINITY i) = 0 ± i
+ * tan(±INFINITY + bi) = NaN + NaN i
* tan(±INFINITY ± INFINITY i) = NaN + NaN i
* tan(±π/2 + 0 i) = ±INFINITY + NaN i
* </code>
@@ -1015,9 +1015,15 @@ public class Complex implements FieldEle
* @since 1.2
*/
public Complex tan() {
- if (isNaN) {
+ if (isNaN || Double.isInfinite(real)) {
return NaN;
}
+ if (imaginary > 20.0) {
+ return createComplex(0.0, 1.0);
+ }
+ if (imaginary < -20.0) {
+ return createComplex(0.0, -1.0);
+ }
double real2 = 2.0 * real;
double imaginary2 = 2.0 * imaginary;
@@ -1038,8 +1044,8 @@ public class Complex implements FieldEle
* </code>
* </pre>
* where the (real) functions on the right-hand side are
- * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
- * {@link FastMath#cosh} and {@link FastMath#sinh}.
+ * {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and
+ * {@link FastMath#sinh}.
* <br/>
* Returns {@link Complex#NaN} if either real or imaginary part of the
* input argument is {@code NaN}.
@@ -1049,8 +1055,8 @@ public class Complex implements FieldEle
* <pre>
* Examples:
* <code>
- * tanh(1 ± INFINITY i) = NaN + NaN i
- * tanh(±INFINITY + i) = NaN + 0 i
+ * tanh(a ± INFINITY i) = NaN + NaN i
+ * tanh(±INFINITY + bi) = ±1 + 0 i
* tanh(±INFINITY ± INFINITY i) = NaN + NaN i
* tanh(0 + (π/2)i) = NaN + INFINITY i
* </code>
@@ -1060,10 +1066,15 @@ public class Complex implements FieldEle
* @since 1.2
*/
public Complex tanh() {
- if (isNaN) {
+ if (isNaN || Double.isInfinite(imaginary)) {
return NaN;
}
-
+ if (real > 20.0) {
+ return createComplex(1.0, 0.0);
+ }
+ if (real < -20.0) {
+ return createComplex(-1.0, 0.0);
+ }
double real2 = 2.0 * real;
double imaginary2 = 2.0 * imaginary;
double d = FastMath.cosh(real2) + FastMath.cos(imaginary2);
Modified:
commons/proper/math/trunk/src/test/java/org/apache/commons/math/complex/ComplexTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/complex/ComplexTest.java?rev=1236548&r1=1236547&r2=1236548&view=diff
==============================================================================
---
commons/proper/math/trunk/src/test/java/org/apache/commons/math/complex/ComplexTest.java
(original)
+++
commons/proper/math/trunk/src/test/java/org/apache/commons/math/complex/ComplexTest.java
Fri Jan 27 07:00:19 2012
@@ -996,6 +996,13 @@ public class ComplexTest {
Complex z = new Complex(3, 4);
Complex expected = new Complex(-0.000187346, 0.999356);
TestUtils.assertEquals(expected, z.tan(), 1.0e-5);
+ /* Check that no overflow occurs (MATH-722) */
+ Complex actual = new Complex(3.0, 1E10).tan();
+ expected = new Complex(0, 1);
+ TestUtils.assertEquals(expected, actual, 1.0e-5);
+ actual = new Complex(3.0, -1E10).tan();
+ expected = new Complex(0, -1);
+ TestUtils.assertEquals(expected, actual, 1.0e-5);
}
@Test
@@ -1005,8 +1012,8 @@ public class ComplexTest {
@Test
public void testTanInf() {
- TestUtils.assertSame(zeroNaN, oneInf.tan());
- TestUtils.assertSame(zeroNaN, oneNegInf.tan());
+ TestUtils.assertSame(Complex.valueOf(0.0, 1.0), oneInf.tan());
+ TestUtils.assertSame(Complex.valueOf(0.0, -1.0), oneNegInf.tan());
TestUtils.assertSame(Complex.NaN, infOne.tan());
TestUtils.assertSame(Complex.NaN, negInfOne.tan());
TestUtils.assertSame(Complex.NaN, infInf.tan());
@@ -1026,6 +1033,13 @@ public class ComplexTest {
Complex z = new Complex(3, 4);
Complex expected = new Complex(1.00071, 0.00490826);
TestUtils.assertEquals(expected, z.tanh(), 1.0e-5);
+ /* Check that no overflow occurs (MATH-722) */
+ Complex actual = new Complex(1E10, 3.0).tanh();
+ expected = new Complex(1, 0);
+ TestUtils.assertEquals(expected, actual, 1.0e-5);
+ actual = new Complex(-1E10, 3.0).tanh();
+ expected = new Complex(-1, 0);
+ TestUtils.assertEquals(expected, actual, 1.0e-5);
}
@Test
@@ -1037,8 +1051,8 @@ public class ComplexTest {
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.valueOf(1.0, 0.0), infOne.tanh());
+ TestUtils.assertSame(Complex.valueOf(-1.0, 0.0), negInfOne.tanh());
TestUtils.assertSame(Complex.NaN, infInf.tanh());
TestUtils.assertSame(Complex.NaN, infNegInf.tanh());
TestUtils.assertSame(Complex.NaN, negInfInf.tanh());