77#ifndef PROXSUITE_PROXQP_DENSE_UTILS_HPP
88#define PROXSUITE_PROXQP_DENSE_UTILS_HPP
99
10+ #include < iostream>
11+ #include < fstream>
12+ #include < cmath>
13+ #include < type_traits>
14+
15+ #include " proxsuite/helpers/common.hpp"
1016#include " proxsuite/proxqp/dense/views.hpp"
1117#include " proxsuite/proxqp/dense/workspace.hpp"
1218#include < proxsuite/proxqp/dense/model.hpp>
1319#include < proxsuite/proxqp/results.hpp>
1420#include < proxsuite/proxqp/utils/prints.hpp>
1521#include < proxsuite/proxqp/settings.hpp>
1622#include < proxsuite/proxqp/dense/preconditioner/ruiz.hpp>
17- #include < iostream>
18- #include < fstream>
19- #include < cmath>
20- #include < type_traits>
23+
2124// #include <fmt/format.h>
2225// #include <fmt/ostream.h>
2326
@@ -110,22 +113,6 @@ save_data(const std::string& filename, const ::Eigen::MatrixBase<Derived>& mat)
110113 }
111114}
112115
113- #define LDLT_DEDUCE_RET (...) \
114- noexcept (noexcept (__VA_ARGS__)) \
115- ->typename std::remove_const<decltype (__VA_ARGS__)>::type \
116- { \
117- return __VA_ARGS__; \
118- } \
119- static_assert (true , " ." )
120- template <typename T>
121- auto
122- positive_part (T const & expr)
123- LDLT_DEDUCE_RET ((expr.array() > 0 ).select(expr, T::Zero(expr.rows())));
124- template <typename T>
125- auto
126- negative_part (T const & expr)
127- LDLT_DEDUCE_RET((expr.array() < 0).select(expr, T::Zero(expr.rows())));
128-
129116/* !
130117 * Derives the global primal residual of the QP problem.
131118 *
@@ -180,8 +167,8 @@ global_primal_residual(const Model<T>& qpmodel,
180167 primal_feasibility_in_rhs_0 = infty_norm (qpwork.primal_residual_in_scaled_up );
181168
182169 qpwork.primal_residual_in_scaled_low =
183- positive_part (qpwork.primal_residual_in_scaled_up - qpmodel.u ) +
184- negative_part (qpwork.primal_residual_in_scaled_up - qpmodel.l );
170+ helpers:: positive_part (qpwork.primal_residual_in_scaled_up - qpmodel.u ) +
171+ helpers:: negative_part (qpwork.primal_residual_in_scaled_up - qpmodel.l );
185172 qpwork.primal_residual_eq_scaled -= qpmodel.b ;
186173
187174 primal_feasibility_in_lhs = infty_norm (qpwork.primal_residual_in_scaled_low );
@@ -236,8 +223,8 @@ global_primal_residual_infeasibility(
236223 ruiz.unscale_dual_residual_in_place (ATdy);
237224 ruiz.unscale_dual_residual_in_place (CTdz);
238225 T eq_inf = dy.to_eigen ().dot (qpwork.b_scaled );
239- T in_inf = positive_part (dz.to_eigen ()).dot (qpwork.u_scaled ) -
240- positive_part (- dz.to_eigen ()).dot (qpwork.l_scaled );
226+ T in_inf = helpers:: positive_part (dz.to_eigen ()).dot (qpwork.u_scaled ) -
227+ helpers::negative_part ( dz.to_eigen ()).dot (qpwork.l_scaled );
241228 ruiz.unscale_dual_in_place_eq (dy);
242229 ruiz.unscale_dual_in_place_in (dz);
243230
@@ -375,7 +362,7 @@ global_dual_residual(Results<T>& qpresults,
375362 ruiz.unscale_primal_in_place (VectorViewMut<T>{ from_eigen, qpresults.x });
376363 duality_gap = (qpmodel.g ).dot (qpresults.x );
377364 rhs_duality_gap = std::abs (duality_gap);
378- T xHx = (qpwork.CTz ).dot (qpresults.x );
365+ const T xHx = (qpwork.CTz ).dot (qpresults.x );
379366 duality_gap += xHx; // contains now xHx+g.Tx
380367 rhs_duality_gap = std::max (rhs_duality_gap, std::abs (xHx));
381368
@@ -402,19 +389,29 @@ global_dual_residual(Results<T>& qpresults,
402389 VectorViewMut<T>{ from_eigen, qpwork.dual_residual_scaled });
403390
404391 ruiz.unscale_dual_in_place_eq (VectorViewMut<T>{ from_eigen, qpresults.y });
405- T by = (qpmodel.b ).dot (qpresults.y );
392+ const T by = (qpmodel.b ).dot (qpresults.y );
406393 rhs_duality_gap = std::max (rhs_duality_gap, std::abs (by));
407394 duality_gap += by;
408395 ruiz.scale_dual_in_place_eq (VectorViewMut<T>{ from_eigen, qpresults.y });
396+
409397 ruiz.unscale_dual_in_place_in (VectorViewMut<T>{ from_eigen, qpresults.z });
410- T zu = positive_part (qpresults.z ).dot (qpmodel.u );
398+
399+ const T zu =
400+ helpers::positive_part (qpresults.z )
401+ .dot (helpers::at_most (qpmodel.u , helpers::infinite_bound<T>::value ()));
411402 rhs_duality_gap = std::max (rhs_duality_gap, std::abs (zu));
412403 duality_gap += zu;
413- T zl = negative_part (qpresults.z ).dot (qpmodel.l );
404+
405+ const T zl =
406+ helpers::negative_part (qpresults.z )
407+ .dot (helpers::at_least (qpmodel.l , -helpers::infinite_bound<T>::value ()));
414408 rhs_duality_gap = std::max (rhs_duality_gap, std::abs (zl));
415409 duality_gap += zl;
410+
416411 ruiz.scale_dual_in_place_in (VectorViewMut<T>{ from_eigen, qpresults.z });
412+
417413 duality_gap /= sqrt_max_dim; // in order to get an a-dimensional duality gap
414+ rhs_duality_gap /= sqrt_max_dim;
418415}
419416
420417} // namespace dense
0 commit comments