1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.math.optimization.general;
19
20 import org.apache.commons.math.FunctionEvaluationException;
21 import org.apache.commons.math.MaxEvaluationsExceededException;
22 import org.apache.commons.math.MaxIterationsExceededException;
23 import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction;
24 import org.apache.commons.math.analysis.MultivariateVectorialFunction;
25 import org.apache.commons.math.optimization.GoalType;
26 import org.apache.commons.math.optimization.OptimizationException;
27 import org.apache.commons.math.optimization.RealConvergenceChecker;
28 import org.apache.commons.math.optimization.DifferentiableMultivariateRealOptimizer;
29 import org.apache.commons.math.optimization.RealPointValuePair;
30 import org.apache.commons.math.optimization.SimpleScalarValueChecker;
31
32 /**
33 * Base class for implementing optimizers for multivariate scalar functions.
34 * <p>This base class handles the boilerplate methods associated to thresholds
35 * settings, iterations and evaluations counting.</p>
36 * @version $Revision: 786466 $ $Date: 2009-06-19 08:03:14 -0400 (Fri, 19 Jun 2009) $
37 * @since 2.0
38 */
39 public abstract class AbstractScalarDifferentiableOptimizer
40 implements DifferentiableMultivariateRealOptimizer {
41
42 /** Default maximal number of iterations allowed. */
43 public static final int DEFAULT_MAX_ITERATIONS = 100;
44
45 /** Maximal number of iterations allowed. */
46 private int maxIterations;
47
48 /** Number of iterations already performed. */
49 private int iterations;
50
51 /** Maximal number of evaluations allowed. */
52 private int maxEvaluations;
53
54 /** Number of evaluations already performed. */
55 private int evaluations;
56
57 /** Number of gradient evaluations. */
58 private int gradientEvaluations;
59
60 /** Convergence checker. */
61 protected RealConvergenceChecker checker;
62
63 /** Objective function. */
64 private DifferentiableMultivariateRealFunction f;
65
66 /** Objective function gradient. */
67 private MultivariateVectorialFunction gradient;
68
69 /** Type of optimization. */
70 protected GoalType goalType;
71
72 /** Current point set. */
73 protected double[] point;
74
75 /** Simple constructor with default settings.
76 * <p>The convergence check is set to a {@link SimpleScalarValueChecker}
77 * and the maximal number of evaluation is set to its default value.</p>
78 */
79 protected AbstractScalarDifferentiableOptimizer() {
80 setConvergenceChecker(new SimpleScalarValueChecker());
81 setMaxIterations(DEFAULT_MAX_ITERATIONS);
82 setMaxEvaluations(Integer.MAX_VALUE);
83 }
84
85 /** {@inheritDoc} */
86 public void setMaxIterations(int maxIterations) {
87 this.maxIterations = maxIterations;
88 }
89
90 /** {@inheritDoc} */
91 public int getMaxIterations() {
92 return maxIterations;
93 }
94
95 /** {@inheritDoc} */
96 public int getIterations() {
97 return iterations;
98 }
99
100 /** {@inheritDoc} */
101 public void setMaxEvaluations(int maxEvaluations) {
102 this.maxEvaluations = maxEvaluations;
103 }
104
105 /** {@inheritDoc} */
106 public int getMaxEvaluations() {
107 return maxEvaluations;
108 }
109
110 /** {@inheritDoc} */
111 public int getEvaluations() {
112 return evaluations;
113 }
114
115 /** {@inheritDoc} */
116 public int getGradientEvaluations() {
117 return gradientEvaluations;
118 }
119
120 /** {@inheritDoc} */
121 public void setConvergenceChecker(RealConvergenceChecker checker) {
122 this.checker = checker;
123 }
124
125 /** {@inheritDoc} */
126 public RealConvergenceChecker getConvergenceChecker() {
127 return checker;
128 }
129
130 /** Increment the iterations counter by 1.
131 * @exception OptimizationException if the maximal number
132 * of iterations is exceeded
133 */
134 protected void incrementIterationsCounter()
135 throws OptimizationException {
136 if (++iterations > maxIterations) {
137 throw new OptimizationException(new MaxIterationsExceededException(maxIterations));
138 }
139 }
140
141 /**
142 * Compute the gradient vector.
143 * @param point point at which the gradient must be evaluated
144 * @return gradient at the specified point
145 * @exception FunctionEvaluationException if the function gradient
146 */
147 protected double[] computeObjectiveGradient(final double[] point)
148 throws FunctionEvaluationException {
149 ++gradientEvaluations;
150 return gradient.value(point);
151 }
152
153 /**
154 * Compute the objective function value.
155 * @param point point at which the objective function must be evaluated
156 * @return objective function value at specified point
157 * @exception FunctionEvaluationException if the function cannot be evaluated
158 * or its dimension doesn't match problem dimension or the maximal number
159 * of iterations is exceeded
160 */
161 protected double computeObjectiveValue(final double[] point)
162 throws FunctionEvaluationException {
163 if (++evaluations > maxEvaluations) {
164 throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations),
165 point);
166 }
167 return f.value(point);
168 }
169
170 /** {@inheritDoc} */
171 public RealPointValuePair optimize(final DifferentiableMultivariateRealFunction f,
172 final GoalType goalType,
173 final double[] startPoint)
174 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {
175
176 // reset counters
177 iterations = 0;
178 evaluations = 0;
179 gradientEvaluations = 0;
180
181 // store optimization problem characteristics
182 this.f = f;
183 gradient = f.gradient();
184 this.goalType = goalType;
185 point = startPoint.clone();
186
187 return doOptimize();
188
189 }
190
191 /** Perform the bulk of optimization algorithm.
192 * @return the point/value pair giving the optimal value for objective function
193 * @exception FunctionEvaluationException if the objective function throws one during
194 * the search
195 * @exception OptimizationException if the algorithm failed to converge
196 * @exception IllegalArgumentException if the start point dimension is wrong
197 */
198 abstract protected RealPointValuePair doOptimize()
199 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException;
200
201 }