6#ifndef PROXSUITE_PROXQP_SPARSE_PRECOND_RUIZ_HPP
7#define PROXSUITE_PROXQP_SPARSE_PRECOND_RUIZ_HPP
15namespace preconditioner {
23template<
typename T,
typename I>
29 I
const*
mi =
m.row_indices();
30 T
const*
mx =
m.values();
32 for (usize
j = 0;
j <
usize(
m.ncols()); ++
j) {
33 auto col_start =
m.col_start(
j);
34 auto col_end =
m.col_end(
j);
36 for (usize p = col_start; p < col_end; ++p) {
37 usize
i = zero_extend(
mi[p]);
44template<
typename T,
typename I>
50 I
const*
hi =
h.row_indices();
51 T
const*
hx =
h.values();
53 for (usize
j = 0;
j <
usize(
h.ncols()); ++
j) {
54 auto col_start =
h.col_start(
j);
55 auto col_end =
h.col_end(
j);
59 for (usize p = col_start; p < col_end; ++p) {
60 usize
i = zero_extend(
hi[p]);
74template<
typename T,
typename I>
80 I
const*
hi =
h.row_indices();
81 T
const*
hx =
h.values();
83 for (usize
j = 0;
j <
usize(
h.ncols()); ++
j) {
84 auto col_start =
h.col_start(
j);
85 auto col_end =
h.col_end(
j);
89 if (col_end > col_start) {
93 usize
i = zero_extend(
hi[p]);
102 if (p <= col_start) {
111template<
typename T,
typename I>
126 isize n =
qp.H.nrows();
127 isize n_eq =
qp.AT.ncols();
128 isize n_in =
qp.CT.ncols();
135 I*
Hi =
qp.H.row_indices_mut();
136 T*
Hx =
qp.H.values_mut();
138 I*
ATi =
qp.AT.row_indices_mut();
139 T*
ATx =
qp.AT.values_mut();
141 I*
CTi =
qp.CT.row_indices_mut();
142 T*
CTx =
qp.CT.values_mut();
144 T
const machine_eps = std::numeric_limits<T>::epsilon();
146 while (infty_norm((1 - delta.array()).matrix()) > epsilon) {
147 if (iter == max_iter) {
176 for (isize
j = 0;
j < n; ++
j) {
186 delta.tail(n_eq + n_in).setOnes();
188 for (usize
j = 0;
j <
usize(n_eq); ++
j) {
191 usize col_start =
qp.AT.col_start(
j);
192 usize col_end =
qp.AT.col_end(
j);
194 for (usize p = col_start; p < col_end; ++p) {
201 for (usize
j = 0;
j <
usize(n_in); ++
j) {
203 usize col_start =
qp.CT.col_start(
j);
204 usize col_end =
qp.CT.col_end(
j);
206 for (usize p = col_start; p < col_end; ++p) {
222 for (usize
j = 0;
j <
usize(n_eq); ++
j) {
223 usize col_start =
qp.AT.col_start(
j);
224 usize col_end =
qp.AT.col_end(
j);
228 for (usize p = col_start; p < col_end; ++p) {
229 usize
i = zero_extend(
ATi[p]);
237 for (usize
j = 0;
j <
usize(n_in); ++
j) {
238 usize col_start =
qp.CT.col_start(
j);
239 usize col_end =
qp.CT.col_end(
j);
241 T
delta_j = delta(n + n_eq + isize(
j));
243 for (usize p = col_start; p < col_end; ++p) {
244 usize
i = zero_extend(
CTi[p]);
254 for (usize
j = 0;
j <
usize(n); ++
j) {
255 usize col_start =
qp.H.col_start(
j);
256 usize col_end =
qp.H.col_end(
j);
259 if (col_end > col_start) {
263 usize
i = zero_extend(
Hi[p]);
269 if (p <= col_start) {
278 for (usize
j = 0;
j <
usize(n); ++
j) {
279 usize col_start =
qp.H.col_start(
j);
280 usize col_end =
qp.H.col_end(
j);
283 for (usize p = col_start; p < col_end; ++p) {
284 usize
i = zero_extend(
Hi[p]);
296 qp.g.to_eigen().array() *= delta.head(n).array();
297 qp.b.to_eigen().array() *= delta.segment(n, n_eq).array();
298 qp.l.to_eigen().array() *= delta.tail(n_in).array();
299 qp.u.to_eigen().array() *= delta.tail(n_in).array();
317 for (isize
i = 0;
i < n; ++
i) {
327 S.array() *= delta.array();
334template<
typename T,
typename I>
351 std::ostream*
logger =
nullptr)
383 { proxqp::from_eigen,
delta },
391 using proxsuite::linalg::sparse::util::zero_extend;
392 isize
n =
qp.H.nrows();
393 isize n_eq =
qp.AT.ncols();
394 isize n_in =
qp.CT.ncols();
396 I*
Hi =
qp.H.row_indices_mut();
397 T*
Hx =
qp.H.values_mut();
399 I*
ATi =
qp.AT.row_indices_mut();
400 T*
ATx =
qp.AT.values_mut();
402 I*
CTi =
qp.CT.row_indices_mut();
403 T*
CTx =
qp.CT.values_mut();
406 for (usize
j = 0;
j <
usize(n_eq); ++
j) {
407 usize col_start =
qp.AT.col_start(
j);
408 usize col_end =
qp.AT.col_end(
j);
412 for (usize p = col_start; p < col_end; ++p) {
413 usize
i = zero_extend(
ATi[p]);
421 for (usize
j = 0;
j <
usize(n_in); ++
j) {
422 usize col_start =
qp.CT.col_start(
j);
423 usize col_end =
qp.CT.col_end(
j);
427 for (usize p = col_start; p < col_end; ++p) {
428 usize
i = zero_extend(
CTi[p]);
439 usize col_start =
qp.H.col_start(
j);
440 usize col_end =
qp.H.col_end(
j);
443 if (col_end > col_start) {
447 usize
i = zero_extend(
Hi[p]);
453 if (p <= col_start) {
463 usize col_start =
qp.H.col_start(
j);
464 usize col_end =
qp.H.col_end(
j);
467 for (usize p = col_start; p < col_end; ++p) {
468 usize
i = zero_extend(
Hi[p]);
480 qp.g.to_eigen().array() *=
delta.head(
n).array();
481 qp.b.to_eigen().array() *=
delta.segment(
n, n_eq).array();
482 qp.l.to_eigen().array() *=
delta.tail(n_in).array();
483 qp.u.to_eigen().array() *=
delta.tail(n_in).array();
485 qp.g.to_eigen() *=
c;
486 qp.H.to_eigen() *=
c;
497 dual.to_eigen().array() =
dual.as_const().to_eigen().array() /
503 dual.to_eigen().array() =
504 dual.as_const().to_eigen().array() /
505 delta.middleRows(
n,
dual.to_eigen().size()).array() *
c;
509 dual.to_eigen().array() =
dual.as_const().to_eigen().array() /
510 delta.tail(
dual.to_eigen().size()).array() *
c;
519 dual.to_eigen().array() =
dual.as_const().to_eigen().array() *
525 dual.to_eigen().array() =
526 dual.as_const().to_eigen().array() *
527 delta.middleRows(
n,
dual.to_eigen().size()).array() /
c;
532 dual.to_eigen().array() =
dual.as_const().to_eigen().array() *
533 delta.tail(
dual.to_eigen().size()).array() /
c;
553 dual.to_eigen().array() *=
delta.head(
n).array() *
c;
571 dual.to_eigen().array() /=
delta.head(
n).array() *
c;
#define LDLT_TEMP_VEC(Type, Name, Rows, Stack)
auto temp_vec_req(proxsuite::linalg::veg::Tag< T >, isize rows) noexcept -> proxsuite::linalg::veg::dynstack::StackReq
void colwise_infty_norm_symhi(T *col_norm, proxsuite::linalg::sparse::MatRef< T, I > h)
void rowwise_infty_norm(T *row_norm, proxsuite::linalg::sparse::MatRef< T, I > m)
auto ruiz_scale_qp_in_place(VectorViewMut< T > delta_, QpViewMut< T, I > qp, T epsilon, isize max_iter, bool preconditioning_for_infeasible_problems, Symmetry sym, proxsuite::linalg::veg::dynstack::DynStackMut stack) -> T
void colwise_infty_norm_symlo(T *col_norm, proxsuite::linalg::sparse::MatRef< T, I > h)
Eigen::Matrix< T, DYN, 1 > Vec
decltype(sizeof(0)) usize
static constexpr auto with_len(proxsuite::linalg::veg::Tag< T >, isize len) noexcept -> StackReq
void scale_dual_in_place_in(VectorViewMut< T > dual) const
void unscale_primal_residual_in_place_in(VectorViewMut< T > primal_in) const
void scale_dual_in_place(VectorViewMut< T > dual)
void unscale_dual_residual_in_place(VectorViewMut< T > dual) const
void scale_dual_residual_in_place(VectorViewMut< T > dual) const
void unscale_dual_in_place_in(VectorViewMut< T > dual) const
void unscale_primal_residual_in_place(VectorViewMut< T > primal) const
void scale_primal_residual_in_place_eq(VectorViewMut< T > primal_eq) const
void scale_primal_in_place(VectorViewMut< T > primal) const
void scale_dual_in_place_eq(VectorViewMut< T > dual) const
void unscale_primal_in_place(VectorViewMut< T > primal) const
RuizEquilibration(isize n_, isize n_eq_in, T epsilon_=T(1e-3), i64 max_iter_=10, Symmetry sym_=Symmetry::UPPER, std::ostream *logger=nullptr)
std::ostream * logger_ptr
void unscale_dual_in_place(VectorViewMut< T > dual) const
static auto scale_qp_in_place_req(proxsuite::linalg::veg::Tag< T > tag, isize n, isize n_eq, isize n_in) -> proxsuite::linalg::veg::dynstack::StackReq
void unscale_primal_residual_in_place_eq(VectorViewMut< T > primal_eq) const
void unscale_dual_in_place_eq(VectorViewMut< T > dual) const
void scale_primal_residual_in_place_in(VectorViewMut< T > primal_in) const
void scale_qp_in_place(QpViewMut< T, I > qp, bool execute_preconditioner, bool preconditioning_for_infeasible_problems, const isize max_iter, const T epsilon, proxsuite::linalg::veg::dynstack::DynStackMut stack)
void scale_primal_residual_in_place(VectorViewMut< T > primal) const