LineSearch.java

  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. import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
  19. import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
  20. import org.apache.commons.math4.legacy.optim.MaxEval;
  21. import org.apache.commons.math4.legacy.optim.univariate.BracketFinder;
  22. import org.apache.commons.math4.legacy.optim.univariate.BrentOptimizer;
  23. import org.apache.commons.math4.legacy.optim.univariate.SearchInterval;
  24. import org.apache.commons.math4.legacy.optim.univariate.SimpleUnivariateValueChecker;
  25. import org.apache.commons.math4.legacy.optim.univariate.UnivariateObjectiveFunction;
  26. import org.apache.commons.math4.legacy.optim.univariate.UnivariateOptimizer;
  27. import org.apache.commons.math4.legacy.optim.univariate.UnivariatePointValuePair;

  28. /**
  29.  * Class for finding the minimum of the objective function along a given
  30.  * direction.
  31.  *
  32.  * @since 3.3
  33.  * @deprecated as of 4.0-beta2.
  34.  * Class is now encapsulated in {@link MultivariateOptimizer}.
  35.  * Subclasses should call {@link MultivariateOptimizer#createLineSearch()}
  36.  * and {@link MultivariateOptimizer#lineSearch(double[],double[])} instead.
  37.  */
  38. @Deprecated
  39. public class LineSearch {
  40.     /**
  41.      * Value that will pass the precondition check for {@link BrentOptimizer}
  42.      * but will not pass the convergence check, so that the custom checker
  43.      * will always decide when to stop the line search.
  44.      */
  45.     private static final double REL_TOL_UNUSED = 1e-15;
  46.     /**
  47.      * Value that will pass the precondition check for {@link BrentOptimizer}
  48.      * but will not pass the convergence check, so that the custom checker
  49.      * will always decide when to stop the line search.
  50.      */
  51.     private static final double ABS_TOL_UNUSED = Double.MIN_VALUE;
  52.     /**
  53.      * Optimizer used for line search.
  54.      */
  55.     private final UnivariateOptimizer lineOptimizer;
  56.     /**
  57.      * Automatic bracketing.
  58.      */
  59.     private final BracketFinder bracket = new BracketFinder();
  60.     /**
  61.      * Extent of the initial interval used to find an interval that
  62.      * brackets the optimum.
  63.      */
  64.     private final double initialBracketingRange;
  65.     /**
  66.      * Optimizer on behalf of which the line search must be performed.
  67.      */
  68.     private final MultivariateOptimizer mainOptimizer;

  69.     /**
  70.      * The {@code BrentOptimizer} default stopping criterion uses the
  71.      * tolerances to check the domain (point) values, not the function
  72.      * values.
  73.      * The {@code relativeTolerance} and {@code absoluteTolerance}
  74.      * arguments are thus passed to a {@link SimpleUnivariateValueChecker
  75.      * custom checker} that will use the function values.
  76.      *
  77.      * @param optimizer Optimizer on behalf of which the line search
  78.      * be performed.
  79.      * Its {@link MultivariateOptimizer#getObjectiveFunction() objective
  80.      * function} will be called by the {@link #search(double[],double[])
  81.      * search} method.
  82.      * @param relativeTolerance Search will stop when the function relative
  83.      * difference between successive iterations is below this value.
  84.      * @param absoluteTolerance Search will stop when the function absolute
  85.      * difference between successive iterations is below this value.
  86.      * @param initialBracketingRange Extent of the initial interval used to
  87.      * find an interval that brackets the optimum.
  88.      * If the optimized function varies a lot in the vicinity of the optimum,
  89.      * it may be necessary to provide a value lower than the distance between
  90.      * successive local minima.
  91.      */
  92.     public LineSearch(MultivariateOptimizer optimizer,
  93.                       double relativeTolerance,
  94.                       double absoluteTolerance,
  95.                       double initialBracketingRange) {
  96.         mainOptimizer = optimizer;
  97.         lineOptimizer = new BrentOptimizer(REL_TOL_UNUSED,
  98.                                            ABS_TOL_UNUSED,
  99.                                            new SimpleUnivariateValueChecker(relativeTolerance,
  100.                                                                             absoluteTolerance));
  101.         this.initialBracketingRange = initialBracketingRange;
  102.     }

  103.     /**
  104.      * Finds the number {@code alpha} that optimizes
  105.      * {@code f(startPoint + alpha * direction)}.
  106.      *
  107.      * @param startPoint Starting point.
  108.      * @param direction Search direction.
  109.      * @return the optimum.
  110.      * @throws org.apache.commons.math4.legacy.exception.TooManyEvaluationsException
  111.      * if the number of evaluations is exceeded.
  112.      */
  113.     public UnivariatePointValuePair search(final double[] startPoint,
  114.                                            final double[] direction) {
  115.         final int n = startPoint.length;
  116.         final MultivariateFunction func = mainOptimizer.getObjectiveFunction();
  117.         final UnivariateFunction f = new UnivariateFunction() {
  118.             /** {@inheritDoc} */
  119.             @Override
  120.             public double value(double alpha) {
  121.                 final double[] x = new double[n];
  122.                 for (int i = 0; i < n; i++) {
  123.                     x[i] = startPoint[i] + alpha * direction[i];
  124.                 }
  125.                 return func.value(x);
  126.             }
  127.         };

  128.         final GoalType goal = mainOptimizer.getGoalType();
  129.         bracket.search(f, goal, 0, initialBracketingRange);
  130.         // Passing "MAX_VALUE" as a dummy value because it is the enclosing
  131.         // class that counts the number of evaluations (and will eventually
  132.         // generate the exception).
  133.         return lineOptimizer.optimize(new MaxEval(Integer.MAX_VALUE),
  134.                                       new UnivariateObjectiveFunction(f),
  135.                                       goal,
  136.                                       new SearchInterval(bracket.getLo(),
  137.                                                          bracket.getHi(),
  138.                                                          bracket.getMid()));
  139.     }
  140. }