Home | History | Annotate | Download | only in univariate
      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