proxsuite-nlp  0.11.0
A primal-dual augmented Lagrangian-type solver for nonlinear programming on manifolds.
 
Loading...
Searching...
No Matches
bfgs-strategy.hpp
Go to the documentation of this file.
1
3#pragma once
5
6namespace proxsuite {
7namespace nlp {
8
9enum BFGSType { Hessian, InverseHessian };
10
11template <typename Scalar, BFGSType BFGS_TYPE = BFGSType::InverseHessian>
12class BFGSStrategy {
14
15public:
16 BFGSStrategy()
17 : is_init(false), is_psd(false), x_prev(), g_prev(), s(), y(),
18 xx_transpose(), xy_transpose(), V(), VMinv(), VMinvVt(),
19 is_valid(false) {}
20
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);
32 }
33
34 void init(const ConstVectorRef &x0, const ConstVectorRef &g0) {
35 if (!is_valid) {
36 throw std::runtime_error("Cannot initialize an invalid BFGSStrategy. Use "
37 "the constructor with num_vars first.");
38 }
39
40 x_prev = x0;
41 g_prev = g0;
42 is_init = true;
43 }
44
45 void update(const ConstVectorRef &x, const ConstVectorRef &g,
46 MatrixXs &hessian) {
47 if (!is_init) {
48 init(x, g);
49 return;
50 }
52 s = x - x_prev;
53 y = g - g_prev;
54 const Scalar sy = s.dot(y);
55
56 if (sy > 0) {
57 if constexpr (BFGS_TYPE == BFGSType::InverseHessian) {
58 // Nocedal and Wright, Numerical Optimization, 2nd ed., p. 140, eqn 6.17
59 // (BFGS update)
60 xx_transpose.noalias() = s * s.transpose();
61 xy_transpose.noalias() = s * y.transpose();
62 } else if constexpr (BFGS_TYPE == BFGSType::Hessian) {
63 // Nocedal and Wright, Numerical Optimization, 2nd ed., p. 139, eqn 6.13
64 // (DFP update)
65 xx_transpose.noalias() = y * y.transpose();
66 xy_transpose.noalias() = y * s.transpose();
67 }
68
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;
73 is_psd = true;
74 } else {
75 is_psd = false;
76 PROXSUITE_NLP_WARN("Skipping BFGS update as s^Ty <= 0");
77 }
78 x_prev = x;
79 g_prev = g;
81 }
82 bool isValid() const { return is_valid; }
83
84public:
85 bool is_init;
86 bool is_psd;
87
88private:
89 VectorXs x_prev; // previous iterate
90 VectorXs g_prev; // previous gradient
91 VectorXs s; // delta iterate
92 VectorXs y; // delta gradient
93 // temporary variables to avoid dynamic memory allocation
94 MatrixXs xx_transpose;
95 MatrixXs xy_transpose;
96 MatrixXs V;
97 MatrixXs VMinv;
98 MatrixXs VMinvVt;
99 bool is_valid;
100};
101
102} // namespace nlp
103} // namespace proxsuite
Forward declarations and configuration macros.
#define PROXSUITE_NLP_NOMALLOC_END
Exiting performance-critical code.
Definition macros.hpp:23
#define PROXSUITE_NLP_NOMALLOC_BEGIN
Entering performance-critical code.
Definition macros.hpp:20
#define PROXSUITE_NLP_DYNAMIC_TYPEDEFS(Scalar)
Definition math.hpp:26
Main package namespace.
Definition bcl-params.hpp:5