alpaqa 0.0.1
Nonconvex constrained optimization
alm-helpers.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <alpaqa/decl/alm.hpp>
4#include <stdexcept>
5
6namespace alpaqa::detail {
7
8inline void project_y(rvec y, // inout
9 crvec z_lb, // in
10 crvec z_ub, // in
11 real_t M // in
12) {
13 // TODO: Handle NaN correctly
14 auto max_lb = [M](real_t y, real_t z_lb) {
15 real_t y_lb = z_lb == -inf ? 0 : -M;
16 return std::max(y, y_lb);
17 };
18 auto min_ub = [M](real_t y, real_t z_ub) {
19 real_t y_ub = z_ub == inf ? 0 : M;
20 return std::min(y, y_ub);
21 };
22 y = y.binaryExpr(z_lb, max_lb).binaryExpr(z_ub, min_ub);
23}
24
26 bool first_iter, rvec e, rvec old_e,
27 real_t norm_e, real_t old_norm_e,
28 crvec Σ_old, rvec Σ) {
29 if (norm_e <= params.δ) {
30 Σ = Σ_old;
31 return;
32 }
33 if (params.single_penalty_factor) {
34 if (first_iter || norm_e > params.θ * old_norm_e) {
35 real_t new_Σ = std::fmin(params.Σ_max, Δ * Σ_old(0));
36 Σ.setConstant(new_Σ);
37 } else {
38 Σ = Σ_old;
39 }
40 } else {
41 for (Eigen::Index i = 0; i < e.rows(); ++i) {
42 if (first_iter || std::abs(e(i)) > params.θ * std::abs(old_e(i))) {
43 Σ(i) = std::fmin(params.Σ_max,
44 std::fmax(Δ * std::abs(e(i)) / norm_e, 1) *
45 Σ_old(i));
46 } else {
47 Σ(i) = Σ_old(i);
48 }
49 }
50 }
51}
52
53inline void initialize_penalty(const Problem &p, const ALMParams &params,
54 crvec x0, rvec Σ) {
55 real_t f0 = p.f(x0);
56 vec g0(p.m);
57 p.g(x0, g0);
58 // TODO: reuse evaluations of f ang g in PANOC?
59 real_t σ = params.σ₀ * std::max(real_t(1), std::abs(f0)) /
60 std::max(real_t(1), 0.5 * g0.squaredNorm());
61 σ = std::max(σ, params.Σ_min);
62 σ = std::min(σ, params.Σ_max);
63 Σ.fill(σ);
64}
65
66inline void apply_preconditioning(const Problem &problem, Problem &prec_problem,
67 crvec x, real_t &prec_f, vec &prec_g) {
69 vec v = vec::Zero(problem.m);
70 vec grad_g(problem.n);
71 problem.grad_f(x, grad_f);
72 prec_f = 1. / std::max(grad_f.lpNorm<Eigen::Infinity>(), real_t{1});
73 prec_g.resize(problem.m);
74
75 for (Eigen::Index i = 0; i < problem.m; ++i) {
76 v(i) = 1;
77 problem.grad_g_prod(x, v, grad_g);
78 v(i) = 0;
79 prec_g(i) = 1. / std::max(grad_g.lpNorm<Eigen::Infinity>(), real_t{1});
80 }
81
82 auto prec_f_fun = [&](crvec x) { return problem.f(x) * prec_f; };
83 auto prec_grad_f_fun = [&](crvec x, rvec grad_f) {
84 problem.grad_f(x, grad_f);
85 grad_f *= prec_f;
86 };
87 auto prec_g_fun = [&](crvec x, rvec g) {
88 problem.g(x, g);
89 g = prec_g.asDiagonal() * g;
90 };
91 auto prec_grad_g_fun = [&](crvec x, crvec v, rvec grad_g) {
92 vec prec_v = prec_g.asDiagonal() * v;
93 problem.grad_g_prod(x, prec_v, grad_g);
94 };
95 prec_problem = Problem{
96 problem.n,
97 problem.m,
98 problem.C,
99 Box{prec_g.asDiagonal() * problem.D.upperbound,
100 prec_g.asDiagonal() * problem.D.lowerbound},
101 std::move(prec_f_fun),
102 std::move(prec_grad_f_fun),
103 std::move(prec_g_fun),
104 std::move(prec_grad_g_fun),
105 [](crvec, unsigned, rvec) {
106 throw std::logic_error("Preconditioning for second-order solvers "
107 "has not yet been implemented");
108 },
109 [](crvec, crvec, crvec, rvec) {
110 throw std::logic_error("Preconditioning for second-order solvers "
111 "has not yet been implemented");
112 },
113 [](crvec, crvec, rmat) {
114 throw std::logic_error("Preconditioning for second-order solvers "
115 "has not yet been implemented");
116 },
117 };
118}
119
120} // namespace alpaqa::detail
void project_y(rvec y, crvec z_lb, crvec z_ub, real_t M)
Definition: alm-helpers.hpp:8
void update_penalty_weights(const ALMParams &params, real_t Δ, bool first_iter, rvec e, rvec old_e, real_t norm_e, real_t old_norm_e, crvec Σ_old, rvec Σ)
Definition: alm-helpers.hpp:25
void initialize_penalty(const Problem &p, const ALMParams &params, crvec x0, rvec Σ)
Definition: alm-helpers.hpp:53
void apply_preconditioning(const Problem &problem, Problem &prec_problem, crvec x, real_t &prec_f, vec &prec_g)
Definition: alm-helpers.hpp:66
int Σ
Definition: test.py:72
Eigen::Ref< const vec > crvec
Default type for immutable references to vectors.
Definition: vec.hpp:18
constexpr real_t inf
Definition: vec.hpp:26
realvec vec
Default type for vectors.
Definition: vec.hpp:14
Eigen::Ref< mat > rmat
Default type for mutable references to matrices.
Definition: vec.hpp:22
double real_t
Default floating point type.
Definition: vec.hpp:8
Eigen::Ref< vec > rvec
Default type for mutable references to vectors.
Definition: vec.hpp:16
Parameters for the Augmented Lagrangian solver.
Definition: decl/alm.hpp:13
problem
Definition: main.py:16
Problem description for minimization problems.