001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.commons.math.optimization.general; 019 020 import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction; 021 import org.apache.commons.math.analysis.MultivariateVectorialFunction; 022 import org.apache.commons.math.FunctionEvaluationException; 023 import org.apache.commons.math.MaxEvaluationsExceededException; 024 import org.apache.commons.math.MaxIterationsExceededException; 025 import org.apache.commons.math.optimization.DifferentiableMultivariateRealOptimizer; 026 import org.apache.commons.math.optimization.GoalType; 027 import org.apache.commons.math.optimization.OptimizationException; 028 import org.apache.commons.math.optimization.RealConvergenceChecker; 029 import org.apache.commons.math.optimization.RealPointValuePair; 030 import org.apache.commons.math.optimization.SimpleScalarValueChecker; 031 032 /** 033 * Base class for implementing optimizers for multivariate scalar functions. 034 * <p>This base class handles the boilerplate methods associated to thresholds 035 * settings, iterations and evaluations counting.</p> 036 * @version $Revision: 1069567 $ $Date: 2011-02-10 22:07:26 +0100 (jeu. 10 f??vr. 2011) $ 037 * @since 2.0 038 */ 039 public abstract class AbstractScalarDifferentiableOptimizer 040 implements DifferentiableMultivariateRealOptimizer { 041 042 /** Default maximal number of iterations allowed. */ 043 public static final int DEFAULT_MAX_ITERATIONS = 100; 044 045 /** Convergence checker. */ 046 @Deprecated 047 protected RealConvergenceChecker checker; 048 049 /** 050 * Type of optimization. 051 * @since 2.1 052 */ 053 @Deprecated 054 protected GoalType goal; 055 056 /** Current point set. */ 057 @Deprecated 058 protected double[] point; 059 060 /** Maximal number of iterations allowed. */ 061 private int maxIterations; 062 063 /** Number of iterations already performed. */ 064 private int iterations; 065 066 /** Maximal number of evaluations allowed. */ 067 private int maxEvaluations; 068 069 /** Number of evaluations already performed. */ 070 private int evaluations; 071 072 /** Number of gradient evaluations. */ 073 private int gradientEvaluations; 074 075 /** Objective function. */ 076 private DifferentiableMultivariateRealFunction function; 077 078 /** Objective function gradient. */ 079 private MultivariateVectorialFunction gradient; 080 081 /** Simple constructor with default settings. 082 * <p>The convergence check is set to a {@link SimpleScalarValueChecker} 083 * and the maximal number of evaluation is set to its default value.</p> 084 */ 085 protected AbstractScalarDifferentiableOptimizer() { 086 setConvergenceChecker(new SimpleScalarValueChecker()); 087 setMaxIterations(DEFAULT_MAX_ITERATIONS); 088 setMaxEvaluations(Integer.MAX_VALUE); 089 } 090 091 /** {@inheritDoc} */ 092 public void setMaxIterations(int maxIterations) { 093 this.maxIterations = maxIterations; 094 } 095 096 /** {@inheritDoc} */ 097 public int getMaxIterations() { 098 return maxIterations; 099 } 100 101 /** {@inheritDoc} */ 102 public int getIterations() { 103 return iterations; 104 } 105 106 /** {@inheritDoc} */ 107 public void setMaxEvaluations(int maxEvaluations) { 108 this.maxEvaluations = maxEvaluations; 109 } 110 111 /** {@inheritDoc} */ 112 public int getMaxEvaluations() { 113 return maxEvaluations; 114 } 115 116 /** {@inheritDoc} */ 117 public int getEvaluations() { 118 return evaluations; 119 } 120 121 /** {@inheritDoc} */ 122 public int getGradientEvaluations() { 123 return gradientEvaluations; 124 } 125 126 /** {@inheritDoc} */ 127 public void setConvergenceChecker(RealConvergenceChecker convergenceChecker) { 128 this.checker = convergenceChecker; 129 } 130 131 /** {@inheritDoc} */ 132 public RealConvergenceChecker getConvergenceChecker() { 133 return checker; 134 } 135 136 /** Increment the iterations counter by 1. 137 * @exception OptimizationException if the maximal number 138 * of iterations is exceeded 139 */ 140 protected void incrementIterationsCounter() 141 throws OptimizationException { 142 if (++iterations > maxIterations) { 143 throw new OptimizationException(new MaxIterationsExceededException(maxIterations)); 144 } 145 } 146 147 /** 148 * Compute the gradient vector. 149 * @param evaluationPoint point at which the gradient must be evaluated 150 * @return gradient at the specified point 151 * @exception FunctionEvaluationException if the function gradient 152 */ 153 protected double[] computeObjectiveGradient(final double[] evaluationPoint) 154 throws FunctionEvaluationException { 155 ++gradientEvaluations; 156 return gradient.value(evaluationPoint); 157 } 158 159 /** 160 * Compute the objective function value. 161 * @param evaluationPoint point at which the objective function must be evaluated 162 * @return objective function value at specified point 163 * @exception FunctionEvaluationException if the function cannot be evaluated 164 * or its dimension doesn't match problem dimension or the maximal number 165 * of iterations is exceeded 166 */ 167 protected double computeObjectiveValue(final double[] evaluationPoint) 168 throws FunctionEvaluationException { 169 if (++evaluations > maxEvaluations) { 170 throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), 171 evaluationPoint); 172 } 173 return function.value(evaluationPoint); 174 } 175 176 /** {@inheritDoc} */ 177 public RealPointValuePair optimize(final DifferentiableMultivariateRealFunction f, 178 final GoalType goalType, 179 final double[] startPoint) 180 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { 181 182 // reset counters 183 iterations = 0; 184 evaluations = 0; 185 gradientEvaluations = 0; 186 187 // store optimization problem characteristics 188 function = f; 189 gradient = f.gradient(); 190 goal = goalType; 191 point = startPoint.clone(); 192 193 return doOptimize(); 194 195 } 196 197 /** Perform the bulk of optimization algorithm. 198 * @return the point/value pair giving the optimal value for objective function 199 * @exception FunctionEvaluationException if the objective function throws one during 200 * the search 201 * @exception OptimizationException if the algorithm failed to converge 202 * @exception IllegalArgumentException if the start point dimension is wrong 203 */ 204 protected abstract RealPointValuePair doOptimize() 205 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; 206 207 }