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    }