Author: erans
Date: Sun Jun 10 15:12:57 2012
New Revision: 1348613

URL: http://svn.apache.org/viewvc?rev=1348613&view=rev
Log:
MATH-804
Parameterized "CurveFitter" with the type of the fitting function. Updated 
subclasses
"PolynomialFitter", "HarmonicFitter", "GaussianFitter" accordingly.

Modified:
    commons/proper/math/trunk/src/changes/changes.xml
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/CurveFitter.java
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/GaussianFitter.java
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/HarmonicFitter.java
    
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/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=1348613&r1=1348612&r2=1348613&view=diff
==============================================================================
--- commons/proper/math/trunk/src/changes/changes.xml (original)
+++ commons/proper/math/trunk/src/changes/changes.xml Sun Jun 10 15:12:57 2012
@@ -52,6 +52,11 @@ If the output is not quite correct, chec
   <body>
     <release version="3.1" date="TBD" description="
 ">
+      <action dev="erans" type="fix" issue="MATH-804">
+        Parameterized "CurveFitter" class (package 
"o.a.c.m.optimization.fitting")
+        with the type of the fitting function. Updated subclasses 
"PolynomialFitter",
+        "HarmonicFitter", "GaussianFitter".
+      </action>
       <action dev="luc" type="fix" issue="MATH-801">
         Fixed a problem when building rotations from two pairs of vectors. In 
very rare cases,
         due to numerical inaccuracies the computed quaternion was not 
