From 9fdb08438309b08715112cae8aa2dd4af3d75705 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Sun, 6 Jun 2010 13:59:06 +0000 Subject: [PATCH] added a test derived from an invalid issue git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@951863 13f79535-47bb-0310-9956-ffa450edef68 --- .../optimization/fitting/CurveFitterTest.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/test/java/org/apache/commons/math/optimization/fitting/CurveFitterTest.java b/src/test/java/org/apache/commons/math/optimization/fitting/CurveFitterTest.java index d5b12bb70..f46e4ec5a 100644 --- a/src/test/java/org/apache/commons/math/optimization/fitting/CurveFitterTest.java +++ b/src/test/java/org/apache/commons/math/optimization/fitting/CurveFitterTest.java @@ -72,6 +72,70 @@ public class CurveFitterTest { } + @Test + public void testMath372() + throws OptimizationException, FunctionEvaluationException { + LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); + CurveFitter curveFitter = new CurveFitter(optimizer); + + curveFitter.addObservedPoint( 15, 4443); + curveFitter.addObservedPoint( 31, 8493); + curveFitter.addObservedPoint( 62, 17586); + curveFitter.addObservedPoint(125, 30582); + curveFitter.addObservedPoint(250, 45087); + curveFitter.addObservedPoint(500, 50683); + + ParametricRealFunction f = new ParametricRealFunction() { + + public double value(double x, double[] parameters) { + + double a = parameters[0]; + double b = parameters[1]; + double c = parameters[2]; + double d = parameters[3]; + + return d + ((a - d) / (1 + Math.pow(x / c, b))); + } + + public double[] gradient(double x, double[] parameters) { + + double a = parameters[0]; + double b = parameters[1]; + double c = parameters[2]; + double d = parameters[3]; + + double[] gradients = new double[4]; + double den = 1 + Math.pow(x / c, b); + + // derivative with respect to a + gradients[0] = 1 / den; + + // derivative with respect to b + // in the reported (invalid) issue, there was a sign error here + gradients[1] = -((a - d) * Math.pow(x / c, b) * Math.log(x / c)) / (den * den); + + // derivative with respect to c + gradients[2] = (b * Math.pow(x / c, b - 1) * (x / (c * c)) * (a - d)) / (den * den); + + // derivative with respect to d + gradients[3] = 1 - (1 / den); + + return gradients; + + } + }; + + double[] initialGuess = new double[] { 1500, 0.95, 65, 35000 }; + double[] estimatedParameters = curveFitter.fit(f, initialGuess); + + Assert.assertEquals( 2411.00, estimatedParameters[0], 500.00); + Assert.assertEquals( 1.62, estimatedParameters[1], 0.04); + Assert.assertEquals( 111.22, estimatedParameters[2], 0.30); + Assert.assertEquals(55347.47, estimatedParameters[3], 300.00); + Assert.assertTrue(optimizer.getRMS() < 600.0); + + } + private static class SimpleInverseFunction implements ParametricRealFunction { public double value(double x, double[] parameters) {