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/12/12 15:11:04 UTC

svn commit: r1420684 [1/15] - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math3/exception/ main/java/org/apache/commons/math3/exception/util/ main/java/org/apache/commons/math3/fitting/ main/java/org/apache/commons/math3/optim/ main...

Author: erans
Date: Wed Dec 12 14:10:38 2012
New Revision: 1420684

URL: http://svn.apache.org/viewvc?rev=1420684&view=rev
Log:
MATH-874
Refactored of the contents of package "o.a.c.m.optimization"
into the new "o.a.c.m.optim" and "o.a.c.m.fitting" packages.
* All deprecated classes/fields/methods have been removed in the
  replacement packages.
* Simplified API: a single "optimize(OptimizationData... data)"
  for all optimizer types.
* Simplified class hierarchy, merged interfaces and abstract
  classes, only base classes are generic.
* The new classes do not use the "DerivativeStructure" type.

Added:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/TooManyIterationsException.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/CurveFitter.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/GaussianFitter.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/HarmonicFitter.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/PolynomialFitter.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/WeightedObservedPoint.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/package-info.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/AbstractConvergenceChecker.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/BaseMultiStartMultivariateOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/BaseMultivariateOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/BaseOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/ConvergenceChecker.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/GoalType.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/InitialGuess.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/MaxEval.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/MaxIter.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/ObjectiveFunction.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/OptimizationData.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/PointValuePair.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/PointVectorValuePair.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/SimpleBounds.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/SimplePointChecker.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/SimpleValueChecker.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/SimpleVectorValueChecker.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/linear/
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/linear/LinearConstraint.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/linear/LinearConstraintSet.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/linear/LinearObjectiveFunction.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/linear/LinearOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/linear/NoFeasibleSolutionException.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/linear/NonNegativeConstraint.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/linear/Relationship.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/linear/SimplexSolver.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/linear/SimplexTableau.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/linear/UnboundedSolutionException.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/linear/package-info.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/GradientMultivariateOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/LeastSquaresConverter.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/MultiStartMultivariateOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionMappingAdapter.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionPenaltyAdapter.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/ObjectiveFunctionGradient.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/NonLinearConjugateGradientOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/Preconditioner.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/package-info.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/AbstractSimplex.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/BOBYQAOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/CMAESOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/MultiDirectionalSimplex.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/NelderMeadSimplex.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/PowellOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/SimplexOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/package-info.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/scalar/package-info.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/JacobianMultivariateVectorOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/ModelFunction.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/ModelFunctionJacobian.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/MultiStartMultivariateVectorOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/MultivariateVectorOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/Target.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/Weight.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/AbstractLeastSquaresOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/GaussNewtonOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/LevenbergMarquardtOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/package-info.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/nonlinear/vector/package-info.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/package-info.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/univariate/
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/univariate/BracketFinder.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/univariate/BrentOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/univariate/MultiStartUnivariateOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/univariate/SearchInterval.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/univariate/SimpleUnivariateValueChecker.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/univariate/UnivariateObjectiveFunction.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/univariate/UnivariateOptimizer.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/univariate/UnivariatePointValuePair.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/univariate/package-info.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/CurveFitterTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/GaussianFitterTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/HarmonicFitterTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/PolynomialFitterTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/PointValuePairTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/PointVectorValuePairTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/SimplePointCheckerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/SimpleValueCheckerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/SimpleVectorValueCheckerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/linear/
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/linear/SimplexSolverTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/linear/SimplexTableauTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultiStartMultivariateOptimizerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionMappingAdapterTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionPenaltyAdapterTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/CircleScalar.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/NonLinearConjugateGradientOptimizerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/BOBYQAOptimizerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/CMAESOptimizerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/PowellOptimizerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/SimplexOptimizerMultiDirectionalTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/SimplexOptimizerNelderMeadTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/MultiStartMultivariateVectorOptimizerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/AbstractLeastSquaresOptimizerAbstractTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/AbstractLeastSquaresOptimizerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/AbstractLeastSquaresOptimizerTestValidation.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/CircleProblem.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/CircleVectorial.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/GaussNewtonOptimizerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/LevenbergMarquardtOptimizerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/MinpackTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/RandomCirclePointGenerator.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/RandomStraightLinePointGenerator.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/StatisticalReferenceDataset.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/StatisticalReferenceDatasetFactory.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/StraightLineProblem.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/univariate/
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/univariate/BracketFinderTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/univariate/BrentOptimizerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/univariate/MultiStartUnivariateOptimizerTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/univariate/SimpleUnivariateValueCheckerTest.java   (with props)
Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
    commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/TooManyIterationsException.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/TooManyIterationsException.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/TooManyIterationsException.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/TooManyIterationsException.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.exception;
+
+import org.apache.commons.math3.exception.util.LocalizedFormats;
+
+/**
+ * Exception to be thrown when the maximal number of iterations is exceeded.
+ *
+ * @since 3.1
+ * @version $Id$
+ */
+public class TooManyIterationsException extends MaxCountExceededException {
+    /** Serializable version Id. */
+    private static final long serialVersionUID = 20121211L;
+
+    /**
+     * Construct the exception.
+     *
+     * @param max Maximum number of evaluations.
+     */
+    public TooManyIterationsException(Number max) {
+        super(max);
+        getContext().addMessage(LocalizedFormats.ITERATIONS);
+    }
+}

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/TooManyIterationsException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java?rev=1420684&r1=1420683&r2=1420684&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java Wed Dec 12 14:10:38 2012
@@ -148,6 +148,7 @@ public enum LocalizedFormats implements 
     INVALID_REGRESSION_OBSERVATION("length of regressor array = {0} does not match the number of variables = {1} in the model"),
     INVALID_ROUNDING_METHOD("invalid rounding method {0}, valid methods: {1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}), {11} ({12}), {13} ({14}), {15} ({16})"),
     ITERATOR_EXHAUSTED("iterator exhausted"),