normalized (some examples

Modified: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/CurveFitter.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/CurveFitter.java?rev=1348613&r1=1348612&r2=1348613&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/CurveFitter.java
 (original)
+++ 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/CurveFitter.java
 Sun Jun 10 15:12:57 2012
@@ -27,7 +27,8 @@ import org.apache.commons.math3.optimiza
 import org.apache.commons.math3.optimization.PointVectorValuePair;
 
 /** Fitter for parametric univariate real functions y = f(x).
- * <p>When a univariate real function y = f(x) does depend on some
+ * <br/>
+ * When a univariate real function y = f(x) does depend on some
  * unknown parameters p<sub>0</sub>, p<sub>1</sub> ... p<sub>n-1</sub>,
  * this class can be used to find these parameters. It does this
  * by <em>fitting</em> the curve so it remains very close to a set of
@@ -35,11 +36,14 @@ import org.apache.commons.math3.optimiza
  * y<sub>1</sub>) ... (x<sub>k-1</sub>, y<sub>k-1</sub>). This fitting
  * is done by finding the parameters values that minimizes the objective
  * function &sum;(y<sub>i</sub>-f(x<sub>i</sub>))<sup>2</sup>. This is
- * really a least squares problem.</p>
+ * really a least squares problem.
+ *
+ * @param <T> Function to use for the fit.
+ *
  * @version $Id$
  * @since 2.0
  */
-public class CurveFitter {
+public class CurveFitter<T extends ParametricUnivariateFunction> {
     /** Optimizer to use for the fitting. */
     private final DifferentiableMultivariateVectorOptimizer optimizer;
     /** Observed points. */
@@ -120,7 +124,7 @@ public class CurveFitter {
      * @throws org.apache.commons.math3.exception.DimensionMismatchException
      * if the start point dimension is wrong.
      */
-    public double[] fit(final ParametricUnivariateFunction f, final double[] 
initialGuess) {
+    public double[] fit(T f, final double[] initialGuess) {
         return fit(Integer.MAX_VALUE, f, initialGuess);
     }
 
@@ -141,7 +145,7 @@ public class CurveFitter {
      * if the start point dimension is wrong.
      * @since 3.0
      */
-    public double[] fit(int maxEval, final ParametricUnivariateFunction f,
+    public double[] fit(int maxEval, T f,
                         final double[] initialGuess) {
         // prepare least squares problem
         double[] target  = new double[observations.size()];

Modified: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/GaussianFitter.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/GaussianFitter.java?rev=1348613&r1=1348612&r2=1348613&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/GaussianFitter.java
 (original)
+++ 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/GaussianFitter.java
 Sun Jun 10 15:12:57 2012
@@ -21,7 +21,6 @@ import java.util.Arrays;
 import java.util.Comparator;
 
 import org.apache.commons.math3.analysis.function.Gaussian;
-import org.apache.commons.math3.analysis.ParametricUnivariateFunction;
 import org.apache.commons.math3.exception.NullArgumentException;
 import org.apache.commons.math3.exception.NumberIsTooSmallException;
 import org.apache.commons.math3.exception.OutOfRangeException;
@@ -58,7 +57,7 @@ import org.apache.commons.math3.optimiza
  * @since 2.2
  * @version $Id$
  */
-public class GaussianFitter extends CurveFitter {
+public class GaussianFitter extends CurveFitter<Gaussian.Parametric> {
     /**
      * Constructs an instance using the specified optimizer.
      *
@@ -82,13 +81,11 @@ public class GaussianFitter extends Curv
      * @since 3.0
      */
     public double[] fit(double[] initialGuess) {
-        final ParametricUnivariateFunction f = new 
ParametricUnivariateFunction() {
-                private final ParametricUnivariateFunction g = new 
Gaussian.Parametric();
-
+        final Gaussian.Parametric f = new Gaussian.Parametric() {
                 public double value(double x, double ... p) {
                     double v = Double.POSITIVE_INFINITY;
                     try {
-                        v = g.value(x, p);
+                        v = super.value(x, p);
                     } catch (NotStrictlyPositiveException e) {
                         // Do nothing.
                     }
@@ -100,7 +97,7 @@ public class GaussianFitter extends Curv
                                    Double.POSITIVE_INFINITY,
                                    Double.POSITIVE_INFINITY };
                     try {
-                        v = g.gradient(x, p);
+                        v = super.gradient(x, p);
                     } catch (NotStrictlyPositiveException e) {
                         // Do nothing.
                     }

Modified: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/HarmonicFitter.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/HarmonicFitter.java?rev=1348613&r1=1348612&r2=1348613&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/HarmonicFitter.java
 (original)
+++ 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/fitting/HarmonicFitter.java
 Sun Jun 10 15:12:57 2012
@@ -36,7 +36,7 @@ import org.apache.commons.math3.util.Fas
  * @version $Id$
  * @since 2.0
  */
-public class HarmonicFitter extends CurveFitter {
+public class HarmonicFitter extends CurveFitter<HarmonicOscillator.Parametric> 
{
     /**
      * Simple constructor.
      * @param optimizer Optimizer to use for the fitting.

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=1348613&r1=1348612&r2=1348613&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
 Sun Jun 10 15:12:57 2012
@@ -20,22 +20,18 @@ package org.apache.commons.math3.optimiz
 import org.apache.commons.math3.analysis.polynomials.PolynomialFunction;
 import 
org.apache.commons.math3.optimization.DifferentiableMultivariateVectorOptimizer;
 
-/** This class implements a curve fitting specialized for polynomials.
- * <p>Polynomial fitting is a very simple case of curve fitting. The
- * estimated coefficients are the polynomial coefficients. They are
- * searched by a least square estimator.</p>
+/**
+ * Polynomial fitting is a very simple case of {@link CurveFitter curve 
fitting}.
+ * The estimated coefficients are the polynomial coefficients (see the
+ * {@link #fit(double[]) fit} method).
+ *
  * @version $Id$
  * @since 2.0
- *
- * @deprecated Since 3.1 (to be removed in 4.0, see <a 
href="https://issues.apache.org/jira/browse/MATH-800";>MATH-800</a>).
- * Please use {@link CurveFitter} directly, by passing an instance of
- * {@link 
org.apache.commons.math3.analysis.polynomials.PolynomialFunction.Parametric 
PolynomialFunction.Parametric}
- * as an argument to the
- * {@link 
CurveFitter#fit(int,org.apache.commons.math3.analysis.ParametricUnivariateFunction,double[])
 fit}
- * method.
  */
-public class PolynomialFitter extends CurveFitter {
-    /** Polynomial degree. */
+public class PolynomialFitter extends 
CurveFitter<PolynomialFunction.Parametric> {
+    /** Polynomial degree.
+     * @deprecated
+     */
     private final int degree;
 
     /**
@@ -45,6 +41,8 @@ public class PolynomialFitter extends Cu
      *
      * @param degree Maximal degree of the polynomial.
      * @param optimizer Optimizer to use for the fitting.
+     * @deprecated Since 3.1 (to be removed in 4.0). Please use
+     * {@link #PolynomialFitter(DifferentiableMultivariateVectorOptimizer)} 
instead.
      */
     public PolynomialFitter(int degree, final 
DifferentiableMultivariateVectorOptimizer optimizer) {
         super(optimizer);
@@ -52,13 +50,38 @@ public class PolynomialFitter extends Cu
     }
 
     /**
+     * Simple constructor.
+     *
+     * @param optimizer Optimizer to use for the fitting.
+     */
+    public PolynomialFitter(DifferentiableMultivariateVectorOptimizer 
optimizer) {
+        super(optimizer);
+        degree = -1; // To avoid compilation error until the instance variable 
is removed.
+    }
+
+    /**
      * Get the polynomial fitting the weighted (x, y) points.
      *
      * @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.
+     * @deprecated Since 3.1 (to be removed in 4.0). Please use {@link 
#fit(double[])} instead.
      */
     public double[] fit() {
         return fit(new PolynomialFunction.Parametric(), new double[degree + 
1]);
     }
+
+    /**
+     * 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.
+     */
+    public double[] fit(double[] guess) {
+        return fit(new PolynomialFunction.Parametric(), guess);
+    }
 }

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=1348613&r1=1348612&r2=1348613&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
 Sun Jun 10 15:12:57 2012
@@ -43,7 +43,7 @@ public class PolynomialFitterTest {
         rng.reSeed(64925784252L);
 
         final LevenbergMarquardtOptimizer optim = new 
LevenbergMarquardtOptimizer();
-        final CurveFitter fitter = new CurveFitter(optim);
+        final PolynomialFitter fitter = new PolynomialFitter(optim);
         final double[] coeff = { 12.9, -3.4, 2.1 }; // 12.9 - 3.4 x + 2.1 x^2
         final PolynomialFunction f = new PolynomialFunction(coeff);
 
@@ -54,8 +54,7 @@ public class PolynomialFitterTest {
         }
 
         // Start fit from initial guesses that are far from the optimal values.
-        final double[] best = fitter.fit(new PolynomialFunction.Parametric(),
-                                         new double[] { -1e-20, 3e15, -5e25 });
+        final double[] best = fitter.fit(new double[] { -1e-20, 3e15, -5e25 });
 
         TestUtils.assertEquals("best != coeff", coeff, best, 1e-12);
     }
@@ -66,15 +65,13 @@ public class PolynomialFitterTest {
         for (int degree = 1; degree < 10; ++degree) {
             PolynomialFunction p = buildRandomPolynomial(degree, randomizer);
 
-            CurveFitter fitter = new CurveFitter(new 
LevenbergMarquardtOptimizer());
+            PolynomialFitter fitter = new PolynomialFitter(new 
LevenbergMarquardtOptimizer());
             for (int i = 0; i <= degree; ++i) {
                 fitter.addObservedPoint(1.0, i, p.value(i));
             }
 
             final double[] init = new double[degree + 1];
-            PolynomialFunction fitted = new 
PolynomialFunction(fitter.fit(Integer.MAX_VALUE,
-                                                                          new 
PolynomialFunction.Parametric(),
-                                                                          
init));
+            PolynomialFunction fitted = new 
PolynomialFunction(fitter.fit(init));
 
             for (double x = -1.0; x < 1.0; x += 0.01) {
                 double error = FastMath.abs(p.value(x) - fitted.value(x)) /
@@ -91,16 +88,14 @@ public class PolynomialFitterTest {
         for (int degree = 0; degree < 10; ++degree) {
             PolynomialFunction p = buildRandomPolynomial(degree, randomizer);
 
-            CurveFitter fitter = new CurveFitter(new 
LevenbergMarquardtOptimizer());
+            PolynomialFitter fitter = new PolynomialFitter(new 
LevenbergMarquardtOptimizer());
             for (double x = -1.0; x < 1.0; x += 0.01) {
                 fitter.addObservedPoint(1.0, x,
                                         p.value(x) + 0.1 * 
randomizer.nextGaussian());
             }
 
             final double[] init = new double[degree + 1];
-            PolynomialFunction fitted = new 
PolynomialFunction(fitter.fit(Integer.MAX_VALUE,
-                                                                          new 
PolynomialFunction.Parametric(),
-                                                                          
init));
+            PolynomialFunction fitted = new 
PolynomialFunction(fitter.fit(init));
 
             for (double x = -1.0; x < 1.0; x += 0.01) {
                 double error = FastMath.abs(p.value(x) - fitted.value(x)) /
@@ -130,7 +125,7 @@ public class PolynomialFitterTest {
         for (int degree = 0; degree < 10; ++degree) {
             PolynomialFunction p = buildRandomPolynomial(degree, randomizer);
 
-            CurveFitter fitter = new CurveFitter(optimizer);
+            PolynomialFitter fitter = new PolynomialFitter(optimizer);
 
             // reusing the same point over and over again does not bring
             // information, the problem cannot be solved in this case for
@@ -142,9 +137,7 @@ public class PolynomialFitterTest {
 
             try {
                 final double[] init = new double[degree + 1];
-                fitter.fit(Integer.MAX_VALUE,
-                           new PolynomialFunction.Parametric(),
-                           init);
+                fitter.fit(init);
                 Assert.assertTrue(solvable || (degree == 0));
             } catch(ConvergenceException e) {
                 Assert.assertTrue((! solvable) && (degree > 0));


Reply via email to