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 }