alpaqa 1.0.0a19
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
8#define ALPAQA_DL_ABI_VERSION 0xA1A000000005
9
10#ifdef ALPAQA_DL_PROBLEM_EXPORT
11#elif defined(_WIN32)
12#define ALPAQA_DL_PROBLEM_EXPORT
13#elif defined(__GNUC__)
14#define ALPAQA_DL_PROBLEM_EXPORT __attribute__((visibility("default")))
15#else
16#define ALPAQA_DL_PROBLEM_EXPORT
17#endif
18
19#ifdef __cplusplus
20extern "C" {
21#define ALPAQA_BEGIN_STRUCT(name) struct name
22#define ALPAQA_END_STRUCT(name)
23#define ALPAQA_DEFAULT(...) \
24 { __VA_ARGS__ }
25#else
26#define ALPAQA_BEGIN_STRUCT(name) typedef struct
27#define ALPAQA_END_STRUCT(name) name
28#define ALPAQA_DEFAULT(...)
29#endif
30
31typedef double alpaqa_real_t;
32typedef ptrdiff_t alpaqa_length_t;
34typedef uint64_t alpaqa_dl_abi_version_t;
35
36typedef enum {
37 /// No type was specified (discouraged).
39 /// The @ref alpaqa_register_arg_t::data pointer points to a C++ `std::any`
40 /// object. Use `reinterpret_cast<std::any *>(data)` to convert back.
41 /// Then use `std::any_cast` to get the actual value out.
42 /// @warning `std::any` relies on RTTI that is included in both the
43 /// dynamically loaded problem module and in the code that
44 /// actually loads that module. Types that need to be passed
45 /// between the loading and loaded code need to be exported as
46 /// public classes to ensure that only a single symbol ends up
47 /// in the final application. If the RTTI symbols are private,
48 /// each library will end up with its own local copy, and the
49 /// type information won't compare equal when using libc++,
50 /// causing `std::any_cast` to fail.
52 /// The @ref alpaqa_register_arg_t::data pointer points to a dynamic C++
53 /// `std::span` of `std::string_view`.
54 /// Use `reinterpret_cast<std::span<std::string_view> *>(data)` to
55 /// convert back.
57 /// The @ref alpaqa_register_arg_t::data pointer points to a C++ tuple of
58 /// `pybind11::args` and `pybind11::kwargs`.
59 /// Use `reinterpret_cast<std::tuple<pybind11::args, pybind11::kwargs> *>(data)`
60 /// to convert back.
63
64/// User-provided argument that is passed to the problem registration functions.
66 /// Pointer to the user-provided argument passed to the problem registration
67 /// functions. Use the @ref type member to determine its type.
68 void *data ALPAQA_DEFAULT(nullptr);
69 /// Specifies the type of the data pointed to by @ref data.
72}
74
75/// @see @ref alpaqa::sparsity::Symmetry
81
82/// @see @ref alpaqa::sparsity::Dense
88
89/// @see @ref alpaqa::sparsity::SparseCSC
90typedef struct {
94 const int *inner_idx;
95 const int *outer_ptr;
96 /// @see @ref alpaqa::sparsity::SparseCSC::Order
97 enum {
98 alpaqa_sparse_csc_unsorted = 0,
99 alpaqa_sparse_csc_sorted_rows = 1,
100 } order;
102
103/// @see @ref alpaqa::sparsity::SparseCSC
104typedef struct {
108 const long *inner_idx;
109 const long *outer_ptr;
110 /// @see @ref alpaqa::sparsity::SparseCSC::Order
111 enum {
112 alpaqa_sparse_csc_l_unsorted = 0,
113 alpaqa_sparse_csc_l_sorted_rows = 1,
114 } order;
116
117/// @see @ref alpaqa::sparsity::SparseCSC
118typedef struct {
122 const long long *inner_idx;
123 const long long *outer_ptr;
124 /// @see @ref alpaqa::sparsity::SparseCSC::Order
125 enum {
126 alpaqa_sparse_csc_ll_unsorted = 0,
127 alpaqa_sparse_csc_ll_sorted_rows = 1,
128 } order;
130
131/// @see @ref alpaqa::sparsity::SparseCOO
132typedef struct {
136 const int *row_indices;
137 const int *col_indices;
138 /// @see @ref alpaqa::sparsity::SparseCOO::Order
139 enum {
140 alpaqa_sparse_coo_unsorted = 0,
141 alpaqa_sparse_coo_sorted_by_cols_and_rows = 1,
142 alpaqa_sparse_coo_sorted_by_cols_only = 2,
143 alpaqa_sparse_coo_sorted_by_rows_and_cols = 3,
144 alpaqa_sparse_coo_sorted_by_rows_only = 4,
145 } order;
148
149/// @see @ref alpaqa::sparsity::SparseCOO
150typedef struct {
154 const long *row_indices;
155 const long *col_indices;
156 /// @see @ref alpaqa::sparsity::SparseCOO::Order
157 enum {
158 alpaqa_sparse_coo_l_unsorted = 0,
159 alpaqa_sparse_coo_l_sorted_by_cols_and_rows = 1,
160 alpaqa_sparse_coo_l_sorted_by_cols_only = 2,
161 alpaqa_sparse_coo_l_sorted_by_rows_and_cols = 3,
162 alpaqa_sparse_coo_l_sorted_by_rows_only = 4,
163 } order;
166
167/// @see @ref alpaqa::sparsity::SparseCOO
168typedef struct {
172 const long long *row_indices;
173 const long long *col_indices;
174 /// @see @ref alpaqa::sparsity::SparseCOO::Order
175 enum {
176 alpaqa_sparse_coo_ll_unsorted = 0,
177 alpaqa_sparse_coo_ll_sorted_by_cols_and_rows = 1,
178 alpaqa_sparse_coo_ll_sorted_by_cols_only = 2,
179 alpaqa_sparse_coo_ll_sorted_by_rows_and_cols = 3,
180 alpaqa_sparse_coo_ll_sorted_by_rows_only = 4,
181 } order;
182 long long first_index;
184
185/// Sparsity of matrices.
186/// @see @ref alpaqa::sparsity::Sparsity
207
208/// C API providing function pointers to problem functions.
209/// Used by @ref alpaqa::dl::DLProblem.
211 /// Number of decision variables.
212 /// @see @ref alpaqa::TypeErasedProblem::get_n()
214 /// Number of constraints.
215 /// @see @ref alpaqa::TypeErasedProblem::get_m()
217 /// Name of the problem.
218 /// @see @ref alpaqa::TypeErasedProblem::get_name()
219 const char *name ALPAQA_DEFAULT(nullptr);
220
221 // clang-format off
222 /// Cost function.
223 /// @see @ref alpaqa::TypeErasedProblem::eval_f()
224 alpaqa_real_t (*eval_f)(
225 void *instance,
226 const alpaqa_real_t *x) ALPAQA_DEFAULT(nullptr);
227 /// Gradient of the cost function.
228 /// @see @ref alpaqa::TypeErasedProblem::eval_grad_f()
229 void (*eval_grad_f)(
230 void *instance,
231 const alpaqa_real_t *x,
232 alpaqa_real_t *grad_fx) ALPAQA_DEFAULT(nullptr);
233 /// Constraints function.
234 /// @see @ref alpaqa::TypeErasedProblem::eval_g()
235 void (*eval_g)(
236 void *instance,
237 const alpaqa_real_t *x,
238 alpaqa_real_t *gx) ALPAQA_DEFAULT(nullptr);
239 /// Gradient-vector product of the constraints function.
240 /// @see @ref alpaqa::TypeErasedProblem::eval_grad_g_prod()
241 void (*eval_grad_g_prod)(
242 void *instance,
243 const alpaqa_real_t *x,
244 const alpaqa_real_t *y,
245 alpaqa_real_t *grad_gxy) ALPAQA_DEFAULT(nullptr);
246
247 /// Difference between point and its projection onto the general constraint
248 /// set D.
249 /// @see @ref alpaqa::TypeErasedProblem::eval_proj_diff_g()
250 void (*eval_proj_diff_g)(
251 void *instance,
252 const alpaqa_real_t *z,
253 alpaqa_real_t *e) ALPAQA_DEFAULT(nullptr);
254 /// Project the Lagrange multipliers.
255 /// @see @ref alpaqa::TypeErasedProblem::eval_proj_multipliers()
256 void (*eval_proj_multipliers)(
257 void *instance,
259 /// Proximal gradient step.
260 /// @see @ref alpaqa::TypeErasedProblem::eval_prox_grad_step()
261 /// If not set, the default implementation from
262 /// @ref alpaqa::BoxConstrProblem is used.
263 alpaqa_real_t (*eval_prox_grad_step)(
264 void *instance,
265 alpaqa_real_t γ,
266 const alpaqa_real_t *x,
267 const alpaqa_real_t *grad_ψ,
268 alpaqa_real_t *x̂,
269 alpaqa_real_t *p) ALPAQA_DEFAULT(nullptr);
270 /// Active indices for proximal operator.
271 /// @see @ref alpaqa::TypeErasedProblem::eval_inactive_indices_res_lna()
272 /// If not set, the default implementation from
273 /// @ref alpaqa::BoxConstrProblem is used.
274 alpaqa_index_t (*eval_inactive_indices_res_lna)(
275 void *instance,
276 alpaqa_real_t γ,
277 const alpaqa_real_t *x,
278 const alpaqa_real_t *grad_ψ,
279 alpaqa_index_t *J) ALPAQA_DEFAULT(nullptr);
280
281 /// Jacobian of the constraints function.
282 /// @see @ref alpaqa::TypeErasedProblem::eval_jac_g()
283 void (*eval_jac_g)(
284 void *instance,
285 const alpaqa_real_t *x,
286 alpaqa_real_t *J_values) ALPAQA_DEFAULT(nullptr);
287 /// Get the sparsity pattern of the Jacobian of the constraints function.
288 /// @see @ref alpaqa::TypeErasedProblem::get_jac_g_sparsity()
289 alpaqa_sparsity_t (*get_jac_g_sparsity)(
290 void *instance) ALPAQA_DEFAULT(nullptr);
291 /// Gradient of specific constraint function.
292 /// @see @ref alpaqa::TypeErasedProblem::eval_grad_gi()
293 void (*eval_grad_gi)(
294 void *instance,
295 const alpaqa_real_t *x,
297 alpaqa_real_t *grad_gi) ALPAQA_DEFAULT(nullptr);
298 /// Hessian-vector product of the Lagrangian.
299 /// @see @ref alpaqa::TypeErasedProblem::eval_hess_L_prod()
300 void (*eval_hess_L_prod)(
301 void *instance,
302 const alpaqa_real_t *x,
303 const alpaqa_real_t *y,
304 alpaqa_real_t scale,
305 const alpaqa_real_t *v,
306 alpaqa_real_t *Hv) ALPAQA_DEFAULT(nullptr);
307 /// Hessian of the Lagrangian.
308 /// @see @ref alpaqa::TypeErasedProblem::eval_hess_L()
309 void (*eval_hess_L)(
310 void *instance,
311 const alpaqa_real_t *x,
312 const alpaqa_real_t *y,
313 alpaqa_real_t scale,
314 alpaqa_real_t *H_values) ALPAQA_DEFAULT(nullptr);
315 /// Get the sparsity pattern of the Hessian of the Lagrangian.
316 /// @see @ref alpaqa::TypeErasedProblem::get_hess_L_sparsity()
317 alpaqa_sparsity_t (*get_hess_L_sparsity)(
318 void *instance) ALPAQA_DEFAULT(nullptr);
319 /// Hessian-vector product of the augmented Lagrangian.
320 /// @see @ref alpaqa::TypeErasedProblem::eval_hess_ψ_prod()
321 void (*eval_hess_ψ_prod)(
322 void *instance,
323 const alpaqa_real_t *x,
324 const alpaqa_real_t *y,
325 const alpaqa_real_t *Σ,
326 alpaqa_real_t scale,
327 const alpaqa_real_t *zl,
328 const alpaqa_real_t *zu,
329 const alpaqa_real_t *v,
330 alpaqa_real_t *Hv) ALPAQA_DEFAULT(nullptr);
331 /// Hessian of the augmented Lagrangian.
332 /// @see @ref alpaqa::TypeErasedProblem::eval_hess_ψ()
333 void (*eval_hess_ψ)(
334 void *instance,
335 const alpaqa_real_t *x,
336 const alpaqa_real_t *y,
337 const alpaqa_real_t *Σ,
338 alpaqa_real_t scale,
339 const alpaqa_real_t *zl,
340 const alpaqa_real_t *zu,
341 alpaqa_real_t *H_values) ALPAQA_DEFAULT(nullptr);
342 /// Get the sparsity pattern of the Hessian of the augmented Lagrangian.
343 /// @see @ref alpaqa::TypeErasedProblem::get_hess_ψ_sparsity()
344 alpaqa_sparsity_t (*get_hess_ψ_sparsity)(
345 void *instance) ALPAQA_DEFAULT(nullptr);
346
347 /// Cost and its gradient.
348 /// @see @ref alpaqa::TypeErasedProblem::eval_f_grad_f()
349 alpaqa_real_t (*eval_f_grad_f)(
350 void *instance,
351 const alpaqa_real_t *x,
352 alpaqa_real_t *grad_fx) ALPAQA_DEFAULT(nullptr);
353 /// Cost and constraints.
354 /// @see @ref alpaqa::TypeErasedProblem::eval_f_g()
355 alpaqa_real_t (*eval_f_g)(
356 void *instance,
357 const alpaqa_real_t *x,
358 alpaqa_real_t *g) ALPAQA_DEFAULT(nullptr);
359 /// Gradient of the cost and gradient-vector product of the constraints.
360 /// @see @ref alpaqa::TypeErasedProblem::eval_grad_f_grad_g_prod()
361 void (*eval_grad_f_grad_g_prod)(
362 void *instance,
363 const alpaqa_real_t *x,
364 const alpaqa_real_t *y,
365 alpaqa_real_t *grad_f,
366 alpaqa_real_t *grad_gxy) ALPAQA_DEFAULT(nullptr);
367 /// Gradient of the Lagrangian.
368 /// @see @ref alpaqa::TypeErasedProblem::eval_grad_L()
369 void (*eval_grad_L)(
370 void *instance,
371 const alpaqa_real_t *x,
372 const alpaqa_real_t *y,
373 alpaqa_real_t *grad_L,
374 alpaqa_real_t *work_n) ALPAQA_DEFAULT(nullptr);
375
376 /// Augmented Lagrangian.
377 /// @see @ref alpaqa::TypeErasedProblem::eval_ψ()
378 alpaqa_real_t (*eval_ψ)(
379 void *instance,
380 const alpaqa_real_t *x,
381 const alpaqa_real_t *y,
382 const alpaqa_real_t *Σ,
383 const alpaqa_real_t *zl,
384 const alpaqa_real_t *zu,
385 alpaqa_real_t *ŷ) ALPAQA_DEFAULT(nullptr);
386 /// Gradient of the augmented Lagrangian.
387 /// @see @ref alpaqa::TypeErasedProblem::eval_grad_ψ()
388 void (*eval_grad_ψ)(
389 void *instance,
390 const alpaqa_real_t *x,
391 const alpaqa_real_t *y,
392 const alpaqa_real_t *Σ,
393 const alpaqa_real_t *zl,
394 const alpaqa_real_t *zu,
395 alpaqa_real_t *grad_ψ,
396 alpaqa_real_t *work_n,
397 alpaqa_real_t *work_m) ALPAQA_DEFAULT(nullptr);
398 /// Augmented Lagrangian and its gradient.
399 /// @see @ref alpaqa::TypeErasedProblem::eval_ψ_grad_ψ()
400 alpaqa_real_t (*eval_ψ_grad_ψ)(
401 void *instance,
402 const alpaqa_real_t *x,
403 const alpaqa_real_t *y,
404 const alpaqa_real_t *Σ,
405 const alpaqa_real_t *zl,
406 const alpaqa_real_t *zu,
407 alpaqa_real_t *grad_ψ,
408 alpaqa_real_t *work_n,
409 alpaqa_real_t *work_m) ALPAQA_DEFAULT(nullptr);
410
411 /// Provide the initial values for the bounds of
412 /// @ref alpaqa::BoxConstrProblem::C, i.e. the constraints on the decision
413 /// variables.
414 void (*initialize_box_C)(
415 void *instance,
416 alpaqa_real_t *lb,
417 alpaqa_real_t *ub) ALPAQA_DEFAULT(nullptr);
418 /// Provide the initial values for the bounds of
419 /// @ref alpaqa::BoxConstrProblem::D, i.e. the general constraints.
420 void (*initialize_box_D)(
421 void *instance,
422 alpaqa_real_t *lb,
423 alpaqa_real_t *ub) ALPAQA_DEFAULT(nullptr);
424 /// Provide the initial values for @ref alpaqa::BoxConstrProblem::l1_reg,
425 /// the ℓ₁-regularization factor.
426 /// This function is called twice:
427 /// 1. with @p lambda set to `nullptr`, and the user should set the size.
428 /// 2. with @p lambda pointing to an array of that size, and the user
429 /// should initialize this array.
430 void (*initialize_l1_reg)(
431 void *instance,
432 alpaqa_real_t *lambda,
433 alpaqa_length_t *size) ALPAQA_DEFAULT(nullptr);
434 // clang-format on
435}
437
438/// Opaque type for a C++-only map of extra functions.
440/// Opaque type for a C++-only exception pointer.
442
443/// @note When used in C, you should initialize this struct by passing a pointer
444/// to your instance to the @ref ALPAQA_PROBLEM_REGISTER_INIT macro.
445/// In C++, this is not necessary, because all members have default
446/// initializers.
448 /// To check whether the loaded problem is compatible with the version of
449 /// the solver.
451 /// Owning pointer.
452 void *instance ALPAQA_DEFAULT(nullptr);
453 /// Non-owning pointer, lifetime at least as long as @ref instance.
455 /// Pointer to the function to clean up @ref instance.
456 void (*cleanup)(void *) ALPAQA_DEFAULT(nullptr);
457 /// Pointer to a map of extra functions (C++ only).
458 /// @see @ref alpaqa::register_function
459 /// @see @ref alpaqa::register_member_function
460 alpaqa_function_dict_t *extra_functions ALPAQA_DEFAULT(nullptr);
461 /// Pointer to an exception that ocurred during problem creation.
463}
465
470
471 // clang-format off
472 void (*get_U)(
473 void *instance,
474 alpaqa_real_t *lb,
475 alpaqa_real_t *ub) ALPAQA_DEFAULT(nullptr);
476 void (*get_D)(
477 void *instance,
478 alpaqa_real_t *lb,
479 alpaqa_real_t *ub) ALPAQA_DEFAULT(nullptr);
480 void (*get_D_N)(
481 void *instance,
482 alpaqa_real_t *lb,
483 alpaqa_real_t *ub) ALPAQA_DEFAULT(nullptr);
484 void (*get_x_init)(
485 void *instance,
486 alpaqa_real_t *x_init) ALPAQA_DEFAULT(nullptr);
487 void (*eval_f)(
488 void *instance,
489 alpaqa_index_t timestep,
490 const alpaqa_real_t *x,
491 const alpaqa_real_t *u,
492 alpaqa_real_t *fxu) ALPAQA_DEFAULT(nullptr);
493 void (*eval_jac_f)(
494 void *instance,
495 alpaqa_index_t timestep,
496 const alpaqa_real_t *x,
497 const alpaqa_real_t *u,
498 alpaqa_real_t *J_fxu) ALPAQA_DEFAULT(nullptr);
499 void (*eval_grad_f_prod)(
500 void *instance,
501 alpaqa_index_t timestep,
502 const alpaqa_real_t *x,
503 const alpaqa_real_t *u,
504 const alpaqa_real_t *p,
505 alpaqa_real_t *grad_fxu_p) ALPAQA_DEFAULT(nullptr);
506 void (*eval_h)(
507 void *instance,
508 alpaqa_index_t timestep,
509 const alpaqa_real_t *x,
510 const alpaqa_real_t *u,
511 alpaqa_real_t *h) ALPAQA_DEFAULT(nullptr);
512 void (*eval_h_N)(
513 void *instance,
514 const alpaqa_real_t *x,
515 alpaqa_real_t *h) ALPAQA_DEFAULT(nullptr);
516 alpaqa_real_t (*eval_l)(
517 void *instance,
518 alpaqa_index_t timestep,
519 const alpaqa_real_t *h) ALPAQA_DEFAULT(nullptr);
520 alpaqa_real_t (*eval_l_N)(
521 void *instance,
522 const alpaqa_real_t *h) ALPAQA_DEFAULT(nullptr);
523 void (*eval_qr)(
524 void *instance,
525 alpaqa_index_t timestep,
526 const alpaqa_real_t *xu,
527 const alpaqa_real_t *h,
528 alpaqa_real_t *qr) ALPAQA_DEFAULT(nullptr);
529 void (*eval_q_N)(
530 void *instance,
531 const alpaqa_real_t *x,
532 const alpaqa_real_t *h,
533 alpaqa_real_t *q) ALPAQA_DEFAULT(nullptr);
534 void (*eval_add_Q)(
535 void *instance,
536 alpaqa_index_t timestep,
537 const alpaqa_real_t *xu,
538 const alpaqa_real_t *h,
539 alpaqa_real_t *Q) ALPAQA_DEFAULT(nullptr);
540 void (*eval_add_Q_N)(
541 void *instance,
542 const alpaqa_real_t *x,
543 const alpaqa_real_t *h,
544 alpaqa_real_t *Q) ALPAQA_DEFAULT(nullptr);
545 void (*eval_add_R_masked)(
546 void *instance,
547 alpaqa_index_t timestep,
548 const alpaqa_real_t *xu,
549 const alpaqa_real_t *h,
550 const alpaqa_index_t *mask,
551 alpaqa_real_t *R,
552 alpaqa_real_t *work) ALPAQA_DEFAULT(nullptr);
553 void (*eval_add_S_masked)(
554 void *instance,
555 alpaqa_index_t timestep,
556 const alpaqa_real_t *xu,
557 const alpaqa_real_t *h,
558 const alpaqa_index_t *mask,
559 alpaqa_real_t *S,
560 alpaqa_real_t *work) ALPAQA_DEFAULT(nullptr);
561 void (*eval_add_R_prod_masked)(
562 void *instance,
563 alpaqa_index_t timestep,
564 const alpaqa_real_t *xu,
565 const alpaqa_real_t *h,
566 const alpaqa_index_t *mask_J,
567 const alpaqa_index_t *mask_K,
568 const alpaqa_real_t *v,
569 alpaqa_real_t *out,
570 alpaqa_real_t *work) ALPAQA_DEFAULT(nullptr);
571 void (*eval_add_S_prod_masked)(
572 void *instance,
573 alpaqa_index_t timestep,
574 const alpaqa_real_t *xu,
575 const alpaqa_real_t *h,
576 const alpaqa_index_t *mask_K,
577 const alpaqa_real_t *v,
578 alpaqa_real_t *out,
579 alpaqa_real_t *work) ALPAQA_DEFAULT(nullptr);
580 alpaqa_length_t (*get_R_work_size)(
581 void *instance) ALPAQA_DEFAULT(nullptr);
582 alpaqa_length_t (*get_S_work_size)(
583 void *instance) ALPAQA_DEFAULT(nullptr);
584 void (*eval_constr)(
585 void *instance,
586 alpaqa_index_t timestep,
587 const alpaqa_real_t *x,
588 alpaqa_real_t *c) ALPAQA_DEFAULT(nullptr);
589 void (*eval_constr_N)(
590 void *instance,
591 const alpaqa_real_t *x,
592 alpaqa_real_t *c) ALPAQA_DEFAULT(nullptr);
593 void (*eval_grad_constr_prod)(
594 void *instance,
595 alpaqa_index_t timestep,
596 const alpaqa_real_t *x,
597 const alpaqa_real_t *p,
598 alpaqa_real_t *grad_cx_p) ALPAQA_DEFAULT(nullptr);
599 void (*eval_grad_constr_prod_N)(
600 void *instance,
601 const alpaqa_real_t *x,
602 const alpaqa_real_t *p,
603 alpaqa_real_t *grad_cx_p) ALPAQA_DEFAULT(nullptr);
604 void (*eval_add_gn_hess_constr)(
605 void *instance,
606 alpaqa_index_t timestep,
607 const alpaqa_real_t *x,
608 const alpaqa_real_t *M,
609 alpaqa_real_t *out) ALPAQA_DEFAULT(nullptr);
610 void (*eval_add_gn_hess_constr_N)(
611 void *instance,
612 const alpaqa_real_t *x,
613 const alpaqa_real_t *M,
614 alpaqa_real_t *out) ALPAQA_DEFAULT(nullptr);
615 // clang-format on
616}
618
619/// @note When used in C, you should initialize this struct by passing a pointer
620/// to your instance to the @ref ALPAQA_PROBLEM_REGISTER_INIT macro.
621/// In C++, this is not necessary, because all members have default
622/// initializers.
624 /// To check whether the loaded problem is compatible with the version of
625 /// the solver.
627 /// Owning pointer.
628 void *instance ALPAQA_DEFAULT(nullptr);
629 /// Non-owning pointer, lifetime at least as long as @ref instance.
631 /// Pointer to the function to clean up @ref instance.
632 void (*cleanup)(void *) ALPAQA_DEFAULT(nullptr);
633 /// Pointer to a map of extra functions (C++ only).
634 alpaqa_function_dict_t *extra_functions ALPAQA_DEFAULT(nullptr);
635 /// Pointer to an exception that ocurred during problem creation.
637}
639
640#ifdef __cplusplus
641}
642#endif
643
644#if !defined(__cplusplus) || defined(DOXYGEN)
645inline static void
651inline static void
657/// Initialize an instance of @ref alpaqa_problem_register_t or
658/// @ref alpaqa_control_problem_register_t. It initializes all members to zero,
659/// except for the ABI version, which is initialized to the current ABI version.
660/// Available in C only (unnecessary in C++).
661/// @param self
662/// A pointer to the instance to initialize.
663#define ALPAQA_PROBLEM_REGISTER_INIT(self) \
664 _Generic((self), \
665 alpaqa_problem_register_t *: alpaqa_problem_register_init, \
666 alpaqa_control_problem_register_t *: alpaqa_control_problem_register_init)( \
667 self)
668#endif
669
670#if defined(__cplusplus) && \
671 (__cplusplus > 201703L || (defined(_MSVC_LANG) && _MSVC_LANG > 201703L))
672
673#include <any>
674#include <exception>
675#include <functional>
676#include <map>
677#include <string>
678
680 std::map<std::string, std::any> dict{};
681};
682
684 std::exception_ptr exc{};
685};
686
687namespace alpaqa {
688
694
695namespace detail {
696/// Custom type for which we can export the RTTI to support std::any across
697/// shared library boundaries when using libc++.
698template <class Signature>
700 std::function<Signature> function;
701};
702template <class Signature>
704} // namespace detail
705
706/// Make the given function available to alpaqa.
707/// @see @ref alpaqa::dl::DLProblem::call_extra_func
708/// @see @ref alpaqa::dl::DLControlProblem::call_extra_func
709template <class Func>
710void register_function(function_dict_t *&extra_functions, std::string name,
711 Func &&func) {
712 if (extra_functions == nullptr)
713 extra_functions = new function_dict_t{};
714 extra_functions->dict.insert_or_assign(
715 std::move(name),
716 detail::function_wrapper_t{std::function{std::forward<Func>(func)}});
717}
718
719template <class Func>
720void register_function(problem_register_t &result, std::string name,
721 Func &&func) {
722 register_function(result.extra_functions, std::move(name),
723 std::forward<Func>(func));
724}
725
726template <class Func>
727void register_function(control_problem_register_t &result, std::string name,
728 Func &&func) {
729 register_function(result.extra_functions, std::move(name),
730 std::forward<Func>(func));
731}
732
733template <class Result, class T, class Ret, class... Args>
734void register_member_function(Result &result, std::string name,
735 Ret (T::*member)(Args...)) {
736 register_function(result, std::move(name),
737 [member](void *self_, Args... args) -> Ret {
738 auto *self = reinterpret_cast<T *>(self_);
739 return (self->*member)(std::forward<Args>(args)...);
740 });
741}
742
743template <class Result, class T, class Ret, class... Args>
744void register_member_function(Result &result, std::string name,
745 Ret (T::*member)(Args...) const) {
746 register_function(result, std::move(name),
747 [member](const void *self_, Args... args) -> Ret {
748 const auto *self = reinterpret_cast<const T *>(self_);
749 return (self->*member)(std::forward<Args>(args)...);
750 });
751}
752
753namespace detail {
754/// Overload for non-const-qualified member functions.
755/// @see @ref alpaqa::member_caller
756template <auto Member, class Class, class Ret, class... Args>
757static auto member_caller(Ret (Class::*)(Args...)) {
758 return [](void *self_, Args... args) -> Ret {
759 auto *self = reinterpret_cast<Class *>(self_);
760 return (self->*Member)(std::forward<Args>(args)...);
761 };
762}
763/// Overload for const-qualified member functions.
764/// @see @ref alpaqa::member_caller
765template <auto Member, class Class, class Ret, class... Args>
766static auto member_caller(Ret (Class::*)(Args...) const) {
767 return []<class Self>(Self *self_, Args... args) -> Ret
768 requires std::is_void_v<Self>
769 {
770 const auto *self = reinterpret_cast<const Class *>(self_);
771 return (self->*Member)(std::forward<Args>(args)...);
772 };
773}
774/// Overload for member variables.
775/// @see @ref alpaqa::member_caller
776template <auto Member, class Class, class Ret>
777static auto member_caller(Ret Class::*) {
778 return []<class Self>(Self *self_) -> decltype(auto)
779 requires std::is_void_v<Self>
780 {
781 using CClass = std::conditional_t<std::is_const_v<Self>,
782 std::add_const_t<Class>, Class>;
783 auto *self = reinterpret_cast<CClass *>(self_);
784 return self->*Member;
785 };
786}
787} // namespace detail
788
789/// Wrap the given member function or variable into a (possibly generic) lambda
790/// function that accepts the instance as a type-erased void pointer.
791///
792/// The signature of the resulting function depends on the signature of the
793/// member function:
794///
795/// - `Ret Class::member(args...)` → `Ret(void *self, args...)`
796/// - `Ret Class::member(args...) const` → `Ret(void *self, args...)`
797/// - `Ret Class::member(args...) const` → `Ret(const void *self, args...)`
798///
799/// If the given member is a variable:
800///
801/// - `Type Class::member` → `Type &(void *self)`
802/// - `Type Class::member` → `const Type &(const void *self)`
803template <auto Member>
804static auto member_caller() {
805 return detail::member_caller<Member>(Member);
806}
807
808/// Cleans up the extra functions registered by @ref register_function.
809/// @note This does not need to be called for the functions returned by the
810/// registration function, those functions will be cleaned up by alpaqa.
811/// @note The @ref alpaqa_problem_register_t and
812/// @ref alpaqa_control_problem_register_t structs are part of the C API
813/// and do not automatically clean up their resources when destroyed,
814/// you have to do it manually by calling this function.
815inline void unregister_functions(function_dict_t *&extra_functions) {
816 delete extra_functions;
817 extra_functions = nullptr;
818}
819
820} // namespace alpaqa
821
822#endif
823
824#undef ALPAQA_DEFAULT
825
826// NOLINTEND(modernize-use-using,modernize-deprecated-headers)
static void alpaqa_control_problem_register_init(alpaqa_control_problem_register_t *self)
Definition dl-problem.h:652
#define ALPAQA_DL_ABI_VERSION
Definition dl-problem.h:8
alpaqa_register_arg_type_t
Definition dl-problem.h:36
@ alpaqa_register_arg_unspecified
No type was specified (discouraged).
Definition dl-problem.h:38
@ alpaqa_register_arg_strings
The alpaqa_register_arg_t::data pointer points to a dynamic C++ std::span of std::string_view.
Definition dl-problem.h:56
@ alpaqa_register_arg_std_any
The alpaqa_register_arg_t::data pointer points to a C++ std::any object.
Definition dl-problem.h:51
@ alpaqa_register_arg_py_args
The alpaqa_register_arg_t::data pointer points to a C++ tuple of pybind11::args and pybind11::kwargs.
Definition dl-problem.h:61
struct alpaqa_function_dict_s alpaqa_function_dict_t
Opaque type for a C++-only map of extra functions.
Definition dl-problem.h:439
ptrdiff_t alpaqa_length_t
Definition dl-problem.h:32
#define ALPAQA_END_STRUCT(name)
Definition dl-problem.h:22
#define ALPAQA_DEFAULT(...)
Definition dl-problem.h:23
alpaqa_length_t alpaqa_index_t
Definition dl-problem.h:33
std::exception_ptr exc
Definition dl-problem.h:684
#define ALPAQA_BEGIN_STRUCT(name)
Definition dl-problem.h:21
uint64_t alpaqa_dl_abi_version_t
Definition dl-problem.h:34
#define ALPAQA_DL_PROBLEM_EXPORT
Definition dl-problem.h:16
double alpaqa_real_t
Definition dl-problem.h:31
std::map< std::string, std::any > dict
Definition dl-problem.h:680
alpaqa_symmetry
Definition dl-problem.h:76
@ alpaqa_unsymmetric
Definition dl-problem.h:77
@ alpaqa_lower
Definition dl-problem.h:79
@ alpaqa_upper
Definition dl-problem.h:78
static void alpaqa_problem_register_init(alpaqa_problem_register_t *self)
Definition dl-problem.h:646
User-provided argument that is passed to the problem registration functions.
Definition dl-problem.h:65
std::function< Signature > function
Definition dl-problem.h:700
Custom type for which we can export the RTTI to support std::any across shared library boundaries whe...
Definition dl-problem.h:699
void unregister_functions(function_dict_t *&extra_functions)
Cleans up the extra functions registered by register_function.
Definition dl-problem.h:815
void register_function(function_dict_t *&extra_functions, std::string name, Func &&func)
Make the given function available to alpaqa.
Definition dl-problem.h:710
void register_member_function(Result &result, std::string name, Ret(T::*member)(Args...))
Definition dl-problem.h:734
constexpr const auto inf
Definition config.hpp:112
static auto member_caller()
Wrap the given member function or variable into a (possibly generic) lambda function that accepts the...
Definition dl-problem.h:804
alpaqa_dl_abi_version_t abi_version
To check whether the loaded problem is compatible with the version of the solver.
Definition dl-problem.h:626
alpaqa_function_dict_t * extra_functions
Pointer to a map of extra functions (C++ only).
Definition dl-problem.h:634
C API providing function pointers to problem functions.
Definition dl-problem.h:210
alpaqa_dl_abi_version_t abi_version
To check whether the loaded problem is compatible with the version of the solver.
Definition dl-problem.h:450
alpaqa_function_dict_t * extra_functions
Pointer to a map of extra functions (C++ only).
Definition dl-problem.h:460
alpaqa_length_t cols
Definition dl-problem.h:151
alpaqa_symmetry symmetry
Definition dl-problem.h:152
alpaqa_length_t nnz
Definition dl-problem.h:153
const long * row_indices
Definition dl-problem.h:154
const long * col_indices
Definition dl-problem.h:155
alpaqa_length_t cols
Definition dl-problem.h:169
alpaqa_symmetry symmetry
Definition dl-problem.h:170
const long long * row_indices
Definition dl-problem.h:172
alpaqa_length_t nnz
Definition dl-problem.h:171
const long long * col_indices
Definition dl-problem.h:173
alpaqa_length_t cols
Definition dl-problem.h:133
const int * col_indices
Definition dl-problem.h:137
alpaqa_symmetry symmetry
Definition dl-problem.h:134
const int * row_indices
Definition dl-problem.h:136
alpaqa_length_t nnz
Definition dl-problem.h:135
alpaqa_length_t cols
Definition dl-problem.h:105
alpaqa_symmetry symmetry
Definition dl-problem.h:106
alpaqa_length_t nnz
Definition dl-problem.h:107
const long * outer_ptr
Definition dl-problem.h:109
const long * inner_idx
Definition dl-problem.h:108
alpaqa_length_t cols
Definition dl-problem.h:119
const long long * inner_idx
Definition dl-problem.h:122
alpaqa_symmetry symmetry
Definition dl-problem.h:120
const long long * outer_ptr
Definition dl-problem.h:123
alpaqa_length_t nnz
Definition dl-problem.h:121
alpaqa_length_t cols
Definition dl-problem.h:91
const int * inner_idx
Definition dl-problem.h:94
alpaqa_symmetry symmetry
Definition dl-problem.h:92
const int * outer_ptr
Definition dl-problem.h:95
alpaqa_length_t nnz
Definition dl-problem.h:93
Sparsity of matrices.
Definition dl-problem.h:187