50 const Vector& xp,
const Vector& drt,
const Scalar& step_max,
51 Scalar& step, Scalar& fx, Vector& grad, Scalar& dg, Vector& x)
54 if (step <= Scalar(0))
55 throw std::invalid_argument(
"'step' must be positive");
58 const Scalar fx_init = fx;
60 const Scalar dg_init = grad.dot(drt);
63 throw std::logic_error(
"the moving direction increases the objective function value");
65 const Scalar test_decr = param.
ftol * dg_init;
69 step_hi = std::numeric_limits<Scalar>::infinity();
75 x.noalias() = xp + step * drt;
79 if (fx > fx_init + step * test_decr || (!std::isfinite(fx)))
91 if (dg < param.
wolfe * dg_init)
101 if (dg > -param.
wolfe * dg_init)
113 if (step_lo > step_hi)
114 throw std::runtime_error(
"the lower bound of the bracketing interval becomes larger than the upper bound");
117 throw std::runtime_error(
"the line search step became smaller than the minimum value allowed");
120 throw std::runtime_error(
"the line search step became larger than the maximum value allowed");
123 step = std::isinf(step_hi) ? 2 * step : step_lo / 2 + step_hi / 2;
127 throw std::runtime_error(
"the line search routine reached the maximum number of iterations");