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