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); + } + }
