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: 786466 $ $Date: 2009-06-19 08:03:14 -0400 (Fri, 19 Jun 2009) $ 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 /** Maximal number of iterations allowed. */ 046 private int maxIterations; 047 048 /** Number of iterations already performed. */ 049 private int iterations; 050 051 /** Maximal number of evaluations allowed. */ 052 private int maxEvaluations; 053 054 /** Number of evaluations already performed. */ 055 private int evaluations; 056 057 /** Number of gradient evaluations. */ 058 private int gradientEvaluations; 059 060 /** Convergence checker. */ 061 protected RealConvergenceChecker checker; 062 063 /** Objective function. */ 064 private DifferentiableMultivariateRealFunction f; 065 066 /** Objective function gradient. */ 067 private MultivariateVectorialFunction gradient; 068 069 /** Type of optimization. */ 070 protected GoalType goalType; 071 072 /** Current point set. */ 073 protected double[] point; 074 075 /** Simple constructor with default settings. 076 * <p>The convergence check is set to a {@link SimpleScalarValueChecker} 077 * and the maximal number of evaluation is set to its default value.</p> 078 */ 079 protected AbstractScalarDifferentiableOptimizer() { 080 setConvergenceChecker(new SimpleScalarValueChecker()); 081 setMaxIterations(DEFAULT_MAX_ITERATIONS); 082 setMaxEvaluations(Integer.MAX_VALUE); 083 } 084 085 /** {@inheritDoc} */ 086 public void setMaxIterations(int maxIterations) { 087 this.maxIterations = maxIterations; 088 } 089 090 /** {@inheritDoc} */ 091 public int getMaxIterations() { 092 return maxIterations; 093 } 094 095 /** {@inheritDoc} */ 096 public int getIterations() { 097 return iterations; 098 } 099 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 }