You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2012/08/18 20:10:35 UTC

svn commit: r1374631 [2/2] - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math3/analysis/function/ test/java/org/apache/commons/math3/analysis/function/

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/LogisticTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/LogisticTest.java?rev=1374631&r1=1374630&r2=1374631&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/LogisticTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/LogisticTest.java Sat Aug 18 18:10:34 2012
@@ -18,6 +18,7 @@
 package org.apache.commons.math3.analysis.function;
 
 import org.apache.commons.math3.analysis.UnivariateFunction;
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
 import org.apache.commons.math3.exception.NotStrictlyPositiveException;
 import org.apache.commons.math3.exception.NullArgumentException;
 import org.apache.commons.math3.exception.DimensionMismatchException;
@@ -87,16 +88,18 @@ public class LogisticTest {
         final Logistic f = new Logistic(k, 0, 1, 1, a, 1);
         final Sigmoid g = new Sigmoid(a, k);
         
-        final UnivariateFunction dfdx = f.derivative();
-        final UnivariateFunction dgdx = g.derivative();
-
         final double min = -10;
         final double max = 10;
         final double n = 20;
         final double delta = (max - min) / n;
         for (int i = 0; i < n; i++) {
-            final double x = min + i * delta;
-            Assert.assertEquals("x=" + x, dgdx.value(x), dfdx.value(x), EPS);
+            final DerivativeStructure x = new DerivativeStructure(1, 5, 0, min + i * delta);
+            for (int order = 0; order <= x.getOrder(); ++order) {
+                Assert.assertEquals("x=" + x.getValue(),
+                                    g.value(x).getPartialDerivative(order),
+                                    f.value(x).getPartialDerivative(order),
+                                    3.0e-15);
+            }
         }
     }
 

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/LogitTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/LogitTest.java?rev=1374631&r1=1374630&r2=1374631&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/LogitTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/LogitTest.java Sat Aug 18 18:10:34 2012
@@ -19,9 +19,14 @@ package org.apache.commons.math3.analysi
 
 import org.apache.commons.math3.analysis.UnivariateFunction;
 import org.apache.commons.math3.analysis.FunctionUtils;
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
+import org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiable;
 import org.apache.commons.math3.exception.NullArgumentException;
 import org.apache.commons.math3.exception.DimensionMismatchException;
 import org.apache.commons.math3.exception.OutOfRangeException;
+import org.apache.commons.math3.random.RandomGenerator;
+import org.apache.commons.math3.random.Well1024a;
+import org.apache.commons.math3.util.FastMath;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -40,6 +45,7 @@ public class LogitTest {
 
         f.value(lo - 1);
     }
