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.ConvergingAlgorithmImpl;
021    import org.apache.commons.math.FunctionEvaluationException;
022    import org.apache.commons.math.MathRuntimeException;
023    import org.apache.commons.math.MaxEvaluationsExceededException;
024    import org.apache.commons.math.analysis.UnivariateRealFunction;
025    import org.apache.commons.math.optimization.UnivariateRealOptimizer;
026    
027    /**
028     * Provide a default implementation for several functions useful to generic
029     * optimizers.
030     *
031     * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $
032     * @since 2.0
033     */
034    public abstract class AbstractUnivariateRealOptimizer
035        extends ConvergingAlgorithmImpl implements UnivariateRealOptimizer {
036    
037        /** Indicates where a root has been computed. */
038        protected boolean resultComputed;
039    
040        /** The last computed root. */
041        protected double result;
042    
043        /** Value of the function at the last computed result. */
044        protected double functionValue;
045    
046        /** Maximal number of evaluations allowed. */
047        private int maxEvaluations;
048    
049        /** Number of evaluations already performed. */
050        private int evaluations;
051    
052        /**
053         * Construct a solver with given iteration count and accuracy.
054         * FunctionEvaluationExceptionFunctionEvaluationException
055         * @param defaultAbsoluteAccuracy maximum absolute error
056         * @param defaultMaximalIterationCount maximum number of iterations
057         * @throws IllegalArgumentException if f is null or the
058         * defaultAbsoluteAccuracy is not valid
059         */
060        protected AbstractUnivariateRealOptimizer(final int defaultMaximalIterationCount,
061                                                  final double defaultAbsoluteAccuracy) {
062            super(defaultMaximalIterationCount, defaultAbsoluteAccuracy);
063            resultComputed = false;
064            setMaxEvaluations(Integer.MAX_VALUE);
065        }
066    
067        /** Check if a result has been computed.
068         * @exception IllegalStateException if no result has been computed
069         */
070        protected void checkResultComputed() throws IllegalStateException {
071            if (!resultComputed) {
072                throw MathRuntimeException.createIllegalStateException("no result available");
073            }
074        }
075    
076        /** {@inheritDoc} */
077        public double getResult() {
078            checkResultComputed();
079            return result;
080        }
081    
082        /** {@inheritDoc} */
083        public double getFunctionValue() {
084            checkResultComputed();
085            return functionValue;
086        }
087    
088        /**
089         * Convenience function for implementations.
090         *
091         * @param x the result to set
092         * @param fx the result to set
093         * @param iterationCount the iteration count to set
094         */
095        protected final void setResult(final double x, final double fx,
096                                       final int iterationCount) {
097            this.result         = x;
098            this.functionValue  = fx;
099            this.iterationCount = iterationCount;
100            this.resultComputed = true;
101        }
102    
103        /**
104         * Convenience function for implementations.
105         */
106        protected final void clearResult() {
107            this.resultComputed = false;
108        }
109    
110        /** {@inheritDoc} */
111        public void setMaxEvaluations(int maxEvaluations) {
112            this.maxEvaluations = maxEvaluations;
113        }
114    
115        /** {@inheritDoc} */
116        public int getMaxEvaluations() {
117            return maxEvaluations;
118        }
119    
120        /** {@inheritDoc} */
121        public int getEvaluations() {
122            return evaluations;
123        }
124    
125        /**
126         * Compute the objective function value.
127         * @param f objective function
128         * @param point point at which the objective function must be evaluated
129         * @return objective function value at specified point
130         * @exception FunctionEvaluationException if the function cannot be evaluated
131         * or the maximal number of iterations is exceeded
132         */
133        protected double computeObjectiveValue(final UnivariateRealFunction f,
134                                               final double point)
135            throws FunctionEvaluationException {
136            if (++evaluations > maxEvaluations) {
137                throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations),
138                                                      point);
139            }
140            return f.value(point);
141        }
142    
143    }