001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.math.optimization.fitting;
019    
020    import org.apache.commons.math.FunctionEvaluationException;
021    import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;
022    import org.apache.commons.math.optimization.OptimizationException;
023    import org.apache.commons.math.optimization.fitting.CurveFitter;
024    import org.apache.commons.math.optimization.fitting.WeightedObservedPoint;
025    
026    /**
027     * Fits points to a Gaussian function (that is, a {@link GaussianFunction}).
028     * <p>
029     * Usage example:
030     * <pre>
031     *   GaussianFitter fitter = new GaussianFitter(
032     *     new LevenbergMarquardtOptimizer());
033     *   fitter.addObservedPoint(4.0254623,  531026.0);
034     *   fitter.addObservedPoint(4.03128248, 984167.0);
035     *   fitter.addObservedPoint(4.03839603, 1887233.0);
036     *   fitter.addObservedPoint(4.04421621, 2687152.0);
037     *   fitter.addObservedPoint(4.05132976, 3461228.0);
038     *   fitter.addObservedPoint(4.05326982, 3580526.0);
039     *   fitter.addObservedPoint(4.05779662, 3439750.0);
040     *   fitter.addObservedPoint(4.0636168,  2877648.0);
041     *   fitter.addObservedPoint(4.06943698, 2175960.0);
042     *   fitter.addObservedPoint(4.07525716, 1447024.0);
043     *   fitter.addObservedPoint(4.08237071, 717104.0);
044     *   fitter.addObservedPoint(4.08366408, 620014.0);
045     *  GaussianFunction fitFunction = fitter.fit();
046     * </pre>
047     *
048     * @see ParametricGaussianFunction
049     * @since 2.2
050     * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 f??vr. 2011) $
051     */
052    public class GaussianFitter {
053    
054        /** Fitter used for fitting. */
055        private final CurveFitter fitter;
056    
057        /**
058         * Constructs an instance using the specified optimizer.
059         *
060         * @param optimizer optimizer to use for the fitting
061         */
062        public GaussianFitter(DifferentiableMultivariateVectorialOptimizer optimizer) {
063            fitter = new CurveFitter(optimizer);
064        }
065    
066        /**
067         * Adds point (<code>x</code>, <code>y</code>) to list of observed points
068         * with a weight of 1.0.
069         *
070         * @param x <tt>x</tt> point value
071         * @param y <tt>y</tt> point value
072         */
073        public void addObservedPoint(double x, double y) {
074            addObservedPoint(1.0, x, y);
075        }
076    
077        /**
078         * Adds point (<code>x</code>, <code>y</code>) to list of observed points
079         * with a weight of <code>weight</code>.
080         *
081         * @param weight weight assigned to point
082         * @param x <tt>x</tt> point value
083         * @param y <tt>y</tt> point value
084         */
085        public void addObservedPoint(double weight, double x, double y) {
086            fitter.addObservedPoint(weight, x, y);
087        }
088    
089        /**
090         * Fits Gaussian function to the observed points.
091         *
092         * @return Gaussian function best fitting the observed points
093         *
094         * @throws FunctionEvaluationException if <code>CurveFitter.fit</code> throws it
095         * @throws OptimizationException if <code>CurveFitter.fit</code> throws it
096         * @throws IllegalArgumentException if <code>CurveFitter.fit</code> throws it
097         *
098         * @see CurveFitter
099         */
100        public GaussianFunction fit() throws FunctionEvaluationException, OptimizationException {
101            return new GaussianFunction(fitter.fit(new ParametricGaussianFunction(),
102                                                   createParametersGuesser(fitter.getObservations()).guess()));
103        }
104    
105        /**
106         * Factory method to create a <code>GaussianParametersGuesser</code>
107         * instance initialized with the specified observations.
108         *
109         * @param observations points used to initialize the created
110         *        <code>GaussianParametersGuesser</code> instance
111         *
112         * @return new <code>GaussianParametersGuesser</code> instance
113         */
114        protected GaussianParametersGuesser createParametersGuesser(WeightedObservedPoint[] observations) {
115            return new GaussianParametersGuesser(observations);
116        }
117    }