View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.math.optimization.fitting;
19  
20  import org.apache.commons.math.FunctionEvaluationException;
21  import org.apache.commons.math.MathRuntimeException;
22  import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
23  import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;
24  import org.apache.commons.math.optimization.OptimizationException;
25  
26  /** This class implements a curve fitting specialized for polynomials.
27   * <p>Polynomial fitting is a very simple case of curve fitting. The
28   * estimated coefficients are the polynomial coefficients. They are
29   * searched by a least square estimator.</p>
30   * @version $Revision: 786479 $ $Date: 2009-06-19 08:36:16 -0400 (Fri, 19 Jun 2009) $
31   * @since 2.0
32   */
33  
34  public class PolynomialFitter {
35  
36      /** Fitter for the coefficients. */
37      private final CurveFitter fitter;
38  
39      /** Polynomial degree. */
40      private final int degree;
41  
42      /** Simple constructor.
43       * <p>The polynomial fitter built this way are complete polynomials,
44       * ie. a n-degree polynomial has n+1 coefficients.</p>
45       * @param degree maximal degree of the polynomial
46       * @param optimizer optimizer to use for the fitting
47       */
48      public PolynomialFitter(int degree, final DifferentiableMultivariateVectorialOptimizer optimizer) {
49          this.fitter = new CurveFitter(optimizer);
50          this.degree = degree;
51      }
52  
53      /** Add an observed weighted (x,y) point to the sample.
54       * @param weight weight of the observed point in the fit
55       * @param x abscissa of the point
56       * @param y observed value of the point at x, after fitting we should
57       * have P(x) as close as possible to this value
58       */
59      public void addObservedPoint(double weight, double x, double y) {
60          fitter.addObservedPoint(weight, x, y);
61      }
62  
63      /** Get the polynomial fitting the weighted (x, y) points.
64       * @return polynomial function best fitting the observed points
65       * @exception OptimizationException if the algorithm failed to converge
66       */
67      public PolynomialFunction fit()
68          throws OptimizationException {
69          try {
70              return new PolynomialFunction(fitter.fit(new ParametricPolynomial(), new double[degree + 1]));
71          } catch (FunctionEvaluationException fee) {
72              // this should never happen
73              throw MathRuntimeException.createInternalError(fee);
74          }
75      }
76  
77      /** Dedicated parametric polynomial class. */
78      private static class ParametricPolynomial implements ParametricRealFunction {
79  
80          /** {@inheritDoc} */
81          public double[] gradient(double x, double[] parameters)
82                  throws FunctionEvaluationException {
83              final double[] gradient = new double[parameters.length];
84              double xn = 1.0;
85              for (int i = 0; i < parameters.length; ++i) {
86                  gradient[i] = xn;
87                  xn *= x;
88              }
89              return gradient;
90          }
91  
92          /** {@inheritDoc} */
93          public double value(final double x, final double[] parameters) {
94              double y = 0;
95              for (int i = parameters.length - 1; i >= 0; --i) {
96                  y = y * x + parameters[i];
97              }
98              return y;
99          }
100         
101     }
102 
103 }