/* * 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.math.optimization.general; import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction; import org.apache.commons.math.analysis.MultivariateVectorialFunction; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MaxEvaluationsExceededException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.optimization.DifferentiableMultivariateRealOptimizer; import org.apache.commons.math.optimization.GoalType; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.RealConvergenceChecker; import org.apache.commons.math.optimization.RealPointValuePair; import org.apache.commons.math.optimization.SimpleScalarValueChecker; /** * Base class for implementing optimizers for multivariate scalar functions. * <p>This base class handles the boilerplate methods associated to thresholds * settings, iterations and evaluations counting.</p> * @version $Revision: 1069567 $ $Date: 2011-02-10 22:07:26 +0100 (jeu. 10 févr. 2011) $ * @since 2.0 */ public abstract class AbstractScalarDifferentiableOptimizer implements DifferentiableMultivariateRealOptimizer { /** Default maximal number of iterations allowed. */ public static final int DEFAULT_MAX_ITERATIONS = 100; /** Convergence checker. */ @Deprecated protected RealConvergenceChecker checker; /** * Type of optimization. * @since 2.1 */ @Deprecated protected GoalType goal; /** Current point set. */ @Deprecated protected double[] point; /** Maximal number of iterations allowed. */ private int maxIterations; /** Number of iterations already performed. */ private int iterations; /** Maximal number of evaluations allowed. */ private int maxEvaluations; /** Number of evaluations already performed. */ private int evaluations; /** Number of gradient evaluations. */ private int gradientEvaluations; /** Objective function. */ private DifferentiableMultivariateRealFunction function; /** Objective function gradient. */ private MultivariateVectorialFunction gradient; /** Simple constructor with default settings. * <p>The convergence check is set to a {@link SimpleScalarValueChecker} * and the maximal number of evaluation is set to its default value.</p> */ protected AbstractScalarDifferentiableOptimizer() { setConvergenceChecker(new SimpleScalarValueChecker()); setMaxIterations(DEFAULT_MAX_ITERATIONS); setMaxEvaluations(Integer.MAX_VALUE); } /** {@inheritDoc} */ public void setMaxIterations(int maxIterations) { this.maxIterations = maxIterations; } /** {@inheritDoc} */ public int getMaxIterations() { return maxIterations; } /** {@inheritDoc} */ public int getIterations() { return iterations; } /** {@inheritDoc} */ public void setMaxEvaluations(int maxEvaluations) { this.maxEvaluations = maxEvaluations; } /** {@inheritDoc} */ public int getMaxEvaluations() { return maxEvaluations; } /** {@inheritDoc} */ public int getEvaluations() { return evaluations; } /** {@inheritDoc} */ public int getGradientEvaluations() { return gradientEvaluations; } /** {@inheritDoc} */ public void setConvergenceChecker(RealConvergenceChecker convergenceChecker) { this.checker = convergenceChecker; } /** {@inheritDoc} */ public RealConvergenceChecker getConvergenceChecker() { return checker; } /** Increment the iterations counter by 1. * @exception OptimizationException if the maximal number * of iterations is exceeded */ protected void incrementIterationsCounter() throws OptimizationException { if (++iterations > maxIterations) { throw new OptimizationException(new MaxIterationsExceededException(maxIterations)); } } /** * Compute the gradient vector. * @param evaluationPoint point at which the gradient must be evaluated * @return gradient at the specified point * @exception FunctionEvaluationException if the function gradient */ protected double[] computeObjectiveGradient(final double[] evaluationPoint) throws FunctionEvaluationException { ++gradientEvaluations; return gradient.value(evaluationPoint); } /** * Compute the objective function value. * @param evaluationPoint point at which the objective function must be evaluated * @return objective function value at specified point * @exception FunctionEvaluationException if the function cannot be evaluated * or its dimension doesn't match problem dimension or the maximal number * of iterations is exceeded */ protected double computeObjectiveValue(final double[] evaluationPoint) throws FunctionEvaluationException { if (++evaluations > maxEvaluations) { throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), evaluationPoint); } return function.value(evaluationPoint); } /** {@inheritDoc} */ public RealPointValuePair optimize(final DifferentiableMultivariateRealFunction f, final GoalType goalType, final double[] startPoint) throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { // reset counters iterations = 0; evaluations = 0; gradientEvaluations = 0; // store optimization problem characteristics function = f; gradient = f.gradient(); goal = goalType; point = startPoint.clone(); return doOptimize(); } /** Perform the bulk of optimization algorithm. * @return the point/value pair giving the optimal value for objective function * @exception FunctionEvaluationException if the objective function throws one during * the search * @exception OptimizationException if the algorithm failed to converge * @exception IllegalArgumentException if the start point dimension is wrong */ protected abstract RealPointValuePair doOptimize() throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; }