alpaqa 1.0.0a10
Nonconvex constrained optimization
Loading...
Searching...
No Matches
type-erased-problem.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <alpaqa/export.hpp>
11#include <chrono>
12#include <stdexcept>
13#include <type_traits>
14#include <utility>
15
16namespace alpaqa {
17
18/// Struct containing function pointers to all problem functions (like the
19/// objective and constraint functions, with their derivatives, and more).
20/// Some default implementations are available.
21/// Internal struct, it is used by @ref TypeErasedProblem.
22template <Config Conf>
26
27 template <class F>
29 template <class F>
32
33 // clang-format off
34
35 // Required
44 required_const_function_t<void(crvec x, rvec grad_fx)>
48 required_const_function_t<void(crvec x, crvec y, rvec grad_gxy)>
52
53 // Second order
54 optional_const_function_t<void(crvec x, rindexvec inner_idx, rindexvec outer_ptr, rvec J_values)>
58 optional_const_function_t<void(crvec x, index_t i, rvec grad_gi)>
60 optional_const_function_t<void(crvec x, crvec y, real_t scale, crvec v, rvec Hv)>
62 optional_const_function_t<void(crvec x, crvec y, real_t scale, rindexvec inner_idx, rindexvec outer_ptr, rvec H_values)>
66 optional_const_function_t<void(crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv)>
68 optional_const_function_t<void(crvec x, crvec y, crvec Σ, real_t scale, rindexvec inner_idx, rindexvec outer_ptr, rvec H_values)>
72
73 // Combined evaluations
78 optional_const_function_t<void(crvec x, crvec y, rvec grad_f, rvec grad_gxy)>
80
81 // Lagrangian and augmented lagrangian evaluations
82 optional_const_function_t<void(crvec x, crvec y, rvec grad_L, rvec work_n)>
86 optional_const_function_t<void(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m)>
88 optional_const_function_t<real_t(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m)>
90
91 // Constraint sets
96
97 // Check
100
101 // clang-format on
102
103 ALPAQA_EXPORT static real_t calc_ŷ_dᵀŷ(const void *self, rvec g_ŷ, crvec y, crvec Σ,
104 const ProblemVTable &vtable);
105 ALPAQA_EXPORT static index_t default_eval_inactive_indices_res_lna(const void *, real_t, crvec,
107 const ProblemVTable &);
108 ALPAQA_EXPORT static void default_eval_jac_g(const void *, crvec, rindexvec, rindexvec, rvec,
109 const ProblemVTable &);
110 ALPAQA_EXPORT static length_t default_get_jac_g_num_nonzeros(const void *,
111 const ProblemVTable &);
112 ALPAQA_EXPORT static void default_eval_grad_gi(const void *, crvec, index_t, rvec,
113 const ProblemVTable &);
114 ALPAQA_EXPORT static void default_eval_hess_L_prod(const void *, crvec, crvec, real_t, crvec,
115 rvec, const ProblemVTable &);
116 ALPAQA_EXPORT static void default_eval_hess_L(const void *, crvec, crvec, real_t, rindexvec,
117 rindexvec, rvec, const ProblemVTable &);
118 ALPAQA_EXPORT static length_t default_get_hess_L_num_nonzeros(const void *,
119 const ProblemVTable &);
120 ALPAQA_EXPORT static void default_eval_hess_ψ_prod(const void *self, crvec x, crvec y, crvec,
121 real_t scale, crvec v, rvec Hv,
122 const ProblemVTable &vtable);
123 ALPAQA_EXPORT static void default_eval_hess_ψ(const void *self, crvec x, crvec y, crvec,
124 real_t scale, rindexvec inner_idx,
125 rindexvec outer_ptr, rvec H_values,
126 const ProblemVTable &vtable);
127 ALPAQA_EXPORT static length_t default_get_hess_ψ_num_nonzeros(const void *,
128 const ProblemVTable &);
129 ALPAQA_EXPORT static real_t default_eval_f_grad_f(const void *self, crvec x, rvec grad_fx,
130 const ProblemVTable &vtable);
131 ALPAQA_EXPORT static real_t default_eval_f_g(const void *self, crvec x, rvec g,
132 const ProblemVTable &vtable);
133 ALPAQA_EXPORT static void default_eval_grad_f_grad_g_prod(const void *self, crvec x, crvec y,
134 rvec grad_f, rvec grad_gxy,
135 const ProblemVTable &vtable);
136 ALPAQA_EXPORT static void default_eval_grad_L(const void *self, crvec x, crvec y, rvec grad_L,
137 rvec work_n, const ProblemVTable &vtable);
138 ALPAQA_EXPORT static real_t default_eval_ψ(const void *self, crvec x, crvec y, crvec Σ, rvec ŷ,
139 const ProblemVTable &vtable);
140 ALPAQA_EXPORT static void default_eval_grad_ψ(const void *self, crvec x, crvec y, crvec Σ,
141 rvec grad_ψ, rvec work_n, rvec work_m,
142 const ProblemVTable &vtable);
143 ALPAQA_EXPORT static real_t default_eval_ψ_grad_ψ(const void *self, crvec x, crvec y, crvec Σ,
144 rvec grad_ψ, rvec work_n, rvec work_m,
145 const ProblemVTable &vtable);
146 ALPAQA_EXPORT static const Box &default_get_box_C(const void *, const ProblemVTable &);
147 ALPAQA_EXPORT static const Box &default_get_box_D(const void *, const ProblemVTable &);
148 ALPAQA_EXPORT static void default_check(const void *, const ProblemVTable &);
149
151
152 template <class P>
153 ProblemVTable(std::in_place_t, P &p) : util::BasicVTable{std::in_place, p} {
154 auto &vtable = *this;
155
156 // Initialize all methods
157
158 // Required
167 // Second order
177 // Combined evaluations
179 ALPAQA_TE_OPTIONAL_METHOD(vtable, P, eval_f_g, p);
181 // Lagrangian and augmented lagrangian evaluations
183 ALPAQA_TE_OPTIONAL_METHOD(vtable, P, eval_ψ, p);
186 // Constraint set
189 // Check
190 ALPAQA_TE_OPTIONAL_METHOD(vtable, P, check, p);
191
192 // Dimensions
193 vtable.n = p.get_n();
194 vtable.m = p.get_m();
195 }
196 ProblemVTable() = default;
197};
198
199// clang-format off
204// clang-format on
205
206/// @addtogroup grp_Problems
207/// @{
208
209/// The main polymorphic minimization problem interface.
210///
211/// This class wraps the actual problem implementation class, filling in the
212/// missing member functions with sensible defaults, and providing a uniform
213/// interface that is used by the solvers.
214///
215/// The problem implementations do not inherit from an abstract base class.
216/// Instead, [structural typing](https://en.wikipedia.org/wiki/Structural_type_system)
217/// is used. The @ref ProblemVTable constructor uses reflection to discover
218/// which member functions are provided by the problem implementation. See
219/// @ref page_problem_formulations for more information, and
220/// @ref C++/CustomCppProblem/main.cpp for an example.
221template <Config Conf = DefaultConfig, class Allocator = std::allocator<std::byte>>
223 public:
227 using allocator_type = Allocator;
229 using TypeErased::TypeErased;
230
231 protected:
232 using TypeErased::call;
233 using TypeErased::self;
234 using TypeErased::vtable;
235
236 public:
237 template <class T, class... Args>
238 static TypeErasedProblem make(Args &&...args) {
239 return TypeErased::template make<TypeErasedProblem, T>(std::forward<Args>(args)...);
240 }
241
242 /// @name Problem dimensions
243 /// @{
244
245 /// **[Required]**
246 /// Number of decision variables.
248 /// **[Required]**
249 /// Number of constraints.
251
252 /// @}
253
254 /// @name Required cost and constraint functions
255 /// @{
256
257 /// **[Required]**
258 /// Function that evaluates the cost, @f$ f(x) @f$
259 /// @param [in] x
260 /// Decision variable @f$ x \in \R^n @f$
262 /// **[Required]**
263 /// Function that evaluates the gradient of the cost, @f$ \nabla f(x) @f$
264 /// @param [in] x
265 /// Decision variable @f$ x \in \R^n @f$
266 /// @param [out] grad_fx
267 /// Gradient of cost function @f$ \nabla f(x) \in \R^n @f$
268 void eval_grad_f(crvec x, rvec grad_fx) const;
269 /// **[Required]**
270 /// Function that evaluates the constraints, @f$ g(x) @f$
271 /// @param [in] x
272 /// Decision variable @f$ x \in \R^n @f$
273 /// @param [out] gx
274 /// Value of the constraints @f$ g(x) \in \R^m @f$
275 void eval_g(crvec x, rvec gx) const;
276 /// **[Required]**
277 /// Function that evaluates the gradient of the constraints times a vector,
278 /// @f$ \nabla g(x)\,y = \tp{\jac_g(x)}y @f$
279 /// @param [in] x
280 /// Decision variable @f$ x \in \R^n @f$
281 /// @param [in] y
282 /// Vector @f$ y \in \R^m @f$ to multiply the gradient by
283 /// @param [out] grad_gxy
284 /// Gradient of the constraints
285 /// @f$ \nabla g(x)\,y \in \R^n @f$
286 void eval_grad_g_prod(crvec x, crvec y, rvec grad_gxy) const;
287
288 /// @}
289
290 /// @name Projections onto constraint sets and proximal mappings
291 /// @{
292
293 /// **[Required]**
294 /// Function that evaluates the difference between the given point @f$ z @f$
295 /// and its projection onto the constraint set @f$ D @f$.
296 /// @param [in] z
297 /// Slack variable, @f$ z \in \R^m @f$
298 /// @param [out] e
299 /// The difference relative to its projection,
300 /// @f$ e = z - \Pi_D(z) \in \R^m @f$
301 /// @note @p z and @p e can refer to the same vector.
302 void eval_proj_diff_g(crvec z, rvec e) const;
303 /// **[Required]**
304 /// Function that projects the Lagrange multipliers for ALM.
305 /// @param [inout] y
306 /// Multipliers, @f$ y \leftarrow \Pi_Y(y) \in \R^m @f$
307 /// @param [in] M
308 /// The radius/size of the set @f$ Y @f$.
309 /// See @ref ALMParams::max_multiplier.
311 /// **[Required]**
312 /// Function that computes a proximal gradient step.
313 /// @param [in] γ
314 /// Step size, @f$ \gamma \in \R_{>0} @f$
315 /// @param [in] x
316 /// Decision variable @f$ x \in \R^n @f$
317 /// @param [in] grad_ψ
318 /// Gradient of the subproblem cost, @f$ \nabla\psi(x) \in \R^n @f$
319 /// @param [out] x̂
320 /// Next proximal gradient iterate, @f$ \hat x = T_\gamma(x) =
321 /// \prox_{\gamma h}(x - \gamma\nabla\psi(x)) \in \R^n @f$
322 /// @param [out] p
323 /// The proximal gradient step,
324 /// @f$ p = \hat x - x \in \R^n @f$
325 /// @return The nonsmooth function evaluated at x̂,
326 /// @f$ h(\hat x) @f$.
327 /// @note The vector @f$ p @f$ is often used in stopping criteria, so its
328 /// numerical accuracy is more important than that of @f$ \hat x @f$.
329 real_t eval_prox_grad_step(real_t γ, crvec x, crvec grad_ψ, rvec x̂, rvec p) const;
330 /// **[Optional]**
331 /// Function that computes the inactive indices @f$ \mathcal J(x) @f$ for
332 /// the evaluation of the linear Newton approximation of the residual, as in
333 /// @cite pas2022alpaqa.
334 /// @param [in] γ
335 /// Step size, @f$ \gamma \in \R_{>0} @f$
336 /// @param [in] x
337 /// Decision variable @f$ x \in \R^n @f$
338 /// @param [in] grad_ψ
339 /// Gradient of the subproblem cost, @f$ \nabla\psi(x) \in \R^n @f$
340 /// @param [out] J
341 /// The indices of the components of @f$ x @f$ that are in the
342 /// index set @f$ \mathcal J(x) @f$. In ascending order, at most n.
343 /// @return The number of inactive constraints, @f$ \# \mathcal J(x) @f$.
344 ///
345 /// For example, in the case of box constraints, we have
346 /// @f[ \mathcal J(x) \defeq \defset{i \in \N_{[0, n-1]}}{\underline x_i
347 /// \lt x_i - \gamma\nabla_{\!x_i}\psi(x) \lt \overline x_i}. @f]
349
350 /// @}
351
352 /// @name Constraint sets
353 /// @{
354
355 /// **[Optional]**
356 /// Get the rectangular constraint set of the decision variables,
357 /// @f$ x \in C @f$.
358 const Box &get_box_C() const;
359 /// **[Optional]**
360 /// Get the rectangular constraint set of the general constraint function,
361 /// @f$ g(x) \in D @f$.
362 const Box &get_box_D() const;
363
364 /// @}
365
366 /// @name Functions for second-order solvers
367 /// @{
368
369 /// **[Optional]**
370 /// Function that evaluates the Jacobian of the constraints as a sparse
371 /// matrix, @f$ \jac_g(x) @f$
372 /// @param [in] x
373 /// Decision variable @f$ x \in \R^n @f$
374 /// @param [inout] inner_idx
375 /// Inner indices (row indices of nonzeros).
376 /// @param [inout] outer_ptr
377 /// Outer pointers (points to the first nonzero in each column).
378 /// @param [out] J_values
379 /// Nonzero values of the Jacobian
380 /// @f$ \jac_g(x) \in \R^{m\times n} @f$
381 /// If @p J_values has size zero, this function should initialize
382 /// @p inner_idx and @p outer_ptr. If @p J_values is nonempty, @p inner_idx
383 /// and @p outer_ptr can be assumed to be initialized, and this function
384 /// should evaluate @p J_values.
385 ///
386 /// Required for second-order solvers only.
387 void eval_jac_g(crvec x, rindexvec inner_idx, rindexvec outer_ptr, rvec J_values) const;
388 /// **[Optional]**
389 /// Function that gets the number of nonzeros of the sparse Jacobian of the
390 /// constraints. Should return -1 for a dense Jacobian.
391 ///
392 /// Required for second-order solvers only.
394 /// **[Optional]**
395 /// Function that evaluates the gradient of one specific constraint,
396 /// @f$ \nabla g_i(x) @f$
397 /// @param [in] x
398 /// Decision variable @f$ x \in \R^n @f$
399 /// @param [in] i
400 /// Which constraint @f$ 0 \le i \lt m @f$
401 /// @param [out] grad_gi
402 /// Gradient of the constraint
403 /// @f$ \nabla g_i(x) \in \R^n @f$
404 ///
405 /// Required for second-order solvers only.
406 void eval_grad_gi(crvec x, index_t i, rvec grad_gi) const;
407 /// **[Optional]**
408 /// Function that evaluates the Hessian of the Lagrangian multiplied by a
409 /// vector,
410 /// @f$ \nabla_{xx}^2L(x, y)\,v @f$
411 /// @param [in] x
412 /// Decision variable @f$ x \in \R^n @f$
413 /// @param [in] y
414 /// Lagrange multipliers @f$ y \in \R^m @f$
415 /// @param [in] scale
416 /// Scale factor for the cost function.
417 /// @param [in] v
418 /// Vector to multiply by @f$ v \in \R^n @f$
419 /// @param [out] Hv
420 /// Hessian-vector product
421 /// @f$ \nabla_{xx}^2 L(x, y)\,v \in \R^{n} @f$
422 ///
423 /// Required for second-order solvers only.
424 void eval_hess_L_prod(crvec x, crvec y, real_t scale, crvec v, rvec Hv) const;
425 /// **[Optional]**
426 /// Function that evaluates the Hessian of the Lagrangian as a sparse matrix,
427 /// @f$ \nabla_{xx}^2L(x, y) @f$
428 /// @param [in] x
429 /// Decision variable @f$ x \in \R^n @f$
430 /// @param [in] y
431 /// Lagrange multipliers @f$ y \in \R^m @f$
432 /// @param [in] scale
433 /// Scale factor for the cost function.
434 /// @param [inout] inner_idx
435 /// Inner indices (row indices of nonzeros).
436 /// @param [inout] outer_ptr
437 /// Outer pointers (points to the first nonzero in each column).
438 /// @param [out] H_values
439 /// Nonzero values of the Hessian
440 /// @f$ \nabla_{xx}^2 L(x, y) \in \R^{n\times n} @f$.
441 /// If @p H_values has size zero, this function should initialize
442 /// @p inner_idx and @p outer_ptr. If @p H_values is nonempty, @p inner_idx
443 /// and @p outer_ptr can be assumed to be initialized, and this function
444 /// should evaluate @p H_values.
445 ///
446 /// Required for second-order solvers only.
447 void eval_hess_L(crvec x, crvec y, real_t scale, rindexvec inner_idx, rindexvec outer_ptr,
448 rvec H_values) const;
449 /// **[Optional]**
450 /// Function that gets the number of nonzeros of the sparse Hessian of the
451 /// Lagrangian. Should return -1 for a dense Hessian.
452 ///
453 /// Required for second-order solvers only.
455 /// **[Optional]**
456 /// Function that evaluates the Hessian of the augmented Lagrangian
457 /// multiplied by a vector,
458 /// @f$ \nabla_{xx}^2L_\Sigma(x, y)\,v @f$
459 /// @param [in] x
460 /// Decision variable @f$ x \in \R^n @f$
461 /// @param [in] y
462 /// Lagrange multipliers @f$ y \in \R^m @f$
463 /// @param [in] Σ
464 /// Penalty weights @f$ \Sigma @f$
465 /// @param [in] scale
466 /// Scale factor for the cost function.
467 /// @param [in] v
468 /// Vector to multiply by @f$ v \in \R^n @f$
469 /// @param [out] Hv
470 /// Hessian-vector product
471 /// @f$ \nabla_{xx}^2 L_\Sigma(x, y)\,v \in \R^{n} @f$
472 ///
473 /// Required for second-order solvers only.
474 void eval_hess_ψ_prod(crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv) const;
475 /// **[Optional]**
476 /// Function that evaluates the Hessian of the augmented Lagrangian,
477 /// @f$ \nabla_{xx}^2L_\Sigma(x, y) @f$
478 /// @param [in] x
479 /// Decision variable @f$ x \in \R^n @f$
480 /// @param [in] y
481 /// Lagrange multipliers @f$ y \in \R^m @f$
482 /// @param [in] Σ
483 /// Penalty weights @f$ \Sigma @f$
484 /// @param [in] scale
485 /// Scale factor for the cost function.
486 /// @param [inout] inner_idx
487 /// Inner indices (row indices of nonzeros).
488 /// @param [inout] outer_ptr
489 /// Outer pointers (points to the first nonzero in each column).
490 /// @param [out] H_values
491 /// Nonzero values of the Hessian
492 /// @f$ \nabla_{xx}^2 L_\Sigma(x, y) \in \R^{n\times n} @f$
493 /// If @p H_values has size zero, this function should initialize
494 /// @p inner_idx and @p outer_ptr. If @p H_values is nonempty, @p inner_idx
495 /// and @p outer_ptr can be assumed to be initialized, and this function
496 /// should evaluate @p H_values.
497 ///
498 /// Required for second-order solvers only.
499 void eval_hess_ψ(crvec x, crvec y, crvec Σ, real_t scale, rindexvec inner_idx,
500 rindexvec outer_ptr, rvec H_values) const;
501 /// **[Optional]**
502 /// Function that gets the number of nonzeros of the Hessian of the
503 /// augmented Lagrangian.
504 ///
505 /// Required for second-order solvers only.
507
508 /// @}
509
510 /// @name Combined evaluations
511 /// @{
512
513 /// **[Optional]**
514 /// Evaluate both @f$ f(x) @f$ and its gradient, @f$ \nabla f(x) @f$.
515 /// @default_impl ProblemVTable::default_eval_f_grad_f
516 real_t eval_f_grad_f(crvec x, rvec grad_fx) const;
517 /// **[Optional]**
518 /// Evaluate both @f$ f(x) @f$ and @f$ g(x) @f$.
519 /// @default_impl ProblemVTable::default_eval_f_g
521 /// **[Optional]**
522 /// Evaluate both @f$ \nabla f(x) @f$ and @f$ \nabla g(x)\,y @f$.
523 /// @default_impl ProblemVTable::default_eval_grad_f_grad_g_prod
524 void eval_grad_f_grad_g_prod(crvec x, crvec y, rvec grad_f, rvec grad_gxy) const;
525 /// **[Optional]**
526 /// Evaluate the gradient of the Lagrangian
527 /// @f$ \nabla_x L(x, y) = \nabla f(x) + \nabla g(x)\,y @f$
528 /// @default_impl ProblemVTable::default_eval_grad_L
529 void eval_grad_L(crvec x, crvec y, rvec grad_L, rvec work_n) const;
530
531 /// @}
532
533 /// @name Augmented Lagrangian
534 /// @{
535
536 /// **[Optional]**
537 /// Calculate both ψ(x) and the vector ŷ that can later be used to compute
538 /// ∇ψ.
539 /// @f[ \psi(x) = f(x) + \tfrac{1}{2}
540 /// \text{dist}_\Sigma^2\left(g(x) + \Sigma^{-1}y,\;D\right) @f]
541 /// @f[ \hat y = \Sigma\, \left(g(x) + \Sigma^{-1}y - \Pi_D\left(g(x)
542 /// + \Sigma^{-1}y\right)\right) @f]
543 /// @default_impl ProblemVTable::default_eval_ψ
544 real_t eval_ψ(crvec x, ///< [in] Decision variable @f$ x @f$
545 crvec y, ///< [in] Lagrange multipliers @f$ y @f$
546 crvec Σ, ///< [in] Penalty weights @f$ \Sigma @f$
547 rvec ŷ ///< [out] @f$ \hat y @f$
548 ) const;
549 /// **[Optional]**
550 /// Calculate the gradient ∇ψ(x).
551 /// @f[ \nabla \psi(x) = \nabla f(x) + \nabla g(x)\,\hat y(x) @f]
552 /// @default_impl ProblemVTable::default_eval_grad_ψ
553 void eval_grad_ψ(crvec x, ///< [in] Decision variable @f$ x @f$
554 crvec y, ///< [in] Lagrange multipliers @f$ y @f$
555 crvec Σ, ///< [in] Penalty weights @f$ \Sigma @f$
556 rvec grad_ψ, ///< [out] @f$ \nabla \psi(x) @f$
557 rvec work_n, ///< Dimension @f$ n @f$
558 rvec work_m ///< Dimension @f$ m @f$
559 ) const;
560 /// **[Optional]**
561 /// Calculate both ψ(x) and its gradient ∇ψ(x).
562 /// @f[ \psi(x) = f(x) + \tfrac{1}{2}
563 /// \text{dist}_\Sigma^2\left(g(x) + \Sigma^{-1}y,\;D\right) @f]
564 /// @f[ \nabla \psi(x) = \nabla f(x) + \nabla g(x)\,\hat y(x) @f]
565 /// @default_impl ProblemVTable::default_eval_ψ_grad_ψ
566 real_t eval_ψ_grad_ψ(crvec x, ///< [in] Decision variable @f$ x @f$
567 crvec y, ///< [in] Lagrange multipliers @f$ y @f$
568 crvec Σ, ///< [in] Penalty weights @f$ \Sigma @f$
569 rvec grad_ψ, ///< [out] @f$ \nabla \psi(x) @f$
570 rvec work_n, ///< Dimension @f$ n @f$
571 rvec work_m ///< Dimension @f$ m @f$
572 ) const;
573
574 /// @}
575
576 /// @name Checks
577 /// @{
578
579 /// **[Optional]**
580 /// Check that the problem formulation is well-defined, the dimensions match,
581 /// etc. Throws an exception if this is not the case.
582 void check() const;
583
584 /// @}
585
586 /// @name Querying specialized implementations
587 /// @{
588
589 /// Returns true if the problem provides an implementation of
590 /// @ref eval_inactive_indices_res_lna.
591 [[nodiscard]] bool provides_eval_inactive_indices_res_lna() const {
592 return vtable.eval_inactive_indices_res_lna != vtable.default_eval_inactive_indices_res_lna;
593 }
594 /// Returns true if the problem provides an implementation of
595 /// @ref eval_jac_g.
596 [[nodiscard]] bool provides_eval_jac_g() const {
597 return vtable.eval_jac_g != vtable.default_eval_jac_g;
598 }
599 /// Returns true if the problem provides an implementation of
600 /// @ref get_jac_g_num_nonzeros.
601 [[nodiscard]] bool provides_get_jac_g_num_nonzeros() const {
602 return vtable.get_jac_g_num_nonzeros != vtable.default_get_jac_g_num_nonzeros;
603 }
604 /// Returns true if the problem provides an implementation of
605 /// @ref eval_grad_gi.
606 [[nodiscard]] bool provides_eval_grad_gi() const {
607 return vtable.eval_grad_gi != vtable.default_eval_grad_gi;
608 }
609 /// Returns true if the problem provides an implementation of
610 /// @ref eval_hess_L_prod.
611 [[nodiscard]] bool provides_eval_hess_L_prod() const {
612 return vtable.eval_hess_L_prod != vtable.default_eval_hess_L_prod;
613 }
614 /// Returns true if the problem provides an implementation of
615 /// @ref eval_hess_L.
616 [[nodiscard]] bool provides_eval_hess_L() const {
617 return vtable.eval_hess_L != vtable.default_eval_hess_L;
618 }
619 /// Returns true if the problem provides an implementation of
620 /// @ref get_hess_L_num_nonzeros.
621 [[nodiscard]] bool provides_get_hess_L_num_nonzeros() const {
622 return vtable.get_hess_L_num_nonzeros != vtable.default_get_hess_L_num_nonzeros;
623 }
624 /// Returns true if the problem provides an implementation of
625 /// @ref eval_hess_ψ_prod.
626 [[nodiscard]] bool provides_eval_hess_ψ_prod() const {
627 return vtable.eval_hess_ψ_prod != vtable.default_eval_hess_ψ_prod;
628 }
629 /// Returns true if the problem provides an implementation of
630 /// @ref eval_hess_ψ.
631 [[nodiscard]] bool provides_eval_hess_ψ() const {
632 return vtable.eval_hess_ψ != vtable.default_eval_hess_ψ;
633 }
634 /// Returns true if the problem provides an implementation of
635 /// @ref get_hess_ψ_num_nonzeros.
636 [[nodiscard]] bool provides_get_hess_ψ_num_nonzeros() const {
637 return vtable.get_hess_ψ_num_nonzeros != vtable.default_get_hess_ψ_num_nonzeros;
638 }
639 /// Returns true if the problem provides a specialized implementation of
640 /// @ref eval_f_grad_f, false if it uses the default implementation.
641 [[nodiscard]] bool provides_eval_f_grad_f() const {
642 return vtable.eval_f_grad_f != vtable.default_eval_f_grad_f;
643 }
644 /// Returns true if the problem provides a specialized implementation of
645 /// @ref eval_f_g, false if it uses the default implementation.
646 [[nodiscard]] bool provides_eval_f_g() const {
647 return vtable.eval_f_g != vtable.default_eval_f_g;
648 }
649 /// Returns true if the problem provides a specialized implementation of
650 /// @ref eval_grad_f_grad_g_prod, false if it uses the default implementation.
651 [[nodiscard]] bool provides_eval_grad_f_grad_g_prod() const {
652 return vtable.eval_grad_f_grad_g_prod != vtable.default_eval_grad_f_grad_g_prod;
653 }
654 /// Returns true if the problem provides a specialized implementation of
655 /// @ref eval_grad_L, false if it uses the default implementation.
656 [[nodiscard]] bool provides_eval_grad_L() const {
657 return vtable.eval_grad_L != vtable.default_eval_grad_L;
658 }
659 /// Returns true if the problem provides a specialized implementation of
660 /// @ref eval_ψ, false if it uses the default implementation.
661 [[nodiscard]] bool provides_eval_ψ() const { return vtable.eval_ψ != vtable.default_eval_ψ; }
662 /// Returns true if the problem provides a specialized implementation of
663 /// @ref eval_grad_ψ, false if it uses the default implementation.
664 [[nodiscard]] bool provides_eval_grad_ψ() const {
665 return vtable.eval_grad_ψ != vtable.default_eval_grad_ψ;
666 }
667 /// Returns true if the problem provides a specialized implementation of
668 /// @ref eval_ψ_grad_ψ, false if it uses the default implementation.
669 [[nodiscard]] bool provides_eval_ψ_grad_ψ() const {
670 return vtable.eval_ψ_grad_ψ != vtable.default_eval_ψ_grad_ψ;
671 }
672 /// Returns true if the problem provides an implementation of
673 /// @ref get_box_C.
674 [[nodiscard]] bool provides_get_box_C() const {
675 return vtable.get_box_C != vtable.default_get_box_C;
676 }
677 /// Returns true if the problem provides an implementation of
678 /// @ref get_box_D.
679 [[nodiscard]] bool provides_get_box_D() const {
680 return vtable.get_box_D != vtable.default_get_box_D;
681 }
682 /// Returns true if the problem provides an implementation of @ref check.
683 [[nodiscard]] bool provides_check() const { return vtable.check != vtable.default_check; }
684
685 /// @}
686
687 /// @name Helpers
688 /// @{
689
690 /// Given g(x), compute the intermediate results ŷ and dᵀŷ that can later be
691 /// used to compute ψ(x) and ∇ψ(x).
692 ///
693 /// Computes the result using the following algorithm:
694 /// @f[ \begin{aligned}
695 /// \zeta &= g(x) + \Sigma^{-1} y \\[]
696 /// d &= \zeta - \Pi_D(\zeta)
697 /// = \operatorname{eval\_proj\_diff\_g}(\zeta, \zeta) \\[]
698 /// \hat y &= \Sigma d \\[]
699 /// \end{aligned} @f]
700 /// @see @ref page_math
701 ///
702 /// @param[inout] g_ŷ
703 /// Input @f$ g(x) @f$, outputs @f$ \hat y @f$
704 /// @param[in] y
705 /// Lagrange multipliers @f$ y @f$
706 /// @param[in] Σ
707 /// Penalty weights @f$ \Sigma @f$
708 /// @return The inner product @f$ d^\top \hat y @f$
710
711 /// @}
712};
713
714/// @}
715
716#ifndef DOXYGEN
717template <class Tref>
718explicit TypeErasedProblem(Tref &&d)
720
721template <class Tref, class Allocator>
722explicit TypeErasedProblem(Tref &&d, Allocator alloc)
724#endif
725
726template <Config Conf, class Allocator>
728 return vtable.n;
729}
730template <Config Conf, class Allocator>
732 return vtable.m;
733}
734
735template <Config Conf, class Allocator>
737 return call(vtable.eval_proj_diff_g, z, e);
738}
739template <Config Conf, class Allocator>
741 return call(vtable.eval_proj_multipliers, y, M);
742}
743template <Config Conf, class Allocator>
745 rvec x̂, rvec p) const -> real_t {
746 return call(vtable.eval_prox_grad_step, γ, x, grad_ψ, x̂, p);
747}
748template <Config Conf, class Allocator>
750 crvec grad_ψ,
751 rindexvec J) const
752 -> index_t {
753 return call(vtable.eval_inactive_indices_res_lna, γ, x, grad_ψ, J);
754}
755template <Config Conf, class Allocator>
757 return call(vtable.eval_f, x);
758}
759template <Config Conf, class Allocator>
761 return call(vtable.eval_grad_f, x, grad_fx);
762}
763template <Config Conf, class Allocator>
765 return call(vtable.eval_g, x, gx);
766}
767template <Config Conf, class Allocator>
769 return call(vtable.eval_grad_g_prod, x, y, grad_gxy);
770}
771template <Config Conf, class Allocator>
773 return call(vtable.eval_grad_gi, x, i, grad_gi);
774}
775template <Config Conf, class Allocator>
777 rindexvec outer_ptr, rvec J_values) const {
778 return call(vtable.eval_jac_g, x, inner_idx, outer_ptr, J_values);
779}
780template <Config Conf, class Allocator>
782 return call(vtable.get_jac_g_num_nonzeros);
783}
784template <Config Conf, class Allocator>
786 rvec Hv) const {
787 return call(vtable.eval_hess_L_prod, x, y, scale, v, Hv);
788}
789template <Config Conf, class Allocator>
791 rindexvec inner_idx, rindexvec outer_ptr,
792 rvec H_values) const {
793 return call(vtable.eval_hess_L, x, y, scale, inner_idx, outer_ptr, H_values);
794}
795template <Config Conf, class Allocator>
797 return call(vtable.get_hess_L_num_nonzeros);
798}
799template <Config Conf, class Allocator>
801 crvec v, rvec Hv) const {
802 return call(vtable.eval_hess_ψ_prod, x, y, Σ, scale, v, Hv);
803}
804template <Config Conf, class Allocator>
806 rindexvec inner_idx, rindexvec outer_ptr,
807 rvec H_values) const {
808 return call(vtable.eval_hess_ψ, x, y, Σ, scale, inner_idx, outer_ptr, H_values);
809}
810template <Config Conf, class Allocator>
812 return call(vtable.get_hess_ψ_num_nonzeros);
813}
814template <Config Conf, class Allocator>
816 return call(vtable.eval_f_grad_f, x, grad_fx);
817}
818template <Config Conf, class Allocator>
820 return call(vtable.eval_f_g, x, g);
821}
822template <Config Conf, class Allocator>
824 rvec grad_gxy) const {
825 return call(vtable.eval_grad_f_grad_g_prod, x, y, grad_f, grad_gxy);
826}
827template <Config Conf, class Allocator>
829 rvec work_n) const {
830 return call(vtable.eval_grad_L, x, y, grad_L, work_n);
831}
832template <Config Conf, class Allocator>
834 return call(vtable.eval_ψ, x, y, Σ, ŷ);
835}
836template <Config Conf, class Allocator>
838 rvec work_n, rvec work_m) const {
839 return call(vtable.eval_grad_ψ, x, y, Σ, grad_ψ, work_n, work_m);
840}
841template <Config Conf, class Allocator>
843 rvec work_n, rvec work_m) const -> real_t {
844 return call(vtable.eval_ψ_grad_ψ, x, y, Σ, grad_ψ, work_n, work_m);
845}
846template <Config Conf, class Allocator>
848 return call(vtable.calc_ŷ_dᵀŷ, g_ŷ, y, Σ);
849}
850template <Config Conf, class Allocator>
852 return call(vtable.get_box_C);
853}
854template <Config Conf, class Allocator>
856 return call(vtable.get_box_D);
857}
858template <Config Conf, class Allocator>
860 return call(vtable.check);
861}
862
863/// @addtogroup grp_Problems
864/// @{
865
866template <Config Conf>
867void print_provided_functions(std::ostream &os, const TypeErasedProblem<Conf> &problem) {
868 os << "inactive_indices_res_lna: " << problem.provides_eval_inactive_indices_res_lna() << '\n'
869 << " grad_gi: " << problem.provides_eval_grad_gi() << '\n'
870 << " jac_g: " << problem.provides_eval_jac_g() << '\n'
871 << " hess_L_prod: " << problem.provides_eval_hess_L_prod() << '\n'
872 << " hess_L: " << problem.provides_eval_hess_L() << '\n'
873 << " hess_ψ_prod: " << problem.provides_eval_hess_ψ_prod() << '\n'
874 << " hess_ψ: " << problem.provides_eval_hess_ψ() << '\n'
875 << " f_grad_f: " << problem.provides_eval_f_grad_f() << '\n'
876 << " f_g: " << problem.provides_eval_f_g() << '\n'
877 << " grad_f_grad_g_prod: " << problem.provides_eval_grad_f_grad_g_prod() << '\n'
878 << " grad_L: " << problem.provides_eval_grad_L() << '\n'
879 << " ψ: " << problem.provides_eval_ψ() << '\n'
880 << " grad_ψ: " << problem.provides_eval_grad_ψ() << '\n'
881 << " ψ_grad_ψ: " << problem.provides_eval_ψ_grad_ψ() << '\n'
882 << " get_box_C: " << problem.provides_get_box_C() << '\n'
883 << " get_box_D: " << problem.provides_get_box_D() << '\n'
884 << " check: " << problem.provides_check() << '\n';
885}
886
887/// @}
888
889} // namespace alpaqa
The main polymorphic minimization problem interface.
bool provides_eval_hess_L() const
Returns true if the problem provides an implementation of eval_hess_L.
real_t eval_prox_grad_step(real_t γ, crvec x, crvec grad_ψ, rvec x̂, rvec p) const
[Required] Function that computes a proximal gradient step.
real_t eval_ψ_grad_ψ(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const
[Optional] Calculate both ψ(x) and its gradient ∇ψ(x).
const Box & get_box_D() const
[Optional] Get the rectangular constraint set of the general constraint function, .
void eval_grad_gi(crvec x, index_t i, rvec grad_gi) const
[Optional] Function that evaluates the gradient of one specific constraint,
void eval_hess_ψ(crvec x, crvec y, crvec Σ, real_t scale, rindexvec inner_idx, rindexvec outer_ptr, rvec H_values) const
[Optional] Function that evaluates the Hessian of the augmented Lagrangian,
bool provides_eval_hess_ψ_prod() const
Returns true if the problem provides an implementation of eval_hess_ψ_prod.
bool provides_eval_ψ_grad_ψ() const
Returns true if the problem provides a specialized implementation of eval_ψ_grad_ψ,...
bool provides_get_box_C() const
Returns true if the problem provides an implementation of get_box_C.
real_t eval_f_g(crvec x, rvec g) const
[Optional] Evaluate both and .
bool provides_get_hess_L_num_nonzeros() const
Returns true if the problem provides an implementation of get_hess_L_num_nonzeros.
bool provides_get_jac_g_num_nonzeros() const
Returns true if the problem provides an implementation of get_jac_g_num_nonzeros.
bool provides_eval_jac_g() const
Returns true if the problem provides an implementation of eval_jac_g.
bool provides_check() const
Returns true if the problem provides an implementation of check.
length_t get_n() const
[Required] Number of decision variables.
void check() const
[Optional] Check that the problem formulation is well-defined, the dimensions match,...
length_t get_m() const
[Required] Number of constraints.
real_t eval_ψ(crvec x, crvec y, crvec Σ, rvec ŷ) const
[Optional] Calculate both ψ(x) and the vector ŷ that can later be used to compute ∇ψ.
bool provides_eval_inactive_indices_res_lna() const
Returns true if the problem provides an implementation of eval_inactive_indices_res_lna.
void eval_grad_L(crvec x, crvec y, rvec grad_L, rvec work_n) const
[Optional] Evaluate the gradient of the Lagrangian
void eval_grad_f_grad_g_prod(crvec x, crvec y, rvec grad_f, rvec grad_gxy) const
[Optional] Evaluate both and .
bool provides_eval_grad_f_grad_g_prod() const
Returns true if the problem provides a specialized implementation of eval_grad_f_grad_g_prod,...
void eval_hess_L(crvec x, crvec y, real_t scale, rindexvec inner_idx, rindexvec outer_ptr, rvec H_values) const
[Optional] Function that evaluates the Hessian of the Lagrangian as a sparse matrix,
static TypeErasedProblem make(Args &&...args)
index_t eval_inactive_indices_res_lna(real_t γ, crvec x, crvec grad_ψ, rindexvec J) const
[Optional] Function that computes the inactive indices for the evaluation of the linear Newton appro...
bool provides_eval_hess_L_prod() const
Returns true if the problem provides an implementation of eval_hess_L_prod.
bool provides_get_hess_ψ_num_nonzeros() const
Returns true if the problem provides an implementation of get_hess_ψ_num_nonzeros.
real_t eval_f_grad_f(crvec x, rvec grad_fx) const
[Optional] Evaluate both and its gradient, .
bool provides_eval_f_grad_f() const
Returns true if the problem provides a specialized implementation of eval_f_grad_f,...
void eval_grad_g_prod(crvec x, crvec y, rvec grad_gxy) const
[Required] Function that evaluates the gradient of the constraints times a vector,
void eval_hess_L_prod(crvec x, crvec y, real_t scale, crvec v, rvec Hv) const
[Optional] Function that evaluates the Hessian of the Lagrangian multiplied by a vector,
bool provides_eval_grad_gi() const
Returns true if the problem provides an implementation of eval_grad_gi.
void eval_proj_multipliers(rvec y, real_t M) const
[Required] Function that projects the Lagrange multipliers for ALM.
bool provides_eval_f_g() const
Returns true if the problem provides a specialized implementation of eval_f_g, false if it uses the d...
void eval_grad_f(crvec x, rvec grad_fx) const
[Required] Function that evaluates the gradient of the cost,
real_t eval_f(crvec x) const
[Required] Function that evaluates the cost,
bool provides_eval_grad_L() const
Returns true if the problem provides a specialized implementation of eval_grad_L, false if it uses th...
bool provides_eval_grad_ψ() const
Returns true if the problem provides a specialized implementation of eval_grad_ψ, false if it uses th...
void eval_g(crvec x, rvec gx) const
[Required] Function that evaluates the constraints,
length_t get_jac_g_num_nonzeros() const
[Optional] Function that gets the number of nonzeros of the sparse Jacobian of the constraints.
bool provides_eval_hess_ψ() const
Returns true if the problem provides an implementation of eval_hess_ψ.
real_t calc_ŷ_dᵀŷ(rvec g_ŷ, crvec y, crvec Σ) const
Given g(x), compute the intermediate results ŷ and dᵀŷ that can later be used to compute ψ(x) and ∇ψ(...
bool provides_get_box_D() const
Returns true if the problem provides an implementation of get_box_D.
const Box & get_box_C() const
[Optional] Get the rectangular constraint set of the decision variables, .
void eval_proj_diff_g(crvec z, rvec e) const
[Required] Function that evaluates the difference between the given point and its projection onto th...
void eval_jac_g(crvec x, rindexvec inner_idx, rindexvec outer_ptr, rvec J_values) const
[Optional] Function that evaluates the Jacobian of the constraints as a sparse matrix,
void eval_grad_ψ(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const
[Optional] Calculate the gradient ∇ψ(x).
bool provides_eval_ψ() const
Returns true if the problem provides a specialized implementation of eval_ψ, false if it uses the def...
void eval_hess_ψ_prod(crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv) const
[Optional] Function that evaluates the Hessian of the augmented Lagrangian multiplied by a vector,
length_t get_hess_ψ_num_nonzeros() const
[Optional] Function that gets the number of nonzeros of the Hessian of the augmented Lagrangian.
length_t get_hess_L_num_nonzeros() const
[Optional] Function that gets the number of nonzeros of the sparse Hessian of the Lagrangian.
Class for polymorphism through type erasure.
#define USING_ALPAQA_CONFIG(Conf)
Definition: config.hpp:54
#define ALPAQA_IF_QUADF(...)
Definition: config.hpp:171
#define ALPAQA_IF_LONGD(...)
Definition: config.hpp:183
#define ALPAQA_IF_FLOAT(...)
Definition: config.hpp:177
#define ALPAQA_EXPORT_EXTERN_TEMPLATE(...)
Definition: export.hpp:21
void print_provided_functions(std::ostream &os, const TypeErasedProblem< Conf > &problem)
typename Conf::real_t real_t
Definition: config.hpp:63
typename Conf::rindexvec rindexvec
Definition: config.hpp:77
typename Conf::index_t index_t
Definition: config.hpp:75
typename Conf::length_t length_t
Definition: config.hpp:74
typename Conf::rvec rvec
Definition: config.hpp:67
typename Conf::crvec crvec
Definition: config.hpp:68
#define ALPAQA_TE_OPTIONAL_METHOD(vtable, type, member, instance)
#define ALPAQA_TE_REQUIRED_METHOD(vtable, type, member)
Double-precision double configuration.
Definition: config.hpp:127
Single-precision float configuration.
Definition: config.hpp:123
long double configuration.
Definition: config.hpp:132
Struct containing function pointers to all problem functions (like the objective and constraint funct...
required_const_function_t< real_t(crvec x)> eval_f
util::BasicVTable::optional_const_function_t< F, ProblemVTable > optional_const_function_t
optional_const_function_t< void(crvec x, crvec y, real_t scale, crvec v, rvec Hv)> eval_hess_L_prod
required_const_function_t< real_t(real_t γ, crvec x, crvec grad_ψ, rvec x̂, rvec p)> eval_prox_grad_step
static real_t default_eval_ψ(const void *self, crvec x, crvec y, crvec Σ, rvec ŷ, const ProblemVTable &vtable)
optional_const_function_t< real_t(crvec x, rvec grad_fx)> eval_f_grad_f
static length_t default_get_hess_L_num_nonzeros(const void *, const ProblemVTable &)
optional_const_function_t< void(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m)> eval_grad_ψ
static void default_eval_hess_L(const void *, crvec, crvec, real_t, rindexvec, rindexvec, rvec, const ProblemVTable &)
static void default_eval_hess_L_prod(const void *, crvec, crvec, real_t, crvec, rvec, const ProblemVTable &)
optional_const_function_t< void(crvec x, crvec y, rvec grad_L, rvec work_n)> eval_grad_L
static void default_eval_hess_ψ_prod(const void *self, crvec x, crvec y, crvec, real_t scale, crvec v, rvec Hv, const ProblemVTable &vtable)
optional_const_function_t< real_t(crvec x, crvec y, crvec Σ, rvec ŷ)> eval_ψ
optional_const_function_t< index_t(real_t γ, crvec x, crvec grad_ψ, rindexvec J)> eval_inactive_indices_res_lna
ProblemVTable(std::in_place_t, P &p)
optional_const_function_t< void(crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv)> eval_hess_ψ_prod
static void default_eval_jac_g(const void *, crvec, rindexvec, rindexvec, rvec, const ProblemVTable &)
optional_const_function_t< length_t()> get_hess_ψ_num_nonzeros
optional_const_function_t< void()> check
optional_const_function_t< real_t(crvec x, rvec g)> eval_f_g
static void default_eval_grad_gi(const void *, crvec, index_t, rvec, const ProblemVTable &)
optional_const_function_t< real_t(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m)> eval_ψ_grad_ψ
util::BasicVTable::optional_function_t< F, ProblemVTable > optional_function_t
static length_t default_get_jac_g_num_nonzeros(const void *, const ProblemVTable &)
static void default_eval_grad_ψ(const void *self, crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m, const ProblemVTable &vtable)
required_const_function_t< void(crvec x, rvec gx)> eval_g
optional_const_function_t< length_t()> get_jac_g_num_nonzeros
optional_const_function_t< void(crvec x, crvec y, crvec Σ, real_t scale, rindexvec inner_idx, rindexvec outer_ptr, rvec H_values)> eval_hess_ψ
optional_const_function_t< const Box &()> get_box_D
optional_const_function_t< void(crvec x, crvec y, real_t scale, rindexvec inner_idx, rindexvec outer_ptr, rvec H_values)> eval_hess_L
static const Box & default_get_box_C(const void *, const ProblemVTable &)
static void default_eval_grad_L(const void *self, crvec x, crvec y, rvec grad_L, rvec work_n, const ProblemVTable &vtable)
static const Box & default_get_box_D(const void *, const ProblemVTable &)
optional_const_function_t< void(crvec x, crvec y, rvec grad_f, rvec grad_gxy)> eval_grad_f_grad_g_prod
required_const_function_t< void(crvec z, rvec e)> eval_proj_diff_g
static real_t default_eval_f_g(const void *self, crvec x, rvec g, const ProblemVTable &vtable)
optional_const_function_t< void(crvec x, index_t i, rvec grad_gi)> eval_grad_gi
optional_const_function_t< length_t()> get_hess_L_num_nonzeros
static void default_eval_hess_ψ(const void *self, crvec x, crvec y, crvec, real_t scale, rindexvec inner_idx, rindexvec outer_ptr, rvec H_values, 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 calc_ŷ_dᵀŷ(const void *self, rvec g_ŷ, crvec y, crvec Σ, const ProblemVTable &vtable)
static void default_eval_grad_f_grad_g_prod(const void *self, crvec x, crvec y, rvec grad_f, rvec grad_gxy, const ProblemVTable &vtable)
required_const_function_t< void(crvec x, crvec y, rvec grad_gxy)> eval_grad_g_prod
static real_t default_eval_f_grad_f(const void *self, crvec x, rvec grad_fx, const ProblemVTable &vtable)
required_const_function_t< void(rvec y, real_t M)> eval_proj_multipliers
required_const_function_t< void(crvec x, rvec grad_fx)> eval_grad_f
optional_const_function_t< void(crvec x, rindexvec inner_idx, rindexvec outer_ptr, rvec J_values)> eval_jac_g
static length_t default_get_hess_ψ_num_nonzeros(const void *, const ProblemVTable &)
static real_t default_eval_ψ_grad_ψ(const void *self, crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m, const ProblemVTable &vtable)
optional_const_function_t< const Box &()> get_box_C
Struct that stores the size of a polymorphic object, as well as pointers to functions to copy,...
typename optional_function< F, VTable >::type optional_function_t
An optional function includes a void pointer to self, the arguments of F, and an additional reference...
typename required_const_function< F >::type required_const_function_t
A required function includes a void pointer to self, in addition to the arguments of F.
typename optional_const_function< F, VTable >::type optional_const_function_t
An optional function includes a void pointer to self, the arguments of F, and an additional reference...