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.FunctionEvaluationException; 021 import org.apache.commons.math.MaxEvaluationsExceededException; 022 import org.apache.commons.math.MaxIterationsExceededException; 023 import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction; 024 import org.apache.commons.math.analysis.MultivariateVectorialFunction; 025 import org.apache.commons.math.optimization.GoalType; 026 import org.apache.commons.math.optimization.OptimizationException; 027 import org.apache.commons.math.optimization.RealConvergenceChecker; 028 import org.apache.commons.math.optimization.DifferentiableMultivariateRealOptimizer; 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: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ 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 protected RealConvergenceChecker checker; 047 048 /** 049 * Type of optimization. 050 * @since 2.1 051 */ 052 protected GoalType goal; 053 054 /** Current point set. */ 055 protected double[] point; 056 057 /** Maximal number of iterations allowed. */ 058 private int maxIterations; 059 060 /** Number of iterations already performed. */ 061 private int iterations; 062 063 /** Maximal number of evaluations allowed. */ 064 private int maxEvaluations; 065 066 /** Number of evaluations already performed. */ 067 private int evaluations; 068 069 /** Number of gradient evaluations. */ 070 private int gradientEvaluations; 071 072 /** Objective function. */ 073 private DifferentiableMultivariateRealFunction function; 074 075 /** Objective function gradient. */ 076 private MultivariateVectorialFunction gradient; 077 078 /** Simple constructor with default settings. 079 * <p>The convergence check is set to a {@link SimpleScalarValueChecker} 080 * and the maximal number of evaluation is set to its default value.</p> 081 */ 082 protected AbstractScalarDifferentiableOptimizer() { 083 setConvergenceChecker(new SimpleScalarValueChecker()); 084 setMaxIterations(DEFAULT_MAX_ITERATIONS); 085 setMaxEvaluations(Integer.MAX_VALUE); 086 } 087 088 /** {@inheritDoc} */ 089 public void setMaxIterations(int maxIterations) { 090 this.maxIterations = maxIterations; 091 } 092 093 /** {@inheritDoc} */ 094 public int getMaxIterations() { 095 return maxIterations; 096 } 097 098 /** {@inheritDoc} */ 099 public int getIterations() { 100 return iterations; 101 } 102 103 /** {@inheritDoc} */ 104 public void setMaxEvaluations(int maxEvaluations) { 105 this.maxEvaluations = maxEvaluations; 106 } 107 108 /** {@inheritDoc} */ 109 public int getMaxEvaluations() { 110 return maxEvaluations; 111 } 112 113 /** {@inheritDoc} */ 114 public int getEvaluations() { 115 return evaluations; 116 } 117 118 /** {@inheritDoc} */ 119 public int getGradientEvaluations() { 120 return gradientEvaluations; 121 } 122 123 /** {@inheritDoc} */ 124 public void setConvergenceChecker(RealConvergenceChecker convergenceChecker) { 125 this.checker = convergenceChecker; 126 } 127 128 /** {@inheritDoc} */ 129 public RealConvergenceChecker getConvergenceChecker() { 130 return checker; 131 } 132 133 /** Increment the iterations counter by 1. 134 * @exception OptimizationException if the maximal number 135 * of iterations is exceeded 136 */ 137 protected void incrementIterationsCounter() 138 throws OptimizationException { 139 if (++iterations > maxIterations) { 140 throw new OptimizationException(new MaxIterationsExceededException(maxIterations)); 141 } 142 } 143 144 /** 145 * Compute the gradient vector. 146 * @param evaluationPoint point at which the gradient must be evaluated 147 * @return gradient at the specified point 148 * @exception FunctionEvaluationException if the function gradient 149 */ 150 protected double[] computeObjectiveGradient(final double[] evaluationPoint) 151 throws FunctionEvaluationException { 152 ++gradientEvaluations; 153 return gradient.value(evaluationPoint); 154 } 155 156 /** 157 * Compute the objective function value. 158 * @param evaluationPoint point at which the objective function must be evaluated 159 * @return objective function value at specified point 160 * @exception FunctionEvaluationException if the function cannot be evaluated 161 * or its dimension doesn't match problem dimension or the maximal number 162 * of iterations is exceeded 163 */ 164 protected double computeObjectiveValue(final double[] evaluationPoint) 165 throws FunctionEvaluationException { 166 if (++evaluations > maxEvaluations) { 167 throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), 168 evaluationPoint); 169 } 170 return function.value(evaluationPoint); 171 } 172 173 /** {@inheritDoc} */ 174 public RealPointValuePair optimize(final DifferentiableMultivariateRealFunction f, 175 final GoalType goalType, 176 final double[] startPoint) 177 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { 178 179 // reset counters 180 iterations = 0; 181 evaluations = 0; 182 gradientEvaluations = 0; 183 184 // store optimization problem characteristics 185 function = f; 186 gradient = f.gradient(); 187 goal = goalType; 188 point = startPoint.clone(); 189 190 return doOptimize(); 191 192 } 193 194 /** Perform the bulk of optimization algorithm. 195 * @return the point/value pair giving the optimal value for objective function 196 * @exception FunctionEvaluationException if the objective function throws one during 197 * the search 198 * @exception OptimizationException if the algorithm failed to converge 199 * @exception IllegalArgumentException if the start point dimension is wrong 200 */ 201 protected abstract RealPointValuePair doOptimize() 202 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; 203 204 }