alpaqa guanaqo
Nonconvex constrained optimization
Loading...
Searching...
No Matches
qpalm-adapter.cpp
Go to the documentation of this file.
5
6#include <qpalm/sparse.hpp>
7
8#include <cmath>
9#include <stdexcept>
10
11namespace alpaqa {
12
13namespace {
14
16
17int convert_symmetry(sparsity::Symmetry symmetry) {
18 switch (symmetry) {
19 case sparsity::Symmetry::Unsymmetric: return UNSYMMETRIC;
20 case sparsity::Symmetry::Upper: return UPPER;
21 case sparsity::Symmetry::Lower: return LOWER;
22 default: throw std::invalid_argument("Invalid symmetry");
23 }
24}
25
26} // namespace
27
28OwningQPALMData
31
32 // Get the dimensions of the problem matrices
33 const auto n = problem.get_num_variables(),
34 m = problem.get_num_constraints();
35
36 // Dummy data to evaluate Hessian and Jacobian
37 vec x = vec::Zero(n), y = vec::Zero(m), g(m);
38
39 // Construct QPALM problem
41
42 using std::span;
43 using qp_idx_t = qpalm::sp_index_t;
44 using SparseCSC = sparsity::SparseCSC<qp_idx_t, qp_idx_t>;
45 using SparsityConv = sparsity::SparsityConverter<Sparsity, SparseCSC>;
47 { // Evaluate cost Hessian
48 Sparsity sp_Q_orig = problem.get_lagrangian_hessian_sparsity();
49 SparsityConv sp_Q{sp_Q_orig, {.order = SparseCSC::SortedRows}};
50 auto nnz_Q = static_cast<qp_idx_t>(sp_Q.get_sparsity().nnz());
51 auto symm = convert_symmetry(sp_Q.get_sparsity().symmetry);
52 qp.sto->Q = qpalm::ladel_sparse_create(n, n, nnz_Q, symm);
53 qp.Q = qp.sto->Q.get();
54 // Copy sparsity pattern
55 std::ranges::copy(sp_Q.get_sparsity().inner_idx, qp.Q->i);
56 std::ranges::copy(sp_Q.get_sparsity().outer_ptr, qp.Q->p);
57 // Get actual values
58 mvec H_values{qp.Q->x, static_cast<index_t>(nnz_Q)};
59 sp_Q.convert_values_into(as_span(H_values), [&](std::span<real_t> v) {
60 problem.eval_lagrangian_hessian(x, y, 1, as_vec(v));
61 });
62 }
63 { // Evaluate constraints Jacobian
64 Sparsity sp_A_orig = problem.get_constraints_jacobian_sparsity();
65 SparsityConv sp_A{sp_A_orig, {.order = SparseCSC::SortedRows}};
66 auto nnz_A = static_cast<qp_idx_t>(sp_A.get_sparsity().nnz());
67 auto symm = convert_symmetry(sp_A.get_sparsity().symmetry);
68 qp.sto->A = qpalm::ladel_sparse_create(m, n, nnz_A + n, symm);
69 qp.A = qp.sto->A.get();
70 // Copy sparsity pattern
71 std::ranges::copy(sp_A.get_sparsity().inner_idx, qp.A->i);
72 std::ranges::copy(sp_A.get_sparsity().outer_ptr, qp.A->p);
73 // Get actual values
74 mvec J_values{qp.A->x, static_cast<index_t>(nnz_A)};
75 sp_A.convert_values_into(as_span(J_values), [&](std::span<real_t> v) {
76 problem.eval_constraints_jacobian(x, as_vec(v));
77 });
78
79 // Add the bound constraints
80 ConstrConv::SparseView A{
81 .nrow = qp.A->nrow,
82 .ncol = qp.A->ncol,
83 .inner_idx = span{qp.A->i, static_cast<size_t>(qp.A->nzmax)},
84 .outer_ptr = span{qp.A->p, static_cast<size_t>(qp.A->ncol) + 1},
85 .values = span{qp.A->x, static_cast<size_t>(qp.A->nzmax)},
86 };
87 ConstrConv::add_box_constr_to_constr_matrix(
88 A, problem.get_variable_bounds());
89 qp.A->nrow = A.nrow;
90 }
91 { // Evaluate constraints
92 problem.eval_constraints(x, g);
93 }
94 { // Evaluate cost and cost gradient
95 qp.sto->q.resize(n);
96 qp.q = qp.sto->q.data();
97 qp.c = problem.eval_objective_and_gradient(x, qp.sto->q);
98 }
99 { // Combine bound constraints
100 qp.sto->b.lower.resize(qp.A->nrow);
101 qp.sto->b.upper.resize(qp.A->nrow);
102 qp.bmin = qp.sto->b.lower.data();
103 qp.bmax = qp.sto->b.upper.data();
104 // Combine bound constraints and linear constraints
105 auto &&C = problem.get_variable_bounds(),
106 &&D = problem.get_general_bounds();
107 ConstrConv::combine_bound_constr(C, D, qp.sto->b, g);
108 }
109 qp.m = static_cast<size_t>(qp.A->nrow);
110 qp.n = static_cast<size_t>(qp.Q->nrow);
111 return qp;
112}
113
114} // namespace alpaqa
The main polymorphic minimization problem interface.
void eval_constraints(crvec x, rvec gx) const
[Required] Function that evaluates the constraints,
Sparsity get_lagrangian_hessian_sparsity() const
[Optional] Function that returns (a view of) the sparsity pattern of the Hessian of the Lagrangian.
void eval_lagrangian_hessian(crvec x, crvec y, real_t scale, rvec H_values) const
[Optional] Function that evaluates the nonzero values of the Hessian of the Lagrangian,
real_t eval_objective_and_gradient(crvec x, rvec grad_fx) const
[Optional] Evaluate both and its gradient, .
const Box & get_variable_bounds() const
[Optional] Get the rectangular constraint set of the decision variables, .
void eval_constraints_jacobian(crvec x, rvec J_values) const
[Optional] Function that evaluates the nonzero values of the Jacobian matrix of the constraints,
length_t get_num_constraints() const
[Required] Number of constraints.
length_t get_num_variables() const
[Required] Number of decision variables.
Sparsity get_constraints_jacobian_sparsity() const
[Optional] Function that returns (a view of) the sparsity pattern of the Jacobian of the constraints.
const Box & get_general_bounds() const
[Optional] Get the rectangular constraint set of the general constraint function, .
#define USING_ALPAQA_CONFIG(Conf)
Definition config.hpp:77
int convert_symmetry(sparsity::Symmetry symmetry)
typename Conf::mvec mvec
Definition config.hpp:89
auto as_span(Eigen::DenseBase< Derived > &v)
Convert an Eigen vector view to a std::span.
Definition span.hpp:21
OwningQPALMData build_qpalm_problem(const TypeErasedProblem< EigenConfigd > &problem)
typename Conf::index_t index_t
Definition config.hpp:104
auto as_vec(std::span< T, E > s)
Convert a std::span to an Eigen::Vector view.
Definition span.hpp:51
typename Conf::vec vec
Definition config.hpp:88
Double-precision double configuration.
Definition config.hpp:176
std::unique_ptr< Storage > sto