alpaqa 1.0.0a15
Nonconvex constrained optimization
Loading...
Searching...
No Matches
dl-problem.h
Go to the documentation of this file.
1// NOLINTBEGIN(modernize-use-using,modernize-deprecated-headers)
2
3#pragma once
4
5#include <stddef.h>
6#include <stdint.h>
7#include <string.h>
8
9#define ALPAQA_DL_ABI_VERSION 0xA1A000000002
10
11#ifdef __cplusplus
12extern "C" {
13#define ALPAQA_DEFAULT(...) \
14 { __VA_ARGS__ }
15#else
16#define ALPAQA_DEFAULT(...)
17#endif
18
19typedef double alpaqa_real_t;
20typedef ptrdiff_t alpaqa_length_t;
22
23/// @see @ref alpaqa::sparsity::Symmetry
29
30/// @see @ref alpaqa::sparsity::Dense
35
36/// @see @ref alpaqa::sparsity::SparseCSC
37typedef struct {
41 const int *inner_idx;
42 const int *outer_ptr;
43 /// @see @ref alpaqa::sparsity::SparseCSC::Order
44 enum {
45 alpaqa_sparse_csc_unsorted = 0,
46 alpaqa_sparse_csc_sorted_rows = 1,
47 } order;
49
50/// @see @ref alpaqa::sparsity::SparseCSC
51typedef struct {
55 const long *inner_idx;
56 const long *outer_ptr;
57 /// @see @ref alpaqa::sparsity::SparseCSC::Order
58 enum {
59 alpaqa_sparse_csc_l_unsorted = 0,
60 alpaqa_sparse_csc_l_sorted_rows = 1,
61 } order;
63
64/// @see @ref alpaqa::sparsity::SparseCSC
65typedef struct {
69 const long long *inner_idx;
70 const long long *outer_ptr;
71 /// @see @ref alpaqa::sparsity::SparseCSC::Order
72 enum {
73 alpaqa_sparse_csc_ll_unsorted = 0,
74 alpaqa_sparse_csc_ll_sorted_rows = 1,
75 } order;
77
78/// @see @ref alpaqa::sparsity::SparseCOO
79typedef struct {
83 const int *row_indices;
84 const int *col_indices;
85 /// @see @ref alpaqa::sparsity::SparseCOO::Order
86 enum {
87 alpaqa_sparse_coo_unsorted = 0,
88 alpaqa_sparse_coo_sorted_by_cols_and_rows = 1,
89 alpaqa_sparse_coo_sorted_by_cols_only = 2,
90 alpaqa_sparse_coo_sorted_by_rows_and_cols = 3,
91 alpaqa_sparse_coo_sorted_by_rows_only = 4,
92 } order;
95
96/// @see @ref alpaqa::sparsity::SparseCOO
97typedef struct {
101 const long *row_indices;
102 const long *col_indices;
103 /// @see @ref alpaqa::sparsity::SparseCOO::Order
104 enum {
105 alpaqa_sparse_coo_l_unsorted = 0,
106 alpaqa_sparse_coo_l_sorted_by_cols_and_rows = 1,
107 alpaqa_sparse_coo_l_sorted_by_cols_only = 2,
108 alpaqa_sparse_coo_l_sorted_by_rows_and_cols = 3,
109 alpaqa_sparse_coo_l_sorted_by_rows_only = 4,
110 } order;
113
114/// @see @ref alpaqa::sparsity::SparseCOO
115typedef struct {
119 const long long *row_indices;
120 const long long *col_indices;
121 /// @see @ref alpaqa::sparsity::SparseCOO::Order
122 enum {
123 alpaqa_sparse_coo_ll_unsorted = 0,
124 alpaqa_sparse_coo_ll_sorted_by_cols_and_rows = 1,
125 alpaqa_sparse_coo_ll_sorted_by_cols_only = 2,
126 alpaqa_sparse_coo_ll_sorted_by_rows_and_cols = 3,
127 alpaqa_sparse_coo_ll_sorted_by_rows_only = 4,
128 } order;
129 long long first_index;
131
132/// Sparsity of matrices.
133/// @see @ref alpaqa::sparsity::Sparsity
154
155/// C API providing function pointers to problem functions.
156/// Used by @ref alpaqa::dl::DLProblem.
157typedef struct {
158 /// Number of decision variables.
159 /// @see @ref alpaqa::TypeErasedProblem::get_n()
161 /// Number of constraints.
162 /// @see @ref alpaqa::TypeErasedProblem::get_m()
164
165 // clang-format off
166 /// Cost function.
167 /// @see @ref alpaqa::TypeErasedProblem::eval_f()
168 alpaqa_real_t (*eval_f)(
169 void *instance,
170 const alpaqa_real_t *x) ALPAQA_DEFAULT(nullptr);
171 /// Gradient of the cost function.
172 /// @see @ref alpaqa::TypeErasedProblem::eval_grad_f()
173 void (*eval_grad_f)(
174 void *instance,
175 const alpaqa_real_t *x,
176 alpaqa_real_t *grad_fx) ALPAQA_DEFAULT(nullptr);
177 /// Constraints function.
178 /// @see @ref alpaqa::TypeErasedProblem::eval_g()
179 void (*eval_g)(
180 void *instance,
181 const alpaqa_real_t *x,
182 alpaqa_real_t *gx) ALPAQA_DEFAULT(nullptr);
183 /// Gradient-vector product of the constraints function.
184 /// @see @ref alpaqa::TypeErasedProblem::eval_grad_g_prod()
185 void (*eval_grad_g_prod)(
186 void *instance,
187 const alpaqa_real_t *x,
188 const alpaqa_real_t *y,
189 alpaqa_real_t *grad_gxy) ALPAQA_DEFAULT(nullptr);
190 /// Jacobian of the constraints function.
191 /// @see @ref alpaqa::TypeErasedProblem::eval_jac_g()
192 void (*eval_jac_g)(
193 void *instance,
194 const alpaqa_real_t *x,
195 alpaqa_real_t *J_values) ALPAQA_DEFAULT(nullptr);
196 /// Get the sparsity pattern of the Jacobian of the constraints function.
197 /// @see @ref alpaqa::TypeErasedProblem::get_jac_g_sparsity()
198 alpaqa_sparsity_t (*get_jac_g_sparsity)(
199 void *instance) ALPAQA_DEFAULT(nullptr);
200 /// Gradient of specific constraint function.
201 /// @see @ref alpaqa::TypeErasedProblem::eval_grad_gi()
202 void (*eval_grad_gi)(
203 void *instance,
204 const alpaqa_real_t *x,
206 alpaqa_real_t *grad_gi) ALPAQA_DEFAULT(nullptr);
207 /// Hessian-vector product of the Lagrangian.
208 /// @see @ref alpaqa::TypeErasedProblem::eval_hess_L_prod()
209 void (*eval_hess_L_prod)(
210 void *instance,
211 const alpaqa_real_t *x,
212 const alpaqa_real_t *y,
213 alpaqa_real_t scale,
214 const alpaqa_real_t *v,
215 alpaqa_real_t *Hv) ALPAQA_DEFAULT(nullptr);
216 /// Hessian of the Lagrangian.
217 /// @see @ref alpaqa::TypeErasedProblem::eval_hess_L()
218 void (*eval_hess_L)(
219 void *instance,
220 const alpaqa_real_t *x,
221 const alpaqa_real_t *y,
222 alpaqa_real_t scale,
223 alpaqa_real_t *H_values) ALPAQA_DEFAULT(nullptr);
224 /// Get the sparsity pattern of the Hessian of the Lagrangian.
225 /// @see @ref alpaqa::TypeErasedProblem::get_hess_L_sparsity()
226 alpaqa_sparsity_t (*get_hess_L_sparsity)(
227 void *instance) ALPAQA_DEFAULT(nullptr);
228 /// Hessian-vector product of the augmented Lagrangian.
229 /// @see @ref alpaqa::TypeErasedProblem::eval_hess_ψ_prod()
230 void (*eval_hess_ψ_prod)(
231 void *instance,
232 const alpaqa_real_t *x,
233 const alpaqa_real_t *y,
234 const alpaqa_real_t *Σ,
235 alpaqa_real_t scale,
236 const alpaqa_real_t *zl,
237 const alpaqa_real_t *zu,
238 const alpaqa_real_t *v,
239 alpaqa_real_t *Hv) ALPAQA_DEFAULT(nullptr);
240 /// Hessian of the augmented Lagrangian.
241 /// @see @ref alpaqa::TypeErasedProblem::eval_hess_ψ()
242 void (*eval_hess_ψ)(
243 void *instance,
244 const alpaqa_real_t *x,
245 const alpaqa_real_t *y,
246 const alpaqa_real_t *Σ,
247 alpaqa_real_t scale,
248 const alpaqa_real_t *zl,
249 const alpaqa_real_t *zu,
250 alpaqa_real_t *H_values) ALPAQA_DEFAULT(nullptr);
251 /// Get the sparsity pattern of the Hessian of the augmented Lagrangian.
252 /// @see @ref alpaqa::TypeErasedProblem::get_hess_ψ_sparsity()
253 alpaqa_sparsity_t (*get_hess_ψ_sparsity)(
254 void *instance) ALPAQA_DEFAULT(nullptr);
255 /// Cost and its gradient.
256 /// @see @ref alpaqa::TypeErasedProblem::eval_f_grad_f()
257 alpaqa_real_t (*eval_f_grad_f)(
258 void *instance,
259 const alpaqa_real_t *x,
260 alpaqa_real_t *grad_fx) ALPAQA_DEFAULT(nullptr);
261 /// Cost and constraints.
262 /// @see @ref alpaqa::TypeErasedProblem::eval_f_g()
263 alpaqa_real_t (*eval_f_g)(
264 void *instance,
265 const alpaqa_real_t *x,
266 alpaqa_real_t *g) ALPAQA_DEFAULT(nullptr);
267 /// Gradient of the cost and gradient-vector product of the constraints.
268 /// @see @ref alpaqa::TypeErasedProblem::eval_grad_f_grad_g_prod()
269 void (*eval_grad_f_grad_g_prod)(
270 void *instance,
271 const alpaqa_real_t *x,
272 const alpaqa_real_t *y,
273 alpaqa_real_t *grad_f,
274 alpaqa_real_t *grad_gxy) ALPAQA_DEFAULT(nullptr);
275 /// Gradient of the Lagrangian.
276 /// @see @ref alpaqa::TypeErasedProblem::eval_grad_L()
277 void (*eval_grad_L)(
278 void *instance,
279 const alpaqa_real_t *x,
280 const alpaqa_real_t *y,
281 alpaqa_real_t *grad_L,
282 alpaqa_real_t *work_n) ALPAQA_DEFAULT(nullptr);
283 /// Augmented Lagrangian.
284 /// @see @ref alpaqa::TypeErasedProblem::eval_ψ()
285 alpaqa_real_t (*eval_ψ)(
286 void *instance,
287 const alpaqa_real_t *x,
288 const alpaqa_real_t *y,
289 const alpaqa_real_t *Σ,
290 const alpaqa_real_t *zl,
291 const alpaqa_real_t *zu,
292 alpaqa_real_t *ŷ) ALPAQA_DEFAULT(nullptr);
293 /// Gradient of the augmented Lagrangian.
294 /// @see @ref alpaqa::TypeErasedProblem::eval_grad_ψ()
295 void (*eval_grad_ψ)(
296 void *instance,
297 const alpaqa_real_t *x,
298 const alpaqa_real_t *y,
299 const alpaqa_real_t *Σ,
300 const alpaqa_real_t *zl,
301 const alpaqa_real_t *zu,
302 alpaqa_real_t *grad_ψ,
303 alpaqa_real_t *work_n,
304 alpaqa_real_t *work_m) ALPAQA_DEFAULT(nullptr);
305 /// Augmented Lagrangian and its gradient.
306 /// @see @ref alpaqa::TypeErasedProblem::eval_ψ_grad_ψ()
307 alpaqa_real_t (*eval_ψ_grad_ψ)(
308 void *instance,
309 const alpaqa_real_t *x,
310 const alpaqa_real_t *y,
311 const alpaqa_real_t *Σ,
312 const alpaqa_real_t *zl,
313 const alpaqa_real_t *zu,
314 alpaqa_real_t *grad_ψ,
315 alpaqa_real_t *work_n,
316 alpaqa_real_t *work_m) ALPAQA_DEFAULT(nullptr);
317 /// Proximal gradient step.
318 /// @see @ref alpaqa::TypeErasedProblem::eval_prox_grad_step()
319 /// If not set, the default implementation from
320 /// @ref alpaqa::BoxConstrProblem is used.
321 alpaqa_real_t (*eval_prox_grad_step)(
322 void *instance,
323 alpaqa_real_t γ,
324 const alpaqa_real_t *x,
325 const alpaqa_real_t *grad_ψ,
326 alpaqa_real_t *x̂,
327 alpaqa_real_t *p) ALPAQA_DEFAULT(nullptr);
328 /// Provide the initial values for the bounds of
329 /// @ref alpaqa::BoxConstrProblem::C, i.e. the constraints on the decision
330 /// variables.
331 void (*initialize_box_C)(
332 void *instance,
333 alpaqa_real_t *lb,
334 alpaqa_real_t *ub) ALPAQA_DEFAULT(nullptr);
335 /// Provide the initial values for the bounds of
336 /// @ref alpaqa::BoxConstrProblem::D, i.e. the general constraints.
337 void (*initialize_box_D)(
338 void *instance,
339 alpaqa_real_t *lb,
340 alpaqa_real_t *ub) ALPAQA_DEFAULT(nullptr);
341 /// Provide the initial values for @ref alpaqa::BoxConstrProblem::l1_reg,
342 /// the ℓ₁-regularization factor.
343 /// This function is called twice:
344 /// 1. with @p lambda set to `nullptr`, and the user should set the size.
345 /// 2. with @p lambda pointing to an array of that size, and the user
346 /// should initialize this array.
347 void (*initialize_l1_reg)(
348 void *instance,
349 alpaqa_real_t *lambda,
350 alpaqa_length_t *size) ALPAQA_DEFAULT(nullptr);
351 // clang-format on
353
354/// Opaque type for a C++-only map of extra functions.
356/// Opaque type for a C++-only exception pointer.
358
359/// @note When used in C, you should initialize this struct by passing a pointer
360/// to your instance to the @ref ALPAQA_PROBLEM_REGISTER_INIT macro.
361/// In C++, this is not necessary, because all members have default
362/// initializers.
363typedef struct {
364 /// To check whether the loaded problem is compatible with the version of
365 /// the solver.
367 /// Owning pointer.
368 void *instance ALPAQA_DEFAULT(nullptr);
369 /// Non-owning pointer, lifetime at least as long as @ref instance.
371 /// Pointer to the function to clean up @ref instance.
372 void (*cleanup)(void *) ALPAQA_DEFAULT(nullptr);
373 /// Pointer to a map of extra functions (C++ only).
374 /// @see @ref alpaqa::register_function
375 /// @see @ref alpaqa::register_member_function
376 alpaqa_function_dict_t *extra_functions ALPAQA_DEFAULT(nullptr);
377 /// Pointer to an exception that ocurred during problem creation.
380
381typedef struct {
385
386 // clang-format off
387 void (*get_U)(
388 void *instance,
389 alpaqa_real_t *lb,
390 alpaqa_real_t *ub) ALPAQA_DEFAULT(nullptr);
391 void (*get_D)(
392 void *instance,
393 alpaqa_real_t *lb,
394 alpaqa_real_t *ub) ALPAQA_DEFAULT(nullptr);
395 void (*get_D_N)(
396 void *instance,
397 alpaqa_real_t *lb,
398 alpaqa_real_t *ub) ALPAQA_DEFAULT(nullptr);
399 void (*get_x_init)(
400 void *instance,
401 alpaqa_real_t *x_init) ALPAQA_DEFAULT(nullptr);
402 void (*eval_f)(
403 void *instance,
404 alpaqa_index_t timestep,
405 const alpaqa_real_t *x,
406 const alpaqa_real_t *u,
407 alpaqa_real_t *fxu) ALPAQA_DEFAULT(nullptr);
408 void (*eval_jac_f)(
409 void *instance,
410 alpaqa_index_t timestep,
411 const alpaqa_real_t *x,
412 const alpaqa_real_t *u,
413 alpaqa_real_t *J_fxu) ALPAQA_DEFAULT(nullptr);
414 void (*eval_grad_f_prod)(
415 void *instance,
416 alpaqa_index_t timestep,
417 const alpaqa_real_t *x,
418 const alpaqa_real_t *u,
419 const alpaqa_real_t *p,
420 alpaqa_real_t *grad_fxu_p) ALPAQA_DEFAULT(nullptr);
421 void (*eval_h)(
422 void *instance,
423 alpaqa_index_t timestep,
424 const alpaqa_real_t *x,
425 const alpaqa_real_t *u,
426 alpaqa_real_t *h) ALPAQA_DEFAULT(nullptr);
427 void (*eval_h_N)(
428 void *instance,
429 const alpaqa_real_t *x,
430 alpaqa_real_t *h) ALPAQA_DEFAULT(nullptr);
431 alpaqa_real_t (*eval_l)(
432 void *instance,
433 alpaqa_index_t timestep,
434 const alpaqa_real_t *h) ALPAQA_DEFAULT(nullptr);
435 alpaqa_real_t (*eval_l_N)(
436 void *instance,
437 const alpaqa_real_t *h) ALPAQA_DEFAULT(nullptr);
438 void (*eval_qr)(
439 void *instance,
440 alpaqa_index_t timestep,
441 const alpaqa_real_t *xu,
442 const alpaqa_real_t *h,
443 alpaqa_real_t *qr) ALPAQA_DEFAULT(nullptr);
444 void (*eval_q_N)(
445 void *instance,
446 const alpaqa_real_t *x,
447 const alpaqa_real_t *h,
448 alpaqa_real_t *q) ALPAQA_DEFAULT(nullptr);
449 void (*eval_add_Q)(
450 void *instance,
451 alpaqa_index_t timestep,
452 const alpaqa_real_t *xu,
453 const alpaqa_real_t *h,
454 alpaqa_real_t *Q) ALPAQA_DEFAULT(nullptr);
455 void (*eval_add_Q_N)(
456 void *instance,
457 const alpaqa_real_t *x,
458 const alpaqa_real_t *h,
459 alpaqa_real_t *Q) ALPAQA_DEFAULT(nullptr);
460 void (*eval_add_R_masked)(
461 void *instance,
462 alpaqa_index_t timestep,
463 const alpaqa_real_t *xu,
464 const alpaqa_real_t *h,
465 const alpaqa_index_t *mask,
466 alpaqa_real_t *R,
467 alpaqa_real_t *work) ALPAQA_DEFAULT(nullptr);
468 void (*eval_add_S_masked)(
469 void *instance,
470 alpaqa_index_t timestep,
471 const alpaqa_real_t *xu,
472 const alpaqa_real_t *h,
473 const alpaqa_index_t *mask,
474 alpaqa_real_t *S,
475 alpaqa_real_t *work) ALPAQA_DEFAULT(nullptr);
476 void (*eval_add_R_prod_masked)(
477 void *instance,
478 alpaqa_index_t timestep,
479 const alpaqa_real_t *xu,
480 const alpaqa_real_t *h,
481 const alpaqa_index_t *mask_J,
482 const alpaqa_index_t *mask_K,
483 const alpaqa_real_t *v,
484 alpaqa_real_t *out,
485 alpaqa_real_t *work) ALPAQA_DEFAULT(nullptr);
486 void (*eval_add_S_prod_masked)(
487 void *instance,
488 alpaqa_index_t timestep,
489 const alpaqa_real_t *xu,
490 const alpaqa_real_t *h,
491 const alpaqa_index_t *mask_K,
492 const alpaqa_real_t *v,
493 alpaqa_real_t *out,
494 alpaqa_real_t *work) ALPAQA_DEFAULT(nullptr);
495 alpaqa_length_t (*get_R_work_size)(
496 void *instance) ALPAQA_DEFAULT(nullptr);
497 alpaqa_length_t (*get_S_work_size)(
498 void *instance) ALPAQA_DEFAULT(nullptr);
499 void (*eval_constr)(
500 void *instance,
501 alpaqa_index_t timestep,
502 const alpaqa_real_t *x,
503 alpaqa_real_t *c) ALPAQA_DEFAULT(nullptr);
504 void (*eval_constr_N)(
505 void *instance,
506 const alpaqa_real_t *x,
507 alpaqa_real_t *c) ALPAQA_DEFAULT(nullptr);
508 void (*eval_grad_constr_prod)(
509 void *instance,
510 alpaqa_index_t timestep,
511 const alpaqa_real_t *x,
512 const alpaqa_real_t *p,
513 alpaqa_real_t *grad_cx_p) ALPAQA_DEFAULT(nullptr);
514 void (*eval_grad_constr_prod_N)(
515 void *instance,
516 const alpaqa_real_t *x,
517 const alpaqa_real_t *p,
518 alpaqa_real_t *grad_cx_p) ALPAQA_DEFAULT(nullptr);
519 void (*eval_add_gn_hess_constr)(
520 void *instance,
521 alpaqa_index_t timestep,
522 const alpaqa_real_t *x,
523 const alpaqa_real_t *M,
524 alpaqa_real_t *out) ALPAQA_DEFAULT(nullptr);
525 void (*eval_add_gn_hess_constr_N)(
526 void *instance,
527 const alpaqa_real_t *x,
528 const alpaqa_real_t *M,
529 alpaqa_real_t *out) ALPAQA_DEFAULT(nullptr);
530 // clang-format on
532
533/// @note When used in C, you should initialize this struct by passing a pointer
534/// to your instance to the @ref ALPAQA_PROBLEM_REGISTER_INIT macro.
535/// In C++, this is not necessary, because all members have default
536/// initializers.
537typedef struct {
538 /// To check whether the loaded problem is compatible with the version of
539 /// the solver.
541 /// Owning pointer.
542 void *instance ALPAQA_DEFAULT(nullptr);
543 /// Non-owning pointer, lifetime at least as long as @ref instance.
545 /// Pointer to the function to clean up @ref instance.
546 void (*cleanup)(void *) ALPAQA_DEFAULT(nullptr);
547 /// Pointer to a map of extra functions (C++ only).
548 alpaqa_function_dict_t *extra_functions ALPAQA_DEFAULT(nullptr);
549 /// Pointer to an exception that ocurred during problem creation.
552
553#ifdef __cplusplus
554}
555#endif
556
557#if !defined(__cplusplus) || defined(DOXYGEN)
558inline static void
564inline static void
570/// Initialize an instance of @ref alpaqa_problem_register_t or
571/// @ref alpaqa_control_problem_register_t. It initializes all members to zero,
572/// except for the ABI version, which is initialized to the current ABI version.
573/// Available in C only (unnecessary in C++).
574/// @param self
575/// A pointer to the instance to initialize.
576#define ALPAQA_PROBLEM_REGISTER_INIT(self) \
577 _Generic((self), \
578 alpaqa_problem_register_t *: alpaqa_problem_register_init, \
579 alpaqa_control_problem_register_t *: alpaqa_control_problem_register_init)( \
580 self)
581#endif
582
583#if defined(__cplusplus) && __cplusplus > 201703L
584
585#include <any>
586#include <exception>
587#include <functional>
588#include <map>
589#include <string>
590
592 std::map<std::string, std::any> dict{};
593};
594
596 std::exception_ptr exc{};
597};
598
599namespace alpaqa {
600
606
607/// Make the given function available to alpaqa.
608/// @see @ref alpaqa::dl::DLProblem::call_extra_func
609/// @see @ref alpaqa::dl::DLControlProblem::call_extra_func
610template <class Func>
611void register_function(function_dict_t *&extra_functions, std::string name,
612 Func &&func) {
613 if (extra_functions == nullptr)
614 extra_functions = new function_dict_t{};
615 extra_functions->dict.insert_or_assign(
616 std::move(name), std::function{std::forward<Func>(func)});
617}
618
619template <class Func>
620void register_function(problem_register_t &result, std::string name,
621 Func &&func) {
622 register_function(result.extra_functions, std::move(name),
623 std::forward<Func>(func));
624}
625
626template <class Func>
627void register_function(control_problem_register_t &result, std::string name,
628 Func &&func) {
629 register_function(result.extra_functions, std::move(name),
630 std::forward<Func>(func));
631}
632
633template <class Result, class T, class Ret, class... Args>
634void register_member_function(Result &result, std::string name,
635 Ret (T::*member)(Args...)) {
636 register_function(result, std::move(name),
637 [member](void *self_, Args... args) -> Ret {
638 auto *self = reinterpret_cast<T *>(self_);
639 return (self->*member)(std::forward<Args>(args)...);
640 });
641}
642
643template <class Result, class T, class Ret, class... Args>
644void register_member_function(Result &result, std::string name,
645 Ret (T::*member)(Args...) const) {
646 register_function(result, std::move(name),
647 [member](const void *self_, Args... args) -> Ret {
648 const auto *self = reinterpret_cast<const T *>(self_);
649 return (self->*member)(std::forward<Args>(args)...);
650 });
651}
652
653namespace detail {
654/// Overload for non-const-qualified member functions.
655/// @see @ref alpaqa::member_caller
656template <auto Member, class Class, class Ret, class... Args>
657static auto member_caller(Ret (Class::*)(Args...)) {
658 return [](void *self_, Args... args) -> Ret {
659 auto *self = reinterpret_cast<Class *>(self_);
660 return (self->*Member)(std::forward<Args>(args)...);
661 };
662}
663/// Overload for const-qualified member functions.
664/// @see @ref alpaqa::member_caller
665template <auto Member, class Class, class Ret, class... Args>
666static auto member_caller(Ret (Class::*)(Args...) const) {
667 return []<class Self>(Self * self_, Args... args) -> Ret
668 requires std::is_void_v<Self>
669 {
670 const auto *self = reinterpret_cast<const Class *>(self_);
671 return (self->*Member)(std::forward<Args>(args)...);
672 };
673}
674/// Overload for member variables.
675/// @see @ref alpaqa::member_caller
676template <auto Member, class Class, class Ret>
677static auto member_caller(Ret Class::*) {
678 return []<class Self>(Self * self_) -> decltype(auto)
679 requires std::is_void_v<Self>
680 {
681 using CClass = std::conditional_t<std::is_const_v<Self>,
682 std::add_const_t<Class>, Class>;
683 auto *self = reinterpret_cast<CClass *>(self_);
684 return self->*Member;
685 };
686}
687} // namespace detail
688
689/// Wrap the given member function or variable into a (possibly generic) lambda
690/// function that accepts the instance as a type-erased void pointer.
691///
692/// The signature of the resulting function depends on the signature of the
693/// member function:
694///
695/// - `Ret Class::member(args...)` → `Ret(void *self, args...)`
696/// - `Ret Class::member(args...) const` → `Ret(void *self, args...)`
697/// - `Ret Class::member(args...) const` → `Ret(const void *self, args...)`
698///
699/// If the given member is a variable:
700///
701/// - `Type Class::member` → `Type &(void *self)`
702/// - `Type Class::member` → `const Type &(const void *self)`
703template <auto Member>
704static auto member_caller() {
705 return detail::member_caller<Member>(Member);
706}
707
708/// Cleans up the extra functions registered by @ref register_function.
709/// @note This does not need to be called for the functions returned by the
710/// registration function, those functions will be cleaned up by alpaqa.
711/// @note The @ref alpaqa_problem_register_t and
712/// @ref alpaqa_control_problem_register_t structs are part of the C API
713/// and do not automatically clean up their resources when destroyed,
714/// you have to do it manually by calling this function.
715inline void unregister_functions(function_dict_t *&extra_functions) {
716 delete extra_functions;
717 extra_functions = nullptr;
718}
719
720} // namespace alpaqa
721
722#endif
723
724#undef ALPAQA_DEFAULT
725
726// NOLINTEND(modernize-use-using,modernize-deprecated-headers)
static void alpaqa_control_problem_register_init(alpaqa_control_problem_register_t *self)
Definition dl-problem.h:565
#define ALPAQA_DL_ABI_VERSION
Definition dl-problem.h:9
struct alpaqa_function_dict_s alpaqa_function_dict_t
Opaque type for a C++-only map of extra functions.
Definition dl-problem.h:355
ptrdiff_t alpaqa_length_t
Definition dl-problem.h:20
#define ALPAQA_DEFAULT(...)
Definition dl-problem.h:13
alpaqa_length_t alpaqa_index_t
Definition dl-problem.h:21
std::exception_ptr exc
Definition dl-problem.h:596
double alpaqa_real_t
Definition dl-problem.h:19
std::map< std::string, std::any > dict
Definition dl-problem.h:592
alpaqa_symmetry
Definition dl-problem.h:24
@ alpaqa_unsymmetric
Definition dl-problem.h:25
@ alpaqa_lower
Definition dl-problem.h:27
@ alpaqa_upper
Definition dl-problem.h:26
static void alpaqa_problem_register_init(alpaqa_problem_register_t *self)
Definition dl-problem.h:559
void unregister_functions(function_dict_t *&extra_functions)
Cleans up the extra functions registered by register_function.
Definition dl-problem.h:715
void register_function(function_dict_t *&extra_functions, std::string name, Func &&func)
Make the given function available to alpaqa.
Definition dl-problem.h:611
void register_member_function(Result &result, std::string name, Ret(T::*member)(Args...))
Definition dl-problem.h:634
constexpr const auto inf
Definition config.hpp:85
static auto member_caller()
Wrap the given member function or variable into a (possibly generic) lambda function that accepts the...
Definition dl-problem.h:704
alpaqa_function_dict_t * extra_functions
Pointer to a map of extra functions (C++ only).
Definition dl-problem.h:548
uint64_t abi_version
To check whether the loaded problem is compatible with the version of the solver.
Definition dl-problem.h:540
C API providing function pointers to problem functions.
Definition dl-problem.h:157
alpaqa_function_dict_t * extra_functions
Pointer to a map of extra functions (C++ only).
Definition dl-problem.h:376
uint64_t abi_version
To check whether the loaded problem is compatible with the version of the solver.
Definition dl-problem.h:366
alpaqa_length_t cols
Definition dl-problem.h:98
alpaqa_symmetry symmetry
Definition dl-problem.h:99
alpaqa_length_t nnz
Definition dl-problem.h:100
const long * row_indices
Definition dl-problem.h:101
const long * col_indices
Definition dl-problem.h:102
alpaqa_length_t cols
Definition dl-problem.h:116
alpaqa_symmetry symmetry
Definition dl-problem.h:117
const long long * row_indices
Definition dl-problem.h:119
alpaqa_length_t nnz
Definition dl-problem.h:118
const long long * col_indices
Definition dl-problem.h:120
alpaqa_length_t cols
Definition dl-problem.h:80
const int * col_indices
Definition dl-problem.h:84
alpaqa_symmetry symmetry
Definition dl-problem.h:81
const int * row_indices
Definition dl-problem.h:83
alpaqa_length_t nnz
Definition dl-problem.h:82
alpaqa_length_t cols
Definition dl-problem.h:52
alpaqa_symmetry symmetry
Definition dl-problem.h:53
alpaqa_length_t nnz
Definition dl-problem.h:54
const long * outer_ptr
Definition dl-problem.h:56
const long * inner_idx
Definition dl-problem.h:55
alpaqa_length_t cols
Definition dl-problem.h:66
const long long * inner_idx
Definition dl-problem.h:69
alpaqa_symmetry symmetry
Definition dl-problem.h:67
const long long * outer_ptr
Definition dl-problem.h:70
alpaqa_length_t nnz
Definition dl-problem.h:68
alpaqa_length_t cols
Definition dl-problem.h:38
const int * inner_idx
Definition dl-problem.h:41
alpaqa_symmetry symmetry
Definition dl-problem.h:39
const int * outer_ptr
Definition dl-problem.h:42
alpaqa_length_t nnz
Definition dl-problem.h:40
Sparsity of matrices.
Definition dl-problem.h:134