+
     @Test(expected=OutOfRangeException.class)
     public void testPreconditions2() {
         final double lo = -1;
@@ -65,22 +71,38 @@ public class LogitTest {
         final double lo = 1;
         final double hi = 2;
         final Logit f = new Logit(lo, hi);
-        final UnivariateFunction dfdx = f.derivative();
+        final DerivativeStructure f15 = f.value(new DerivativeStructure(1, 1, 0, 1.5));
 
-        Assert.assertEquals(4, dfdx.value(1.5), EPS);
+        Assert.assertEquals(4, f15.getPartialDerivative(1), EPS);
     }
 
     @Test
     public void testDerivativeLargeArguments() {
         final Logit f = new Logit(1, 2);
-        final UnivariateFunction dfdx = f.derivative();
 
-        Assert.assertEquals(0, dfdx.value(Double.NEGATIVE_INFINITY), 0);
-        Assert.assertEquals(0, dfdx.value(-Double.MAX_VALUE), 0);
-        Assert.assertEquals(0, dfdx.value(-1e155), 0);
-        Assert.assertEquals(0, dfdx.value(1e155), 0);
-        Assert.assertEquals(0, dfdx.value(Double.MAX_VALUE), 0);
-        Assert.assertEquals(0, dfdx.value(Double.POSITIVE_INFINITY), 0);        
+        for (double arg : new double[] {
+            Double.NEGATIVE_INFINITY, -Double.MAX_VALUE, -1e155, 1e155, Double.MAX_VALUE, Double.POSITIVE_INFINITY
+            }) {
+            try {
+                f.value(new DerivativeStructure(1, 1, 0, arg));
+                Assert.fail("an exception should have been thrown");
+            } catch (OutOfRangeException ore) {
+                // expected
+            } catch (Exception e) {
+                Assert.fail("wrong exception caught: " + e.getMessage());
+            }
+        }
+    }
+
+    @Test
+    public void testDerivativesHighOrder() {
+        DerivativeStructure l = new Logit(1, 3).value(new DerivativeStructure(1, 5, 0, 1.2));
+        Assert.assertEquals(-2.1972245773362193828, l.getPartialDerivative(0), 1.0e-16);
+        Assert.assertEquals(5.5555555555555555555,  l.getPartialDerivative(1), 9.0e-16);
+        Assert.assertEquals(-24.691358024691358025, l.getPartialDerivative(2), 2.0e-14);
+        Assert.assertEquals(250.34293552812071331,  l.getPartialDerivative(3), 2.0e-13);
+        Assert.assertEquals(-3749.4284407864654778, l.getPartialDerivative(4), 4.0e-12);
+        Assert.assertEquals(75001.270131585632282,  l.getPartialDerivative(5), 8.0e-11);
     }
 
     @Test(expected=NullArgumentException.class)
@@ -137,35 +159,67 @@ public class LogitTest {
         final double hi = 3;
         final Logit f = new Logit(lo, hi);
         final Sigmoid g = new Sigmoid(lo, hi);
-        final UnivariateFunction id = FunctionUtils.compose(g, f);
-        
+        RandomGenerator random = new Well1024a(0x49914cdd9f0b8db5l);
+        final UnivariateDifferentiable id = FunctionUtils.compose((UnivariateDifferentiable) g,
+                                                                (UnivariateDifferentiable) f);
+
         for (int i = 0; i < 10; i++) {
-            final double x = lo + Math.random() * (hi - lo);
-            Assert.assertEquals(x, id.value(x), EPS);
+            final double x = lo + random.nextDouble() * (hi - lo);
+            Assert.assertEquals(x, id.value(new DerivativeStructure(1, 1, 0, x)).getValue(), EPS);
         }
 
-        Assert.assertEquals(lo, id.value(lo), EPS);
-        Assert.assertEquals(hi, id.value(hi), EPS);
+        Assert.assertEquals(lo, id.value(new DerivativeStructure(1, 1, 0, lo)).getValue(), EPS);
+        Assert.assertEquals(hi, id.value(new DerivativeStructure(1, 1, 0, hi)).getValue(), EPS);
     }
 
     @Test
-    public void testDerivativeWithInverseFunction() {
+    public void testDerivativesWithInverseFunction() {
+        double[] epsilon = new double[] { 1.0e-20, 4.0e-16, 3.0e-15, 2.0e-11, 3.0e-9, 1.0e-6 };
         final double lo = 2;
         final double hi = 3;
         final Logit f = new Logit(lo, hi);
-        final UnivariateFunction dfdx = f.derivative();
         final Sigmoid g = new Sigmoid(lo, hi);
-        final UnivariateFunction dgdx = g.derivative();
-        final UnivariateFunction chain
-            = FunctionUtils.compose(new Inverse(), FunctionUtils.compose(dgdx, f));
-        
-        for (int i = 0; i < 10; i++) {
-            final double x = lo + Math.random() * (hi - lo);
-            final double r = dfdx.value(x);
-            Assert.assertEquals(r, chain.value(x), r * 1e-15);
-        }
+        RandomGenerator random = new Well1024a(0x96885e9c1f81cea5l);
+        final UnivariateDifferentiable id =
+                FunctionUtils.compose((UnivariateDifferentiable) g, (UnivariateDifferentiable) f);
+        for (int maxOrder = 0; maxOrder < 6; ++maxOrder) {
+            double max = 0;
+            for (int i = 0; i < 10; i++) {
+                final double x = lo + random.nextDouble() * (hi - lo);
+                final DerivativeStructure dsX = new DerivativeStructure(1, maxOrder, 0, x);
+                max = FastMath.max(max, FastMath.abs(dsX.getPartialDerivative(maxOrder) -
+                                                     id.value(dsX).getPartialDerivative(maxOrder)));
+                Assert.assertEquals(dsX.getPartialDerivative(maxOrder),
+                                    id.value(dsX).getPartialDerivative(maxOrder),
+                                    epsilon[maxOrder]);
+            }
+
+            // each function evaluates correctly near boundaries,
+            // but combination leads to NaN as some intermediate point is infinite
+            final DerivativeStructure dsLo = new DerivativeStructure(1, maxOrder, 0, lo);
+            if (maxOrder == 0) {
+                Assert.assertTrue(Double.isInfinite(f.value(dsLo).getPartialDerivative(maxOrder)));
+                Assert.assertEquals(lo, id.value(dsLo).getPartialDerivative(maxOrder), epsilon[maxOrder]);
+            } else if (maxOrder == 1) {
+                Assert.assertTrue(Double.isInfinite(f.value(dsLo).getPartialDerivative(maxOrder)));
+                Assert.assertTrue(Double.isNaN(id.value(dsLo).getPartialDerivative(maxOrder)));
+            } else {
+                Assert.assertTrue(Double.isNaN(f.value(dsLo).getPartialDerivative(maxOrder)));
+                Assert.assertTrue(Double.isNaN(id.value(dsLo).getPartialDerivative(maxOrder)));
+            }
+
+            final DerivativeStructure dsHi = new DerivativeStructure(1, maxOrder, 0, hi);
+            if (maxOrder == 0) {
+                Assert.assertTrue(Double.isInfinite(f.value(dsHi).getPartialDerivative(maxOrder)));
+                Assert.assertEquals(hi, id.value(dsHi).getPartialDerivative(maxOrder), epsilon[maxOrder]);
+            } else if (maxOrder == 1) {
+                Assert.assertTrue(Double.isInfinite(f.value(dsHi).getPartialDerivative(maxOrder)));
+                Assert.assertTrue(Double.isNaN(id.value(dsHi).getPartialDerivative(maxOrder)));
+            } else {
+                Assert.assertTrue(Double.isNaN(f.value(dsHi).getPartialDerivative(maxOrder)));
+                Assert.assertTrue(Double.isNaN(id.value(dsHi).getPartialDerivative(maxOrder)));
+            }
 
-        Assert.assertEquals(dfdx.value(lo), chain.value(lo), 0); // -inf
-        Assert.assertEquals(dfdx.value(hi), chain.value(hi), 0); // +inf
+        }
     }
 }

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/SigmoidTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/SigmoidTest.java?rev=1374631&r1=1374630&r2=1374631&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/SigmoidTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/SigmoidTest.java Sat Aug 18 18:10:34 2012
@@ -18,6 +18,7 @@
 package org.apache.commons.math3.analysis.function;
 
 import org.apache.commons.math3.analysis.UnivariateFunction;
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
 import org.apache.commons.math3.exception.NullArgumentException;
 import org.apache.commons.math3.exception.DimensionMismatchException;
 
@@ -42,24 +43,34 @@ public class SigmoidTest {
     @Test
     public void testDerivative() {
         final Sigmoid f = new Sigmoid();
-        final UnivariateFunction dfdx = f.derivative();
+        final DerivativeStructure f0 = f.value(new DerivativeStructure(1, 1, 0, 0.0));
 
-        Assert.assertEquals(0.25, dfdx.value(0), 0);
+        Assert.assertEquals(0.25, f0.getPartialDerivative(1), 0);
+    }
+
+    @Test
+    public void testDerivativesHighOrder() {
+        DerivativeStructure s = new Sigmoid(1, 3).value(new DerivativeStructure(1, 5, 0, 1.2));
+        Assert.assertEquals(2.5370495669980352859, s.getPartialDerivative(0), 5.0e-16);
+        Assert.assertEquals(0.35578888129361140441, s.getPartialDerivative(1), 6.0e-17);
+        Assert.assertEquals(-0.19107626464144938116,  s.getPartialDerivative(2), 6.0e-17);
+        Assert.assertEquals(-0.02396830286286711696,  s.getPartialDerivative(3), 4.0e-17);
+        Assert.assertEquals(0.21682059798981049049,   s.getPartialDerivative(4), 3.0e-17);
+        Assert.assertEquals(-0.19186320234632658055,  s.getPartialDerivative(5), 2.0e-16);
     }
 
     @Test
     public void testDerivativeLargeArguments() {
         final Sigmoid f = new Sigmoid(1, 2);
-        final UnivariateFunction dfdx = f.derivative();
 
-        Assert.assertEquals(0, dfdx.value(Double.NEGATIVE_INFINITY), 0);
-        Assert.assertEquals(0, dfdx.value(-Double.MAX_VALUE), 0);
-        Assert.assertEquals(0, dfdx.value(-1e50), 0);
-        Assert.assertEquals(0, dfdx.value(-1e3), 0);
-        Assert.assertEquals(0, dfdx.value(1e3), 0);
-        Assert.assertEquals(0, dfdx.value(1e50), 0);
-        Assert.assertEquals(0, dfdx.value(Double.MAX_VALUE), 0);
-        Assert.assertEquals(0, dfdx.value(Double.POSITIVE_INFINITY), 0);        
+        Assert.assertEquals(0, f.value(new DerivativeStructure(1, 1, 0, Double.NEGATIVE_INFINITY)).getPartialDerivative(1), 0);
+        Assert.assertEquals(0, f.value(new DerivativeStructure(1, 1, 0, -Double.MAX_VALUE)).getPartialDerivative(1), 0);
+        Assert.assertEquals(0, f.value(new DerivativeStructure(1, 1, 0, -1e50)).getPartialDerivative(1), 0);
+        Assert.assertEquals(0, f.value(new DerivativeStructure(1, 1, 0, -1e3)).getPartialDerivative(1), 0);
+        Assert.assertEquals(0, f.value(new DerivativeStructure(1, 1, 0, 1e3)).getPartialDerivative(1), 0);
+        Assert.assertEquals(0, f.value(new DerivativeStructure(1, 1, 0, 1e50)).getPartialDerivative(1), 0);
+        Assert.assertEquals(0, f.value(new DerivativeStructure(1, 1, 0, Double.MAX_VALUE)).getPartialDerivative(1), 0);
+        Assert.assertEquals(0, f.value(new DerivativeStructure(1, 1, 0, Double.POSITIVE_INFINITY)).getPartialDerivative(1), 0);        
     }
 
     @Test(expected=NullArgumentException.class)

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/SincTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/SincTest.java?rev=1374631&r1=1374630&r2=1374631&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/SincTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/SincTest.java Sat Aug 18 18:10:34 2012
@@ -17,9 +17,13 @@
 package org.apache.commons.math3.analysis.function;
 
 import org.apache.commons.math3.analysis.UnivariateFunction;
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
+import org.apache.commons.math3.dfp.Dfp;
+import org.apache.commons.math3.dfp.DfpField;
+import org.apache.commons.math3.dfp.DfpMath;
 import org.apache.commons.math3.util.FastMath;
-import org.junit.Test;
 import org.junit.Assert;
+import org.junit.Test;
 
 public class SincTest {
 
@@ -27,15 +31,16 @@ public class SincTest {
    public void testShortcut() {
        final Sinc s = new Sinc();
        final UnivariateFunction f = new UnivariateFunction() {
-               public double value(double x) {
-                   return FastMath.sin(x) / x;
-               }
-           };
+           public double value(double x) {
+               Dfp dfpX = new DfpField(25).newDfp(x);
+               return DfpMath.sin(dfpX).divide(dfpX).toDouble();
+           }
+       };
 
        for (double x = 1e-30; x < 1e10; x *= 2) {
            final double fX = f.value(x);
            final double sX = s.value(x);
-           Assert.assertEquals("x=" + x, fX, sX, 0);
+           Assert.assertEquals("x=" + x, fX, sX, 2.0e-16);
        }
    }
 
@@ -70,24 +75,46 @@ public class SincTest {
 
    @Test
    public void testDerivativeZero() {
-       final UnivariateFunction sPrime = (new Sinc(true)).derivative();
+       final DerivativeStructure s0 = new Sinc(true).value(new DerivativeStructure(1, 1, 0, 0.0));
+       Assert.assertEquals(0, s0.getPartialDerivative(1), 0);
+   }
 
-       Assert.assertEquals(0, sPrime.value(0), 0);
+   @Test
+   public void testDerivatives1Dot2Unnormalized() {
+       DerivativeStructure s = new Sinc(false).value(new DerivativeStructure(1, 5, 0, 1.2));
+       Assert.assertEquals( 0.77669923830602195806, s.getPartialDerivative(0), 1.0e-16);
+       Assert.assertEquals(-0.34528456985779031701, s.getPartialDerivative(1), 1.0e-16);
+       Assert.assertEquals(-0.2012249552097047631,  s.getPartialDerivative(2), 1.0e-16);
+       Assert.assertEquals( 0.2010975926270339262,  s.getPartialDerivative(3), 4.0e-16);
+       Assert.assertEquals( 0.106373929549242204,   s.getPartialDerivative(4), 1.0e-15);
+       Assert.assertEquals(-0.1412599110579478695,  s.getPartialDerivative(5), 3.0e-15);
+   }
+
+   @Test
+   public void testDerivatives1Dot2Normalized() {
+       DerivativeStructure s = new Sinc(true).value(new DerivativeStructure(1, 5, 0, 1.2));
+       Assert.assertEquals(-0.15591488063143983888, s.getPartialDerivative(0), 6.0e-17);
+       Assert.assertEquals(-0.54425176145292298767, s.getPartialDerivative(1), 2.0e-16);
+       Assert.assertEquals(2.4459044611635856107,   s.getPartialDerivative(2), 9.0e-16);
+       Assert.assertEquals(0.5391369206235909586,   s.getPartialDerivative(3), 7.0e-16);
+       Assert.assertEquals(-16.984649869728849865,  s.getPartialDerivative(4), 8.0e-15);
+       Assert.assertEquals(5.0980327462666316586,   s.getPartialDerivative(5), 9.0e-15);
    }
 
    @Test
    public void testDerivativeShortcut() {
-       final UnivariateFunction sPrime = (new Sinc()).derivative();
+       final Sinc sinc = new Sinc();
        final UnivariateFunction f = new UnivariateFunction() {
                public double value(double x) {
-                   return (FastMath.cos(x) - FastMath.sin(x) / x) / x;
+                   Dfp dfpX = new DfpField(25).newDfp(x);
+                   return DfpMath.cos(dfpX).subtract(DfpMath.sin(dfpX).divide(dfpX)).divide(dfpX).toDouble();
                }
            };
 
        for (double x = 1e-30; x < 1e10; x *= 2) {
            final double fX = f.value(x);
-           final double sX = sPrime.value(x);
-           Assert.assertEquals("x=" + x, fX, sX, 0);
+           final DerivativeStructure sX = sinc.value(new DerivativeStructure(1, 1, 0, x));
+           Assert.assertEquals("x=" + x, fX, sX.getPartialDerivative(1), 3.0e-13);
        }
    }
 }

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/SqrtTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/SqrtTest.java?rev=1374631&r1=1374630&r2=1374631&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/SqrtTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/function/SqrtTest.java Sat Aug 18 18:10:34 2012
@@ -17,6 +17,9 @@
 package org.apache.commons.math3.analysis.function;
 
 import org.apache.commons.math3.analysis.UnivariateFunction;
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
+import org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiable;
+import org.apache.commons.math3.util.FastMath;
 
 import org.junit.Test;
 import org.junit.Assert;
@@ -40,7 +43,7 @@ public class SqrtTest {
 
    @Test
    public void testDerivativeComparison() {
-       final UnivariateFunction sPrime = (new Sqrt()).derivative();
+       final UnivariateDifferentiable sPrime = new Sqrt();
        final UnivariateFunction f = new UnivariateFunction() {
                public double value(double x) {
                    return 1 / (2 * Math.sqrt(x));
@@ -49,8 +52,20 @@ public class SqrtTest {
 
        for (double x = 1e-30; x < 1e10; x *= 2) {
            final double fX = f.value(x);
-           final double sX = sPrime.value(x);
-           Assert.assertEquals("x=" + x, fX, sX, 0);
+           final double sX = sPrime.value(new DerivativeStructure(1, 1, 0, x)).getPartialDerivative(1);
+           Assert.assertEquals("x=" + x, fX, sX, FastMath.ulp(fX));
        }
    }
+
+   @Test
+   public void testDerivativesHighOrder() {
+       DerivativeStructure s = new Sqrt().value(new DerivativeStructure(1, 5, 0, 1.2));
+       Assert.assertEquals(1.0954451150103322269, s.getPartialDerivative(0), 1.0e-16);
+       Assert.assertEquals(0.45643546458763842789, s.getPartialDerivative(1), 1.0e-16);
+       Assert.assertEquals(-0.1901814435781826783,  s.getPartialDerivative(2), 1.0e-16);
+       Assert.assertEquals(0.23772680447272834785,  s.getPartialDerivative(3), 1.0e-16);
+       Assert.assertEquals(-0.49526417598485072465,   s.getPartialDerivative(4), 1.0e-16);
+       Assert.assertEquals(1.4445205132891479465,  s.getPartialDerivative(5), 3.0e-16);
+   }
+
 }