You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2012/07/04 20:00:03 UTC

svn commit: r1357353 - in /commons/proper/math/trunk/src: changes/ main/java/org/apache/commons/math3/optimization/fitting/ test/java/org/apache/commons/math3/optimization/fitting/

Author: erans
Date: Wed Jul  4 18:00:02 2012
New Revision: 1357353

URL: http://svn.apache.org/viewvc?rev=1357353&view=rev
Log:
MATH-798
Added overridden "fit" method where one can specify the maximum number of
function evaluations.

Modified:
    commons/proper/math/trunk/src/changes/changes.xml
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/PolynomialFitter.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/CurveFitterTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/PolynomialFitterTest.java

Modified: commons/proper/math/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/changes/changes.xml?rev=1357353&r1=1357352&r2=1357353&view=diff
==============================================================================
--- commons/proper/math/trunk/src/changes/changes.xml (original)
+++ commons/proper/math/trunk/src/changes/changes.xml Wed Jul  4 18:00:02 2012
@@ -52,6 +52,10 @@ If the output is not quite correct, chec
   <body>
     <release version="3.1" date="TBD" description="
 ">
+      <action dev="erans" type="fix" issue="MATH-798">
+        Added overridden method in "PolynomialFitter" (package
+        "o.a.c.m.optimization.fitting") to limit the number of evaluations.
+      </action>
       <action dev="celestin" type="add" issue="MATH-807">
         Added a new constructor to o.a.c.m.utils.IterationManager, allowing
         for the specification of a callback function in case the maximum

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/PolynomialFitter.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/PolynomialFitter.java?rev=1357353&r1=1357352&r2=1357353&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/PolynomialFitter.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/PolynomialFitter.java Wed Jul  4 18:00:02 2012
@@ -77,6 +77,23 @@ public class PolynomialFitter extends Cu
      *
      * @param guess First guess for the coefficients. They must be sorted in
      * increasing order of the polynomial's degree.
