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.univariate;
019    
020    import org.apache.commons.math.util.Incrementor;
021    import org.apache.commons.math.exception.MaxCountExceededException;
022    import org.apache.commons.math.exception.TooManyEvaluationsException;
023    import org.apache.commons.math.exception.NullArgumentException;
024    import org.apache.commons.math.analysis.UnivariateRealFunction;
025    import org.apache.commons.math.optimization.GoalType;
026    import org.apache.commons.math.optimization.ConvergenceChecker;
027    
028    /**
029     * Provide a default implementation for several functions useful to generic
030     * optimizers.
031     *
032     * @version $Id: AbstractUnivariateRealOptimizer.java 1166311 2011-09-07 18:48:06Z luc $
033     * @since 2.0
034     */
035    public abstract class AbstractUnivariateRealOptimizer
036        implements UnivariateRealOptimizer {
037        /** Convergence checker. */
038        private ConvergenceChecker<UnivariateRealPointValuePair> checker;
039        /** Evaluations counter. */
040        private final Incrementor evaluations = new Incrementor();
041        /** Optimization type */
042        private GoalType goal;
043        /** Lower end of search interval. */
044        private double searchMin;
045        /** Higher end of search interval. */
046        private double searchMax;
047        /** Initial guess . */
048        private double searchStart;
049        /** Function to optimize. */
050        private UnivariateRealFunction function;
051    
052        /** {@inheritDoc} */
053        public int getMaxEvaluations() {
054            return evaluations.getMaximalCount();
055        }
056    
057        /** {@inheritDoc} */
058        public int getEvaluations() {
059            return evaluations.getCount();
060        }
061    
062        /**
063         * @return the optimization type.
064         */
065        public GoalType getGoalType() {
066            return goal;
067        }
068        /**
069         * @return the lower end of the search interval.
070         */
071        public double getMin() {
072            return searchMin;
073        }
074        /**
075         * @return the higher end of the search interval.
076         */
077        public double getMax() {
078            return searchMax;
079        }
080        /**
081         * @return the initial guess.
082         */
083        public double getStartValue() {
084            return searchStart;
085        }
086    
087        /**
088         * Compute the objective function value.
089         *
090         * @param point Point at which the objective function must be evaluated.
091         * @return the objective function value at specified point.
092         * @throws TooManyEvaluationsException if the maximal number of evaluations
093         * is exceeded.
094         */
095        protected double computeObjectiveValue(double point) {
096            try {
097                evaluations.incrementCount();
098            } catch (MaxCountExceededException e) {
099                throw new TooManyEvaluationsException(e.getMax());
100            }
101            return function.value(point);
102        }
103    
104        /** {@inheritDoc} */
105        public UnivariateRealPointValuePair optimize(int maxEval, UnivariateRealFunction f,
106                                                     GoalType goalType,
107                                                     double min, double max,
108                                                     double startValue) {
109            // Checks.
110            if (f == null) {
111                throw new NullArgumentException();
112            }
113            if (goalType == null) {
114                throw new NullArgumentException();
115            }
116    
117            // Reset.
118            searchMin = min;
119            searchMax = max;
120            searchStart = startValue;
121            goal = goalType;
122            function = f;
123            evaluations.setMaximalCount(maxEval);
124            evaluations.resetCount();
125    
126            // Perform computation.
127            return doOptimize();
128        }
129    
130        /** {@inheritDoc} */
131        public UnivariateRealPointValuePair optimize(int maxEval,
132                                                     UnivariateRealFunction f,
133                                                     GoalType goalType,
134                                                     double min, double max){
135            return optimize(maxEval, f, goalType, min, max, min + 0.5 * (max - min));
136        }
137    
138        /**
139         * {@inheritDoc}
140         */
141        public void setConvergenceChecker(ConvergenceChecker<UnivariateRealPointValuePair> c) {
142            checker = c;
143        }
144    
145        /**
146         * {@inheritDoc}
147         */
148        public ConvergenceChecker<UnivariateRealPointValuePair> getConvergenceChecker() {
149            return checker;
150        }
151    
152        /**
153         * Method for implementing actual optimization algorithms in derived
154         * classes.
155         *
156         * @return the optimum and its corresponding function value.
157         * @throws TooManyEvaluationsException if the maximal number of evaluations
158         * is exceeded.
159         */
160        protected abstract UnivariateRealPointValuePair doOptimize();
161    }