7#ifndef PROXSUITE_PROXQP_DENSE_UTILS_HPP
8#define PROXSUITE_PROXQP_DENSE_UTILS_HPP
36 const bool box_constraints,
44 std::cout <<
"problem: " << std::noshowpos << std::endl;
45 std::cout <<
" variables n = " << model.
dim
46 <<
", equality constraints n_eq = " << model.
n_eq <<
",\n"
47 <<
" inequality constraints n_in = " << model.
n_in
51 std::cout <<
"settings: " << std::endl;
52 std::cout <<
" backend = dense," << std::endl;
53 std::cout <<
" eps_abs = " << settings.
eps_abs
54 <<
" eps_rel = " << settings.
eps_rel << std::endl;
56 <<
", eps_dual_inf = " << settings.
eps_dual_inf <<
"," << std::endl;
58 std::cout <<
" rho = " << results.
info.rho
59 <<
", mu_eq = " << results.
info.mu_eq
60 <<
", mu_in = " << results.
info.mu_in <<
"," << std::endl;
61 std::cout <<
" max_iter = " << settings.
max_iter
62 <<
", max_iter_in = " << settings.
max_iter_in <<
"," << std::endl;
63 if (box_constraints) {
64 std::cout <<
" box constraints: on, " << std::endl;
66 std::cout <<
" box constraints: off, " << std::endl;
68 switch (dense_backend) {
70 std::cout <<
" dense backend: PrimalDualLDLT, " << std::endl;
73 std::cout <<
" dense backend: PrimalLDLT, " << std::endl;
78 switch (hessian_type) {
80 std::cout <<
" problem type: Quadratic Program, " << std::endl;
83 std::cout <<
" problem type: Linear Program, " << std::endl;
87 <<
" problem type: Quadratic Program with diagonal Hessian, "
92 std::cout <<
" scaling: on, " << std::endl;
94 std::cout <<
" scaling: off, " << std::endl;
97 std::cout <<
" timings: on, " << std::endl;
99 std::cout <<
" timings: off, " << std::endl;
103 std::cout <<
" initial guess: warm start. \n" << std::endl;
106 std::cout <<
" initial guess: no initial guess. \n" << std::endl;
110 <<
" initial guess: warm start with previous result. \n"
115 <<
" initial guess: cold start with previous result. \n"
120 <<
" initial guess: equality constrained initial guess. \n"
131template<
typename Derived>
133save_data(
const std::string& filename, const ::Eigen::MatrixBase<Derived>& mat)
136 const static Eigen::IOFormat CSVFormat(
137 Eigen::FullPrecision, Eigen::DontAlignCols,
", ",
"\n");
139 std::ofstream file(filename);
140 if (file.is_open()) {
141 file << mat.format(CSVFormat);
171 const bool box_constraints,
172 T& primal_feasibility_lhs,
173 T& primal_feasibility_eq_rhs_0,
174 T& primal_feasibility_in_rhs_0,
175 T& primal_feasibility_eq_lhs,
176 T& primal_feasibility_in_lhs)
192 qpresults.
se.noalias() = qpwork.
A_scaled * qpresults.
x;
195 if (box_constraints) {
209 primal_feasibility_eq_rhs_0 = infty_norm(qpresults.
se);
212 primal_feasibility_in_rhs_0 =
214 qpresults.
si.head(qpmodel.
n_in) =
219 if (box_constraints) {
220 qpresults.
si.tail(qpmodel.
dim) =
226 qpresults.
x - qpresults.
si.tail(qpmodel.
dim);
227 primal_feasibility_in_rhs_0 =
228 std::max(primal_feasibility_in_rhs_0,
230 primal_feasibility_in_rhs_0 =
231 std::max(primal_feasibility_in_rhs_0, infty_norm(qpresults.
x));
234 qpresults.
se -= qpmodel.
b;
236 primal_feasibility_in_lhs = infty_norm(qpresults.
si);
238 primal_feasibility_eq_lhs = infty_norm(qpresults.
se);
239 primal_feasibility_lhs =
240 std::max(primal_feasibility_eq_lhs, primal_feasibility_in_lhs);
243 qpwork.
rhs.head(qpmodel.
dim).noalias() =
244 qpmodel.
A.transpose() * qpresults.
se;
245 qpwork.
rhs.head(qpmodel.
dim).noalias() +=
246 qpmodel.
C.transpose() * qpresults.
si;
247 primal_feasibility_lhs = infty_norm(qpwork.
rhs.head(qpmodel.
dim));
279 const bool box_constraints,
292 bool res = infty_norm(dy.
to_eigen()) != 0 || infty_norm(dz.
to_eigen()) != 0;
306 if (box_constraints) {
322 res = lower_bound_2 <= upper_bound && lower_bound_1 <= -upper_bound;
353 const bool box_constraints,
375 if (box_constraints) {
383 T bound_neg = -bound;
385 bool first_cond = infty_norm(Adx.
to_eigen()) <= bound;
387 for (i64 iter = 0; iter < qpmodel.
n_in; ++iter) {
390 first_cond = first_cond && Cdx_i <= bound && Cdx_i >= bound_neg;
391 }
else if (qpwork.
u_scaled[iter] > 1.E20) {
392 first_cond = first_cond && Cdx_i >= bound_neg;
393 }
else if (qpwork.
l_scaled[iter] < -1.E20) {
394 first_cond = first_cond && Cdx_i <= bound;
397 if (box_constraints) {
398 for (i64 iter = 0; iter < qpmodel.
dim; ++iter) {
403 first_cond = first_cond && dx_i <= bound && dx_i >= bound_neg;
405 first_cond = first_cond && dx_i >= bound_neg;
407 first_cond = first_cond && dx_i <= bound;
413 bool second_cond_alt1 =
414 infty_norm(Hdx.
to_eigen()) <= bound && gdx <= bound_neg;
417 bool res = first_cond && second_cond_alt1 && infty_norm(dx.
to_eigen()) != 0;
442 const bool box_constraints,
444 T& dual_feasibility_lhs,
445 T& dual_feasibility_rhs_0,
446 T& dual_feasibility_rhs_1,
447 T& dual_feasibility_rhs_3,
461 switch (hessian_type) {
463 dual_feasibility_rhs_0 = 0;
466 qpwork.
CTz.noalias() =
467 qpwork.
H_scaled.template selfadjointView<Eigen::Lower>() * qpresults.
x;
471 dual_feasibility_rhs_0 = infty_norm(qpwork.
CTz);
475 qpwork.
H_scaled.diagonal().array() * qpresults.
x.array();
479 dual_feasibility_rhs_0 = infty_norm(qpwork.
CTz);
483 duality_gap = (qpmodel.
g).dot(qpresults.
x);
484 rhs_duality_gap = std::fabs(duality_gap);
486 switch (hessian_type) {
490 xHx = (qpwork.
CTz).dot(qpresults.
x);
492 rhs_duality_gap = std::max(rhs_duality_gap, std::abs(xHx));
495 xHx = (qpwork.
CTz).dot(qpresults.
x);
497 rhs_duality_gap = std::max(rhs_duality_gap, std::abs(xHx));
502 qpwork.
CTz.noalias() = qpwork.
A_scaled.transpose() * qpresults.
y;
506 dual_feasibility_rhs_1 = infty_norm(qpwork.
CTz);
508 qpwork.
CTz.noalias() =
509 qpwork.
C_scaled.transpose() * qpresults.
z.head(qpmodel.
n_in);
513 dual_feasibility_rhs_3 = infty_norm(qpwork.
CTz);
514 if (box_constraints) {
515 qpwork.
CTz.noalias() = qpresults.
z.tail(qpmodel.
dim);
524 dual_feasibility_rhs_3 =
525 std::max(infty_norm(qpwork.
CTz), dual_feasibility_rhs_3);
537 const T by = (qpmodel.
b).dot(qpresults.
y);
538 rhs_duality_gap = std::max(rhs_duality_gap, std::abs(by));
547 qpresults.
z.head(qpmodel.
n_in),
550 rhs_duality_gap = std::max(rhs_duality_gap, std::abs(zu));
555 qpresults.
z.head(qpmodel.
n_in),
558 rhs_duality_gap = std::max(rhs_duality_gap, std::abs(zl));
564 if (box_constraints) {
569 qpresults.
z.tail(qpmodel.
dim),
573 rhs_duality_gap = std::max(rhs_duality_gap, std::abs(zu));
577 qpresults.
z.tail(qpmodel.
dim),
581 rhs_duality_gap = std::max(rhs_duality_gap, std::abs(zl));
auto select(Condition const &condition, T const &expr, const Scalar value) PROXSUITE_DEDUCE_RET((condition).select(expr
Select the components of the expression if the condition is fullfiled. Otherwise, set the component t...
auto positive_part(T const &expr) PROXSUITE_DEDUCE_RET((expr.array() > 0).select(expr
Returns the positive part of an expression.
auto at_least(T const &expr, const Scalar value) PROXSUITE_DEDUCE_RET((expr.array() > value).select(expr
Returns the part of the expression which is greater than value.
auto at_most(T const &expr, const Scalar value) PROXSUITE_DEDUCE_RET((expr.array()< value).select(expr
Returns the part of the expression which is lower than value.
auto negative_part(T const &expr) PROXSUITE_DEDUCE_RET((expr.array()< 0).select(expr
Returns the negative part of an expression.
void global_dual_residual(Results< T > &qpresults, Workspace< T > &qpwork, const Model< T > &qpmodel, const bool box_constraints, const preconditioner::RuizEquilibration< T > &ruiz, T &dual_feasibility_lhs, T &dual_feasibility_rhs_0, T &dual_feasibility_rhs_1, T &dual_feasibility_rhs_3, T &rhs_duality_gap, T &duality_gap, const HessianType &hessian_type)
bool global_dual_residual_infeasibility(VectorViewMut< T > Adx, VectorViewMut< T > Cdx, VectorViewMut< T > Hdx, VectorViewMut< T > dx, Workspace< T > &qpwork, const Settings< T > &qpsettings, const Model< T > &qpmodel, const bool box_constraints, const preconditioner::RuizEquilibration< T > &ruiz)
bool global_primal_residual_infeasibility(VectorViewMut< T > ATdy, VectorViewMut< T > CTdz, VectorViewMut< T > dy, VectorViewMut< T > dz, Workspace< T > &qpwork, const Model< T > &qpmodel, const Settings< T > &qpsettings, const bool box_constraints, const preconditioner::RuizEquilibration< T > &ruiz)
void global_primal_residual(const Model< T > &qpmodel, Results< T > &qpresults, const Settings< T > &qpsettings, Workspace< T > &qpwork, const preconditioner::RuizEquilibration< T > &ruiz, const bool box_constraints, T &primal_feasibility_lhs, T &primal_feasibility_eq_rhs_0, T &primal_feasibility_in_rhs_0, T &primal_feasibility_eq_lhs, T &primal_feasibility_in_lhs)
void print_setup_header(const Settings< T > &settings, const Results< T > &results, const Model< T > &model, const bool box_constraints, const DenseBackend &dense_backend, const HessianType &hessian_type)
void save_data(const std::string &filename, const ::Eigen::MatrixBase< Derived > &mat)
@ COLD_START_WITH_PREVIOUS_RESULT
@ EQUALITY_CONSTRAINED_INITIAL_GUESS
@ WARM_START_WITH_PREVIOUS_RESULT
@ PROXQP_PRIMAL_INFEASIBLE
This class stores all the results of PROXQP solvers with sparse and dense backends.
This class defines the settings of PROXQP solvers with sparse and dense backends.
bool primal_infeasibility_solving
InitialGuessStatus initial_guess
bool compute_preconditioner
VEG_INLINE auto to_eigen() const -> detail::VecMapMut< T >
This class stores the model of the QP problem.
This class defines the workspace of the dense solver.
Vec< T > primal_residual_in_scaled_up
Vec< T > dual_residual_scaled
void unscale_primal_in_place(VectorViewMut< T > primal) const
void scale_primal_residual_in_place_eq(VectorViewMut< T > primal_eq) const
void scale_box_dual_in_place_in(VectorViewMut< T > dual) const
void unscale_dual_in_place_in(VectorViewMut< T > dual) const
void unscale_primal_residual_in_place_in(VectorViewMut< T > primal_in) const
void scale_primal_in_place(VectorViewMut< T > primal) const
void unscale_dual_in_place_eq(VectorViewMut< T > dual) const
void unscale_primal_residual_in_place_eq(VectorViewMut< T > primal_eq) const
void unscale_dual_residual_in_place(VectorViewMut< T > dual) const
void scale_dual_residual_in_place(VectorViewMut< T > dual) const
void scale_dual_in_place_in(VectorViewMut< T > dual) const
void scale_dual_in_place_eq(VectorViewMut< T > dual) const
void unscale_box_dual_in_place_in(VectorViewMut< T > dual) const
void unscale_box_primal_residual_in_place_in(VectorViewMut< T > primal_in) const