+    ITERATIONS("iterations"), /* keep */
     LCM_OVERFLOW_32_BITS("overflow: lcm({0}, {1}) is 2^31"),
     LCM_OVERFLOW_64_BITS("overflow: lcm({0}, {1}) is 2^63"),
     LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE("list of chromosomes bigger than maxPopulationSize"),

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/CurveFitter.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/CurveFitter.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/CurveFitter.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/CurveFitter.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,230 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.fitting;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.math3.analysis.MultivariateVectorFunction;
+import org.apache.commons.math3.analysis.MultivariateMatrixFunction;
+import org.apache.commons.math3.analysis.ParametricUnivariateFunction;
+import org.apache.commons.math3.optim.MaxEval;
+import org.apache.commons.math3.optim.InitialGuess;
+import org.apache.commons.math3.optim.PointVectorValuePair;
+import org.apache.commons.math3.optim.nonlinear.vector.MultivariateVectorOptimizer;
+import org.apache.commons.math3.optim.nonlinear.vector.ModelFunction;
+import org.apache.commons.math3.optim.nonlinear.vector.ModelFunctionJacobian;
+import org.apache.commons.math3.optim.nonlinear.vector.Target;
+import org.apache.commons.math3.optim.nonlinear.vector.Weight;
+
+/**
+ * Fitter for parametric univariate real functions y = f(x).
+ * <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
+ * observed points (x<sub>0</sub>, y<sub>0</sub>), (x<sub>1</sub>,
+ * 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.
+ *
+ * @param <T> Function to use for the fit.
+ *
+ * @version $Id: CurveFitter.java 1416643 2012-12-03 19:37:14Z tn $
+ * @since 2.0
+ */
+public class CurveFitter<T extends ParametricUnivariateFunction> {
+    /** Optimizer to use for the fitting. */
+    private final MultivariateVectorOptimizer optimizer;
+    /** Observed points. */
+    private final List<WeightedObservedPoint> observations;
+
+    /**
+     * Simple constructor.
+     *
+     * @param optimizer Optimizer to use for the fitting.
+     * @since 3.1
+     */
+    public CurveFitter(final MultivariateVectorOptimizer optimizer) {
+        this.optimizer = optimizer;
+        observations = new ArrayList<WeightedObservedPoint>();
+    }
+
+    /** Add an observed (x,y) point to the sample with unit weight.
+     * <p>Calling this method is equivalent to call
+     * {@code addObservedPoint(1.0, x, y)}.</p>
+     * @param x abscissa of the point
+     * @param y observed value of the point at x, after fitting we should
+     * have f(x) as close as possible to this value
+     * @see #addObservedPoint(double, double, double)
+     * @see #addObservedPoint(WeightedObservedPoint)
+     * @see #getObservations()
+     */
+    public void addObservedPoint(double x, double y) {
+        addObservedPoint(1.0, x, y);
+    }
+
+    /** Add an observed weighted (x,y) point to the sample.
+     * @param weight weight of the observed point in the fit
+     * @param x abscissa of the point
+     * @param y observed value of the point at x, after fitting we should
+     * have f(x) as close as possible to this value
+     * @see #addObservedPoint(double, double)
+     * @see #addObservedPoint(WeightedObservedPoint)
+     * @see #getObservations()
+     */
+    public void addObservedPoint(double weight, double x, double y) {
+        observations.add(new WeightedObservedPoint(weight, x, y));
+    }
+
+    /** Add an observed weighted (x,y) point to the sample.
+     * @param observed observed point to add
+     * @see #addObservedPoint(double, double)
+     * @see #addObservedPoint(double, double, double)
+     * @see #getObservations()
+     */
+    public void addObservedPoint(WeightedObservedPoint observed) {
+        observations.add(observed);
+    }
+
+    /** Get the observed points.
+     * @return observed points
+     * @see #addObservedPoint(double, double)
+     * @see #addObservedPoint(double, double, double)
+     * @see #addObservedPoint(WeightedObservedPoint)
+     */
+    public WeightedObservedPoint[] getObservations() {
+        return observations.toArray(new WeightedObservedPoint[observations.size()]);
+    }
+
+    /**
+     * Remove all observations.
+     */
+    public void clearObservations() {
+        observations.clear();
+    }
+
+    /**
+     * Fit a curve.
+     * This method compute the coefficients of the curve that best
+     * fit the sample of observed points previously given through calls
+     * to the {@link #addObservedPoint(WeightedObservedPoint)
+     * addObservedPoint} method.
+     *
+     * @param f parametric function to fit.
+     * @param initialGuess first guess of the function parameters.
+     * @return the fitted parameters.
+     * @throws org.apache.commons.math3.exception.DimensionMismatchException
+     * if the start point dimension is wrong.
+     */
+    public double[] fit(T f, final double[] initialGuess) {
+        return fit(Integer.MAX_VALUE, f, initialGuess);
+    }
+
+    /**
+     * Fit a curve.
+     * This method compute the coefficients of the curve that best
+     * fit the sample of observed points previously given through calls
+     * to the {@link #addObservedPoint(WeightedObservedPoint)
+     * addObservedPoint} method.
+     *
+     * @param f parametric function to fit.
+     * @param initialGuess first guess of the function parameters.
+     * @param maxEval Maximum number of function evaluations.
+     * @return the fitted parameters.
+     * @throws org.apache.commons.math3.exception.TooManyEvaluationsException
+     * if the number of allowed evaluations is exceeded.
+     * @throws org.apache.commons.math3.exception.DimensionMismatchException
+     * if the start point dimension is wrong.
+     * @since 3.0
+     */
+    public double[] fit(int maxEval, T f,
+                        final double[] initialGuess) {
+        // Prepare least squares problem.
+        double[] target  = new double[observations.size()];
+        double[] weights = new double[observations.size()];
+        int i = 0;
+        for (WeightedObservedPoint point : observations) {
+            target[i]  = point.getY();
+            weights[i] = point.getWeight();
+            ++i;
+        }
+
+        // Input to the optimizer: the model and its Jacobian.
+        final TheoreticalValuesFunction model = new TheoreticalValuesFunction(f);
+
+        // Perform the fit.
+        final PointVectorValuePair optimum
+            = optimizer.optimize(new MaxEval(maxEval),
+                                 model.getModelFunction(),
+                                 model.getModelFunctionJacobian(),
+                                 new Target(target),
+                                 new Weight(weights),
+                                 new InitialGuess(initialGuess));
+        // Extract the coefficients.
+        return optimum.getPointRef();
+    }
+
+    /** Vectorial function computing function theoretical values. */
+    private class TheoreticalValuesFunction {
+        /** Function to fit. */
+        private final ParametricUnivariateFunction f;
+
+        /**
+         * @param f function to fit.
+         */
+        public TheoreticalValuesFunction(final ParametricUnivariateFunction f) {
+            this.f = f;
+        }
+
+        /**
+         * @return the model function values.
+         */
+        public ModelFunction getModelFunction() {
+            return new ModelFunction(new MultivariateVectorFunction() {
+                    /** {@inheritDoc} */
+                    public double[] value(double[] point) {
+                        // compute the residuals
+                        final double[] values = new double[observations.size()];
+                        int i = 0;
+                        for (WeightedObservedPoint observed : observations) {
+                            values[i++] = f.value(observed.getX(), point);
+                        }
+
+                        return values;
+                    }
+                });
+        }
+
+        /**
+         * @return the model function Jacobian.
+         */
+        public ModelFunctionJacobian getModelFunctionJacobian() {
+            return new ModelFunctionJacobian(new MultivariateMatrixFunction() {
+                    public double[][] value(double[] point) {
+                        final double[][] jacobian = new double[observations.size()][];
+                        int i = 0;
+                        for (WeightedObservedPoint observed : observations) {
+                            jacobian[i++] = f.gradient(observed.getX(), point);
+                        }
+                        return jacobian;
+                    }
+                });
+        }
+    }
+}

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/CurveFitter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/GaussianFitter.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/GaussianFitter.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/GaussianFitter.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/GaussianFitter.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,362 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.fitting;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import org.apache.commons.math3.analysis.function.Gaussian;
+import org.apache.commons.math3.exception.NullArgumentException;
+import org.apache.commons.math3.exception.NumberIsTooSmallException;
+import org.apache.commons.math3.exception.OutOfRangeException;
+import org.apache.commons.math3.exception.ZeroException;
+import org.apache.commons.math3.exception.NotStrictlyPositiveException;
+import org.apache.commons.math3.exception.util.LocalizedFormats;
+import org.apache.commons.math3.optim.nonlinear.vector.MultivariateVectorOptimizer;
+import org.apache.commons.math3.util.FastMath;
+
+/**
+ * Fits points to a {@link
+ * org.apache.commons.math3.analysis.function.Gaussian.Parametric Gaussian} function.
+ * <p>
+ * Usage example:
+ * <pre>
+ *   GaussianFitter fitter = new GaussianFitter(
+ *     new LevenbergMarquardtOptimizer());
+ *   fitter.addObservedPoint(4.0254623,  531026.0);
+ *   fitter.addObservedPoint(4.03128248, 984167.0);
+ *   fitter.addObservedPoint(4.03839603, 1887233.0);
+ *   fitter.addObservedPoint(4.04421621, 2687152.0);
+ *   fitter.addObservedPoint(4.05132976, 3461228.0);
+ *   fitter.addObservedPoint(4.05326982, 3580526.0);
+ *   fitter.addObservedPoint(4.05779662, 3439750.0);
+ *   fitter.addObservedPoint(4.0636168,  2877648.0);
+ *   fitter.addObservedPoint(4.06943698, 2175960.0);
+ *   fitter.addObservedPoint(4.07525716, 1447024.0);
+ *   fitter.addObservedPoint(4.08237071, 717104.0);
+ *   fitter.addObservedPoint(4.08366408, 620014.0);
+ *   double[] parameters = fitter.fit();
+ * </pre>
+ *
+ * @since 2.2
+ * @version $Id: GaussianFitter.java 1416643 2012-12-03 19:37:14Z tn $
+ */
+public class GaussianFitter extends CurveFitter<Gaussian.Parametric> {
+    /**
+     * Constructs an instance using the specified optimizer.
+     *
+     * @param optimizer Optimizer to use for the fitting.
+     */
+    public GaussianFitter(MultivariateVectorOptimizer optimizer) {
+        super(optimizer);
+    }
+
+    /**
+     * Fits a Gaussian function to the observed points.
+     *
+     * @param initialGuess First guess values in the following order:
+     * <ul>
+     *  <li>Norm</li>
+     *  <li>Mean</li>
+     *  <li>Sigma</li>
+     * </ul>
+     * @return the parameters of the Gaussian function that best fits the
+     * observed points (in the same order as above).
+     * @since 3.0
+     */
+    public double[] fit(double[] initialGuess) {
+        final Gaussian.Parametric f = new Gaussian.Parametric() {
+                @Override
+                public double value(double x, double ... p) {
+                    double v = Double.POSITIVE_INFINITY;
+                    try {
+                        v = super.value(x, p);
+                    } catch (NotStrictlyPositiveException e) {
+                        // Do nothing.
+                    }
+                    return v;
+                }
+
+                @Override
+                public double[] gradient(double x, double ... p) {
+                    double[] v = { Double.POSITIVE_INFINITY,
+                                   Double.POSITIVE_INFINITY,
+                                   Double.POSITIVE_INFINITY };
+                    try {
+                        v = super.gradient(x, p);
+                    } catch (NotStrictlyPositiveException e) {
+                        // Do nothing.
+                    }
+                    return v;
+                }
+            };
+
+        return fit(f, initialGuess);
+    }
+
+    /**
+     * Fits a Gaussian function to the observed points.
+     *
+     * @return the parameters of the Gaussian function that best fits the
+     * observed points (in the same order as above).
+     */
+    public double[] fit() {
+        final double[] guess = (new ParameterGuesser(getObservations())).guess();
+        return fit(guess);
+    }
+
+    /**
+     * Guesses the parameters {@code norm}, {@code mean}, and {@code sigma}
+     * of a {@link org.apache.commons.math3.analysis.function.Gaussian.Parametric}
+     * based on the specified observed points.
+     */
+    public static class ParameterGuesser {
+        /** Normalization factor. */
+        private final double norm;
+        /** Mean. */
+        private final double mean;
+        /** Standard deviation. */
+        private final double sigma;
+
+        /**
+         * Constructs instance with the specified observed points.
+         *
+         * @param observations Observed points from which to guess the
+         * parameters of the Gaussian.
+         * @throws NullArgumentException if {@code observations} is
+         * {@code null}.
+         * @throws NumberIsTooSmallException if there are less than 3
+         * observations.
+         */
+        public ParameterGuesser(WeightedObservedPoint[] observations) {
+            if (observations == null) {
+                throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
+            }
+            if (observations.length < 3) {
+                throw new NumberIsTooSmallException(observations.length, 3, true);
+            }
+
+            final WeightedObservedPoint[] sorted = sortObservations(observations);
+            final double[] params = basicGuess(sorted);
+
+            norm = params[0];
+            mean = params[1];
+            sigma = params[2];
+        }
+
+        /**
+         * Gets an estimation of the parameters.
+         *
+         * @return the guessed parameters, in the following order:
+         * <ul>
+         *  <li>Normalization factor</li>
+         *  <li>Mean</li>
+         *  <li>Standard deviation</li>
+         * </ul>
+         */
+        public double[] guess() {
+            return new double[] { norm, mean, sigma };
+        }
+
+        /**
+         * Sort the observations.
+         *
+         * @param unsorted Input observations.
+         * @return the input observations, sorted.
+         */
+        private WeightedObservedPoint[] sortObservations(WeightedObservedPoint[] unsorted) {
+            final WeightedObservedPoint[] observations = unsorted.clone();
+            final Comparator<WeightedObservedPoint> cmp
+                = new Comparator<WeightedObservedPoint>() {
+                public int compare(WeightedObservedPoint p1,
+                                   WeightedObservedPoint p2) {
+                    if (p1 == null && p2 == null) {
+                        return 0;
+                    }
+                    if (p1 == null) {
+                        return -1;
+                    }
+                    if (p2 == null) {
+                        return 1;
+                    }
+                    if (p1.getX() < p2.getX()) {
+                        return -1;
+                    }
+                    if (p1.getX() > p2.getX()) {
+                        return 1;
+                    }
+                    if (p1.getY() < p2.getY()) {
+                        return -1;
+                    }
+                    if (p1.getY() > p2.getY()) {
+                        return 1;
+                    }
+                    if (p1.getWeight() < p2.getWeight()) {
+                        return -1;
+                    }
+                    if (p1.getWeight() > p2.getWeight()) {
+                        return 1;
+                    }
+                    return 0;
+                }
+            };
+
+            Arrays.sort(observations, cmp);
+            return observations;
+        }
+
+        /**
+         * Guesses the parameters based on the specified observed points.
+         *
+         * @param points Observed points, sorted.
+         * @return the guessed parameters (normalization factor, mean and
+         * sigma).
+         */
+        private double[] basicGuess(WeightedObservedPoint[] points) {
+            final int maxYIdx = findMaxY(points);
+            final double n = points[maxYIdx].getY();
+            final double m = points[maxYIdx].getX();
+
+            double fwhmApprox;
+            try {
+                final double halfY = n + ((m - n) / 2);
+                final double fwhmX1 = interpolateXAtY(points, maxYIdx, -1, halfY);
+                final double fwhmX2 = interpolateXAtY(points, maxYIdx, 1, halfY);
+                fwhmApprox = fwhmX2 - fwhmX1;
+            } catch (OutOfRangeException e) {
+                // TODO: Exceptions should not be used for flow control.
+                fwhmApprox = points[points.length - 1].getX() - points[0].getX();
+            }
+            final double s = fwhmApprox / (2 * FastMath.sqrt(2 * FastMath.log(2)));
+
+            return new double[] { n, m, s };
+        }
+
+        /**
+         * Finds index of point in specified points with the largest Y.
+         *
+         * @param points Points to search.
+         * @return the index in specified points array.
+         */
+        private int findMaxY(WeightedObservedPoint[] points) {
+            int maxYIdx = 0;
+            for (int i = 1; i < points.length; i++) {
+                if (points[i].getY() > points[maxYIdx].getY()) {
+                    maxYIdx = i;
+                }
+            }
+            return maxYIdx;
+        }
+
+        /**
+         * Interpolates using the specified points to determine X at the
+         * specified Y.
+         *
+         * @param points Points to use for interpolation.
+         * @param startIdx Index within points from which to start the search for
+         * interpolation bounds points.
+         * @param idxStep Index step for searching interpolation bounds points.
+         * @param y Y value for which X should be determined.
+         * @return the value of X for the specified Y.
+         * @throws ZeroException if {@code idxStep} is 0.
+         * @throws OutOfRangeException if specified {@code y} is not within the
+         * range of the specified {@code points}.
+         */
+        private double interpolateXAtY(WeightedObservedPoint[] points,
+                                       int startIdx,
+                                       int idxStep,
+                                       double y)
+            throws OutOfRangeException {
+            if (idxStep == 0) {
+                throw new ZeroException();
+            }
+            final WeightedObservedPoint[] twoPoints
+                = getInterpolationPointsForY(points, startIdx, idxStep, y);
+            final WeightedObservedPoint p1 = twoPoints[0];
+            final WeightedObservedPoint p2 = twoPoints[1];
+            if (p1.getY() == y) {
+                return p1.getX();
+            }
+            if (p2.getY() == y) {
+                return p2.getX();
+            }
+            return p1.getX() + (((y - p1.getY()) * (p2.getX() - p1.getX())) /
+                                (p2.getY() - p1.getY()));
+        }
+
+        /**
+         * Gets the two bounding interpolation points from the specified points
+         * suitable for determining X at the specified Y.
+         *
+         * @param points Points to use for interpolation.
+         * @param startIdx Index within points from which to start search for
+         * interpolation bounds points.
+         * @param idxStep Index step for search for interpolation bounds points.
+         * @param y Y value for which X should be determined.
+         * @return the array containing two points suitable for determining X at
+         * the specified Y.
+         * @throws ZeroException if {@code idxStep} is 0.
+         * @throws OutOfRangeException if specified {@code y} is not within the
+         * range of the specified {@code points}.
+         */
+        private WeightedObservedPoint[] getInterpolationPointsForY(WeightedObservedPoint[] points,
+                                                                   int startIdx,
+                                                                   int idxStep,
+                                                                   double y)
+            throws OutOfRangeException {
+            if (idxStep == 0) {
+                throw new ZeroException();
+            }
+            for (int i = startIdx;
+                 idxStep < 0 ? i + idxStep >= 0 : i + idxStep < points.length;
+                 i += idxStep) {
+                final WeightedObservedPoint p1 = points[i];
+                final WeightedObservedPoint p2 = points[i + idxStep];
+                if (isBetween(y, p1.getY(), p2.getY())) {
+                    if (idxStep < 0) {
+                        return new WeightedObservedPoint[] { p2, p1 };
+                    } else {
+                        return new WeightedObservedPoint[] { p1, p2 };
+                    }
+                }
+            }
+
+            // Boundaries are replaced by dummy values because the raised
+            // exception is caught and the message never displayed.
+            // TODO: Exceptions should not be used for flow control.
+            throw new OutOfRangeException(y,
+                                          Double.NEGATIVE_INFINITY,
+                                          Double.POSITIVE_INFINITY);
+        }
+
+        /**
+         * Determines whether a value is between two other values.
+         *
+         * @param value Value to test whether it is between {@code boundary1}
+         * and {@code boundary2}.
+         * @param boundary1 One end of the range.
+         * @param boundary2 Other end of the range.
+         * @return {@code true} if {@code value} is between {@code boundary1} and
+         * {@code boundary2} (inclusive), {@code false} otherwise.
+         */
+        private boolean isBetween(double value,
+                                  double boundary1,
+                                  double boundary2) {
+            return (value >= boundary1 && value <= boundary2) ||
+                (value >= boundary2 && value <= boundary1);
+        }
+    }
+}

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/GaussianFitter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/HarmonicFitter.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/HarmonicFitter.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/HarmonicFitter.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/HarmonicFitter.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,382 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.fitting;
+
+import org.apache.commons.math3.optim.nonlinear.vector.MultivariateVectorOptimizer;
+import org.apache.commons.math3.analysis.function.HarmonicOscillator;
+import org.apache.commons.math3.exception.ZeroException;
+import org.apache.commons.math3.exception.NumberIsTooSmallException;
+import org.apache.commons.math3.exception.MathIllegalStateException;
+import org.apache.commons.math3.exception.util.LocalizedFormats;
+import org.apache.commons.math3.util.FastMath;
+
+/**
+ * Class that implements a curve fitting specialized for sinusoids.
+ *
+ * Harmonic fitting is a very simple case of curve fitting. The
+ * estimated coefficients are the amplitude a, the pulsation &omega; and
+ * the phase &phi;: <code>f (t) = a cos (&omega; t + &phi;)</code>. They are
+ * searched by a least square estimator initialized with a rough guess
+ * based on integrals.
+ *
+ * @version $Id: HarmonicFitter.java 1416643 2012-12-03 19:37:14Z tn $
+ * @since 2.0
+ */
+public class HarmonicFitter extends CurveFitter<HarmonicOscillator.Parametric> {
+    /**
+     * Simple constructor.
+     * @param optimizer Optimizer to use for the fitting.
+     */
+    public HarmonicFitter(final MultivariateVectorOptimizer optimizer) {
+        super(optimizer);
+    }
+
+    /**
+     * Fit an harmonic function to the observed points.
+     *
+     * @param initialGuess First guess values in the following order:
+     * <ul>
+     *  <li>Amplitude</li>
+     *  <li>Angular frequency</li>
+     *  <li>Phase</li>
+     * </ul>
+     * @return the parameters of the harmonic function that best fits the
+     * observed points (in the same order as above).
+     */
+    public double[] fit(double[] initialGuess) {
+        return fit(new HarmonicOscillator.Parametric(), initialGuess);
+    }
+
+    /**
+     * Fit an harmonic function to the observed points.
+     * An initial guess will be automatically computed.
+     *
+     * @return the parameters of the harmonic function that best fits the
+     * observed points (see the other {@link #fit(double[]) fit} method.
+     * @throws NumberIsTooSmallException if the sample is too short for the
+     * the first guess to be computed.
+     * @throws ZeroException if the first guess cannot be computed because
+     * the abscissa range is zero.
+     */
+    public double[] fit() {
+        return fit((new ParameterGuesser(getObservations())).guess());
+    }
+
+    /**
+     * This class guesses harmonic coefficients from a sample.
+     * <p>The algorithm used to guess the coefficients is as follows:</p>
+     *
+     * <p>We know f (t) at some sampling points t<sub>i</sub> and want to find a,
+     * &omega; and &phi; such that f (t) = a cos (&omega; t + &phi;).
+     * </p>
+     *
+     * <p>From the analytical expression, we can compute two primitives :
+     * <pre>
+     *     If2  (t) = &int; f<sup>2</sup>  = a<sup>2</sup> &times; [t + S (t)] / 2
+     *     If'2 (t) = &int; f'<sup>2</sup> = a<sup>2</sup> &omega;<sup>2</sup> &times; [t - S (t)] / 2
+     *     where S (t) = sin (2 (&omega; t + &phi;)) / (2 &omega;)
+     * </pre>
+     * </p>
+     *
+     * <p>We can remove S between these expressions :
+     * <pre>
+     *     If'2 (t) = a<sup>2</sup> &omega;<sup>2</sup> t - &omega;<sup>2</sup> If2 (t)
+     * </pre>
+     * </p>
+     *
+     * <p>The preceding expression shows that If'2 (t) is a linear
+     * combination of both t and If2 (t): If'2 (t) = A &times; t + B &times; If2 (t)
+     * </p>
+     *
+     * <p>From the primitive, we can deduce the same form for definite
+     * integrals between t<sub>1</sub> and t<sub>i</sub> for each t<sub>i</sub> :
+     * <pre>
+     *   If2 (t<sub>i</sub>) - If2 (t<sub>1</sub>) = A &times; (t<sub>i</sub> - t<sub>1</sub>) + B &times; (If2 (t<sub>i</sub>) - If2 (t<sub>1</sub>))
+     * </pre>
+     * </p>
+     *
+     * <p>We can find the coefficients A and B that best fit the sample
+     * to this linear expression by computing the definite integrals for
+     * each sample points.
+     * </p>
+     *
+     * <p>For a bilinear expression z (x<sub>i</sub>, y<sub>i</sub>) = A &times; x<sub>i</sub> + B &times; y<sub>i</sub>, the
+     * coefficients A and B that minimize a least square criterion
+     * &sum; (z<sub>i</sub> - z (x<sub>i</sub>, y<sub>i</sub>))<sup>2</sup> are given by these expressions:</p>
+     * <pre>
+     *
+     *         &sum;y<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>z<sub>i</sub> - &sum;x<sub>i</sub>y<sub>i</sub> &sum;y<sub>i</sub>z<sub>i</sub>
+     *     A = ------------------------
+     *         &sum;x<sub>i</sub>x<sub>i</sub> &sum;y<sub>i</sub>y<sub>i</sub> - &sum;x<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>y<sub>i</sub>
+     *
+     *         &sum;x<sub>i</sub>x<sub>i</sub> &sum;y<sub>i</sub>z<sub>i</sub> - &sum;x<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>z<sub>i</sub>
+     *     B = ------------------------
+     *         &sum;x<sub>i</sub>x<sub>i</sub> &sum;y<sub>i</sub>y<sub>i</sub> - &sum;x<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>y<sub>i</sub>
+     * </pre>
+     * </p>
+     *
+     *
+     * <p>In fact, we can assume both a and &omega; are positive and
+     * compute them directly, knowing that A = a<sup>2</sup> &omega;<sup>2</sup> and that
+     * B = - &omega;<sup>2</sup>. The complete algorithm is therefore:</p>
+     * <pre>
+     *
+     * for each t<sub>i</sub> from t<sub>1</sub> to t<sub>n-1</sub>, compute:
+     *   f  (t<sub>i</sub>)
+     *   f' (t<sub>i</sub>) = (f (t<sub>i+1</sub>) - f(t<sub>i-1</sub>)) / (t<sub>i+1</sub> - t<sub>i-1</sub>)
+     *   x<sub>i</sub> = t<sub>i</sub> - t<sub>1</sub>
+     *   y<sub>i</sub> = &int; f<sup>2</sup> from t<sub>1</sub> to t<sub>i</sub>
+     *   z<sub>i</sub> = &int; f'<sup>2</sup> from t<sub>1</sub> to t<sub>i</sub>
+     *   update the sums &sum;x<sub>i</sub>x<sub>i</sub>, &sum;y<sub>i</sub>y<sub>i</sub>, &sum;x<sub>i</sub>y<sub>i</sub>, &sum;x<sub>i</sub>z<sub>i</sub> and &sum;y<sub>i</sub>z<sub>i</sub>
+     * end for
+     *
+     *            |--------------------------
+     *         \  | &sum;y<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>z<sub>i</sub> - &sum;x<sub>i</sub>y<sub>i</sub> &sum;y<sub>i</sub>z<sub>i</sub>
+     * a     =  \ | ------------------------
+     *           \| &sum;x<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>z<sub>i</sub> - &sum;x<sub>i</sub>x<sub>i</sub> &sum;y<sub>i</sub>z<sub>i</sub>
+     *
+     *
+     *            |--------------------------
+     *         \  | &sum;x<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>z<sub>i</sub> - &sum;x<sub>i</sub>x<sub>i</sub> &sum;y<sub>i</sub>z<sub>i</sub>
+     * &omega;     =  \ | ------------------------
+     *           \| &sum;x<sub>i</sub>x<sub>i</sub> &sum;y<sub>i</sub>y<sub>i</sub> - &sum;x<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>y<sub>i</sub>
+     *
+     * </pre>
+     * </p>
+     *
+     * <p>Once we know &omega;, we can compute:
+     * <pre>
+     *    fc = &omega; f (t) cos (&omega; t) - f' (t) sin (&omega; t)
+     *    fs = &omega; f (t) sin (&omega; t) + f' (t) cos (&omega; t)
+     * </pre>
+     * </p>
+     *
+     * <p>It appears that <code>fc = a &omega; cos (&phi;)</code> and
+     * <code>fs = -a &omega; sin (&phi;)</code>, so we can use these
+     * expressions to compute &phi;. The best estimate over the sample is
+     * given by averaging these expressions.
+     * </p>
+     *
+     * <p>Since integrals and means are involved in the preceding
+     * estimations, these operations run in O(n) time, where n is the
+     * number of measurements.</p>
+     */
+    public static class ParameterGuesser {
+        /** Amplitude. */
+        private final double a;
+        /** Angular frequency. */
+        private final double omega;
+        /** Phase. */
+        private final double phi;
+
+        /**
+         * Simple constructor.
+         *
+         * @param observations Sampled observations.
+         * @throws NumberIsTooSmallException if the sample is too short.
+         * @throws ZeroException if the abscissa range is zero.
+         * @throws MathIllegalStateException when the guessing procedure cannot
+         * produce sensible results.
+         */
+        public ParameterGuesser(WeightedObservedPoint[] observations) {
+            if (observations.length < 4) {
+                throw new NumberIsTooSmallException(LocalizedFormats.INSUFFICIENT_OBSERVED_POINTS_IN_SAMPLE,
+                                                    observations.length, 4, true);
+            }
+
+            final WeightedObservedPoint[] sorted = sortObservations(observations);
+
+            final double aOmega[] = guessAOmega(sorted);
+            a = aOmega[0];
+            omega = aOmega[1];
+
+            phi = guessPhi(sorted);
+        }
+
+        /**
+         * Gets an estimation of the parameters.
+         *
+         * @return the guessed parameters, in the following order:
+         * <ul>
+         *  <li>Amplitude</li>
+         *  <li>Angular frequency</li>
+         *  <li>Phase</li>
+         * </ul>
+         */
+        public double[] guess() {
+            return new double[] { a, omega, phi };
+        }
+
+        /**
+         * Sort the observations with respect to the abscissa.
+         *
+         * @param unsorted Input observations.
+         * @return the input observations, sorted.
+         */
+        private WeightedObservedPoint[] sortObservations(WeightedObservedPoint[] unsorted) {
+            final WeightedObservedPoint[] observations = unsorted.clone();
+
+            // Since the samples are almost always already sorted, this
+            // method is implemented as an insertion sort that reorders the
+            // elements in place. Insertion sort is very efficient in this case.
+            WeightedObservedPoint curr = observations[0];
+            for (int j = 1; j < observations.length; ++j) {
+                WeightedObservedPoint prec = curr;
+                curr = observations[j];
+                if (curr.getX() < prec.getX()) {
+                    // the current element should be inserted closer to the beginning
+                    int i = j - 1;
+                    WeightedObservedPoint mI = observations[i];
+                    while ((i >= 0) && (curr.getX() < mI.getX())) {
+                        observations[i + 1] = mI;
+                        if (i-- != 0) {
+                            mI = observations[i];
+                        }
+                    }
+                    observations[i + 1] = curr;
+                    curr = observations[j];
+                }
+            }
+
+            return observations;
+        }
+
+        /**
+         * Estimate a first guess of the amplitude and angular frequency.
+         * This method assumes that the {@link #sortObservations()} method
+         * has been called previously.
+         *
+         * @param observations Observations, sorted w.r.t. abscissa.
+         * @throws ZeroException if the abscissa range is zero.
+         * @throws MathIllegalStateException when the guessing procedure cannot
+         * produce sensible results.
+         * @return the guessed amplitude (at index 0) and circular frequency
+         * (at index 1).
+         */
+        private double[] guessAOmega(WeightedObservedPoint[] observations) {
+            final double[] aOmega = new double[2];
+
+            // initialize the sums for the linear model between the two integrals
+            double sx2 = 0;
+            double sy2 = 0;
+            double sxy = 0;
+            double sxz = 0;
+            double syz = 0;
+
+            double currentX = observations[0].getX();
+            double currentY = observations[0].getY();
+            double f2Integral = 0;
+            double fPrime2Integral = 0;
+            final double startX = currentX;
+            for (int i = 1; i < observations.length; ++i) {
+                // one step forward
+                final double previousX = currentX;
+                final double previousY = currentY;
+                currentX = observations[i].getX();
+                currentY = observations[i].getY();
+
+                // update the integrals of f<sup>2</sup> and f'<sup>2</sup>
+                // considering a linear model for f (and therefore constant f')
+                final double dx = currentX - previousX;
+                final double dy = currentY - previousY;
+                final double f2StepIntegral =
+                    dx * (previousY * previousY + previousY * currentY + currentY * currentY) / 3;
+                final double fPrime2StepIntegral = dy * dy / dx;
+
+                final double x = currentX - startX;
+                f2Integral += f2StepIntegral;
+                fPrime2Integral += fPrime2StepIntegral;
+
+                sx2 += x * x;
+                sy2 += f2Integral * f2Integral;
+                sxy += x * f2Integral;
+                sxz += x * fPrime2Integral;
+                syz += f2Integral * fPrime2Integral;
+            }
+
+            // compute the amplitude and pulsation coefficients
+            double c1 = sy2 * sxz - sxy * syz;
+            double c2 = sxy * sxz - sx2 * syz;
+            double c3 = sx2 * sy2 - sxy * sxy;
+            if ((c1 / c2 < 0) || (c2 / c3 < 0)) {
+                final int last = observations.length - 1;
+                // Range of the observations, assuming that the
+                // observations are sorted.
+                final double xRange = observations[last].getX() - observations[0].getX();
+                if (xRange == 0) {
+                    throw new ZeroException();
+                }
+                aOmega[1] = 2 * Math.PI / xRange;
+
+                double yMin = Double.POSITIVE_INFINITY;
+                double yMax = Double.NEGATIVE_INFINITY;
+                for (int i = 1; i < observations.length; ++i) {
+                    final double y = observations[i].getY();
+                    if (y < yMin) {
+                        yMin = y;
+                    }
+                    if (y > yMax) {
+                        yMax = y;
+                    }
+                }
+                aOmega[0] = 0.5 * (yMax - yMin);
+            } else {
+                if (c2 == 0) {
+                    // In some ill-conditioned cases (cf. MATH-844), the guesser
+                    // procedure cannot produce sensible results.
+                    throw new MathIllegalStateException(LocalizedFormats.ZERO_DENOMINATOR);
+                }
+
+                aOmega[0] = FastMath.sqrt(c1 / c2);
+                aOmega[1] = FastMath.sqrt(c2 / c3);
+            }
+
+            return aOmega;
+        }
+
+        /**
+         * Estimate a first guess of the phase.
+         *
+         * @param observations Observations, sorted w.r.t. abscissa.
+         * @return the guessed phase.
+         */
+        private double guessPhi(WeightedObservedPoint[] observations) {
+            // initialize the means
+            double fcMean = 0;
+            double fsMean = 0;
+
+            double currentX = observations[0].getX();
+            double currentY = observations[0].getY();
+            for (int i = 1; i < observations.length; ++i) {
+                // one step forward
+                final double previousX = currentX;
+                final double previousY = currentY;
+                currentX = observations[i].getX();
+                currentY = observations[i].getY();
+                final double currentYPrime = (currentY - previousY) / (currentX - previousX);
+
+                double omegaX = omega * currentX;
+                double cosine = FastMath.cos(omegaX);
+                double sine = FastMath.sin(omegaX);
+                fcMean += omega * currentY * cosine - currentYPrime * sine;
+                fsMean += omega * currentY * sine + currentYPrime * cosine;
+            }
+
+            return FastMath.atan2(-fsMean, fcMean);
+        }
+    }
+}

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/HarmonicFitter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/PolynomialFitter.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/PolynomialFitter.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/PolynomialFitter.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/PolynomialFitter.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.fitting;
+
+import org.apache.commons.math3.analysis.polynomials.PolynomialFunction;
+import org.apache.commons.math3.optim.nonlinear.vector.MultivariateVectorOptimizer;
+
+/**
+ * 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: PolynomialFitter.java 1416643 2012-12-03 19:37:14Z tn $
+ * @since 2.0
+ */
+public class PolynomialFitter extends CurveFitter<PolynomialFunction.Parametric> {
+    /**
+     * Simple constructor.
+     *
+     * @param optimizer Optimizer to use for the fitting.
+     */
+    public PolynomialFitter(MultivariateVectorOptimizer optimizer) {
+        super(optimizer);
+    }
+
+    /**
+     * 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.
+     * @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.
+     */
+    public double[] fit(double[] guess) {
+        return fit(new PolynomialFunction.Parametric(), guess);
+    }
+}

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/PolynomialFitter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/WeightedObservedPoint.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/WeightedObservedPoint.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/WeightedObservedPoint.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/WeightedObservedPoint.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.fitting;
+
+import java.io.Serializable;
+
+/**
+ * This class is a simple container for weighted observed point in
+ * {@link CurveFitter curve fitting}.
+ * <p>Instances of this class are guaranteed to be immutable.</p>
+ * @version $Id: WeightedObservedPoint.java 1416643 2012-12-03 19:37:14Z tn $
+ * @since 2.0
+ */
+public class WeightedObservedPoint implements Serializable {
+    /** Serializable version id. */
+    private static final long serialVersionUID = 5306874947404636157L;
+    /** Weight of the measurement in the fitting process. */
+    private final double weight;
+    /** Abscissa of the point. */
+    private final double x;
+    /** Observed value of the function at x. */
+    private final double y;
+
+    /**
+     * Simple constructor.
+     *
+     * @param weight Weight of the measurement in the fitting process.
+     * @param x Abscissa of the measurement.
+     * @param y Ordinate of the measurement.
+     */
+    public WeightedObservedPoint(final double weight, final double x, final double y) {
+        this.weight = weight;
+        this.x      = x;
+        this.y      = y;
+    }
+
+    /**
+     * Gets the weight of the measurement in the fitting process.
+     *
+     * @return the weight of the measurement in the fitting process.
+     */
+    public double getWeight() {
+        return weight;
+    }
+
+    /**
+     * Gets the abscissa of the point.
+     *
+     * @return the abscissa of the point.
+     */
+    public double getX() {
+        return x;
+    }
+
+    /**
+     * Gets the observed value of the function at x.
+     *
+     * @return the observed value of the function at x.
+     */
+    public double getY() {
+        return y;
+    }
+
+}
+

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/WeightedObservedPoint.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/package-info.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/package-info.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/package-info.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/package-info.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Classes to perform curve fitting.
+ *
+ * Curve fitting is a special case of a least squares problem
+ * were the parameters are the coefficients of a function {@code f}
+ * whose graph {@code y = f(x)} should pass through sample points, and
+ * were the objective function is the squared sum of the residuals
+ * <code>f(x<sub>i</sub>) - y<sub>i</sub></code> for observed points
+ * <code>(x<sub>i</sub>, y<sub>i</sub>)</code>.
+ */
+package org.apache.commons.math3.fitting;

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/AbstractConvergenceChecker.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/AbstractConvergenceChecker.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/AbstractConvergenceChecker.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/AbstractConvergenceChecker.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.optim;
+
+/**
+ * Base class for all convergence checker implementations.
+ *
+ * @param <PAIR> Type of (point, value) pair.
+ *
+ * @version $Id: AbstractConvergenceChecker.java 1370215 2012-08-07 12:38:59Z sebb $
+ * @since 3.0
+ */
+public abstract class AbstractConvergenceChecker<PAIR>
+    implements ConvergenceChecker<PAIR> {
+    /**
+     * Relative tolerance threshold.
+     */
+    private final double relativeThreshold;
+    /**
+     * Absolute tolerance threshold.
+     */
+    private final double absoluteThreshold;
+
+    /**
+     * Build an instance with a specified thresholds.
+     *
+     * @param relativeThreshold relative tolerance threshold
+     * @param absoluteThreshold absolute tolerance threshold
+     */
+    public AbstractConvergenceChecker(final double relativeThreshold,
+                                      final double absoluteThreshold) {
+        this.relativeThreshold = relativeThreshold;
+        this.absoluteThreshold = absoluteThreshold;
+    }
+
+    /**
+     * @return the relative threshold.
+     */
+    public double getRelativeThreshold() {
+        return relativeThreshold;
+    }
+
+    /**
+     * @return the absolute threshold.
+     */
+    public double getAbsoluteThreshold() {
+        return absoluteThreshold;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public abstract boolean converged(int iteration,
+                                      PAIR previous,
+                                      PAIR current);
+}

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/AbstractConvergenceChecker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/BaseMultiStartMultivariateOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/BaseMultiStartMultivariateOptimizer.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/BaseMultiStartMultivariateOptimizer.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/BaseMultiStartMultivariateOptimizer.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.optim;
+
+import org.apache.commons.math3.exception.MathIllegalStateException;
+import org.apache.commons.math3.exception.NotStrictlyPositiveException;
+import org.apache.commons.math3.exception.NullArgumentException;
+import org.apache.commons.math3.random.RandomVectorGenerator;
+import org.apache.commons.math3.optim.InitialGuess;
+
+/**
+ * Base class multi-start optimizer for a multivariate function.
+ * <br/>
+ * This class wraps an optimizer in order to use it several times in
+ * turn with different starting points (trying to avoid being trapped
+ * in a local extremum when looking for a global one).
+ * <em>It is not a "user" class.</em>
+ *
+ * @param <PAIR> Type of the point/value pair returned by the optimization
+ * algorithm.
+ *
+ * @version $Id$
+ * @since 3.0
+ */
+public abstract class BaseMultiStartMultivariateOptimizer<PAIR>
+    extends BaseMultivariateOptimizer<PAIR> {
+    /** Underlying classical optimizer. */
+    private final BaseMultivariateOptimizer<PAIR> optimizer;
+    /** Number of evaluations already performed for all starts. */
+    private int totalEvaluations;
+    /** Number of starts to go. */
+    private int starts;
+    /** Random generator for multi-start. */
+    private RandomVectorGenerator generator;
+    /** Optimization data. */
+    private OptimizationData[] optimData;
+    /**
+     * Location in {@link #optimData} where the updated maximum
+     * number of evaluations will be stored.
+     */
+    private int maxEvalIndex = -1;
+    /**
+     * Location in {@link #optimData} where the updated start value
+     * will be stored.
+     */
+    private int initialGuessIndex = -1;
+
+    /**
+     * Create a multi-start optimizer from a single-start optimizer.
+     *
+     * @param optimizer Single-start optimizer to wrap.
+     * @param starts Number of starts to perform. If {@code starts == 1},
+     * the {@link #optimize(OptimizationData[]) optimize} will return the
+     * same solution as the given {@code optimizer} would return.
+     * @param generator Random vector generator to use for restarts.
+     * @throws NullArgumentException if {@code optimizer} or {@code generator}
+     * is {@code null}.
+     * @throws NotStrictlyPositiveException if {@code starts < 1}.
+     */
+    public BaseMultiStartMultivariateOptimizer(final BaseMultivariateOptimizer<PAIR> optimizer,
+                                               final int starts,
+                                               final RandomVectorGenerator generator) {
+        super(optimizer.getConvergenceChecker());
+
+        if (optimizer == null ||
+            generator == null) {
+            throw new NullArgumentException();
+        }
+        if (starts < 1) {
+            throw new NotStrictlyPositiveException(starts);
+        }
+
+        this.optimizer = optimizer;
+        this.starts = starts;
+        this.generator = generator;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getEvaluations() {
+        return totalEvaluations;
+    }
+
+    /**
+     * Gets all the optima found during the last call to {@code optimize}.
+     * The optimizer stores all the optima found during a set of
+     * restarts. The {@code optimize} method returns the best point only.
+     * This method returns all the points found at the end of each starts,
+     * including the best one already returned by the {@code optimize} method.
+     * <br/>
+     * The returned array as one element for each start as specified
+     * in the constructor. It is ordered with the results from the
+     * runs that did converge first, sorted from best to worst
+     * objective value (i.e in ascending order if minimizing and in
+     * descending order if maximizing), followed by {@code null} elements
+     * corresponding to the runs that did not converge. This means all
+     * elements will be {@code null} if the {@code optimize} method did throw
+     * an exception.
+     * This also means that if the first element is not {@code null}, it is
+     * the best point found across all starts.
+     * <br/>
+     * The behaviour is undefined if this method is called before
+     * {@code optimize}; it will likely throw {@code NullPointerException}.
+     *
+     * @return an array containing the optima sorted from best to worst.
+     */
+    public abstract PAIR[] getOptima();
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws MathIllegalStateException if {@code optData} does not contain an
+     * instance of {@link MaxEval} or {@link InitialGuess}.
+     */
+    @Override
+    public PAIR optimize(OptimizationData... optData) {
+        // Store arguments in order to pass them to the internal optimizer.
+       optimData = optData;
+        // Set up base class and perform computations.
+        return super.optimize(optData);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected PAIR doOptimize() {
+        // Remove all instances of "MaxEval" and "InitialGuess" from the
+        // array that will be passed to the internal optimizer.
+        // The former is to enforce smaller numbers of allowed evaluations
+        // (according to how many have been used up already), and the latter
+        // to impose a different start value for each start.
+        for (int i = 0; i < optimData.length; i++) {
+            if (optimData[i] instanceof MaxEval) {
+                optimData[i] = null;
+                maxEvalIndex = i;
+            }
+            if (optimData[i] instanceof InitialGuess) {
+                optimData[i] = null;
+                initialGuessIndex = i;
+                continue;
+            }
+        }
+        if (maxEvalIndex == -1) {
+            throw new MathIllegalStateException();
+        }
+        if (initialGuessIndex == -1) {
+            throw new MathIllegalStateException();
+        }
+
+        RuntimeException lastException = null;
+        totalEvaluations = 0;
+        clear();
+
+        final int maxEval = getMaxEvaluations();
+        final double[] min = getLowerBound();
+        final double[] max = getUpperBound();
+        final double[] startPoint = getStartPoint();
+
+        // Multi-start loop.
+        for (int i = 0; i < starts; i++) {
+            // CHECKSTYLE: stop IllegalCatch
+            try {
+                // Decrease number of allowed evaluations.
+                optimData[maxEvalIndex] = new MaxEval(maxEval - totalEvaluations);
+                // New start value.
+                final double[] s = (i == 0) ?
+                    startPoint :
+                    generator.nextVector(); // XXX This does not enforce bounds!
+                optimData[initialGuessIndex] = new InitialGuess(s);
+                // Optimize.
+                final PAIR result = optimizer.optimize(optimData);
+                store(result);
+            } catch (RuntimeException mue) {
+                lastException = mue;
+            }
+            // CHECKSTYLE: resume IllegalCatch
+
+            totalEvaluations += optimizer.getEvaluations();
+        }
+
+        final PAIR[] optima = getOptima();
+        if (optima.length == 0) {
+            // All runs failed.
+            throw lastException; // Cannot be null if starts >= 1.
+        }
+
+        // Return the best optimum.
+        return optima[0];
+    }
+
+    /**
+     * Method that will be called in order to store each found optimum.
+     *
+     * @param optimum Result of an optimization run.
+     */
+    protected abstract void store(PAIR optimum);
+    /**
+     * Method that will called in order to clear all stored optima.
+     */
+    protected abstract void clear();
+}

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optim/BaseMultiStartMultivariateOptimizer.java
------------------------------------------------------------------------------
    svn:eol-style = native