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 }