alpaqa pantr
Nonconvex constrained optimization
Loading...
Searching...
No Matches
dl-problem.h
Go to the documentation of this file.
1#pragma once
2
3#include <stddef.h>
4
5#ifdef __cplusplus
6extern "C" {
7#endif
8
9typedef double alpaqa_real_t;
10typedef ptrdiff_t alpaqa_length_t;
12
13typedef struct {
14 char version[16];
16
17 // clang-format off
18 alpaqa_real_t (*eval_f)(
19 void *instance,
20 const alpaqa_real_t *x);
21 void (*eval_grad_f)(
22 void *instance,
23 const alpaqa_real_t *x,
24 alpaqa_real_t *grad_fx);
25 void (*eval_g)(
26 void *instance,
27 const alpaqa_real_t *x,
28 alpaqa_real_t *gx);
29 void (*eval_grad_g_prod)(
30 void *instance,
31 const alpaqa_real_t *x,
32 const alpaqa_real_t *y,
33 alpaqa_real_t *grad_gxy);
34 void (*eval_jac_g)(
35 void *instance,
36 const alpaqa_real_t *x,
37 alpaqa_index_t *inner_idx,
38 alpaqa_index_t *outer_ptr,
39 alpaqa_real_t *J_values);
40 alpaqa_length_t (*get_jac_g_num_nonzeros)(
41 void *instance);
42 void (*eval_grad_gi)(
43 void *instance,
44 const alpaqa_real_t *x,
46 alpaqa_real_t *grad_gi);
47 void (*eval_hess_L_prod)(
48 void *instance,
49 const alpaqa_real_t *x,
50 const alpaqa_real_t *y,
51 alpaqa_real_t scale,
52 const alpaqa_real_t *v,
53 alpaqa_real_t *Hv);
54 void (*eval_hess_L)(
55 void *instance,
56 const alpaqa_real_t *x,
57 const alpaqa_real_t *y,
58 alpaqa_real_t scale,
59 alpaqa_index_t *inner_idx,
60 alpaqa_index_t *outer_ptr,
61 alpaqa_real_t *H_values);
62 alpaqa_length_t (*get_hess_L_num_nonzeros)(
63 void *instance);
64 void (*eval_hess_ψ_prod)(
65 void *instance,
66 const alpaqa_real_t *x,
67 const alpaqa_real_t *y,
68 const alpaqa_real_t *Σ,
69 alpaqa_real_t scale,
70 const alpaqa_real_t *zl,
71 const alpaqa_real_t *zu,
72 const alpaqa_real_t *v,
73 alpaqa_real_t *Hv);
74 void (*eval_hess_ψ)(
75 void *instance,
76 const alpaqa_real_t *x,
77 const alpaqa_real_t *y,
78 const alpaqa_real_t *Σ,
79 alpaqa_real_t scale,
80 const alpaqa_real_t *zl,
81 const alpaqa_real_t *zu,
82 alpaqa_index_t *inner_idx,
83 alpaqa_index_t *outer_ptr,
84 alpaqa_real_t *H_values);
85 alpaqa_length_t (*get_hess_ψ_num_nonzeros)(
86 void *instance);
87 alpaqa_real_t (*eval_f_grad_f)(
88 void *instance,
89 const alpaqa_real_t *x,
90 alpaqa_real_t *grad_fx);
91 alpaqa_real_t (*eval_f_g)(
92 void *instance,
93 const alpaqa_real_t *x,
94 alpaqa_real_t *g);
95 void (*eval_grad_f_grad_g_prod)(
96 void *instance,
97 const alpaqa_real_t *x,
98 const alpaqa_real_t *y,
99 alpaqa_real_t *grad_f,
100 alpaqa_real_t *grad_gxy);
101 void (*eval_grad_L)(
102 void *instance,
103 const alpaqa_real_t *x,
104 const alpaqa_real_t *y,
105 alpaqa_real_t *grad_L,
106 alpaqa_real_t *work_n);
107 alpaqa_real_t (*eval_ψ)(
108 void *instance,
109 const alpaqa_real_t *x,
110 const alpaqa_real_t *y,
111 const alpaqa_real_t *Σ,
112 const alpaqa_real_t *zl,
113 const alpaqa_real_t *zu,
114 alpaqa_real_t *ŷ);
115 void (*eval_grad_ψ)(
116 void *instance,
117 const alpaqa_real_t *x,
118 const alpaqa_real_t *y,
119 const alpaqa_real_t *Σ,
120 const alpaqa_real_t *zl,
121 const alpaqa_real_t *zu,
122 alpaqa_real_t *grad_ψ,
123 alpaqa_real_t *work_n,
124 alpaqa_real_t *work_m);
125 alpaqa_real_t (*eval_ψ_grad_ψ)(
126 void *instance,
127 const alpaqa_real_t *x,
128 const alpaqa_real_t *y,
129 const alpaqa_real_t *Σ,
130 const alpaqa_real_t *zl,
131 const alpaqa_real_t *zu,
132 alpaqa_real_t *grad_ψ,
133 alpaqa_real_t *work_n,
134 alpaqa_real_t *work_m);
135 alpaqa_real_t (*eval_prox_grad_step)(
136 void *instance,
137 alpaqa_real_t γ,
138 const alpaqa_real_t *x,
139 const alpaqa_real_t *grad_ψ,
140 alpaqa_real_t *x̂,
141 alpaqa_real_t *p);
142 void (*initialize_box_C)(
143 void *instance,
144 alpaqa_real_t *lb,
145 alpaqa_real_t *ub);
146 void (*initialize_box_D)(
147 void *instance,
148 alpaqa_real_t *lb,
149 alpaqa_real_t *ub);
150 void (*initialize_l1_reg)(
151 void *instance,
152 alpaqa_real_t *lambda,
153 alpaqa_length_t *size);
154 // clang-format on
156
157/// Opaque type for a C++-only map of extra functions.
159
160typedef struct {
161 /// Owning pointer.
162 void *instance;
163 /// Non-owning pointer, lifetime at least as long as @ref instance.
165 /// Pointer to the function to clean up @ref instance.
166 void (*cleanup)(void *);
167 /// Pointer to a map of extra functions (C++ only).
170
171typedef struct {
172 char version[16];
173 alpaqa_length_t N, nx, nu, nh, nh_N, nc, nc_N;
174
175 // clang-format off
176 void (*get_U)(
177 void *instance,
178 alpaqa_real_t *lb,
179 alpaqa_real_t *ub);
180 void (*get_D)(
181 void *instance,
182 alpaqa_real_t *lb,
183 alpaqa_real_t *ub);
184 void (*get_D_N)(
185 void *instance,
186 alpaqa_real_t *lb,
187 alpaqa_real_t *ub);
188 void (*get_x_init)(
189 void *instance,
190 alpaqa_real_t *x_init);
191 void (*eval_f)(
192 void *instance,
193 alpaqa_index_t timestep,
194 const alpaqa_real_t *x,
195 const alpaqa_real_t *u,
196 alpaqa_real_t *fxu);
197 void (*eval_jac_f)(
198 void *instance,
199 alpaqa_index_t timestep,
200 const alpaqa_real_t *x,
201 const alpaqa_real_t *u,
202 alpaqa_real_t *J_fxu);
203 void (*eval_grad_f_prod)(
204 void *instance,
205 alpaqa_index_t timestep,
206 const alpaqa_real_t *x,
207 const alpaqa_real_t *u,
208 const alpaqa_real_t *p,
209 alpaqa_real_t *grad_fxu_p);
210 void (*eval_h)(
211 void *instance,
212 alpaqa_index_t timestep,
213 const alpaqa_real_t *x,
214 const alpaqa_real_t *u,
215 alpaqa_real_t *h);
216 void (*eval_h_N)(
217 void *instance,
218 const alpaqa_real_t *x,
219 alpaqa_real_t *h);
220 alpaqa_real_t (*eval_l)(
221 void *instance,
222 alpaqa_index_t timestep,
223 const alpaqa_real_t *h);
224 alpaqa_real_t (*eval_l_N)(
225 void *instance,
226 const alpaqa_real_t *h);
227 void (*eval_qr)(
228 void *instance,
229 alpaqa_index_t timestep,
230 const alpaqa_real_t *xu,
231 const alpaqa_real_t *h,
232 alpaqa_real_t *qr);
233 void (*eval_q_N)(
234 void *instance,
235 const alpaqa_real_t *x,
236 const alpaqa_real_t *h,
237 alpaqa_real_t *q);
238 void (*eval_add_Q)(
239 void *instance,
240 alpaqa_index_t timestep,
241 const alpaqa_real_t *xu,
242 const alpaqa_real_t *h,
243 alpaqa_real_t *Q);
244 void (*eval_add_Q_N)(
245 void *instance,
246 const alpaqa_real_t *x,
247 const alpaqa_real_t *h,
248 alpaqa_real_t *Q);
249 void (*eval_add_R_masked)(
250 void *instance,
251 alpaqa_index_t timestep,
252 const alpaqa_real_t *xu,
253 const alpaqa_real_t *h,
254 const alpaqa_index_t *mask,
255 alpaqa_real_t *R,
256 alpaqa_real_t *work);
257 void (*eval_add_S_masked)(
258 void *instance,
259 alpaqa_index_t timestep,
260 const alpaqa_real_t *xu,
261 const alpaqa_real_t *h,
262 const alpaqa_index_t *mask,
263 alpaqa_real_t *S,
264 alpaqa_real_t *work);
265 void (*eval_add_R_prod_masked)(
266 void *instance,
267 alpaqa_index_t timestep,
268 const alpaqa_real_t *xu,
269 const alpaqa_real_t *h,
270 const alpaqa_index_t *mask_J,
271 const alpaqa_index_t *mask_K,
272 const alpaqa_real_t *v,
273 alpaqa_real_t *out,
274 alpaqa_real_t *work);
275 void (*eval_add_S_prod_masked)(
276 void *instance,
277 alpaqa_index_t timestep,
278 const alpaqa_real_t *xu,
279 const alpaqa_real_t *h,
280 const alpaqa_index_t *mask_K,
281 const alpaqa_real_t *v,
282 alpaqa_real_t *out,
283 alpaqa_real_t *work);
284 alpaqa_length_t (*get_R_work_size)(
285 void *instance);
286 alpaqa_length_t (*get_S_work_size)(
287 void *instance);
288 void (*eval_constr)(
289 void *instance,
290 alpaqa_index_t timestep,
291 const alpaqa_real_t *x,
292 alpaqa_real_t *c);
293 void (*eval_constr_N)(
294 void *instance,
295 const alpaqa_real_t *x,
296 alpaqa_real_t *c);
297 void (*eval_grad_constr_prod)(
298 void *instance,
299 alpaqa_index_t timestep,
300 const alpaqa_real_t *x,
301 const alpaqa_real_t *p,
302 alpaqa_real_t *grad_cx_p);
303 void (*eval_grad_constr_prod_N)(
304 void *instance,
305 const alpaqa_real_t *x,
306 const alpaqa_real_t *p,
307 alpaqa_real_t *grad_cx_p);
308 void (*eval_add_gn_hess_constr)(
309 void *instance,
310 alpaqa_index_t timestep,
311 const alpaqa_real_t *x,
312 const alpaqa_real_t *M,
313 alpaqa_real_t *out);
314 void (*eval_add_gn_hess_constr_N)(
315 void *instance,
316 const alpaqa_real_t *x,
317 const alpaqa_real_t *M,
318 alpaqa_real_t *out);
319 // clang-format on
321
322typedef struct {
323 /// Owning pointer.
324 void *instance;
325 /// Non-owning pointer, lifetime at least as long as @ref instance.
327 /// Pointer to the function to clean up @ref instance.
328 void (*cleanup)(void *);
329 /// Pointer to a map of extra functions (C++ only).
332
333#ifdef __cplusplus
334}
335#endif
336
337#if defined(__cplusplus) && __cplusplus > 201703L
338
339#include <any>
340#include <functional>
341#include <map>
342#include <string>
343
345 std::map<std::string, std::any> dict{};
346};
347
348namespace alpaqa {
349
355
356/// Make the given function available to alpaqa.
357/// @see @ref alpaqa::dl::DLProblem::call_extra_func
358/// @see @ref alpaqa::dl::DLControlProblem::call_extra_func
359template <class Func>
360void register_function(function_dict_t *&extra_functions, std::string name,
361 Func &&func) {
362 if (extra_functions == nullptr)
363 extra_functions = new function_dict_t{};
364 extra_functions->dict.insert_or_assign(
365 std::move(name), std::function{std::forward<Func>(func)});
366}
367
368template <class Func>
369void register_function(problem_register_t &result, std::string name,
370 Func &&func) {
371 register_function(result.extra_functions, std::move(name),
372 std::forward<Func>(func));
373}
374
375template <class Func>
376void register_function(control_problem_register_t &result, std::string name,
377 Func &&func) {
378 register_function(result.extra_functions, std::move(name),
379 std::forward<Func>(func));
380}
381
382template <class Result, class T, class Ret, class... Args>
383void register_member_function(Result &result, std::string name,
384 Ret (T::*member)(Args...)) {
385 register_function(result, std::move(name),
386 [member](void *self_, Args... args) -> Ret {
387 auto *self = reinterpret_cast<T *>(self_);
388 return (self->*member)(std::forward<Args>(args)...);
389 });
390}
391
392template <class Result, class T, class Ret, class... Args>
393void register_member_function(Result &result, std::string name,
394 Ret (T::*member)(Args...) const) {
395 register_function(result, std::move(name),
396 [member](const void *self_, Args... args) -> Ret {
397 const auto *self = reinterpret_cast<const T *>(self_);
398 return (self->*member)(std::forward<Args>(args)...);
399 });
400}
401
402namespace detail {
403template <auto Member, class Class, class Ret, class... Args>
404static auto member_caller(Ret (Class::*)(Args...)) {
405 return [](void *self_, Args... args) -> Ret {
406 auto *self = reinterpret_cast<Class *>(self_);
407 return (self->*Member)(std::forward<Args>(args)...);
408 };
409}
410
411template <auto Member, class Class, class Ret, class... Args>
412static auto member_caller(Ret (Class::*)(Args...) const) {
413 return []<class Self>(Self * self_, Args... args) -> Ret
414 requires std::is_void_v<Self>
415 {
416 const auto *self = reinterpret_cast<const Class *>(self_);
417 return (self->*Member)(std::forward<Args>(args)...);
418 };
419}
420
421template <auto Member, class Class, class Ret>
422static auto member_caller(Ret Class::*) {
423 return []<class Self>(Self * self_) -> decltype(auto)
424 requires std::is_void_v<Self>
425 {
426 using CClass = std::conditional_t<std::is_const_v<Self>,
427 std::add_const_t<Class>, Class>;
428 auto *self = reinterpret_cast<CClass *>(self_);
429 return self->*Member;
430 };
431}
432} // namespace detail
433
434/// Wrap the given member function of signature into a lambda function that
435/// accepts the instance as a void pointer.
436///
437/// - `Ret Class::member(args...)` → `Ret(void *self, args...)`
438/// - `Ret Class::member(args...) const` → `Ret(const void *self, args...)`
439/// - `Type Class::member` → `Type &(void *self)`
440/// - `Type Class::member` → `const Type &(const void *self)`
441template <auto Member>
442static auto member_caller() {
443 return detail::member_caller<Member>(Member);
444}
445
446/// Cleans up the extra functions registered by @ref register_function.
447/// @note This does not need to be called for the functions returned by the
448/// registration function, those functions will be cleaned up by alpaqa.
449/// @note The @ref alpaqa_problem_register_t and
450/// @ref alpaqa_control_problem_register_t structs are part of the C API
451/// and do not automatically clean up their resources when destroyed,
452/// you have to do it manually by calling this function.
453inline void unregister_functions(function_dict_t *&extra_functions) {
454 delete extra_functions;
455}
456
457} // namespace alpaqa
458
459#endif
struct alpaqa_function_dict_s alpaqa_function_dict_t
Opaque type for a C++-only map of extra functions.
Definition: dl-problem.h:158
ptrdiff_t alpaqa_length_t
Definition: dl-problem.h:10
alpaqa_length_t alpaqa_index_t
Definition: dl-problem.h:11
double alpaqa_real_t
Definition: dl-problem.h:9
std::map< std::string, std::any > dict
Definition: dl-problem.h:345
void unregister_functions(function_dict_t *&extra_functions)
Cleans up the extra functions registered by register_function.
Definition: dl-problem.h:453
void register_function(function_dict_t *&extra_functions, std::string name, Func &&func)
Make the given function available to alpaqa.
Definition: dl-problem.h:360
void register_member_function(Result &result, std::string name, Ret(T::*member)(Args...))
Definition: dl-problem.h:383
static auto member_caller()
Wrap the given member function of signature into a lambda function that accepts the instance as a voi...
Definition: dl-problem.h:442
alpaqa_function_dict_t * extra_functions
Pointer to a map of extra functions (C++ only).
Definition: dl-problem.h:330
alpaqa_control_problem_functions_t * functions
Non-owning pointer, lifetime at least as long as instance.
Definition: dl-problem.h:326
void * instance
Owning pointer.
Definition: dl-problem.h:324
alpaqa_function_dict_t * extra_functions
Pointer to a map of extra functions (C++ only).
Definition: dl-problem.h:168
void * instance
Owning pointer.
Definition: dl-problem.h:162
alpaqa_problem_functions_t * functions
Non-owning pointer, lifetime at least as long as instance.
Definition: dl-problem.h:164