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.analysis.DifferentiableMultivariateRealFunction;
21 import org.apache.commons.math.analysis.MultivariateVectorialFunction;
22 import org.apache.commons.math.FunctionEvaluationException;
23 import org.apache.commons.math.MaxEvaluationsExceededException;
24 import org.apache.commons.math.MaxIterationsExceededException;
25 import org.apache.commons.math.optimization.DifferentiableMultivariateRealOptimizer;
26 import org.apache.commons.math.optimization.GoalType;
27 import org.apache.commons.math.optimization.OptimizationException;
28 import org.apache.commons.math.optimization.RealConvergenceChecker;
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: 1069567 $ $Date: 2011-02-10 22:07:26 +0100 (jeu. 10 févr. 2011) $
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     /** Convergence checker. */
46     @Deprecated
47     protected RealConvergenceChecker checker;
48 
49     /**
50      * Type of optimization.
51      * @since 2.1
52      */
53     @Deprecated
54     protected GoalType goal;
55 
56     /** Current point set. */
57     @Deprecated
58     protected double[] point;
59 
60     /** Maximal number of iterations allowed. */
61     private int maxIterations;
62 
63     /** Number of iterations already performed. */
64     private int iterations;
65 
66     /** Maximal number of evaluations allowed. */
67     private int maxEvaluations;
68 
69     /** Number of evaluations already performed. */
70     private int evaluations;
71 
72     /** Number of gradient evaluations. */
73     private int gradientEvaluations;
74 
75     /** Objective function. */
76     private DifferentiableMultivariateRealFunction function;
77 
78     /** Objective function gradient. */
79     private MultivariateVectorialFunction gradient;
80 
81     /** Simple constructor with default settings.
82      * <p>The convergence check is set to a {@link SimpleScalarValueChecker}
83      * and the maximal number of evaluation is set to its default value.</p>
84      */
AbstractScalarDifferentiableOptimizer()85     protected AbstractScalarDifferentiableOptimizer() {
86         setConvergenceChecker(new SimpleScalarValueChecker());
87         setMaxIterations(DEFAULT_MAX_ITERATIONS);
88         setMaxEvaluations(Integer.MAX_VALUE);
89     }
90 
91     /** {@inheritDoc} */
setMaxIterations(int maxIterations)92     public void setMaxIterations(int maxIterations) {
93         this.maxIterations = maxIterations;
94     }
95 
96     /** {@inheritDoc} */
getMaxIterations()97     public int getMaxIterations() {
98         return maxIterations;
99     }
100 
101     /** {@inheritDoc} */
getIterations()102     public int getIterations() {
103         return iterations;
104     }
105 
106     /** {@inheritDoc} */
setMaxEvaluations(int maxEvaluations)107     public void setMaxEvaluations(int maxEvaluations) {
108         this.maxEvaluations = maxEvaluations;
109     }
110 
111     /** {@inheritDoc} */
getMaxEvaluations()112     public int getMaxEvaluations() {
113         return maxEvaluations;
114     }
115 
116     /** {@inheritDoc} */
getEvaluations()117     public int getEvaluations() {
118         return evaluations;
119     }
120 
121     /** {@inheritDoc} */
getGradientEvaluations()122     public int getGradientEvaluations() {
123         return gradientEvaluations;
124     }
125 
126     /** {@inheritDoc} */
setConvergenceChecker(RealConvergenceChecker convergenceChecker)127     public void setConvergenceChecker(RealConvergenceChecker convergenceChecker) {
128         this.checker = convergenceChecker;
129     }
130 
131     /** {@inheritDoc} */
getConvergenceChecker()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      */
incrementIterationsCounter()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      */
computeObjectiveGradient(final double[] evaluationPoint)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      */
computeObjectiveValue(final double[] evaluationPoint)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} */
optimize(final DifferentiableMultivariateRealFunction f, final GoalType goalType, final double[] startPoint)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      */
doOptimize()204     protected abstract RealPointValuePair doOptimize()
205         throws FunctionEvaluationException, OptimizationException, IllegalArgumentException;
206 
207 }
208