alpaqa 1.1.0a1
Nonconvex constrained optimization
Loading...
Searching...
No Matches
type-erased-problem.tpp
Go to the documentation of this file.
1#pragma once
2
4#include <stdexcept>
5
6namespace alpaqa {
7
8template <Config Conf>
9auto ProblemVTable<Conf>::calc_ŷ_dᵀŷ(const void *self, rvec g_ŷ, crvec y, crvec Σ,
10 const ProblemVTable &vtable) -> real_t {
11 if constexpr (requires { Σ(0); })
12 if (Σ.size() == 1) {
13 // ζ = g(x) + Σ⁻¹y
14 g_ŷ += (1 / Σ(0)) * y;
15 // d = ζ - Π(ζ, D)
16 vtable.eval_projecting_difference_constraints(self, g_ŷ, g_ŷ);
17 // dᵀŷ, ŷ = Σ d
18 real_t dᵀŷ = Σ(0) * g_ŷ.dot(g_ŷ);
19 g_ŷ *= Σ(0);
20 return dᵀŷ;
21 }
22 if (Σ.size() != y.size())
23 throw std::logic_error("Penalty/multiplier size mismatch");
24 // ζ = g(x) + Σ⁻¹y
25 g_ŷ += y.cwiseQuotient(Σ);
26 // d = ζ - Π(ζ, D)
27 vtable.eval_projecting_difference_constraints(self, g_ŷ, g_ŷ);
28 // dᵀŷ, ŷ = Σ d
29 real_t dᵀŷ = g_ŷ.dot(Σ.cwiseProduct(g_ŷ));
30 g_ŷ = Σ.cwiseProduct(g_ŷ);
31 return dᵀŷ;
32}
33
34template <Config Conf>
37 const ProblemVTable &) -> index_t {
38 throw not_implemented_error("eval_inactive_indices_res_lna");
39}
40
41template <Config Conf>
43 const ProblemVTable &vtable) {
44 if (vtable.m != 0)
45 throw not_implemented_error("eval_constraints_jacobian");
46}
47
48template <Config Conf>
50 const void *, const ProblemVTable &vtable) -> Sparsity {
51 return sparsity::Dense{vtable.m, vtable.n};
52}
53
54template <Config Conf>
56 const ProblemVTable &) {
57 throw not_implemented_error("eval_grad_gi");
58}
59
60template <Config Conf>
63 const ProblemVTable &) {
64 throw not_implemented_error("eval_lagrangian_hessian_product");
65}
66
67template <Config Conf>
69 const ProblemVTable &) {
70 throw not_implemented_error("eval_lagrangian_hessian");
71}
72
73template <Config Conf>
75 const void *, const ProblemVTable &vtable) -> Sparsity {
76 return sparsity::Dense{vtable.n, vtable.n, sparsity::Symmetry::Upper};
77}
78
79template <Config Conf>
81 const void *self, crvec x, crvec y, crvec, real_t scale, crvec v, rvec Hv,
82 const ProblemVTable &vtable) {
83 if (vtable.m == 0 && vtable.eval_lagrangian_hessian_product !=
85 return vtable.eval_lagrangian_hessian_product(self, x, y, scale, v, Hv, vtable);
86 throw not_implemented_error("eval_augmented_lagrangian_hessian_product");
87}
88
89template <Config Conf>
91 crvec y, crvec, real_t scale,
92 rvec H_values,
93 const ProblemVTable &vtable) {
95 return vtable.eval_lagrangian_hessian(self, x, y, scale, H_values, vtable);
96 throw not_implemented_error("eval_augmented_lagrangian_hessian");
97}
98
99template <Config Conf>
101 const void *self, const ProblemVTable &vtable) -> Sparsity {
102 if (vtable.m == 0 &&
103 vtable.get_lagrangian_hessian_sparsity != default_get_lagrangian_hessian_sparsity)
104 return vtable.get_lagrangian_hessian_sparsity(self, vtable);
105 return sparsity::Dense{vtable.n, vtable.n, sparsity::Symmetry::Upper};
106}
107
108/** @implementation{ProblemVTable<Conf>::default_eval_objective_and_gradient} */
109template <Config Conf>
110/* [ProblemVTable<Conf>::default_eval_objective_and_gradient] */
112 const void *self, crvec x, rvec grad_fx, const ProblemVTable &vtable) -> real_t {
113 vtable.eval_objective_gradient(self, x, grad_fx);
114 return vtable.eval_objective(self, x);
115}
116/* [ProblemVTable<Conf>::default_eval_objective_and_gradient] */
117
118/** @implementation{ProblemVTable<Conf>::default_eval_objective_and_constraints} */
119template <Config Conf>
120/* [ProblemVTable<Conf>::default_eval_objective_and_constraints] */
122 const void *self, crvec x, rvec g, const ProblemVTable &vtable) -> real_t {
123 vtable.eval_constraints(self, x, g);
124 return vtable.eval_objective(self, x);
125}
126/* [ProblemVTable<Conf>::default_eval_objective_and_constraints] */
127
128/** @implementation{ProblemVTable<Conf>::default_eval_objective_gradient_and_constraints_gradient_product} */
129template <Config Conf>
130/* [ProblemVTable<Conf>::default_eval_objective_gradient_and_constraints_gradient_product] */
132 const void *self, crvec x, crvec y, rvec grad_f, rvec grad_gxy, const ProblemVTable &vtable) {
133 vtable.eval_objective_gradient(self, x, grad_f);
134 vtable.eval_constraints_gradient_product(self, x, y, grad_gxy);
135}
136/* [ProblemVTable<Conf>::default_eval_objective_gradient_and_constraints_gradient_product] */
137
138/** @implementation{ProblemVTable<Conf>::default_eval_lagrangian_gradient} */
139template <Config Conf>
140/* [ProblemVTable<Conf>::default_eval_lagrangian_gradient] */
142 rvec grad_L, rvec work_n,
143 const ProblemVTable &vtable) {
144 if (y.size() == 0) /* [[unlikely]] */
145 return vtable.eval_objective_gradient(self, x, grad_L);
146 vtable.eval_objective_gradient_and_constraints_gradient_product(self, x, y, grad_L, work_n,
147 vtable);
148 grad_L += work_n;
149}
150/* [ProblemVTable<Conf>::default_eval_lagrangian_gradient] */
151
152/** @implementation{ProblemVTable<Conf>::default_eval_augmented_lagrangian} */
153template <Config Conf>
154/* [ProblemVTable<Conf>::default_eval_augmented_lagrangian] */
156 crvec Σ, rvec ŷ,
157 const ProblemVTable &vtable) -> real_t {
158 if (y.size() == 0) /* [[unlikely]] */
159 return vtable.eval_objective(self, x);
160
161 auto f = vtable.eval_objective_and_constraints(self, x, ŷ, vtable);
162 auto dᵀŷ = calc_ŷ_dᵀŷ(self, ŷ, y, Σ, vtable);
163 // ψ(x) = f(x) + ½ dᵀŷ
164 auto ψ = f + real_t(0.5) * dᵀŷ;
165 return ψ;
166}
167/* [ProblemVTable<Conf>::default_eval_augmented_lagrangian] */
168
169/** @implementation{ProblemVTable<Conf>::default_eval_augmented_lagrangian_gradient} */
170template <Config Conf>
171/* [ProblemVTable<Conf>::default_eval_augmented_lagrangian_gradient] */
173 crvec y, crvec Σ, rvec grad_ψ,
174 rvec work_n, rvec work_m,
175 const ProblemVTable &vtable) {
176 if (y.size() == 0) /* [[unlikely]] */ {
177 vtable.eval_objective_gradient(self, x, grad_ψ);
178 } else {
179 vtable.eval_constraints(self, x, work_m);
180 (void)calc_ŷ_dᵀŷ(self, work_m, y, Σ, vtable);
181 vtable.eval_lagrangian_gradient(self, x, work_m, grad_ψ, work_n, vtable);
182 }
183}
184/* [ProblemVTable<Conf>::default_eval_augmented_lagrangian_gradient] */
185
186/** @implementation{ProblemVTable<Conf>::default_eval_augmented_lagrangian_and_gradient} */
187template <Config Conf>
188/* [ProblemVTable<Conf>::default_eval_augmented_lagrangian_and_gradient] */
190 const void *self, crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m,
191 const ProblemVTable &vtable) -> real_t {
192 if (y.size() == 0) /* [[unlikely]] */
193 return vtable.eval_objective_and_gradient(self, x, grad_ψ, vtable);
194
195 auto &ŷ = work_m;
196 // ψ(x) = f(x) + ½ dᵀŷ
197 auto f = vtable.eval_objective_and_constraints(self, x, ŷ, vtable);
198 auto dᵀŷ = calc_ŷ_dᵀŷ(self, ŷ, y, Σ, vtable);
199 auto ψ = f + real_t(0.5) * dᵀŷ;
200 // ∇ψ(x) = ∇f(x) + ∇g(x) ŷ
201 vtable.eval_lagrangian_gradient(self, x, ŷ, grad_ψ, work_n, vtable);
202 return ψ;
203}
204/* [ProblemVTable<Conf>::default_eval_augmented_lagrangian_and_gradient] */
205
206template <Config Conf>
208 const ProblemVTable &) -> const Box & {
209 throw not_implemented_error("get_variable_bounds");
210}
211
212template <Config Conf>
214 const ProblemVTable &) -> const Box & {
215 throw not_implemented_error("get_general_bounds");
216}
217
218template <Config Conf>
220
221template <Config Conf>
222std::string ProblemVTable<Conf>::default_get_name(const void *, const ProblemVTable &) {
223 return "unknown problem";
224}
225
226} // namespace alpaqa
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::rvec rvec
Definition config.hpp:91
typename Conf::crvec crvec
Definition config.hpp:92
static std::string default_get_name(const void *, const ProblemVTable &)
static Sparsity default_get_lagrangian_hessian_sparsity(const void *, const ProblemVTable &)
static Sparsity default_get_constraints_jacobian_sparsity(const void *, const ProblemVTable &)
optional_function_t< void(crvec x, crvec y, real_t scale, rvec H_values) const > eval_lagrangian_hessian
ProblemVTable(std::in_place_t, P &p)
static void default_eval_objective_gradient_and_constraints_gradient_product(const void *self, crvec x, crvec y, rvec grad_f, rvec grad_gxy, const ProblemVTable &vtable)
static real_t default_eval_augmented_lagrangian(const void *self, crvec x, crvec y, crvec Σ, rvec ŷ, const ProblemVTable &vtable)
static void default_eval_lagrangian_hessian(const void *, crvec, crvec, real_t, rvec, const ProblemVTable &)
required_function_t< void(crvec x, rvec grad_fx) const > eval_objective_gradient
static void default_eval_grad_gi(const void *, crvec, index_t, rvec, const ProblemVTable &)
static Sparsity default_get_augmented_lagrangian_hessian_sparsity(const void *, const ProblemVTable &)
static void default_eval_lagrangian_gradient(const void *self, crvec x, crvec y, rvec grad_L, rvec work_n, const ProblemVTable &vtable)
optional_function_t< void(crvec x, crvec y, rvec grad_L, rvec work_n) const > eval_lagrangian_gradient
static const Box & default_get_general_bounds(const void *, const ProblemVTable &)
optional_function_t< void(crvec x, crvec y, rvec grad_f, rvec grad_gxy) const > eval_objective_gradient_and_constraints_gradient_product
static void default_eval_lagrangian_hessian_product(const void *, crvec, crvec, real_t, crvec, rvec, const ProblemVTable &)
required_function_t< void(crvec x, rvec gx) const > eval_constraints
static const Box & default_get_variable_bounds(const void *, const ProblemVTable &)
static void default_eval_constraints_jacobian(const void *, crvec, rvec, const ProblemVTable &)
required_function_t< void(crvec x, crvec y, rvec grad_gxy) const > eval_constraints_gradient_product
static real_t default_eval_objective_and_gradient(const void *self, crvec x, rvec grad_fx, const ProblemVTable &vtable)
alpaqa::Box< config_t > Box
static real_t default_eval_augmented_lagrangian_and_gradient(const void *self, crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m, const ProblemVTable &vtable)
static void default_eval_augmented_lagrangian_hessian_product(const void *self, crvec x, crvec y, crvec, real_t scale, crvec v, rvec Hv, const ProblemVTable &vtable)
static index_t default_eval_inactive_indices_res_lna(const void *, real_t, crvec, crvec, rindexvec, const ProblemVTable &)
static void default_check(const void *, const ProblemVTable &)
static real_t default_eval_objective_and_constraints(const void *self, crvec x, rvec g, const ProblemVTable &vtable)
static real_t calc_ŷ_dᵀŷ(const void *self, rvec g_ŷ, crvec y, crvec Σ, const ProblemVTable &vtable)
optional_function_t< void(crvec x, crvec y, real_t scale, crvec v, rvec Hv) const > eval_lagrangian_hessian_product
static void default_eval_augmented_lagrangian_hessian(const void *self, crvec x, crvec y, crvec, real_t scale, rvec H_values, const ProblemVTable &vtable)
static void default_eval_augmented_lagrangian_gradient(const void *self, crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m, const ProblemVTable &vtable)