View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math4.legacy.optim.univariate;
18  
19  import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
20  import org.apache.commons.math4.legacy.exception.TooManyEvaluationsException;
21  import org.apache.commons.math4.legacy.optim.BaseOptimizer;
22  import org.apache.commons.math4.legacy.optim.ConvergenceChecker;
23  import org.apache.commons.math4.legacy.optim.OptimizationData;
24  import org.apache.commons.math4.legacy.optim.nonlinear.scalar.GoalType;
25  
26  /**
27   * Base class for a univariate scalar function optimizer.
28   *
29   * @since 3.1
30   */
31  public abstract class UnivariateOptimizer
32      extends BaseOptimizer<UnivariatePointValuePair> {
33      /** Objective function. */
34      private UnivariateFunction function;
35      /** Type of optimization. */
36      private GoalType goal;
37      /** Initial guess. */
38      private double start;
39      /** Lower bound. */
40      private double min;
41      /** Upper bound. */
42      private double max;
43  
44      /**
45       * @param checker Convergence checker.
46       */
47      protected UnivariateOptimizer(ConvergenceChecker<UnivariatePointValuePair> checker) {
48          super(checker);
49      }
50  
51      /**
52       * {@inheritDoc}
53       *
54       * @param optData Optimization data. In addition to those documented in
55       * {@link BaseOptimizer#parseOptimizationData(OptimizationData[])
56       * BaseOptimizer}, this method will register the following data:
57       * <ul>
58       *  <li>{@link GoalType}</li>
59       *  <li>{@link SearchInterval}</li>
60       *  <li>{@link UnivariateObjectiveFunction}</li>
61       * </ul>
62       * @return {@inheritDoc}
63       * @throws TooManyEvaluationsException if the maximal number of
64       * evaluations is exceeded.
65       */
66      @Override
67      public UnivariatePointValuePair optimize(OptimizationData... optData)
68          throws TooManyEvaluationsException {
69          // Perform computation.
70          return super.optimize(optData);
71      }
72  
73      /**
74       * @return the optimization type.
75       */
76      public GoalType getGoalType() {
77          return goal;
78      }
79  
80      /**
81       * Scans the list of (required and optional) optimization data that
82       * characterize the problem.
83       *
84       * @param optData Optimization data.
85       * The following data will be looked for:
86       * <ul>
87       *  <li>{@link GoalType}</li>
88       *  <li>{@link SearchInterval}</li>
89       *  <li>{@link UnivariateObjectiveFunction}</li>
90       * </ul>
91       */
92      @Override
93      protected void parseOptimizationData(OptimizationData... optData) {
94          // Allow base class to register its own data.
95          super.parseOptimizationData(optData);
96  
97          // The existing values (as set by the previous call) are reused if
98          // not provided in the argument list.
99          for (OptimizationData data : optData) {
100             if (data instanceof SearchInterval) {
101                 final SearchInterval interval = (SearchInterval) data;
102                 min = interval.getMin();
103                 max = interval.getMax();
104                 start = interval.getStartValue();
105                 continue;
106             }
107             if (data instanceof UnivariateObjectiveFunction) {
108                 final UnivariateFunction delegate = ((UnivariateObjectiveFunction) data).getObjectiveFunction();
109                 function = new UnivariateFunction() {
110                         @Override
111                         public double value(double point) {
112                             incrementEvaluationCount();
113                             return delegate.value(point);
114                         }
115                     };
116                 continue;
117             }
118             if (data instanceof GoalType) {
119                 goal = (GoalType) data;
120                 continue;
121             }
122         }
123     }
124 
125     /**
126      * @return the initial guess.
127      */
128     public double getStartValue() {
129         return start;
130     }
131     /**
132      * @return the lower bounds.
133      */
134     public double getMin() {
135         return min;
136     }
137     /**
138      * @return the upper bounds.
139      */
140     public double getMax() {
141         return max;
142     }
143 
144     /**
145      * @return a wrapper that delegates to the user-supplied function,
146      * and counts the number of evaluations.
147      */
148     protected UnivariateFunction getObjectiveFunction() {
149         return function;
150     }
151 
152     /**
153      * Computes the objective function value.
154      * This method <em>must</em> be called by subclasses to enforce the
155      * evaluation counter limit.
156      *
157      * @param x Point at which the objective function must be evaluated.
158      * @return the objective function value at the specified point.
159      * @throws TooManyEvaluationsException if the maximal number of
160      * evaluations is exceeded.
161      *
162      * @deprecated Use {@link #getObjectiveFunction()} instead.
163      */
164     @Deprecated
165     protected double computeObjectiveValue(double x) {
166         return function.value(x);
167     }
168 }