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.univariate; 19 20 import org.apache.commons.math.ConvergingAlgorithmImpl; 21 import org.apache.commons.math.FunctionEvaluationException; 22 import org.apache.commons.math.MaxEvaluationsExceededException; 23 import org.apache.commons.math.MaxIterationsExceededException; 24 import org.apache.commons.math.analysis.UnivariateRealFunction; 25 import org.apache.commons.math.exception.MathUnsupportedOperationException; 26 import org.apache.commons.math.exception.NoDataException; 27 import org.apache.commons.math.exception.util.LocalizedFormats; 28 import org.apache.commons.math.optimization.GoalType; 29 import org.apache.commons.math.optimization.UnivariateRealOptimizer; 30 31 /** 32 * Provide a default implementation for several functions useful to generic 33 * optimizers. 34 * 35 * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 fvr. 2011) $ 36 * @since 2.0 37 */ 38 public abstract class AbstractUnivariateRealOptimizer 39 extends ConvergingAlgorithmImpl implements UnivariateRealOptimizer { 40 /** Indicates where a root has been computed. */ 41 protected boolean resultComputed; 42 /** The last computed root. */ 43 protected double result; 44 /** Value of the function at the last computed result. */ 45 protected double functionValue; 46 /** Maximal number of evaluations allowed. */ 47 private int maxEvaluations; 48 /** Number of evaluations already performed. */ 49 private int evaluations; 50 /** Optimization type */ 51 private GoalType optimizationGoal; 52 /** Lower end of search interval. */ 53 private double searchMin; 54 /** Higher end of search interval. */ 55 private double searchMax; 56 /** Initial guess . */ 57 private double searchStart; 58 /** Function to optimize. */ 59 private UnivariateRealFunction function; 60 61 /** 62 * Construct a solver with given iteration count and accuracy. 63 * @param defaultAbsoluteAccuracy maximum absolute error 64 * @param defaultMaximalIterationCount maximum number of iterations 65 * @throws IllegalArgumentException if f is null or the 66 * defaultAbsoluteAccuracy is not valid 67 * @deprecated in 2.2. Please use the "setter" methods to assign meaningful 68 * values to the maximum numbers of iterations and evaluations, and to the 69 * absolute and relative accuracy thresholds. 70 */ 71 @Deprecated 72 protected AbstractUnivariateRealOptimizer(final int defaultMaximalIterationCount, 73 final double defaultAbsoluteAccuracy) { 74 super(defaultMaximalIterationCount, defaultAbsoluteAccuracy); 75 resultComputed = false; 76 setMaxEvaluations(Integer.MAX_VALUE); 77 } 78 79 /** 80 * Default constructor. 81 * To be removed once the single non-default one has been removed. 82 */ 83 protected AbstractUnivariateRealOptimizer() {} 84 85 /** 86 * Check whether a result has been computed. 87 * @throws NoDataException if no result has been computed 88 * @deprecated in 2.2 (no alternative). 89 */ 90 @Deprecated 91 protected void checkResultComputed() { 92 if (!resultComputed) { 93 throw new NoDataException(); 94 } 95 } 96 97 /** {@inheritDoc} */ 98 public double getResult() { 99 if (!resultComputed) { 100 throw new NoDataException(); 101 } 102 return result; 103 } 104 105 /** {@inheritDoc} */ 106 public double getFunctionValue() throws FunctionEvaluationException { 107 if (Double.isNaN(functionValue)) { 108 final double opt = getResult(); 109 functionValue = function.value(opt); 110 } 111 return functionValue; 112 } 113 114 /** 115 * Convenience function for implementations. 116 * 117 * @param x the result to set 118 * @param fx the result to set 119 * @param iterationCount the iteration count to set 120 * @deprecated in 2.2 (no alternative). 121 */ 122 @Deprecated 123 protected final void setResult(final double x, final double fx, 124 final int iterationCount) { 125 this.result = x; 126 this.functionValue = fx; 127 this.iterationCount = iterationCount; 128 this.resultComputed = true; 129 } 130 131 /** 132 * Convenience function for implementations. 133 * @deprecated in 2.2 (no alternative). 134 */ 135 @Deprecated 136 protected final void clearResult() { 137 this.resultComputed = false; 138 } 139 140 /** {@inheritDoc} */ 141 public void setMaxEvaluations(int maxEvaluations) { 142 this.maxEvaluations = maxEvaluations; 143 } 144 145 /** {@inheritDoc} */ 146 public int getMaxEvaluations() { 147 return maxEvaluations; 148 } 149 150 /** {@inheritDoc} */ 151 public int getEvaluations() { 152 return evaluations; 153 } 154 155 /** 156 * @return the optimization type. 157 */ 158 public GoalType getGoalType() { 159 return optimizationGoal; 160 } 161 /** 162 * @return the lower of the search interval. 163 */ 164 public double getMin() { 165 return searchMin; 166 } 167 /** 168 * @return the higher of the search interval. 169 */ 170 public double getMax() { 171 return searchMax; 172 } 173 /** 174 * @return the initial guess. 175 */ 176 public double getStartValue() { 177 return searchStart; 178 } 179 180 /** 181 * Compute the objective function value. 182 * @param f objective function 183 * @param point point at which the objective function must be evaluated 184 * @return objective function value at specified point 185 * @exception FunctionEvaluationException if the function cannot be evaluated 186 * or the maximal number of iterations is exceeded 187 * @deprecated in 2.2. Use this {@link #computeObjectiveValue(double) 188 * replacement} instead. 189 */ 190 @Deprecated 191 protected double computeObjectiveValue(final UnivariateRealFunction f, 192 final double point) 193 throws FunctionEvaluationException { 194 if (++evaluations > maxEvaluations) { 195 throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), point); 196 } 197 return f.value(point); 198 } 199 200 /** 201 * Compute the objective function value. 202 * 203 * @param point Point at which the objective function must be evaluated. 204 * @return the objective function value at specified point. 205 * @exception FunctionEvaluationException if the function cannot be evaluated 206 * or the maximal number of iterations is exceeded. 207 */ 208 protected double computeObjectiveValue(double point) 209 throws FunctionEvaluationException { 210 if (++evaluations > maxEvaluations) { 211 resultComputed = false; 212 throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), point); 213 } 214 return function.value(point); 215 } 216 217 /** {@inheritDoc} */ 218 public double optimize(UnivariateRealFunction f, GoalType goal, 219 double min, double max, double startValue) 220 throws MaxIterationsExceededException, FunctionEvaluationException { 221 // Initialize. 222 this.searchMin = min; 223 this.searchMax = max; 224 this.searchStart = startValue; 225 this.optimizationGoal = goal; 226 this.function = f; 227 228 // Reset. 229 functionValue = Double.NaN; 230 evaluations = 0; 231 resetIterationsCounter(); 232 233 // Perform computation. 234 result = doOptimize(); 235 resultComputed = true; 236 237 return result; 238 } 239 240 /** 241 * Set the value at the optimum. 242 * 243 * @param functionValue Value of the objective function at the optimum. 244 */ 245 protected void setFunctionValue(double functionValue) { 246 this.functionValue = functionValue; 247 } 248 249 /** {@inheritDoc} */ 250 public double optimize(UnivariateRealFunction f, GoalType goal, 251 double min, double max) 252 throws MaxIterationsExceededException, FunctionEvaluationException { 253 return optimize(f, goal, min, max, min + 0.5 * (max - min)); 254 } 255 256 /** 257 * Method for implementing actual optimization algorithms in derived 258 * classes. 259 * 260 * From version 3.0 onwards, this method will be abstract - i.e. 261 * concrete implementations will have to implement it. If this method 262 * is not implemented, subclasses must override 263 * {@link #optimize(UnivariateRealFunction, GoalType, double, double)}. 264 * 265 * @return the optimum. 266 * @throws MaxIterationsExceededException if the maximum iteration count 267 * is exceeded. 268 * @throws FunctionEvaluationException if an error occurs evaluating 269 * the function. 270 */ 271 protected double doOptimize() 272 throws MaxIterationsExceededException, FunctionEvaluationException { 273 throw new MathUnsupportedOperationException(LocalizedFormats.NOT_OVERRIDEN); 274 } 275 } 276