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 ∑(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 ω and
+ * the phase φ: <code>f (t) = a cos (ω t + φ)</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,
+ * ω and φ such that f (t) = a cos (ω t + φ).
+ * </p>
+ *
+ * <p>From the analytical expression, we can compute two primitives :
+ * <pre>
+ * If2 (t) = ∫ f<sup>2</sup> = a<sup>2</sup> × [t + S (t)] / 2
+ * If'2 (t) = ∫ f'<sup>2</sup> = a<sup>2</sup> ω<sup>2</sup> × [t - S (t)] / 2
+ * where S (t) = sin (2 (ω t + φ)) / (2 ω)
+ * </pre>
+ * </p>
+ *
+ * <p>We can remove S between these expressions :
+ * <pre>
+ * If'2 (t) = a<sup>2</sup> ω<sup>2</sup> t - ω<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 × t + B × 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 × (t<sub>i</sub> - t<sub>1</sub>) + B × (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 × x<sub>i</sub> + B × y<sub>i</sub>, the
+ * coefficients A and B that minimize a least square criterion
+ * ∑ (z<sub>i</sub> - z (x<sub>i</sub>, y<sub>i</sub>))<sup>2</sup> are given by these expressions:</p>
+ * <pre>
+ *
+ * ∑y<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>z<sub>i</sub> - ∑x<sub>i</sub>y<sub>i</sub> ∑y<sub>i</sub>z<sub>i</sub>
+ * A = ------------------------
+ * ∑x<sub>i</sub>x<sub>i</sub> ∑y<sub>i</sub>y<sub>i</sub> - ∑x<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>y<sub>i</sub>
+ *
+ * ∑x<sub>i</sub>x<sub>i</sub> ∑y<sub>i</sub>z<sub>i</sub> - ∑x<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>z<sub>i</sub>
+ * B = ------------------------
+ * ∑x<sub>i</sub>x<sub>i</sub> ∑y<sub>i</sub>y<sub>i</sub> - ∑x<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>y<sub>i</sub>
+ * </pre>
+ * </p>
+ *
+ *
+ * <p>In fact, we can assume both a and ω are positive and
+ * compute them directly, knowing that A = a<sup>2</sup> ω<sup>2</sup> and that
+ * B = - ω<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> = ∫ f<sup>2</sup> from t<sub>1</sub> to t<sub>i</sub>
+ * z<sub>i</sub> = ∫ f'<sup>2</sup> from t<sub>1</sub> to t<sub>i</sub>
+ * update the sums ∑x<sub>i</sub>x<sub>i</sub>, ∑y<sub>i</sub>y<sub>i</sub>, ∑x<sub>i</sub>y<sub>i</sub>, ∑x<sub>i</sub>z<sub>i</sub> and ∑y<sub>i</sub>z<sub>i</sub>
+ * end for
+ *
+ * |--------------------------
+ * \ | ∑y<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>z<sub>i</sub> - ∑x<sub>i</sub>y<sub>i</sub> ∑y<sub>i</sub>z<sub>i</sub>
+ * a = \ | ------------------------
+ * \| ∑x<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>z<sub>i</sub> - ∑x<sub>i</sub>x<sub>i</sub> ∑y<sub>i</sub>z<sub>i</sub>
+ *
+ *
+ * |--------------------------
+ * \ | ∑x<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>z<sub>i</sub> - ∑x<sub>i</sub>x<sub>i</sub> ∑y<sub>i</sub>z<sub>i</sub>
+ * ω = \ | ------------------------
+ * \| ∑x<sub>i</sub>x<sub>i</sub> ∑y<sub>i</sub>y<sub>i</sub> - ∑x<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>y<sub>i</sub>
+ *
+ * </pre>
+ * </p>
+ *
+ * <p>Once we know ω, we can compute:
+ * <pre>
+ * fc = ω f (t) cos (ω t) - f' (t) sin (ω t)
+ * fs = ω f (t) sin (ω t) + f' (t) cos (ω t)
+ * </pre>
+ * </p>
+ *
+ * <p>It appears that <code>fc = a ω cos (φ)</code> and
+ * <code>fs = -a ω sin (φ)</code>, so we can use these
+ * expressions to compute φ. 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