View Javadoc

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 }