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.nonlinear.scalar;
18  
19  import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
20  import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
21  import org.apache.commons.math4.legacy.optim.MaxEval;
22  import org.apache.commons.math4.legacy.optim.univariate.BracketFinder;
23  import org.apache.commons.math4.legacy.optim.univariate.BrentOptimizer;
24  import org.apache.commons.math4.legacy.optim.univariate.SearchInterval;
25  import org.apache.commons.math4.legacy.optim.univariate.SimpleUnivariateValueChecker;
26  import org.apache.commons.math4.legacy.optim.univariate.UnivariateObjectiveFunction;
27  import org.apache.commons.math4.legacy.optim.univariate.UnivariateOptimizer;
28  import org.apache.commons.math4.legacy.optim.univariate.UnivariatePointValuePair;
29  
30  /**
31   * Class for finding the minimum of the objective function along a given
32   * direction.
33   *
34   * @since 3.3
35   * @deprecated as of 4.0-beta2.
36   * Class is now encapsulated in {@link MultivariateOptimizer}.
37   * Subclasses should call {@link MultivariateOptimizer#createLineSearch()}
38   * and {@link MultivariateOptimizer#lineSearch(double[],double[])} instead.
39   */
40  @Deprecated
41  public class LineSearch {
42      /**
43       * Value that will pass the precondition check for {@link BrentOptimizer}
44       * but will not pass the convergence check, so that the custom checker
45       * will always decide when to stop the line search.
46       */
47      private static final double REL_TOL_UNUSED = 1e-15;
48      /**
49       * Value that will pass the precondition check for {@link BrentOptimizer}
50       * but will not pass the convergence check, so that the custom checker
51       * will always decide when to stop the line search.
52       */
53      private static final double ABS_TOL_UNUSED = Double.MIN_VALUE;
54      /**
55       * Optimizer used for line search.
56       */
57      private final UnivariateOptimizer lineOptimizer;
58      /**
59       * Automatic bracketing.
60       */
61      private final BracketFinder bracket = new BracketFinder();
62      /**
63       * Extent of the initial interval used to find an interval that
64       * brackets the optimum.
65       */
66      private final double initialBracketingRange;
67      /**
68       * Optimizer on behalf of which the line search must be performed.
69       */
70      private final MultivariateOptimizer mainOptimizer;
71  
72      /**
73       * The {@code BrentOptimizer} default stopping criterion uses the
74       * tolerances to check the domain (point) values, not the function
75       * values.
76       * The {@code relativeTolerance} and {@code absoluteTolerance}
77       * arguments are thus passed to a {@link SimpleUnivariateValueChecker
78       * custom checker} that will use the function values.
79       *
80       * @param optimizer Optimizer on behalf of which the line search
81       * be performed.
82       * Its {@link MultivariateOptimizer#getObjectiveFunction() objective
83       * function} will be called by the {@link #search(double[],double[])
84       * search} method.
85       * @param relativeTolerance Search will stop when the function relative
86       * difference between successive iterations is below this value.
87       * @param absoluteTolerance Search will stop when the function absolute
88       * difference between successive iterations is below this value.
89       * @param initialBracketingRange Extent of the initial interval used to
90       * find an interval that brackets the optimum.
91       * If the optimized function varies a lot in the vicinity of the optimum,
92       * it may be necessary to provide a value lower than the distance between
93       * successive local minima.
94       */
95      public LineSearch(MultivariateOptimizer optimizer,
96                        double relativeTolerance,
97                        double absoluteTolerance,
98                        double initialBracketingRange) {
99          mainOptimizer = optimizer;
100         lineOptimizer = new BrentOptimizer(REL_TOL_UNUSED,
101                                            ABS_TOL_UNUSED,
102                                            new SimpleUnivariateValueChecker(relativeTolerance,
103                                                                             absoluteTolerance));
104         this.initialBracketingRange = initialBracketingRange;
105     }
106 
107     /**
108      * Finds the number {@code alpha} that optimizes
109      * {@code f(startPoint + alpha * direction)}.
110      *
111      * @param startPoint Starting point.
112      * @param direction Search direction.
113      * @return the optimum.
114      * @throws org.apache.commons.math4.legacy.exception.TooManyEvaluationsException
115      * if the number of evaluations is exceeded.
116      */
117     public UnivariatePointValuePair search(final double[] startPoint,
118                                            final double[] direction) {
119         final int n = startPoint.length;
120         final MultivariateFunction func = mainOptimizer.getObjectiveFunction();
121         final UnivariateFunction f = new UnivariateFunction() {
122             /** {@inheritDoc} */
123             @Override
124             public double value(double alpha) {
125                 final double[] x = new double[n];
126                 for (int i = 0; i < n; i++) {
127                     x[i] = startPoint[i] + alpha * direction[i];
128                 }
129                 return func.value(x);
130             }
131         };
132 
133         final GoalType goal = mainOptimizer.getGoalType();
134         bracket.search(f, goal, 0, initialBracketingRange);
135         // Passing "MAX_VALUE" as a dummy value because it is the enclosing
136         // class that counts the number of evaluations (and will eventually
137         // generate the exception).
138         return lineOptimizer.optimize(new MaxEval(Integer.MAX_VALUE),
139                                       new UnivariateObjectiveFunction(f),
140                                       goal,
141                                       new SearchInterval(bracket.getLo(),
142                                                          bracket.getHi(),
143                                                          bracket.getMid()));
144     }
145 }