Skip to content

Commit 16f0839

Browse files
fabinschjcarpent
authored andcommitted
duality gap as optional stopping criteria
- use settings to decide whether or not to check the duality gap
1 parent 4f9aec9 commit 16f0839

File tree

4 files changed

+39
-8
lines changed

4 files changed

+39
-8
lines changed

include/proxsuite/proxqp/dense/solver.hpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,8 +1074,13 @@ qp_solve( //
10741074
ruiz.scale_dual_in_place_in(VectorViewMut<T>{ from_eigen, qpresults.z });
10751075
}
10761076
if (is_primal_feasible && is_dual_feasible) {
1077-
if (std::abs(qpresults.info.duality_gap) <=
1078-
qpsettings.eps_abs + qpsettings.eps_rel * rhs_duality_gap) {
1077+
if (qpsettings.check_duality_gap) {
1078+
if (std::abs(qpresults.info.duality_gap) <=
1079+
qpsettings.eps_abs + qpsettings.eps_rel * rhs_duality_gap) {
1080+
qpresults.info.status = QPSolverOutput::PROXQP_SOLVED;
1081+
break;
1082+
}
1083+
} else {
10791084
qpresults.info.status = QPSolverOutput::PROXQP_SOLVED;
10801085
break;
10811086
}
@@ -1155,8 +1160,13 @@ qp_solve( //
11551160
std::max(dual_feasibility_rhs_1, qpwork.dual_feasibility_rhs_2)));
11561161

11571162
if (is_dual_feasible) {
1158-
if (std::abs(qpresults.info.duality_gap) <=
1159-
qpsettings.eps_abs + qpsettings.eps_rel * rhs_duality_gap) {
1163+
if (qpsettings.check_duality_gap) {
1164+
if (std::abs(qpresults.info.duality_gap) <=
1165+
qpsettings.eps_abs + qpsettings.eps_rel * rhs_duality_gap) {
1166+
qpresults.info.status = QPSolverOutput::PROXQP_SOLVED;
1167+
break;
1168+
}
1169+
} else {
11601170
qpresults.info.status = QPSolverOutput::PROXQP_SOLVED;
11611171
break;
11621172
}

include/proxsuite/proxqp/settings.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ struct Settings
8484
bool update_preconditioner;
8585
bool compute_preconditioner;
8686
bool compute_timings;
87+
bool check_duality_gap;
8788

8889
isize preconditioner_max_iter;
8990
T preconditioner_accuracy;
@@ -136,6 +137,8 @@ struct Settings
136137
* @param compute_timings If set to true, timings will be computed by the
137138
* solver (setup time, solving time, and run time = setup time + solving
138139
* time).
140+
* @param check_duality_gap If set to true, duality gap will be calculated and
141+
* included in the stopping criterion.
139142
* @param preconditioner_max_iter maximal number of authorized iterations for
140143
* the preconditioner.
141144
* @param preconditioner_accuracy accuracy level of the preconditioner.
@@ -183,6 +186,7 @@ struct Settings
183186
bool update_preconditioner = true,
184187
bool compute_preconditioner = true,
185188
bool compute_timings = false,
189+
bool check_duality_gap = false,
186190
isize preconditioner_max_iter = 10,
187191
T preconditioner_accuracy = 1.e-3,
188192
T eps_primal_inf = 1.E-4,
@@ -218,6 +222,7 @@ struct Settings
218222
, update_preconditioner(update_preconditioner)
219223
, compute_preconditioner(compute_preconditioner)
220224
, compute_timings(compute_timings)
225+
, check_duality_gap(check_duality_gap)
221226
, preconditioner_max_iter(preconditioner_max_iter)
222227
, preconditioner_accuracy(preconditioner_accuracy)
223228
, eps_primal_inf(eps_primal_inf)
@@ -263,6 +268,7 @@ operator==(const Settings<T>& settings1, const Settings<T>& settings2)
263268
settings1.update_preconditioner == settings2.update_preconditioner &&
264269
settings1.compute_preconditioner == settings2.compute_preconditioner &&
265270
settings1.compute_timings == settings2.compute_timings &&
271+
settings1.check_duality_gap == settings2.check_duality_gap &&
266272
settings1.preconditioner_max_iter == settings2.preconditioner_max_iter &&
267273
settings1.preconditioner_accuracy == settings2.preconditioner_accuracy &&
268274
settings1.eps_primal_inf == settings2.eps_primal_inf &&

include/proxsuite/proxqp/sparse/solver.hpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -842,8 +842,15 @@ qp_solve(Results<T>& results,
842842
}
843843
if (is_primal_feasible(primal_feasibility_lhs) &&
844844
is_dual_feasible(dual_feasibility_lhs)) {
845-
if (std::abs(results.info.duality_gap) <=
846-
settings.eps_abs + settings.eps_rel * rhs_duality_gap) {
845+
if (settings.check_duality_gap) {
846+
if (std::abs(results.info.duality_gap) <=
847+
settings.eps_abs + settings.eps_rel * rhs_duality_gap) {
848+
results.info.pri_res = primal_feasibility_lhs;
849+
results.info.dua_res = dual_feasibility_lhs;
850+
results.info.status = QPSolverOutput::PROXQP_SOLVED;
851+
break;
852+
}
853+
} else {
847854
results.info.pri_res = primal_feasibility_lhs;
848855
results.info.dua_res = dual_feasibility_lhs;
849856
results.info.status = QPSolverOutput::PROXQP_SOLVED;
@@ -1235,8 +1242,15 @@ qp_solve(Results<T>& results,
12351242

12361243
if (is_primal_feasible(primal_feasibility_lhs_new) &&
12371244
is_dual_feasible(dual_feasibility_lhs_new)) {
1238-
if (std::fabs(results.info.duality_gap) <=
1239-
settings.eps_abs + settings.eps_rel * rhs_duality_gap) {
1245+
if (settings.check_duality_gap) {
1246+
if (std::fabs(results.info.duality_gap) <=
1247+
settings.eps_abs + settings.eps_rel * rhs_duality_gap) {
1248+
results.info.pri_res = primal_feasibility_lhs_new;
1249+
results.info.dua_res = dual_feasibility_lhs_new;
1250+
results.info.status = QPSolverOutput::PROXQP_SOLVED;
1251+
break;
1252+
}
1253+
} else {
12401254
results.info.pri_res = primal_feasibility_lhs_new;
12411255
results.info.dua_res = dual_feasibility_lhs_new;
12421256
results.info.status = QPSolverOutput::PROXQP_SOLVED;

include/proxsuite/serialization/settings.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ serialize(Archive& archive, proxsuite::proxqp::Settings<T>& settings)
4545
CEREAL_NVP(settings.update_preconditioner),
4646
CEREAL_NVP(settings.compute_preconditioner),
4747
CEREAL_NVP(settings.compute_timings),
48+
CEREAL_NVP(settings.check_duality_gap),
4849
CEREAL_NVP(settings.preconditioner_max_iter),
4950
CEREAL_NVP(settings.preconditioner_accuracy),
5051
CEREAL_NVP(settings.eps_primal_inf),

0 commit comments

Comments
 (0)