    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.nonlinear.scalar;
    018
    019    import org.apache.commons.math3.analysis.MultivariateFunction;
    020    import org.apache.commons.math3.optim.BaseMultivariateOptimizer;
    021    import org.apache.commons.math3.optim.OptimizationData;
    022    import org.apache.commons.math3.optim.ConvergenceChecker;
    023    import org.apache.commons.math3.optim.PointValuePair;
    024    import org.apache.commons.math3.exception.TooManyEvaluationsException;
    025
    026    /**
    027     * Base class for a multivariate scalar function optimizer.
    028     *
    029     * @version $Id$
    030     * @since 3.1
    031     */
    032    public abstract class MultivariateOptimizer
    033        extends BaseMultivariateOptimizer<PointValuePair> {
    034        /** Objective function. */
    035        private MultivariateFunction function;
    036        /** Type of optimization. */
    037        private GoalType goal;
    038
    039        /**
    040         * @param checker Convergence checker.
    041         */
    042        protected MultivariateOptimizer(ConvergenceChecker<PointValuePair> checker) {
    043            super(checker);
    044        }
    045
    046        /**
    047         * {@inheritDoc}
    048         *
    049         * @param optData Optimization data. The following data will be looked for:
    050         * <ul>
    051         *  <li>{@link org.apache.commons.math3.optim.MaxEval}</li>
    052         *  <li>{@link org.apache.commons.math3.optim.InitialGuess}</li>
    053         *  <li>{@link org.apache.commons.math3.optim.SimpleBounds}</li>
    054         *  <li>{@link ObjectiveFunction}</li>
    055         *  <li>{@link GoalType}</li>
    056         * </ul>
    057         * @return {@inheritDoc}
    058         * @throws TooManyEvaluationsException if the maximal number of
    059         * evaluations is exceeded.
    060         */
    061        @Override
    062        public PointValuePair optimize(OptimizationData... optData)
    063            throws TooManyEvaluationsException {
    064             // Retrieve settings.
    065            parseOptimizationData(optData);
    066            // Set up base class and perform computation.
    067            return super.optimize(optData);
    068        }
    069
    070        /**
    071         * Scans the list of (required and optional) optimization data that
    072         * characterize the problem.
    073         *
    074         * @param optData Optimization data.
    075         * The following data will be looked for:
    076         * <ul>
    077         *  <li>{@link ObjectiveFunction}</li>
    078         *  <li>{@link GoalType}</li>
    079         * </ul>
    080         */
    081        private void parseOptimizationData(OptimizationData... optData) {
    082            // The existing values (as set by the previous call) are reused if
    083            // not provided in the argument list.
    084            for (OptimizationData data : optData) {
    085                if (data instanceof GoalType) {
    086                    goal = (GoalType) data;
    087                    continue;
    088                }
    089                if  (data instanceof ObjectiveFunction) {
    090                    function = ((ObjectiveFunction) data).getObjectiveFunction();
    091                    continue;
    092                }
    093            }
    094        }
    095
    096        /**
    097         * @return the optimization type.
    098         */
    099        public GoalType getGoalType() {
    100            return goal;
    101        }
    102
    103        /**
    104         * Computes the objective function value.
    105         * This method <em>must</em> be called by subclasses to enforce the
    106         * evaluation counter limit.
    107         *
    108         * @param params Point at which the objective function must be evaluated.
    109         * @return the objective function value at the specified point.
    110         * @throws TooManyEvaluationsException if the maximal number of
    111         * evaluations is exceeded.
    112         */
    113        protected double computeObjectiveValue(double[] params) {
    114            super.incrementEvaluationCount();
    115            return function.value(params);
    116        }
    117    }