You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2019/12/05 00:45:52 UTC

[commons-numbers] 01/04: Complex: Added test for function odd/even.

This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git

commit 19e272f1b61ef4b2432c52aa219ba422e7ad970d
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Wed Dec 4 23:08:16 2019 +0000

    Complex: Added test for function odd/even.
    
    These tests currently fail with sign errors on infinite edge cases for:
    
    asinh
    atanh
    cosh
    sinh
    
    tanh is OK.
    
    The failing tests are commented out.
---
 .../commons/numbers/complex/CStandardTest.java     | 81 ++++++++++++++++++++--
 1 file changed, 75 insertions(+), 6 deletions(-)

diff --git a/commons-numbers-complex/src/test/java/org/apache/commons/numbers/complex/CStandardTest.java b/commons-numbers-complex/src/test/java/org/apache/commons/numbers/complex/CStandardTest.java
index 18efe0f..7285399 100644
--- a/commons-numbers-complex/src/test/java/org/apache/commons/numbers/complex/CStandardTest.java
+++ b/commons-numbers-complex/src/test/java/org/apache/commons/numbers/complex/CStandardTest.java
@@ -89,6 +89,8 @@ public class CStandardTest {
     private static final Complex maxMax = complex(max, max);
     private static final Complex maxNan = complex(max, nan);
     private static final Complex nanMax = complex(nan, max);
+    private static final boolean ODD = true;
+    private static final boolean EVEN = false;
 
     /**
      * Assert the two complex numbers have equivalent real and imaginary components as
@@ -184,6 +186,73 @@ public class CStandardTest {
     }
 
     /**
+     * Assert the operation on the complex number is odd or even.
+     *
+     * <pre>
+     * Odd : f(z) = -f(-z)
+     * Even: f(z) =  f(-z)
+     * </pre>
+     *
+     * <p>The results must be binary equal. This includes the sign of zero.
+     *
+     * @param operation the operation
+     * @param odd true if odd
+     */
+    private static void assertOddOrEven(UnaryOperator<Complex> operation, boolean odd) {
+        // Edge cases
+        final double[] parts = {Double.NEGATIVE_INFINITY, -1, -0.0, 0.0, 1,
+                                Double.POSITIVE_INFINITY, Double.NaN};
+        for (final double x : parts) {
+            for (final double y : parts) {
+                assertOddOrEven(x, y, operation, odd);
+            }
+        }
+        // Random numbers
+        final UniformRandomProvider rng = RandomSource.create(RandomSource.SPLIT_MIX_64);
+        for (int i = 0; i < 100; i++) {
+            final double x = next(rng);
+            final double y = next(rng);
+            assertOddOrEven(x, y, operation, odd);
+        }
+    }
+
+    /**
+     * Assert the operation on the complex number is odd or even.
+     *
+     * <pre>
+     * Odd : f(z) = -f(-z)
+     * Even: f(z) =  f(-z)
+     * </pre>
+     *
+     * <p>The results must be binary equal. This includes the sign of zero.
+     *
+     * @param operation the operation
+     *
+     * @param re the real component
+     * @param im the imaginary component
+     * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
+     * values between the real (resp. imaginary) parts of {@code x} and
+     * {@code y}.
+     * @param operation the operation
+     */
+    private static void assertOddOrEven(double re, double im,
+            UnaryOperator<Complex> operation, boolean odd) {
+        final Complex z = complex(re, im);
+        final Complex c1 = operation.apply(z);
+        Complex c2 = operation.apply(z.negate());
+        if (odd) {
+            c2 = c2.negate();
+        }
+
+        // Test for binary equality
+        if (!equals(c1.getReal(), c2.getReal()) ||
+            !equals(c1.getImaginary(), c2.getImaginary())) {
+            Assertions.fail(String.format("%s equality failed (z=%s). Expected: %s but was: %s",
+                                          odd ? "Odd" : "Even", z, c2, c1));
+        }
+    }
+
+    /**
      * Assert the operation on the complex number is equal to the expected value.
      * If the imaginary part is not NaN the operation must also satisfy the conjugate equality.
      *
@@ -539,7 +608,7 @@ public class CStandardTest {
         assertComplex(NAN, Complex::acosh, NAN);
     }
 
-    // TODO: test the 'IS ODD/ EVEN' specification
+    // TODO: fix the 'IS ODD/ EVEN' specification
 
     /**
      * ISO C Standard G.6.2.2.
@@ -547,7 +616,7 @@ public class CStandardTest {
     @Test
     public void testAsinh() {
         assertConjugateEquality(Complex::asinh);
-        // AND ASINH IS ODD
+        //assertOddOrEven(Complex::asinh, ODD);
         assertComplex(Complex.ZERO, Complex::asinh, Complex.ZERO);
         assertComplex(negZeroZero, Complex::asinh, negZeroZero);
         assertComplex(zeroNaN, Complex::asinh, NAN);
@@ -573,7 +642,7 @@ public class CStandardTest {
     @Test
     public void testAtanh() {
         assertConjugateEquality(Complex::atanh);
-        // AND ATANH IS ODD
+        //assertOddOrEven(Complex::atanh, ODD);
         assertComplex(Complex.ZERO, Complex::atanh, Complex.ZERO);
         assertComplex(negZeroZero, Complex::atanh, negZeroZero);
         assertComplex(zeroNaN, Complex::atanh, zeroNaN);
@@ -600,7 +669,7 @@ public class CStandardTest {
     @Test
     public void testCosh() {
         assertConjugateEquality(Complex::cosh);
-        // AND CCOSH IS EVEN
+        //assertOddOrEven(Complex::cosh, EVEN);
         assertComplex(Complex.ZERO, Complex::cosh, Complex.ONE);
         assertComplex(negZeroZero, Complex::cosh, oneNegZero);
         assertComplex(zeroInf, Complex::cosh, nanZero);
@@ -639,7 +708,7 @@ public class CStandardTest {
     @Test
     public void testSinh() {
         assertConjugateEquality(Complex::sinh);
-        // AND CSINH IS ODD
+        //assertOddOrEven(Complex::sinh, ODD);
         assertComplex(Complex.ZERO, Complex::sinh, Complex.ZERO);
         assertComplex(negZeroZero, Complex::sinh, negZeroZero);
         assertComplex(zeroInf, Complex::sinh, zeroNaN);
@@ -678,7 +747,7 @@ public class CStandardTest {
     @Test
     public void testTanh() {
         assertConjugateEquality(Complex::tanh);
-        // AND TANH IS ODD
+        assertOddOrEven(Complex::tanh, ODD);
         assertComplex(Complex.ZERO, Complex::tanh, Complex.ZERO);
         assertComplex(negZeroZero, Complex::tanh, negZeroZero);
         assertComplex(zeroInf, Complex::tanh, NAN);