14template <Config Conf,
class IndexT,
class StorageIndexT>
17 using real_t =
typename config_t::real_t;
30 static bool is_bound(std::span<const real_t> lbx,
31 std::span<const real_t> ubx,
size_t i) {
33 return isnan(lbx[i] + ubx[i]) == 0;
36 typename config_t::index_t i) {
38 static_cast<size_t>(i));
42 std::span<const real_t> ubx) {
43 auto n =
static_cast<index_t>(lbx.size());
44 assert(
static_cast<index_t>(ubx.size()) == n);
46 for (
index_t col = 0; col < n; ++col)
47 shift +=
is_bound(lbx, ubx, col) ? 1 : 0;
56 std::span<const real_t> lbx,
57 std::span<const real_t> ubx) {
58 auto n = A.cols(), m = A.rows();
61 B << mat<config_t>::Zero(shift, n), A;
63 for (
index_t col = 0; col < n; ++col)
77 std::span<const real_t> lbx,
78 std::span<const real_t> ubx) {
79 index_t n = A.cols(), shift = A.rows() - n_row;
81 for (
index_t col = n; col-- > 0;)
82 std::ranges::reverse_copy(
83 A.col(col).topRows(n_row),
84 std::reverse_iterator{A.data() + (col + 1) * A.rows()});
86 A.topRows(shift).setZero();
88 for (
index_t col = 0; col < n; ++col)
91 assert(shift == A.rows() - n_row);
102 std::span<const real_t> lbx, std::span<const real_t> ubx) {
103 assert(A.size() % n_col == 0);
104 index_t tot_rows = A.size() / n_col;
105 index_t shift = tot_rows - n_row;
107 auto A_old = A.topRows(n_row * n_col).reshaped(n_row, n_col);
108 auto A_new = A.reshaped(tot_rows, n_col);
109 for (
index_t col = n_col; col-- > 0;)
110 std::ranges::reverse_copy(
111 A_old.col(col).topRows(n_row),
112 std::reverse_iterator{A.data() + (col + 1) * A_new.rows()});
114 A_new.topRows(shift).setZero();
116 for (
index_t col = 0; col < n_col; ++col)
118 A_new(shift++, col) = 1;
119 assert(shift == A_new.rows() - n_row);
138 std::span<const real_t> lbx,
139 std::span<const real_t> ubx);
150 std::span<const real_t> ubx,
151 std::span<const real_t> lbg,
152 std::span<const real_t> ubg,
153 std::span<real_t> new_lbg,
154 std::span<real_t> new_ubg,
155 std::span<const real_t> g0);
159 typename config_t::crvec g0) {
167 std::span<real_t> new_lbg,
168 std::span<real_t> new_ubg,
169 typename config_t::crvec g0) {
176template <Config Conf,
class IndexT,
class StorageIndexT>
179 std::span<const real_t> ubx) {
180 auto n =
static_cast<size_t>(A.
ncol);
181 assert(A.
outer_ptr.size() ==
static_cast<size_t>(n) + 1);
193 for (
size_t col = 0; col < n; ++col) {
194 shift +=
is_bound(lbx, ubx, col) ? 1 : 0;
197 assert(A.
inner_idx.size() >=
static_cast<size_t>(old_nnz + shift));
200 auto num_bound_constr =
static_cast<index_t>(shift);
204 i += num_bound_constr;
215 for (
size_t col = n; col-- > 0;) {
223 auto inners_ptr = A.
inner_idx.begin() + curr_outer,
224 inners_end = A.
inner_idx.begin() + next_outer;
225 auto values_ptr = A.
values.begin() + curr_outer,
226 values_end = A.
values.begin() + next_outer;
229 std::shift_right(inners_ptr, inners_end + shift, shift);
230 std::shift_right(values_ptr, values_end + shift, shift);
233 inners_ptr[shift - 1] =
static_cast<index_t>(shift) - 1;
234 values_ptr[shift - 1] = 1;
240 A.
nrow += num_bound_constr;
243template <Config Conf,
class IndexT,
class StorageIndexT>
245 std::span<const real_t> lbx, std::span<const real_t> ubx,
246 std::span<const real_t> lbg, std::span<const real_t> ubg,
247 std::span<real_t> new_lbg, std::span<real_t> new_ubg,
248 std::span<const real_t> g0) {
249 const auto n = lbx.size(), m [[maybe_unused]] = lbg.size();
250 assert(ubx.size() == n);
251 assert(ubg.size() == m);
252 assert(g0.size() == m);
254 for (
size_t i = 0; i < n; ++i) {
261 assert(c + m == new_lbg.size());
262 std::ranges::transform(lbg, g0, &new_lbg[c], std::minus{});
263 std::ranges::transform(ubg, g0, &new_ubg[c], std::minus{});
auto as_span(Eigen::DenseBase< Derived > &v)
Convert an Eigen vector view to a std::span.
std::span< storage_index_t > outer_ptr
static void combine_bound_constr(const sets::Box< config_t > &C, const sets::Box< config_t > &D, std::span< real_t > new_lbg, std::span< real_t > new_ubg, typename config_t::crvec g0)
static void add_box_constr_to_constr_matrix(mat< config_t > &A, const sets::Box< config_t > &C)
typename config_t::real_t real_t
static index_t count_bounds(const sets::Box< config_t > &C)
static void add_box_constr_to_constr_matrix_inplace(index_t n_row, rmat< config_t > A, std::span< const real_t > lbx, std::span< const real_t > ubx)
static void add_box_constr_to_constr_matrix_inplace_vec(index_t n_row, index_t n_col, rvec< config_t > A, const sets::Box< config_t > &C)
static void add_box_constr_to_constr_matrix(SparseView &A, const sets::Box< config_t > &C)
static index_t count_bounds(std::span< const real_t > lbx, std::span< const real_t > ubx)
std::span< real_t > values
std::span< index_t > inner_idx
StorageIndexT storage_index_t
static bool is_bound(std::span< const real_t > lbx, std::span< const real_t > ubx, size_t i)
Check if the variable with the given index has bound constraints, i.e.
static void add_box_constr_to_constr_matrix_inplace_vec(index_t n_row, index_t n_col, rvec< config_t > A, std::span< const real_t > lbx, std::span< const real_t > ubx)
static void add_box_constr_to_constr_matrix_inplace(index_t n_row, rmat< config_t > A, const sets::Box< config_t > &C)
static void combine_bound_constr(std::span< const real_t > lbx, std::span< const real_t > ubx, std::span< const real_t > lbg, std::span< const real_t > ubg, std::span< real_t > new_lbg, std::span< real_t > new_ubg, std::span< const real_t > g0)
For each constraint lbx(i)/ubx(i) with finite bounds, insert these bounds into new_lbg(i)/new_ubg(i),...
static bool is_bound(const sets::Box< config_t > &C, typename config_t::index_t i)
static void combine_bound_constr(const sets::Box< config_t > &C, const sets::Box< config_t > &D, sets::Box< config_t > &new_D, typename config_t::crvec g0)
static void add_box_constr_to_constr_matrix(mat< config_t > &A, std::span< const real_t > lbx, std::span< const real_t > ubx)