86 const Vector& xp,
const Vector& drt,
const Scalar& step_max,
87 Scalar& step, Scalar& fx, Vector& grad, Scalar& dg, Vector& x)
92 if (step <= Scalar(0))
93 throw std::invalid_argument(
"'step' must be positive");
96 throw std::invalid_argument(
"'param.linesearch' must be 'LBFGS_LINESEARCH_BACKTRACKING_STRONG_WOLFE' for LineSearchNocedalWright");
109 const Scalar expansion = Scalar(2);
112 const Scalar fx_init = fx;
114 const Scalar dg_init = dg;
116 if (dg_init > Scalar(0))
117 throw std::logic_error(
"the moving direction increases the objective function value");
119 const Scalar test_decr = param.
ftol * dg_init,
120 test_curv = -param.
wolfe * dg_init;
124 Scalar step_hi, fx_hi;
125 Scalar step_lo = Scalar(0), fx_lo = fx_init, dg_lo = dg_init;
128 Vector x_lo = xp, grad_lo = grad;
146 x.noalias() = xp + step * drt;
151 if (fx - fx_init > step * test_decr || (Scalar(0) < step_lo && fx >= fx_lo))
162 if (abs(dg) <= test_curv)
216 step = quad_interp(step_lo, step_hi, fx_lo, fx_hi, dg_lo);
219 x.noalias() = xp + step * drt;
224 if (fx - fx_init > step * test_decr || fx >= fx_lo)
227 throw std::runtime_error(
"the line search routine failed, possibly due to insufficient numeric precision");
236 if (abs(dg) <= test_curv)
239 if (dg * (step_hi - step_lo) >= Scalar(0))
247 throw std::runtime_error(
"the line search routine failed, possibly due to insufficient numeric precision");
266 if (step_lo <= Scalar(0))
267 throw std::runtime_error(
"the line search routine failed, unable to sufficiently decrease the function value");