17 : is_init(
false), is_psd(
false), x_prev(), g_prev(), s(), y(),
18 xx_transpose(), xy_transpose(), V(), VMinv(), VMinvVt(),
21 explicit BFGSStrategy(
const int num_vars)
22 : is_init(
false), is_psd(
true), x_prev(VectorXs::Zero(num_vars)),
23 g_prev(VectorXs::Zero(num_vars)), s(VectorXs::Zero(num_vars)),
24 y(VectorXs::Zero(num_vars)),
25 xx_transpose(MatrixXs::Zero(num_vars, num_vars)),
26 xy_transpose(MatrixXs::Zero(num_vars, num_vars)),
27 V(MatrixXs::Zero(num_vars, num_vars)),
28 VMinv(MatrixXs::Zero(num_vars, num_vars)),
29 VMinvVt(MatrixXs::Zero(num_vars, num_vars)), is_valid(
true) {
30 x_prev = VectorXs::Zero(num_vars);
31 g_prev = VectorXs::Zero(num_vars);
34 void init(
const ConstVectorRef &x0,
const ConstVectorRef &g0) {
36 throw std::runtime_error(
"Cannot initialize an invalid BFGSStrategy. Use "
37 "the constructor with num_vars first.");
45 void update(
const ConstVectorRef &x,
const ConstVectorRef &g,
54 const Scalar sy = s.dot(y);
57 if constexpr (BFGS_TYPE == BFGSType::InverseHessian) {
60 xx_transpose.noalias() = s * s.transpose();
61 xy_transpose.noalias() = s * y.transpose();
62 }
else if constexpr (BFGS_TYPE == BFGSType::Hessian) {
65 xx_transpose.noalias() = y * y.transpose();
66 xy_transpose.noalias() = y * s.transpose();
69 V.noalias() = MatrixXs::Identity(s.size(), s.size()) - xy_transpose / sy;
70 VMinv.noalias() = V * hessian;
71 VMinvVt.noalias() = VMinv * V.transpose();
72 hessian.noalias() = VMinvVt + xx_transpose / sy;
76 PROXSUITE_NLP_WARN(
"Skipping BFGS update as s^Ty <= 0");
82 bool isValid()
const {
return is_valid; }
94 MatrixXs xx_transpose;
95 MatrixXs xy_transpose;