1 #ifndef STAN__OPTIMIZATION__LBFGS_UPDATE_HPP
2 #define STAN__OPTIMIZATION__LBFGS_UPDATE_HPP
6 #include <boost/tuple/tuple.hpp>
7 #include <boost/circular_buffer.hpp>
12 namespace optimization {
18 template<
typename Scalar = double,
19 int DimAtCompile = Eigen::Dynamic>
22 typedef Eigen::Matrix<Scalar,DimAtCompile,1>
VectorT;
23 typedef Eigen::Matrix<Scalar,DimAtCompile,DimAtCompile>
HessianT;
24 typedef boost::tuple<Scalar,VectorT,VectorT>
UpdateT;
34 _buf.rset_capacity(L);
50 Scalar skyk = yk.dot(sk);
54 B0fact = yk.squaredNorm()/skyk;
62 Scalar invskyk = 1.0/skyk;
63 _gammak = skyk/yk.squaredNorm();
65 _buf.back() = boost::tie(invskyk,yk,sk);
79 std::vector<Scalar> alphas(
_buf.size());
80 typename boost::circular_buffer<UpdateT>::const_reverse_iterator buf_rit;
81 typename boost::circular_buffer<UpdateT>::const_iterator buf_it;
82 typename std::vector<Scalar>::const_iterator alpha_it;
83 typename std::vector<Scalar>::reverse_iterator alpha_rit;
86 for (buf_rit =
_buf.rbegin(), alpha_rit = alphas.rbegin();
87 buf_rit !=
_buf.rend();
88 buf_rit++, alpha_rit++) {
90 const Scalar &rhoi(boost::get<0>(*buf_rit));
91 const VectorT &yi(boost::get<1>(*buf_rit));
92 const VectorT &si(boost::get<2>(*buf_rit));
94 alpha = rhoi * si.dot(pk);
99 for (buf_it =
_buf.begin(), alpha_it = alphas.begin();
100 buf_it !=
_buf.end();
101 buf_it++, alpha_it++) {
103 const Scalar &rhoi(boost::get<0>(*buf_it));
104 const VectorT &yi(boost::get<1>(*buf_it));
105 const VectorT &si(boost::get<2>(*buf_it));
107 beta = rhoi*yi.dot(pk);
108 pk += (*alpha_it - beta)*si;
113 boost::circular_buffer<UpdateT>
_buf;
void search_direction(VectorT &pk, const VectorT &gk) const
Compute the search direction based on the current (inverse) Hessian approximation and given gradient...
Eigen::Matrix< Scalar, DimAtCompile, DimAtCompile > HessianT
Scalar update(const VectorT &yk, const VectorT &sk, bool reset=false)
Add a new set of update vectors to the history.
boost::circular_buffer< UpdateT > _buf
void set_history_size(size_t L)
Set the number of inverse Hessian updates to keep.
boost::tuple< Scalar, VectorT, VectorT > UpdateT
Eigen::Matrix< Scalar, DimAtCompile, 1 > VectorT
Implement a limited memory version of the BFGS update.