LBFGS++ 0.4.0
A header-only C++ library for L-BFGS and L-BFGS-B algorithms.
Loading...
Searching...
No Matches
LineSearchBacktracking.h
1// Copyright (C) 2016-2026 Yixuan Qiu <yixuan.qiu@cos.name>
2// Under MIT license
3
4#ifndef LBFGSPP_LINE_SEARCH_BACKTRACKING_H
5#define LBFGSPP_LINE_SEARCH_BACKTRACKING_H
6
7#include <Eigen/Core>
8#include <stdexcept> // std::runtime_error
9#include "Param.h"
10
11namespace LBFGSpp {
12
16template <typename Scalar>
18{
19private:
20 using Vector = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
21
22public:
44 template <typename Foo>
45 static void LineSearch(Foo& f, const LBFGSParam<Scalar>& param,
46 const Vector& xp, const Vector& drt, const Scalar& step_max,
47 Scalar& step, Scalar& fx, Vector& grad, Scalar& dg, Vector& x)
48 {
49 // Decreasing and increasing factors
50 const Scalar dec = 0.5;
51 const Scalar inc = 2.1;
52
53 // Check the value of step
54 if (step <= Scalar(0))
55 throw std::invalid_argument("'step' must be positive");
56
57 // Save the function value at the current x
58 const Scalar fx_init = fx;
59 // Projection of gradient on the search direction
60 const Scalar dg_init = grad.dot(drt);
61 // Make sure d points to a descent direction
62 if (dg_init > 0)
63 throw std::logic_error("the moving direction increases the objective function value");
64
65 const Scalar test_decr = param.ftol * dg_init;
66 Scalar width;
67
68 int iter;
69 for (iter = 0; iter < param.max_linesearch; iter++)
70 {
71 // x_{k+1} = x_k + step * d_k
72 x.noalias() = xp + step * drt;
73 // Evaluate this candidate
74 fx = f(x, grad);
75
76 if (fx > fx_init + step * test_decr || (fx != fx))
77 {
78 width = dec;
79 }
80 else
81 {
82 dg = grad.dot(drt);
83
84 // Armijo condition is met
86 break;
87
88 if (dg < param.wolfe * dg_init)
89 {
90 width = inc;
91 }
92 else
93 {
94 // Regular Wolfe condition is met
96 break;
97
98 if (dg > -param.wolfe * dg_init)
99 {
100 width = dec;
101 }
102 else
103 {
104 // Strong Wolfe condition is met
105 break;
106 }
107 }
108 }
109
110 if (step < param.min_step)
111 throw std::runtime_error("the line search step became smaller than the minimum value allowed");
112
113 if (step > param.max_step)
114 throw std::runtime_error("the line search step became larger than the maximum value allowed");
115
116 step *= width;
117 }
118
119 if (iter >= param.max_linesearch)
120 throw std::runtime_error("the line search routine reached the maximum number of iterations");
121 }
122};
123
124} // namespace LBFGSpp
125
126#endif // LBFGSPP_LINE_SEARCH_BACKTRACKING_H
static void LineSearch(Foo &f, const LBFGSParam< Scalar > &param, const Vector &xp, const Vector &drt, const Scalar &step_max, Scalar &step, Scalar &fx, Vector &grad, Scalar &dg, Vector &x)
@ LBFGS_LINESEARCH_BACKTRACKING_ARMIJO
Definition Param.h:35
@ LBFGS_LINESEARCH_BACKTRACKING_WOLFE
Definition Param.h:51