// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors may be
//   used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Author: sameeragarwal@google.com (Sameer Agarwal)

#include "ceres/line_search.h"

#include <iomanip>
#include <iostream>  // NOLINT

#include "ceres/evaluator.h"
#include "ceres/fpclassify.h"
#include "ceres/function_sample.h"
#include "ceres/internal/eigen.h"
#include "ceres/map_util.h"
#include "ceres/polynomial.h"
#include "ceres/stringprintf.h"
#include "ceres/wall_time.h"
#include "glog/logging.h"

namespace ceres {
namespace internal {

using std::map;
using std::ostream;
using std::string;
using std::vector;

namespace {
// Precision used for floating point values in error message output.
const int kErrorMessageNumericPrecision = 8;
}  // namespace

ostream& operator<<(ostream &os, const FunctionSample& sample);

// Convenience stream operator for pushing FunctionSamples into log messages.
ostream& operator<<(ostream &os, const FunctionSample& sample) {
  os << sample.ToDebugString();
  return os;
}

LineSearch::LineSearch(const LineSearch::Options& options)
    : options_(options) {}

LineSearch* LineSearch::Create(const LineSearchType line_search_type,
                               const LineSearch::Options& options,
                               string* error) {
  LineSearch* line_search = NULL;
  switch (line_search_type) {
  case ceres::ARMIJO:
    line_search = new ArmijoLineSearch(options);
    break;
  case ceres::WOLFE:
    line_search = new WolfeLineSearch(options);
    break;
  default:
    *error = string("Invalid line search algorithm type: ") +
        LineSearchTypeToString(line_search_type) +
        string(", unable to create line search.");
    return NULL;
  }
  return line_search;
}

LineSearchFunction::LineSearchFunction(Evaluator* evaluator)
    : evaluator_(evaluator),
      position_(evaluator->NumParameters()),
      direction_(evaluator->NumEffectiveParameters()),
      scaled_direction_(evaluator->NumEffectiveParameters()),
      initial_evaluator_residual_time_in_seconds(0.0),
      initial_evaluator_jacobian_time_in_seconds(0.0) {}

void LineSearchFunction::Init(const Vector& position,
                              const Vector& direction) {
  position_ = position;
  direction_ = direction;
}

void LineSearchFunction::Evaluate(const double x,
                                  const bool evaluate_gradient,
                                  FunctionSample* output) {
  output->x = x;
  output->vector_x_is_valid = false;
  output->value_is_valid = false;
  output->gradient_is_valid = false;
  output->vector_gradient_is_valid = false;

  scaled_direction_ = output->x * direction_;
  output->vector_x.resize(position_.rows(), 1);
  if (!evaluator_->Plus(position_.data(),
                        scaled_direction_.data(),
                        output->vector_x.data())) {
    return;
  }
  output->vector_x_is_valid = true;

  double* gradient = NULL;
  if (evaluate_gradient) {
    output->vector_gradient.resize(direction_.rows(), 1);
    gradient = output->vector_gradient.data();
  }
  const bool eval_status = evaluator_->Evaluate(
      output->vector_x.data(), &(output->value), NULL, gradient, NULL);

  if (!eval_status || !IsFinite(output->value)) {
    return;
  }

  output->value_is_valid = true;
  if (!evaluate_gradient) {
    return;
  }

  output->gradient = direction_.dot(output->vector_gradient);
  if (!IsFinite(output->gradient)) {
    return;
  }

  output->gradient_is_valid = true;
  output->vector_gradient_is_valid = true;
}

double LineSearchFunction::DirectionInfinityNorm() const {
  return direction_.lpNorm<Eigen::Infinity>();
}

void LineSearchFunction::ResetTimeStatistics() {
  const map<string, double> evaluator_time_statistics =
      evaluator_->TimeStatistics();
  initial_evaluator_residual_time_in_seconds =
      FindWithDefault(evaluator_time_statistics, "Evaluator::Residual", 0.0);
  initial_evaluator_jacobian_time_in_seconds =
      FindWithDefault(evaluator_time_statistics, "Evaluator::Jacobian", 0.0);
}

void LineSearchFunction::TimeStatistics(
    double* cost_evaluation_time_in_seconds,
    double* gradient_evaluation_time_in_seconds) const {
  const map<string, double> evaluator_time_statistics =
      evaluator_->TimeStatistics();
  *cost_evaluation_time_in_seconds =
      FindWithDefault(evaluator_time_statistics, "Evaluator::Residual", 0.0) -
      initial_evaluator_residual_time_in_seconds;
  // Strictly speaking this will slightly underestimate the time spent
  // evaluating the gradient of the line search univariate cost function as it
  // does not count the time spent performing the dot product with the direction
  // vector.  However, this will typically be small by comparison, and also
  // allows direct subtraction of the timing information from the totals for
  // the evaluator returned in the solver summary.
  *gradient_evaluation_time_in_seconds =
      FindWithDefault(evaluator_time_statistics, "Evaluator::Jacobian", 0.0) -
      initial_evaluator_jacobian_time_in_seconds;
}

void LineSearch::Search(double step_size_estimate,
                        double initial_cost,
                        double initial_gradient,
                        Summary* summary) const {
  const double start_time = WallTimeInSeconds();
  *CHECK_NOTNULL(summary) = LineSearch::Summary();

  summary->cost_evaluation_time_in_seconds = 0.0;
  summary->gradient_evaluation_time_in_seconds = 0.0;
  summary->polynomial_minimization_time_in_seconds = 0.0;
  options().function->ResetTimeStatistics();
  this->DoSearch(step_size_estimate, initial_cost, initial_gradient, summary);
  options().function->
      TimeStatistics(&summary->cost_evaluation_time_in_seconds,
                     &summary->gradient_evaluation_time_in_seconds);

  summary->total_time_in_seconds = WallTimeInSeconds() - start_time;
}

// Returns step_size \in [min_step_size, max_step_size] which minimizes the
// polynomial of degree defined by interpolation_type which interpolates all
// of the provided samples with valid values.
double LineSearch::InterpolatingPolynomialMinimizingStepSize(
    const LineSearchInterpolationType& interpolation_type,
    const FunctionSample& lowerbound,
    const FunctionSample& previous,
    const FunctionSample& current,
    const double min_step_size,
    const double max_step_size) const {
  if (!current.value_is_valid ||
      (interpolation_type == BISECTION &&
       max_step_size <= current.x)) {
    // Either: sample is invalid; or we are using BISECTION and contracting
    // the step size.
    return std::min(std::max(current.x * 0.5, min_step_size), max_step_size);
  } else if (interpolation_type == BISECTION) {
    CHECK_GT(max_step_size, current.x);
    // We are expanding the search (during a Wolfe bracketing phase) using
    // BISECTION interpolation.  Using BISECTION when trying to expand is
    // strictly speaking an oxymoron, but we define this to mean always taking
    // the maximum step size so that the Armijo & Wolfe implementations are
    // agnostic to the interpolation type.
    return max_step_size;
  }
  // Only check if lower-bound is valid here, where it is required
  // to avoid replicating current.value_is_valid == false
  // behaviour in WolfeLineSearch.
  CHECK(lowerbound.value_is_valid)
      << std::scientific << std::setprecision(kErrorMessageNumericPrecision)
      << "Ceres bug: lower-bound sample for interpolation is invalid, "
      << "please contact the developers!, interpolation_type: "
      << LineSearchInterpolationTypeToString(interpolation_type)
      << ", lowerbound: " << lowerbound << ", previous: " << previous
      << ", current: " << current;

  // Select step size by interpolating the function and gradient values
  // and minimizing the corresponding polynomial.
  vector<FunctionSample> samples;
  samples.push_back(lowerbound);

  if (interpolation_type == QUADRATIC) {
    // Two point interpolation using function values and the
    // gradient at the lower bound.
    samples.push_back(FunctionSample(current.x, current.value));

    if (previous.value_is_valid) {
      // Three point interpolation, using function values and the
      // gradient at the lower bound.
      samples.push_back(FunctionSample(previous.x, previous.value));
    }
  } else if (interpolation_type == CUBIC) {
    // Two point interpolation using the function values and the gradients.
    samples.push_back(current);

    if (previous.value_is_valid) {
      // Three point interpolation using the function values and
      // the gradients.
      samples.push_back(previous);
    }
  } else {
    LOG(FATAL) << "Ceres bug: No handler for interpolation_type: "
               << LineSearchInterpolationTypeToString(interpolation_type)
               << ", please contact the developers!";
  }

  double step_size = 0.0, unused_min_value = 0.0;
  MinimizeInterpolatingPolynomial(samples, min_step_size, max_step_size,
                                  &step_size, &unused_min_value);
  return step_size;
}

ArmijoLineSearch::ArmijoLineSearch(const LineSearch::Options& options)
    : LineSearch(options) {}

void ArmijoLineSearch::DoSearch(const double step_size_estimate,
                                const double initial_cost,
                                const double initial_gradient,
                                Summary* summary) const {
  CHECK_GE(step_size_estimate, 0.0);
  CHECK_GT(options().sufficient_decrease, 0.0);
  CHECK_LT(options().sufficient_decrease, 1.0);
  CHECK_GT(options().max_num_iterations, 0);
  LineSearchFunction* function = options().function;

  // Note initial_cost & initial_gradient are evaluated at step_size = 0,
  // not step_size_estimate, which is our starting guess.
  FunctionSample initial_position(0.0, initial_cost, initial_gradient);
  initial_position.vector_x = function->position();
  initial_position.vector_x_is_valid = true;

  const double descent_direction_max_norm = function->DirectionInfinityNorm();
  FunctionSample previous;
  FunctionSample current;

  // As the Armijo line search algorithm always uses the initial point, for
  // which both the function value and derivative are known, when fitting a
  // minimizing polynomial, we can fit up to a quadratic without requiring the
  // gradient at the current query point.
  const bool kEvaluateGradient = options().interpolation_type == CUBIC;

  ++summary->num_function_evaluations;
  if (kEvaluateGradient) {
    ++summary->num_gradient_evaluations;
  }

  function->Evaluate(step_size_estimate, kEvaluateGradient, &current);
  while (!current.value_is_valid ||
         current.value > (initial_cost
                          + options().sufficient_decrease
                          * initial_gradient
                          * current.x)) {
    // If current.value_is_valid is false, we treat it as if the cost at that
    // point is not large enough to satisfy the sufficient decrease condition.
    ++summary->num_iterations;
    if (summary->num_iterations >= options().max_num_iterations) {
      summary->error =
          StringPrintf("Line search failed: Armijo failed to find a point "
                       "satisfying the sufficient decrease condition within "
                       "specified max_num_iterations: %d.",
                       options().max_num_iterations);
      LOG_IF(WARNING, !options().is_silent) << summary->error;
      return;
    }

    const double polynomial_minimization_start_time = WallTimeInSeconds();
    const double step_size =
        this->InterpolatingPolynomialMinimizingStepSize(
            options().interpolation_type,
            initial_position,
            previous,
            current,
            (options().max_step_contraction * current.x),
            (options().min_step_contraction * current.x));
    summary->polynomial_minimization_time_in_seconds +=
        (WallTimeInSeconds() - polynomial_minimization_start_time);

    if (step_size * descent_direction_max_norm < options().min_step_size) {
      summary->error =
          StringPrintf("Line search failed: step_size too small: %.5e "
                       "with descent_direction_max_norm: %.5e.", step_size,
                       descent_direction_max_norm);
      LOG_IF(WARNING, !options().is_silent) << summary->error;
      return;
    }

    previous = current;

    ++summary->num_function_evaluations;
    if (kEvaluateGradient) {
      ++summary->num_gradient_evaluations;
    }

    function->Evaluate(step_size, kEvaluateGradient, &current);
  }

  summary->optimal_point = current;
  summary->success = true;
}

WolfeLineSearch::WolfeLineSearch(const LineSearch::Options& options)
    : LineSearch(options) {}

void WolfeLineSearch::DoSearch(const double step_size_estimate,
                               const double initial_cost,
                               const double initial_gradient,
                               Summary* summary) const {
  // All parameters should have been validated by the Solver, but as
  // invalid values would produce crazy nonsense, hard check them here.
  CHECK_GE(step_size_estimate, 0.0);
  CHECK_GT(options().sufficient_decrease, 0.0);
  CHECK_GT(options().sufficient_curvature_decrease,
           options().sufficient_decrease);
  CHECK_LT(options().sufficient_curvature_decrease, 1.0);
  CHECK_GT(options().max_step_expansion, 1.0);

  // Note initial_cost & initial_gradient are evaluated at step_size = 0,
  // not step_size_estimate, which is our starting guess.
  FunctionSample initial_position(0.0, initial_cost, initial_gradient);
  initial_position.vector_x = options().function->position();
  initial_position.vector_x_is_valid = true;
  bool do_zoom_search = false;
  // Important: The high/low in bracket_high & bracket_low refer to their
  // _function_ values, not their step sizes i.e. it is _not_ required that
  // bracket_low.x < bracket_high.x.
  FunctionSample solution, bracket_low, bracket_high;

  // Wolfe bracketing phase: Increases step_size until either it finds a point
  // that satisfies the (strong) Wolfe conditions, or an interval that brackets
  // step sizes which satisfy the conditions.  From Nocedal & Wright [1] p61 the
  // interval: (step_size_{k-1}, step_size_{k}) contains step lengths satisfying
  // the strong Wolfe conditions if one of the following conditions are met:
  //
  //   1. step_size_{k} violates the sufficient decrease (Armijo) condition.
  //   2. f(step_size_{k}) >= f(step_size_{k-1}).
  //   3. f'(step_size_{k}) >= 0.
  //
  // Caveat: If f(step_size_{k}) is invalid, then step_size is reduced, ignoring
  // this special case, step_size monotonically increases during bracketing.
  if (!this->BracketingPhase(initial_position,
                             step_size_estimate,
                             &bracket_low,
                             &bracket_high,
                             &do_zoom_search,
                             summary)) {
    // Failed to find either a valid point, a valid bracket satisfying the Wolfe
    // conditions, or even a step size > minimum tolerance satisfying the Armijo
    // condition.
    return;
  }

  if (!do_zoom_search) {
    // Either: Bracketing phase already found a point satisfying the strong
    // Wolfe conditions, thus no Zoom required.
    //
    // Or: Bracketing failed to find a valid bracket or a point satisfying the
    // strong Wolfe conditions within max_num_iterations, or whilst searching
    // shrank the bracket width until it was below our minimum tolerance.
    // As these are 'artificial' constraints, and we would otherwise fail to
    // produce a valid point when ArmijoLineSearch would succeed, we return the
    // point with the lowest cost found thus far which satsifies the Armijo
    // condition (but not the Wolfe conditions).
    summary->optimal_point = bracket_low;
    summary->success = true;
    return;
  }

  VLOG(3) << std::scientific << std::setprecision(kErrorMessageNumericPrecision)
          << "Starting line search zoom phase with bracket_low: "
          << bracket_low << ", bracket_high: " << bracket_high
          << ", bracket width: " << fabs(bracket_low.x - bracket_high.x)
          << ", bracket abs delta cost: "
          << fabs(bracket_low.value - bracket_high.value);

  // Wolfe Zoom phase: Called when the Bracketing phase finds an interval of
  // non-zero, finite width that should bracket step sizes which satisfy the
  // (strong) Wolfe conditions (before finding a step size that satisfies the
  // conditions).  Zoom successively decreases the size of the interval until a
  // step size which satisfies the Wolfe conditions is found.  The interval is
  // defined by bracket_low & bracket_high, which satisfy:
  //
  //   1. The interval bounded by step sizes: bracket_low.x & bracket_high.x
  //      contains step sizes that satsify the strong Wolfe conditions.
  //   2. bracket_low.x is of all the step sizes evaluated *which satisifed the
  //      Armijo sufficient decrease condition*, the one which generated the
  //      smallest function value, i.e. bracket_low.value <
  //      f(all other steps satisfying Armijo).
  //        - Note that this does _not_ (necessarily) mean that initially
  //          bracket_low.value < bracket_high.value (although this is typical)
  //          e.g. when bracket_low = initial_position, and bracket_high is the
  //          first sample, and which does not satisfy the Armijo condition,
  //          but still has bracket_high.value < initial_position.value.
  //   3. bracket_high is chosen after bracket_low, s.t.
  //      bracket_low.gradient * (bracket_high.x - bracket_low.x) < 0.
  if (!this->ZoomPhase(initial_position,
                       bracket_low,
                       bracket_high,
                       &solution,
                       summary) && !solution.value_is_valid) {
    // Failed to find a valid point (given the specified decrease parameters)
    // within the specified bracket.
    return;
  }
  // Ensure that if we ran out of iterations whilst zooming the bracket, or
  // shrank the bracket width to < tolerance and failed to find a point which
  // satisfies the strong Wolfe curvature condition, that we return the point
  // amongst those found thus far, which minimizes f() and satisfies the Armijo
  // condition.

  if (!solution.value_is_valid || solution.value > bracket_low.value) {
    summary->optimal_point = bracket_low;
  } else {
    summary->optimal_point = solution;
  }

  summary->success = true;
}

// Returns true if either:
//
// A termination condition satisfying the (strong) Wolfe bracketing conditions
// is found:
//
// - A valid point, defined as a bracket of zero width [zoom not required].
// - A valid bracket (of width > tolerance), [zoom required].
//
// Or, searching was stopped due to an 'artificial' constraint, i.e. not
// a condition imposed / required by the underlying algorithm, but instead an
// engineering / implementation consideration. But a step which exceeds the
// minimum step size, and satsifies the Armijo condition was still found,
// and should thus be used [zoom not required].
//
// Returns false if no step size > minimum step size was found which
// satisfies at least the Armijo condition.
bool WolfeLineSearch::BracketingPhase(
    const FunctionSample& initial_position,
    const double step_size_estimate,
    FunctionSample* bracket_low,
    FunctionSample* bracket_high,
    bool* do_zoom_search,
    Summary* summary) const {
  LineSearchFunction* function = options().function;

  FunctionSample previous = initial_position;
  FunctionSample current;

  const double descent_direction_max_norm =
      function->DirectionInfinityNorm();

  *do_zoom_search = false;
  *bracket_low = initial_position;

  // As we require the gradient to evaluate the Wolfe condition, we always
  // calculate it together with the value, irrespective of the interpolation
  // type.  As opposed to only calculating the gradient after the Armijo
  // condition is satisifed, as the computational saving from this approach
  // would be slight (perhaps even negative due to the extra call).  Also,
  // always calculating the value & gradient together protects against us
  // reporting invalid solutions if the cost function returns slightly different
  // function values when evaluated with / without gradients (due to numerical
  // issues).
  ++summary->num_function_evaluations;
  ++summary->num_gradient_evaluations;
  const bool kEvaluateGradient = true;
  function->Evaluate(step_size_estimate, kEvaluateGradient, &current);
  while (true) {
    ++summary->num_iterations;

    if (current.value_is_valid &&
        (current.value > (initial_position.value
                          + options().sufficient_decrease
                          * initial_position.gradient
                          * current.x) ||
         (previous.value_is_valid && current.value > previous.value))) {
      // Bracket found: current step size violates Armijo sufficient decrease
      // condition, or has stepped past an inflection point of f() relative to
      // previous step size.
      *do_zoom_search = true;
      *bracket_low = previous;
      *bracket_high = current;
      VLOG(3) << std::scientific
              << std::setprecision(kErrorMessageNumericPrecision)
              << "Bracket found: current step (" << current.x
              << ") violates Armijo sufficient condition, or has passed an "
              << "inflection point of f() based on value.";
      break;
    }

    if (current.value_is_valid &&
        fabs(current.gradient) <=
        -options().sufficient_curvature_decrease * initial_position.gradient) {
      // Current step size satisfies the strong Wolfe conditions, and is thus a
      // valid termination point, therefore a Zoom not required.
      *bracket_low = current;
      *bracket_high = current;
      VLOG(3) << std::scientific
              << std::setprecision(kErrorMessageNumericPrecision)
              << "Bracketing phase found step size: " << current.x
              << ", satisfying strong Wolfe conditions, initial_position: "
              << initial_position << ", current: " << current;
      break;

    } else if (current.value_is_valid && current.gradient >= 0) {
      // Bracket found: current step size has stepped past an inflection point
      // of f(), but Armijo sufficient decrease is still satisfied and
      // f(current) is our best minimum thus far.  Remember step size
      // monotonically increases, thus previous_step_size < current_step_size
      // even though f(previous) > f(current).
      *do_zoom_search = true;
      // Note inverse ordering from first bracket case.
      *bracket_low = current;
      *bracket_high = previous;
      VLOG(3) << "Bracket found: current step (" << current.x
              << ") satisfies Armijo, but has gradient >= 0, thus have passed "
              << "an inflection point of f().";
      break;

    } else if (current.value_is_valid &&
               fabs(current.x - previous.x) * descent_direction_max_norm
               < options().min_step_size) {
      // We have shrunk the search bracket to a width less than our tolerance,
      // and still not found either a point satisfying the strong Wolfe
      // conditions, or a valid bracket containing such a point. Stop searching
      // and set bracket_low to the size size amongst all those tested which
      // minimizes f() and satisfies the Armijo condition.
      LOG_IF(WARNING, !options().is_silent)
          << "Line search failed: Wolfe bracketing phase shrank "
          << "bracket width: " << fabs(current.x - previous.x)
          <<  ", to < tolerance: " << options().min_step_size
          << ", with descent_direction_max_norm: "
          << descent_direction_max_norm << ", and failed to find "
          << "a point satisfying the strong Wolfe conditions or a "
          << "bracketing containing such a point. Accepting "
          << "point found satisfying Armijo condition only, to "
          << "allow continuation.";
      *bracket_low = current;
      break;

    } else if (summary->num_iterations >= options().max_num_iterations) {
      // Check num iterations bound here so that we always evaluate the
      // max_num_iterations-th iteration against all conditions, and
      // then perform no additional (unused) evaluations.
      summary->error =
          StringPrintf("Line search failed: Wolfe bracketing phase failed to "
                       "find a point satisfying strong Wolfe conditions, or a "
                       "bracket containing such a point within specified "
                       "max_num_iterations: %d", options().max_num_iterations);
      LOG_IF(WARNING, !options().is_silent) << summary->error;
      // Ensure that bracket_low is always set to the step size amongst all
      // those tested which minimizes f() and satisfies the Armijo condition
      // when we terminate due to the 'artificial' max_num_iterations condition.
      *bracket_low =
          current.value_is_valid && current.value < bracket_low->value
          ? current : *bracket_low;
      break;
    }
    // Either: f(current) is invalid; or, f(current) is valid, but does not
    // satisfy the strong Wolfe conditions itself, or the conditions for
    // being a boundary of a bracket.

    // If f(current) is valid, (but meets no criteria) expand the search by
    // increasing the step size.
    const double max_step_size =
        current.value_is_valid
        ? (current.x * options().max_step_expansion) : current.x;

    // We are performing 2-point interpolation only here, but the API of
    // InterpolatingPolynomialMinimizingStepSize() allows for up to
    // 3-point interpolation, so pad call with a sample with an invalid
    // value that will therefore be ignored.
    const FunctionSample unused_previous;
    DCHECK(!unused_previous.value_is_valid);
    // Contracts step size if f(current) is not valid.
    const double polynomial_minimization_start_time = WallTimeInSeconds();
    const double step_size =
        this->InterpolatingPolynomialMinimizingStepSize(
            options().interpolation_type,
            previous,
            unused_previous,
            current,
            previous.x,
            max_step_size);
    summary->polynomial_minimization_time_in_seconds +=
        (WallTimeInSeconds() - polynomial_minimization_start_time);
    if (step_size * descent_direction_max_norm < options().min_step_size) {
      summary->error =
          StringPrintf("Line search failed: step_size too small: %.5e "
                       "with descent_direction_max_norm: %.5e", step_size,
                       descent_direction_max_norm);
      LOG_IF(WARNING, !options().is_silent) << summary->error;
      return false;
    }

    previous = current.value_is_valid ? current : previous;
    ++summary->num_function_evaluations;
    ++summary->num_gradient_evaluations;
    function->Evaluate(step_size, kEvaluateGradient, &current);
  }

  // Ensure that even if a valid bracket was found, we will only mark a zoom
  // as required if the bracket's width is greater than our minimum tolerance.
  if (*do_zoom_search &&
      fabs(bracket_high->x - bracket_low->x) * descent_direction_max_norm
      < options().min_step_size) {
    *do_zoom_search = false;
  }

  return true;
}

// Returns true iff solution satisfies the strong Wolfe conditions. Otherwise,
// on return false, if we stopped searching due to the 'artificial' condition of
// reaching max_num_iterations, solution is the step size amongst all those
// tested, which satisfied the Armijo decrease condition and minimized f().
bool WolfeLineSearch::ZoomPhase(const FunctionSample& initial_position,
                                FunctionSample bracket_low,
                                FunctionSample bracket_high,
                                FunctionSample* solution,
                                Summary* summary) const {
  LineSearchFunction* function = options().function;

  CHECK(bracket_low.value_is_valid && bracket_low.gradient_is_valid)
      << std::scientific << std::setprecision(kErrorMessageNumericPrecision)
      << "Ceres bug: f_low input to Wolfe Zoom invalid, please contact "
      << "the developers!, initial_position: " << initial_position
      << ", bracket_low: " << bracket_low
      << ", bracket_high: "<< bracket_high;
  // We do not require bracket_high.gradient_is_valid as the gradient condition
  // for a valid bracket is only dependent upon bracket_low.gradient, and
  // in order to minimize jacobian evaluations, bracket_high.gradient may
  // not have been calculated (if bracket_high.value does not satisfy the
  // Armijo sufficient decrease condition and interpolation method does not
  // require it).
  //
  // We also do not require that: bracket_low.value < bracket_high.value,
  // although this is typical. This is to deal with the case when
  // bracket_low = initial_position, bracket_high is the first sample,
  // and bracket_high does not satisfy the Armijo condition, but still has
  // bracket_high.value < initial_position.value.
  CHECK(bracket_high.value_is_valid)
      << std::scientific << std::setprecision(kErrorMessageNumericPrecision)
      << "Ceres bug: f_high input to Wolfe Zoom invalid, please "
      << "contact the developers!, initial_position: " << initial_position
      << ", bracket_low: " << bracket_low
      << ", bracket_high: "<< bracket_high;

  if (bracket_low.gradient * (bracket_high.x - bracket_low.x) >= 0) {
    // The third condition for a valid initial bracket:
    //
    //   3. bracket_high is chosen after bracket_low, s.t.
    //      bracket_low.gradient * (bracket_high.x - bracket_low.x) < 0.
    //
    // is not satisfied.  As this can happen when the users' cost function
    // returns inconsistent gradient values relative to the function values,
    // we do not CHECK_LT(), but we do stop processing and return an invalid
    // value.
    summary->error =
        StringPrintf("Line search failed: Wolfe zoom phase passed a bracket "
                     "which does not satisfy: bracket_low.gradient * "
                     "(bracket_high.x - bracket_low.x) < 0 [%.8e !< 0] "
                     "with initial_position: %s, bracket_low: %s, bracket_high:"
                     " %s, the most likely cause of which is the cost function "
                     "returning inconsistent gradient & function values.",
                     bracket_low.gradient * (bracket_high.x - bracket_low.x),
                     initial_position.ToDebugString().c_str(),
                     bracket_low.ToDebugString().c_str(),
                     bracket_high.ToDebugString().c_str());
    LOG_IF(WARNING, !options().is_silent) << summary->error;
    solution->value_is_valid = false;
    return false;
  }

  const int num_bracketing_iterations = summary->num_iterations;
  const double descent_direction_max_norm = function->DirectionInfinityNorm();

  while (true) {
    // Set solution to bracket_low, as it is our best step size (smallest f())
    // found thus far and satisfies the Armijo condition, even though it does
    // not satisfy the Wolfe condition.
    *solution = bracket_low;
    if (summary->num_iterations >= options().max_num_iterations) {
      summary->error =
          StringPrintf("Line search failed: Wolfe zoom phase failed to "
                       "find a point satisfying strong Wolfe conditions "
                       "within specified max_num_iterations: %d, "
                       "(num iterations taken for bracketing: %d).",
                       options().max_num_iterations, num_bracketing_iterations);
      LOG_IF(WARNING, !options().is_silent) << summary->error;
      return false;
    }
    if (fabs(bracket_high.x - bracket_low.x) * descent_direction_max_norm
        < options().min_step_size) {
      // Bracket width has been reduced below tolerance, and no point satisfying
      // the strong Wolfe conditions has been found.
      summary->error =
          StringPrintf("Line search failed: Wolfe zoom bracket width: %.5e "
                       "too small with descent_direction_max_norm: %.5e.",
                       fabs(bracket_high.x - bracket_low.x),
                       descent_direction_max_norm);
      LOG_IF(WARNING, !options().is_silent) << summary->error;
      return false;
    }

    ++summary->num_iterations;
    // Polynomial interpolation requires inputs ordered according to step size,
    // not f(step size).
    const FunctionSample& lower_bound_step =
        bracket_low.x < bracket_high.x ? bracket_low : bracket_high;
    const FunctionSample& upper_bound_step =
        bracket_low.x < bracket_high.x ? bracket_high : bracket_low;
    // We are performing 2-point interpolation only here, but the API of
    // InterpolatingPolynomialMinimizingStepSize() allows for up to
    // 3-point interpolation, so pad call with a sample with an invalid
    // value that will therefore be ignored.
    const FunctionSample unused_previous;
    DCHECK(!unused_previous.value_is_valid);
    const double polynomial_minimization_start_time = WallTimeInSeconds();
    const double step_size =
        this->InterpolatingPolynomialMinimizingStepSize(
            options().interpolation_type,
            lower_bound_step,
            unused_previous,
            upper_bound_step,
            lower_bound_step.x,
            upper_bound_step.x);
    summary->polynomial_minimization_time_in_seconds +=
        (WallTimeInSeconds() - polynomial_minimization_start_time);
    // No check on magnitude of step size being too small here as it is
    // lower-bounded by the initial bracket start point, which was valid.
    //
    // As we require the gradient to evaluate the Wolfe condition, we always
    // calculate it together with the value, irrespective of the interpolation
    // type.  As opposed to only calculating the gradient after the Armijo
    // condition is satisifed, as the computational saving from this approach
    // would be slight (perhaps even negative due to the extra call).  Also,
    // always calculating the value & gradient together protects against us
    // reporting invalid solutions if the cost function returns slightly
    // different function values when evaluated with / without gradients (due
    // to numerical issues).
    ++summary->num_function_evaluations;
    ++summary->num_gradient_evaluations;
    const bool kEvaluateGradient = true;
    function->Evaluate(step_size, kEvaluateGradient, solution);
    if (!solution->value_is_valid || !solution->gradient_is_valid) {
      summary->error =
          StringPrintf("Line search failed: Wolfe Zoom phase found "
                       "step_size: %.5e, for which function is invalid, "
                       "between low_step: %.5e and high_step: %.5e "
                       "at which function is valid.",
                       solution->x, bracket_low.x, bracket_high.x);
      LOG_IF(WARNING, !options().is_silent) << summary->error;
      return false;
    }

    VLOG(3) << "Zoom iteration: "
            << summary->num_iterations - num_bracketing_iterations
            << ", bracket_low: " << bracket_low
            << ", bracket_high: " << bracket_high
            << ", minimizing solution: " << *solution;

    if ((solution->value > (initial_position.value
                            + options().sufficient_decrease
                            * initial_position.gradient
                            * solution->x)) ||
        (solution->value >= bracket_low.value)) {
      // Armijo sufficient decrease not satisfied, or not better
      // than current lowest sample, use as new upper bound.
      bracket_high = *solution;
      continue;
    }

    // Armijo sufficient decrease satisfied, check strong Wolfe condition.
    if (fabs(solution->gradient) <=
        -options().sufficient_curvature_decrease * initial_position.gradient) {
      // Found a valid termination point satisfying strong Wolfe conditions.
      VLOG(3) << std::scientific
              << std::setprecision(kErrorMessageNumericPrecision)
              << "Zoom phase found step size: " << solution->x
              << ", satisfying strong Wolfe conditions.";
      break;

    } else if (solution->gradient * (bracket_high.x - bracket_low.x) >= 0) {
      bracket_high = bracket_low;
    }

    bracket_low = *solution;
  }
  // Solution contains a valid point which satisfies the strong Wolfe
  // conditions.
  return true;
}

}  // namespace internal
}  // namespace ceres
