    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    package org.apache.commons.math3.optim.univariate;
    018
    019    import org.apache.commons.math3.analysis.UnivariateFunction;
    020    import org.apache.commons.math3.optim.BaseOptimizer;
    021    import org.apache.commons.math3.optim.OptimizationData;
    022    import org.apache.commons.math3.optim.nonlinear.scalar.GoalType;
    023    import org.apache.commons.math3.optim.ConvergenceChecker;
    024    import org.apache.commons.math3.exception.TooManyEvaluationsException;
    025
    026    /**
    027     * Base class for a univariate scalar function optimizer.
    028     *
    029     * @version $Id$
    030     * @since 3.1
    031     */
    032    public abstract class UnivariateOptimizer
    033        extends BaseOptimizer<UnivariatePointValuePair> {
    034        /** Objective function. */
    035        private UnivariateFunction function;
    036        /** Type of optimization. */
    037        private GoalType goal;
    038        /** Initial guess. */
    039        private double start;
    040        /** Lower bound. */
    041        private double min;
    042        /** Upper bound. */
    043        private double max;
    044
    045        /**
    046         * @param checker Convergence checker.
    047         */
    048        protected UnivariateOptimizer(ConvergenceChecker<UnivariatePointValuePair> checker) {
    049            super(checker);
    050        }
    051
    052        /**
    053         * {@inheritDoc}
    054         *
    055         * @param optData Optimization data.
    056         * The following data will be looked for:
    057         * <ul>
    058         *  <li>{@link GoalType}</li>
    059         *  <li>{@link SearchInterval}</li>
    060         *  <li>{@link UnivariateObjectiveFunction}</li>
    061         * </ul>
    062         * @return {@inheritDoc}
    063         * @throws TooManyEvaluationsException if the maximal number of
    064         * evaluations is exceeded.
    065         */
    066        public UnivariatePointValuePair optimize(OptimizationData... optData)
    067            throws TooManyEvaluationsException {
    068            // Retrieve settings.
    069            parseOptimizationData(optData);
    070            // Perform computation.
    071            return super.optimize(optData);
    072        }
    073
    074        /**
    075         * @return the optimization type.
    076         */
    077        public GoalType getGoalType() {
    078            return goal;
    079        }
    080
    081        /**
    082         * Scans the list of (required and optional) optimization data that
    083         * characterize the problem.
    084         *
    085         * @param optData Optimization data.
    086         * The following data will be looked for:
    087         * <ul>
    088         *  <li>{@link GoalType}</li>
    089         *  <li>{@link SearchInterval}</li>
    090         *  <li>{@link UnivariateObjectiveFunction}</li>
    091         * </ul>
    092         */
    093        private void parseOptimizationData(OptimizationData... optData) {
    094            // The existing values (as set by the previous call) are reused if
    095            // not provided in the argument list.
    096            for (OptimizationData data : optData) {
    097                if (data instanceof SearchInterval) {
    098                    final SearchInterval interval = (SearchInterval) data;
    099                    min = interval.getMin();
    100                    max = interval.getMax();
    101                    start = interval.getStartValue();
    102                    continue;
    103                }
    104                if (data instanceof UnivariateObjectiveFunction) {
    105                    function = ((UnivariateObjectiveFunction) data).getObjectiveFunction();
    106                    continue;
    107                }
    108                if (data instanceof GoalType) {
    109                    goal = (GoalType) data;
    110                    continue;
    111                }
    112            }
    113        }
    114
    115        /**
    116         * @return the initial guess.
    117         */
    118        public double getStartValue() {
    119            return start;
    120        }
    121        /**
    122         * @return the lower bounds.
    123         */
    124        public double getMin() {
    125            return min;
    126        }
    127        /**
    128         * @return the upper bounds.
    129         */
    130        public double getMax() {
    131            return max;
    132        }
    133
    134        /**
    135         * Computes the objective function value.
    136         * This method <em>must</em> be called by subclasses to enforce the
    137         * evaluation counter limit.
    138         *
    139         * @param x Point at which the objective function must be evaluated.
    140         * @return the objective function value at the specified point.
    141         * @throws TooManyEvaluationsException if the maximal number of
    142         * evaluations is exceeded.
    143         */
    144        protected double computeObjectiveValue(double x) {
    145            super.incrementEvaluationCount();
    146            return function.value(x);
    147        }
    148    }