+     * @param maxEval Maximum number of evaluations of the polynomial.
+     * @return the coefficients of the polynomial that best fits the observed points.
+     * @throws org.apache.commons.math3.exception.TooManyEvaluationsException if
+     * the number of evaluations exceeds {@code maxEval}.
+     * @throws org.apache.commons.math3.exception.ConvergenceException
+     * if the algorithm failed to converge.
+     */
+    public double[] fit(int maxEval, double[] guess) {
+        return fit(maxEval, new PolynomialFunction.Parametric(), guess);
+    }
+
+    /**
+     * Get the coefficients of the polynomial fitting the weighted data points.
+     * The degree of the fitting polynomial is {@code guess.length - 1}.
+     *
+     * @param guess First guess for the coefficients. They must be sorted in
+     * increasing order of the polynomial's degree.
      * @return the coefficients of the polynomial that best fits the observed points.
      * @throws org.apache.commons.math3.exception.ConvergenceException
      * if the algorithm failed to converge.

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/CurveFitterTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/CurveFitterTest.java?rev=1357353&r1=1357352&r2=1357353&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/CurveFitterTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/CurveFitterTest.java Wed Jul  4 18:00:02 2012
@@ -138,69 +138,6 @@ public class CurveFitterTest {
 
     }
 
-    @Test
-    public void testMath798() {
-        final double tol = 1e-14;
-        final SimpleVectorValueChecker checker = new SimpleVectorValueChecker(tol, tol);
-        final double[] init = new double[] { 0, 0 };
-        final int maxEval = 3;
-
-        final double[] lm = doMath798(new LevenbergMarquardtOptimizer(checker), maxEval, init);
-        final double[] gn = doMath798(new GaussNewtonOptimizer(checker), maxEval, init);
-
-        for (int i = 0; i <= 1; i++) {
-            Assert.assertEquals(lm[i], gn[i], tol);
-        }
-    }
-
-    /**
-     * @param optimizer Optimizer.
-     * @param maxEval Maximum number of function evaluations.
-     * @param init First guess.
-     * @return the solution found by the given optimizer.
-     */
-    private double[] doMath798(DifferentiableMultivariateVectorOptimizer optimizer,
-                               int maxEval,
-                               double[] init) {
-        final CurveFitter fitter = new CurveFitter(optimizer);
-
-        fitter.addObservedPoint(-0.2, -7.12442E-13);
-        fitter.addObservedPoint(-0.199, -4.33397E-13);
-        fitter.addObservedPoint(-0.198, -2.823E-13);
-        fitter.addObservedPoint(-0.197, -1.40405E-13);
-        fitter.addObservedPoint(-0.196, -7.80821E-15);
-        fitter.addObservedPoint(-0.195, 6.20484E-14);
-        fitter.addObservedPoint(-0.194, 7.24673E-14);
-        fitter.addObservedPoint(-0.193, 1.47152E-13);
-        fitter.addObservedPoint(-0.192, 1.9629E-13);
-        fitter.addObservedPoint(-0.191, 2.12038E-13);
-        fitter.addObservedPoint(-0.19, 2.46906E-13);
-        fitter.addObservedPoint(-0.189, 2.77495E-13);
-        fitter.addObservedPoint(-0.188, 2.51281E-13);
-        fitter.addObservedPoint(-0.187, 2.64001E-13);
-        fitter.addObservedPoint(-0.186, 2.8882E-13);
-        fitter.addObservedPoint(-0.185, 3.13604E-13);
-        fitter.addObservedPoint(-0.184, 3.14248E-13);
-        fitter.addObservedPoint(-0.183, 3.1172E-13);
-        fitter.addObservedPoint(-0.182, 3.12912E-13);
-        fitter.addObservedPoint(-0.181, 3.06761E-13);
-        fitter.addObservedPoint(-0.18, 2.8559E-13);
-        fitter.addObservedPoint(-0.179, 2.86806E-13);
-        fitter.addObservedPoint(-0.178, 2.985E-13);
-        fitter.addObservedPoint(-0.177, 2.67148E-13);
-        fitter.addObservedPoint(-0.176, 2.94173E-13);
-        fitter.addObservedPoint(-0.175, 3.27528E-13);
-        fitter.addObservedPoint(-0.174, 3.33858E-13);
-        fitter.addObservedPoint(-0.173, 2.97511E-13);
-        fitter.addObservedPoint(-0.172, 2.8615E-13);
-        fitter.addObservedPoint(-0.171, 2.84624E-13);
-
-        final double[] coeff = fitter.fit(maxEval,
-                                          new PolynomialFunction.Parametric(),
-                                          init);
-        return coeff;
-    }
-
     private static class SimpleInverseFunction implements ParametricUnivariateFunction {
 
         public double value(double x, double ... parameters) {

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/PolynomialFitterTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/PolynomialFitterTest.java?rev=1357353&r1=1357352&r2=1357353&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/PolynomialFitterTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/fitting/PolynomialFitterTest.java Wed Jul  4 18:00:02 2012
@@ -21,6 +21,7 @@ import java.util.Random;
 
 import org.apache.commons.math3.analysis.polynomials.PolynomialFunction;
 import org.apache.commons.math3.exception.ConvergenceException;
+import org.apache.commons.math3.exception.TooManyEvaluationsException;
 import org.apache.commons.math3.optimization.DifferentiableMultivariateVectorOptimizer;
 import org.apache.commons.math3.optimization.general.GaussNewtonOptimizer;
 import org.apache.commons.math3.optimization.general.LevenbergMarquardtOptimizer;
@@ -108,6 +109,90 @@ public class PolynomialFitterTest {
     }
 
     @Test
+    public void testMath798() {
+        final double tol = 1e-14;
+        final SimpleVectorValueChecker checker = new SimpleVectorValueChecker(tol, tol);
+        final double[] init = new double[] { 0, 0 };
+        final int maxEval = 3;
+
+        final double[] lm = doMath798(new LevenbergMarquardtOptimizer(checker), maxEval, init);
+        final double[] gn = doMath798(new GaussNewtonOptimizer(checker), maxEval, init);
+
+        for (int i = 0; i <= 1; i++) {
+            Assert.assertEquals(lm[i], gn[i], tol);
+        }
+    }
+
+    /**
+     * This test shows that the user can set the maximum number of iterations
+     * to avoid running for too long.
+     * But in the test case, the real problem is that the tolerance is way too
+     * stringent.
+     */
+    @Test(expected=TooManyEvaluationsException.class)
+    public void testMath798WithToleranceTooLow() {
+        final double tol = 1e-100;
+        final SimpleVectorValueChecker checker = new SimpleVectorValueChecker(tol, tol);
+        final double[] init = new double[] { 0, 0 };
+        final int maxEval = 10000; // Trying hard to fit.
+
+        final double[] lm = doMath798(new LevenbergMarquardtOptimizer(checker), maxEval, init);
+        final double[] gn = doMath798(new GaussNewtonOptimizer(checker), maxEval, init);
+
+        for (int i = 0; i <= 1; i++) {
+            Assert.assertEquals(lm[i], gn[i], tol);
+        }
+    }
+
+    /**
+     * @param optimizer Optimizer.
+     * @param maxEval Maximum number of function evaluations.
+     * @param init First guess.
+     * @return the solution found by the given optimizer.
+     */
+    private double[] doMath798(DifferentiableMultivariateVectorOptimizer optimizer,
+                               int maxEval,
+                               double[] init) {
+        final CurveFitter fitter = new CurveFitter(optimizer);
+
+        fitter.addObservedPoint(-0.2, -7.12442E-13);
+        fitter.addObservedPoint(-0.199, -4.33397E-13);
+        fitter.addObservedPoint(-0.198, -2.823E-13);
+        fitter.addObservedPoint(-0.197, -1.40405E-13);
+        fitter.addObservedPoint(-0.196, -7.80821E-15);
+        fitter.addObservedPoint(-0.195, 6.20484E-14);
+        fitter.addObservedPoint(-0.194, 7.24673E-14);
+        fitter.addObservedPoint(-0.193, 1.47152E-13);
+        fitter.addObservedPoint(-0.192, 1.9629E-13);
+        fitter.addObservedPoint(-0.191, 2.12038E-13);
+        fitter.addObservedPoint(-0.19, 2.46906E-13);
+        fitter.addObservedPoint(-0.189, 2.77495E-13);
+        fitter.addObservedPoint(-0.188, 2.51281E-13);
+        fitter.addObservedPoint(-0.187, 2.64001E-13);
+        fitter.addObservedPoint(-0.186, 2.8882E-13);
+        fitter.addObservedPoint(-0.185, 3.13604E-13);
+        fitter.addObservedPoint(-0.184, 3.14248E-13);
+        fitter.addObservedPoint(-0.183, 3.1172E-13);
+        fitter.addObservedPoint(-0.182, 3.12912E-13);
+        fitter.addObservedPoint(-0.181, 3.06761E-13);
+        fitter.addObservedPoint(-0.18, 2.8559E-13);
+        fitter.addObservedPoint(-0.179, 2.86806E-13);
+        fitter.addObservedPoint(-0.178, 2.985E-13);
+        fitter.addObservedPoint(-0.177, 2.67148E-13);
+        fitter.addObservedPoint(-0.176, 2.94173E-13);
+        fitter.addObservedPoint(-0.175, 3.27528E-13);
+        fitter.addObservedPoint(-0.174, 3.33858E-13);
+        fitter.addObservedPoint(-0.173, 2.97511E-13);
+        fitter.addObservedPoint(-0.172, 2.8615E-13);
+        fitter.addObservedPoint(-0.171, 2.84624E-13);
+
+        final double[] coeff = fitter.fit(maxEval,
+                                          new PolynomialFunction.Parametric(),
+                                          init);
+        return coeff;
+    }
+
+    @Test
     public void testRedundantSolvable() {
         // Levenberg-Marquardt should handle redundant information gracefully
         checkUnsolvableProblem(new LevenbergMarquardtOptimizer(), true);