11 [[maybe_unused]]
crvec x_0, [[maybe_unused]]
crvec x̂_0,
12 [[maybe_unused]]
crvec p_0, [[maybe_unused]]
crvec grad_ψx_0) {
14 throw std::invalid_argument(
15 "Structured L-BFGS requires eval_inactive_indices_res_lna()");
16 if (direction_params.hessian_vec &&
17 !direction_params.hessian_vec_finite_differences &&
18 !direction_params.full_augmented_hessian &&
20 throw std::invalid_argument(
21 "Structured L-BFGS requires eval_hess_L_prod(). Alternatively, set "
22 "hessian_vec = false or hessian_vec_finite_differences = true.");
23 if (direction_params.hessian_vec &&
24 !direction_params.hessian_vec_finite_differences &&
25 direction_params.full_augmented_hessian &&
28 throw std::invalid_argument(
29 "Structured L-BFGS requires _eval_hess_ψ_prod() or "
30 "eval_hess_L_prod(). Alternatively, set "
31 "hessian_vec = false or hessian_vec_finite_differences = true.");
32 if (direction_params.hessian_vec &&
33 !direction_params.hessian_vec_finite_differences &&
34 direction_params.full_augmented_hessian &&
37 throw std::invalid_argument(
38 "Structured L-BFGS requires either eval_hess_ψ_prod() or "
39 "get_box_D() and eval_grad_gi(). Alternatively, set hessian_vec = "
40 "false, hessian_vec_finite_differences = true, or "
41 "full_augmented_hessian = false.");
43 this->problem = &problem;
47 const auto n = problem.
get_n();
48 const auto m = problem.
get_m();
52 if (direction_params.hessian_vec_finite_differences) {
56 }
else if (direction_params.full_augmented_hessian) {
66 const auto n = problem->get_n();
69 auto nJ = problem->eval_inactive_indices_res_lna(γₖ, xₖ, grad_ψxₖ, J_sto);
70 auto J = J_sto.topRows(nJ);
80 qₖ = (
real_t(1) / γₖ) * pₖ;
81 return lbfgs.apply(qₖ, γₖ);
85 if (direction_params.hessian_vec)
88 qₖ(J) = (
real_t(1) / γₖ) * pₖ(J);
89 if (direction_params.hessian_vec) {
90 approximate_hessian_vec_term(xₖ, grad_ψxₖ, qₖ, J);
92 qₖ(J) = (
real_t(1) / γₖ) * pₖ(J) - HqK(J);
97 bool success = lbfgs.apply_masked(qₖ, γₖ, J);
105 switch (direction_params.failure_policy) {
106 case DirectionParams::FallbackToProjectedGradient:
return success;
107 case DirectionParams::UseScaledLBFGSInput:
113 default:
return false;
117template <Config Conf>
120 const auto m = problem->get_m();
122 if (direction_params.hessian_vec_finite_differences) {
123 Helpers::calc_augmented_lagrangian_hessian_prod_fd(
124 *problem, xₖ, *y, *Σ, grad_ψxₖ, qₖ, HqK, work_n, work_n2, work_m);
128 if (!direction_params.full_augmented_hessian) {
130 problem->eval_hess_L_prod(xₖ, *y, 1, qₖ, HqK);
132 if (problem->provides_eval_hess_ψ_prod()) {
135 problem->eval_hess_ψ_prod(xₖ, *y, *Σ, 1, qₖ, HqK);
138 problem->eval_hess_L_prod(xₖ, *y, 1, qₖ, HqK);
141 if (direction_params.full_augmented_hessian) {
142 assert(m == 0 || problem->provides_eval_grad_gi());
143 const auto &D = problem->get_box_D();
145 problem->eval_g(xₖ, g);
146 for (
index_t i = 0; i < m; ++i) {
147 real_t ζ = g(i) + (*y)(i) / (*Σ)(i);
149 D.lowerbound(i) < ζ && ζ < D.upperbound(i);
151 problem->eval_grad_gi(xₖ, i, work_n);
152 auto t = (*Σ)(i)*work_n.dot(qₖ);
156 HqK(j) += work_n(j) * t;
bool provides_eval_hess_ψ_prod() const
Returns true if the problem provides an implementation of eval_hess_ψ_prod.
length_t get_n() const
[Required] Number of decision variables.
length_t get_m() const
[Required] Number of constraints.
bool provides_eval_inactive_indices_res_lna() const
Returns true if the problem provides an implementation of eval_inactive_indices_res_lna.
bool provides_eval_hess_L_prod() const
Returns true if the problem provides an implementation of eval_hess_L_prod.
bool provides_eval_grad_gi() const
Returns true if the problem provides an implementation of eval_grad_gi.
bool provides_get_box_D() const
Returns true if the problem provides an implementation of get_box_D.
typename Conf::real_t real_t
typename Conf::index_t index_t
typename Conf::crvec crvec
typename Conf::crindexvec crindexvec
void initialize(const Problem &problem, crvec y, crvec Σ, real_t γ_0, crvec x_0, crvec x̂_0, crvec p_0, crvec grad_ψx_0)
void approximate_hessian_vec_term(crvec xₖ, crvec grad_ψxₖ, rvec qₖ, crindexvec J) const
bool apply(real_t γₖ, crvec xₖ, crvec x̂ₖ, crvec pₖ, crvec grad_ψxₖ, rvec qₖ) const