alpaqa develop
Nonconvex constrained optimization
Loading...
Searching...
No Matches
convex-newton.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <alpaqa/export.hpp>
12#include <alpaqa/util/print.hpp>
13#include <iostream>
14#include <optional>
15#include <stdexcept>
16
17#include <Eigen/Cholesky>
18#include <Eigen/Eigenvalues>
19#include <Eigen/src/Cholesky/LDLT.h>
20
21namespace alpaqa {
22
23/// Parameters for the @ref ConvexNewtonDirection class.
24/// @ingroup grp_Parameters
25template <Config Conf>
32
33/// Parameters for the @ref ConvexNewtonDirection class.
34/// @ingroup grp_Parameters
35template <Config Conf>
38 /// Set this option to a nonzero value to include the Hessian-vector product
39 /// @f$ \nabla^2_{x_\mathcal{J}x_\mathcal{K}}\psi(x) q_\mathcal{K} @f$ from
40 /// equation 12b in @cite pas2022alpaqa, scaled by this parameter.
41 /// Set it to zero to leave out that term.
43 bool quadratic = false;
44};
45
46/// @ingroup grp_DirectionProviders
47template <Config Conf = DefaultConfig>
53
58
61 : reg_params(params.accelerator), direction_params(params.direction) {}
65
66 /// @see @ref PANOCDirection::initialize
72 if (problem.get_m() != 0)
73 throw std::invalid_argument("Convex Newton direction does not "
74 "support general constraints");
76 throw std::invalid_argument("Convex Newton direction requires "
77 "eval_inactive_indices_res_lna");
79 throw std::invalid_argument("Structured Newton requires "
80 "eval_hess_L");
81 // Store reference to problem
82 this->problem = &problem;
83 // Allocate workspaces
84 const auto n = problem.get_n();
85 JK.resize(n);
86 JK_old.resize(n);
87 nJ_old = -1;
88 H.resize(n, n);
89 HJ_storage.resize(n * n);
90 work.resize(n);
91 auto sparsity = problem.get_hess_ψ_sparsity();
92 if (!is_dense(sparsity))
93 std::cerr << "Sparse hessians not yet implemented, converting to "
94 "dense matrix (may be very slow)\n";
95 H_sparsity.emplace(sparsity);
96 have_hess = false;
97 }
98
99 /// @see @ref PANOCDirection::has_initial_direction
100 bool has_initial_direction() const { return true; }
101
102 /// @see @ref PANOCDirection::update
110
111 template <class Solver>
112 void solve(rmat H, rvec q) const {
114 Solver ll{H};
115 if (ll.info() != Eigen::Success)
116 throw std::runtime_error("Cholesky factorization failed. "
117 "Is the problem convex?");
118 ll.solveInPlace(q);
119 }
120
121 /// @see @ref PANOCDirection::apply
123 crvec grad_ψxₖ, rvec qₖ) const {
124 length_t n = xₖ.size();
125 // Evaluate the Hessian
126 if (!have_hess) {
127 const auto &y = null_vec<config_t>;
128 auto eval_h = [&](rvec v) { problem->eval_hess_L(xₖ, y, 1, v); };
129 H_sparsity->convert_values(eval_h, H.reshaped());
131 }
132 // Find inactive indices J
134 auto J = JK.topRows(nJ);
135 auto HJ = HJ_storage.topRows(nJ * nJ).reshaped(nJ, nJ);
136 HJ = H(J, J);
137 // Regularize the Hessian
138 real_t res_sq = pₖ.squaredNorm() / (γₖ * γₖ);
139 real_t reg = reg_params.ζ * std::pow(res_sq, reg_params.ν / 2);
140 HJ += reg * mat::Identity(nJ, nJ);
141 // Compute the right-hand side
142 qₖ = pₖ;
143 rvec w = work.topRows(nJ);
145 rindexvec K = JK.bottomRows(n - nJ);
147 w = (real_t(1) / γₖ) * pₖ(J) -
149 } else {
150 w = (real_t(1) / γₖ) * pₖ(J);
151 }
152 // Solve the system
153 if (H_sparsity->get_sparsity().symmetry == sparsity::Symmetry::Upper)
154 reg_params.ldlt ? solve<Eigen::LDLT<rmat, Eigen::Upper>>(HJ, w)
156 else
159 qₖ(J) = w;
160 return true;
161 }
162
163 /// @see @ref PANOCDirection::changed_γ
166
167 /// @see @ref PANOCDirection::reset
168 void reset() {}
169
170 /// @see @ref PANOCDirection::get_name
171 std::string get_name() const {
172 return "ConvexNewtonDirection<" + std::string(config_t::get_name()) +
173 '>';
174 }
175
176 const auto &get_params() const { return direction_params; }
177
178 private:
179 const Problem *problem = nullptr;
180
182 mutable index_t nJ_old = -1;
183 mutable mat H;
186 mutable std::optional<sp_conv_t> H_sparsity;
188 mutable bool have_hess = false;
189
190 public:
193};
194
195// clang-format off
200// clang-format on
201
202} // namespace alpaqa
bool provides_eval_hess_L() const
Returns true if the problem provides an implementation of eval_hess_L.
Sparsity get_hess_ψ_sparsity() const
[Optional] Function that returns (a view of) the sparsity pattern of the Hessian of the augmented Lag...
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.
index_t eval_inactive_indices_res_lna(real_t γ, crvec x, crvec grad_ψ, rindexvec J) const
[Optional] Function that computes the inactive indices for the evaluation of the linear Newton appro...
void eval_hess_L(crvec x, crvec y, real_t scale, rvec H_values) const
[Optional] Function that evaluates the nonzero values of the Hessian of the Lagrangian,
#define USING_ALPAQA_CONFIG(Conf)
Definition config.hpp:77
#define ALPAQA_IF_QUADF(...)
Definition config.hpp:223
#define ALPAQA_IF_LONGD(...)
Definition config.hpp:235
#define ALPAQA_IF_FLOAT(...)
Definition config.hpp:229
#define ALPAQA_EXPORT_EXTERN_TEMPLATE(...)
Definition export.hpp:21
real_t hessian_vec_factor
Set this option to a nonzero value to include the Hessian-vector product from equation 12b in ,...
Parameters for the ConvexNewtonDirection class.
Parameters for the ConvexNewtonDirection class.
@ Upper
Symmetric, upper-triangular part is stored.
Dense matrix structure.
Definition sparsity.hpp:21
Converts one matrix storage format to another.
typename Conf::mat mat
Definition config.hpp:93
typename Conf::rmat rmat
Definition config.hpp:96
typename Conf::indexvec indexvec
Definition config.hpp:105
typename Conf::real_t real_t
Definition config.hpp:86
typename Conf::rindexvec rindexvec
Definition config.hpp:106
typename Conf::index_t index_t
Definition config.hpp:104
typename Conf::length_t length_t
Definition config.hpp:103
constexpr const auto inf
Definition config.hpp:112
typename Conf::rvec rvec
Definition config.hpp:91
typename Conf::crvec crvec
Definition config.hpp:92
typename Conf::vec vec
Definition config.hpp:88
void changed_γ(real_t γₖ, real_t old_γₖ)
ConvexNewtonDirection(const Params &params)
const auto & get_params() const
bool update(real_t γₖ, real_t γₙₑₓₜ, crvec xₖ, crvec xₙₑₓₜ, crvec pₖ, crvec pₙₑₓₜ, crvec grad_ψxₖ, crvec grad_ψxₙₑₓₜ)
std::optional< sp_conv_t > H_sparsity
ConvexNewtonDirection(const AcceleratorParams &params, const DirectionParams &directionparams={})
void initialize(const Problem &problem, crvec y, crvec Σ, real_t γ_0, crvec x_0, crvec x̂_0, crvec p_0, crvec grad_ψx_0)
bool apply(real_t γₖ, crvec xₖ, crvec x̂ₖ, crvec pₖ, crvec grad_ψxₖ, rvec qₖ) const
void solve(rmat H, rvec q) const
Double-precision double configuration.
Definition config.hpp:176
Single-precision float configuration.
Definition config.hpp:172
long double configuration.
Definition config.hpp:181
static void compute_complement(std::span< const index_t > in, std::span< index_t > out)
Definition index-set.hpp:36