413 const isize n_constraints,
420 qpwork.
err.setZero();
422 i32 it_stability = 0;
427 qpwork.
dw_aug.head(inner_pb_dim) = qpwork.
rhs.head(inner_pb_dim);
436 iterative_residual<T>(
437 qpmodel, qpresults, qpwork, n_constraints, inner_pb_dim, hessian_type);
440 T preverr = infty_norm(qpwork.
err.head(inner_pb_dim));
441 while (infty_norm(qpwork.
err.head(inner_pb_dim)) >= eps) {
456 qpwork.
dw_aug.head(inner_pb_dim) += qpwork.
err.head(inner_pb_dim);
458 qpwork.
err.head(inner_pb_dim).setZero();
459 iterative_residual<T>(
460 qpmodel, qpresults, qpwork, n_constraints, inner_pb_dim, hessian_type);
462 if (infty_norm(qpwork.
err.head(inner_pb_dim)) > preverr) {
468 if (it_stability == 2) {
471 preverr = infty_norm(qpwork.
err.head(inner_pb_dim));
474 if (infty_norm(qpwork.
err.head(inner_pb_dim)) >=
485 qpwork.
dw_aug.head(inner_pb_dim) = qpwork.
rhs.head(inner_pb_dim);
496 iterative_residual<T>(
497 qpmodel, qpresults, qpwork, n_constraints, inner_pb_dim, hessian_type);
499 preverr = infty_norm(qpwork.
err.head(inner_pb_dim));
501 while (infty_norm(qpwork.
err.head(inner_pb_dim)) >= eps) {
516 qpwork.
dw_aug.head(inner_pb_dim) += qpwork.
err.head(inner_pb_dim);
518 qpwork.
err.head(inner_pb_dim).setZero();
519 iterative_residual<T>(
520 qpmodel, qpresults, qpwork, n_constraints, inner_pb_dim, hessian_type);
522 if (infty_norm(qpwork.
err.head(inner_pb_dim)) > preverr) {
527 if (it_stability == 2) {
530 preverr = infty_norm(qpwork.
err.head(inner_pb_dim));
533 if (infty_norm(qpwork.
err.head(inner_pb_dim)) >= eps && qpsettings.
verbose) {
535 std::cout <<
"refact err " << infty_norm(qpwork.
err.head(inner_pb_dim))
538 qpresults.
info.iterative_residual = infty_norm(qpwork.
err.head(inner_pb_dim));
540 qpwork.
rhs.head(inner_pb_dim).setZero();
1095 const bool box_constraints,
1108 isize n_constraints(qpmodel.
n_in);
1109 if (box_constraints) {
1110 n_constraints += qpmodel.
dim;
1113 qpwork.
timer.stop();
1114 qpwork.
timer.start();
1129 qpwork.
cleanup(box_constraints);
1130 qpresults.
cleanup(qpsettings);
1135 qpwork.
cleanup(box_constraints);
1138 { proxsuite::proxqp::from_eigen, qpresults.
x });
1140 { proxsuite::proxqp::from_eigen, qpresults.
y });
1142 { proxsuite::proxqp::from_eigen, qpresults.
z.head(qpmodel.
n_in) });
1143 if (box_constraints) {
1145 { proxsuite::proxqp::from_eigen, qpresults.
z.tail(qpmodel.
dim) });
1150 qpwork.
cleanup(box_constraints);
1151 qpresults.
cleanup(qpsettings);
1155 qpwork.
cleanup(box_constraints);
1160 { proxsuite::proxqp::from_eigen,
1164 { proxsuite::proxqp::from_eigen, qpresults.
y });
1166 { proxsuite::proxqp::from_eigen, qpresults.
z.head(qpmodel.
n_in) });
1167 if (box_constraints) {
1169 { proxsuite::proxqp::from_eigen, qpresults.
z.tail(qpmodel.
dim) });
1178 { proxsuite::proxqp::from_eigen, qpresults.
x });
1180 { proxsuite::proxqp::from_eigen, qpresults.
y });
1182 { proxsuite::proxqp::from_eigen, qpresults.
z.head(qpmodel.
n_in) });
1183 if (box_constraints) {
1185 { proxsuite::proxqp::from_eigen, qpresults.
z.tail(qpmodel.
dim) });
1192 switch (hessian_type) {
1216 qpwork, qpmodel, qpresults, dense_backend, hessian_type);
1232 for (isize i = 0; i < n_constraints; i++) {
1233 if (qpresults.
z[i] != 0) {
1240 qpmodel, qpresults, dense_backend, n_constraints, qpwork);
1249 for (isize i = 0; i < n_constraints; i++) {
1250 if (qpresults.
z[i] != 0) {
1257 qpmodel, qpresults, dense_backend, n_constraints, qpwork);
1273 qpwork, qpmodel, qpresults, dense_backend, hessian_type);
1286 { proxsuite::proxqp::from_eigen,
1291 { proxsuite::proxqp::from_eigen, qpresults.
y });
1293 { proxsuite::proxqp::from_eigen, qpresults.
z.head(qpmodel.
n_in) });
1294 if (box_constraints) {
1296 { proxsuite::proxqp::from_eigen, qpresults.
z.tail(qpmodel.
dim) });
1299 qpwork, qpmodel, qpresults, dense_backend, hessian_type);
1301 for (isize i = 0; i < n_constraints; i++) {
1302 if (qpresults.
z[i] != 0) {
1309 qpmodel, qpresults, dense_backend, n_constraints, qpwork);
1314 qpwork, qpmodel, qpresults, dense_backend, hessian_type);
1320 { proxsuite::proxqp::from_eigen, qpresults.
x });
1322 { proxsuite::proxqp::from_eigen, qpresults.
y });
1324 { proxsuite::proxqp::from_eigen, qpresults.
z.head(qpmodel.
n_in) });
1325 if (box_constraints) {
1327 { proxsuite::proxqp::from_eigen, qpresults.
z.tail(qpmodel.
dim) });
1330 qpwork, qpmodel, qpresults, dense_backend, hessian_type);
1332 for (isize i = 0; i < n_constraints; i++) {
1333 if (qpresults.
z[i] != 0) {
1340 qpmodel, qpresults, dense_backend, n_constraints, qpwork);
1346 { proxsuite::proxqp::from_eigen,
1351 { proxsuite::proxqp::from_eigen, qpresults.
y });
1353 { proxsuite::proxqp::from_eigen, qpresults.
z.head(qpmodel.
n_in) });
1354 if (box_constraints) {
1356 { proxsuite::proxqp::from_eigen, qpresults.
z.tail(qpmodel.
dim) });
1362 qpwork, qpmodel, qpresults, dense_backend, hessian_type);
1364 for (isize i = 0; i < n_constraints; i++) {
1365 if (qpresults.
z[i] != 0) {
1372 qpmodel, qpresults, dense_backend, n_constraints, qpwork);
1378 T bcl_eta_ext_init = pow(T(0.1), qpsettings.
alpha_bcl);
1379 T bcl_eta_ext = bcl_eta_ext_init;
1381 T eps_in_min = std::min(qpsettings.
eps_abs, T(1.E-9));
1383 T primal_feasibility_eq_rhs_0(0);
1384 T primal_feasibility_in_rhs_0(0);
1385 T dual_feasibility_rhs_0(0);
1386 T dual_feasibility_rhs_1(0);
1387 T dual_feasibility_rhs_3(0);
1388 T primal_feasibility_lhs(0);
1389 T primal_feasibility_eq_lhs(0);
1390 T primal_feasibility_in_lhs(0);
1391 T dual_feasibility_lhs(0);
1394 T rhs_duality_gap(0);
1395 T scaled_eps(qpsettings.
eps_abs);
1397 for (i64 iter = 0; iter < qpsettings.
max_iter; ++iter) {
1408 primal_feasibility_lhs,
1409 primal_feasibility_eq_rhs_0,
1410 primal_feasibility_in_rhs_0,
1411 primal_feasibility_eq_lhs,
1412 primal_feasibility_in_lhs);
1419 dual_feasibility_lhs,
1420 dual_feasibility_rhs_0,
1421 dual_feasibility_rhs_1,
1422 dual_feasibility_rhs_3,
1427 qpresults.
info.pri_res = primal_feasibility_lhs;
1428 qpresults.
info.dua_res = dual_feasibility_lhs;
1429 qpresults.
info.duality_gap = duality_gap;
1431 T new_bcl_mu_in(qpresults.
info.mu_in);
1432 T new_bcl_mu_eq(qpresults.
info.mu_eq);
1433 T new_bcl_mu_in_inv(qpresults.
info.mu_in_inv);
1434 T new_bcl_mu_eq_inv(qpresults.
info.mu_eq_inv);
1436 T rhs_pri(scaled_eps);
1437 if (qpsettings.
eps_rel != 0) {
1438 rhs_pri += qpsettings.
eps_rel * std::max(primal_feasibility_eq_rhs_0,
1439 primal_feasibility_in_rhs_0);
1441 bool is_primal_feasible = primal_feasibility_lhs <= rhs_pri;
1443 T rhs_dua(qpsettings.
eps_abs);
1444 if (qpsettings.
eps_rel != 0) {
1448 std::max(dual_feasibility_rhs_3, dual_feasibility_rhs_0),
1452 bool is_dual_feasible = dual_feasibility_lhs <= rhs_dua;
1461 if (box_constraints) {
1467 qpresults.
info.objValue = 0;
1468 for (Eigen::Index j = 0; j < qpmodel.
dim; ++j) {
1469 qpresults.
info.objValue +=
1470 0.5 * (qpresults.
x(j) * qpresults.
x(j)) * qpmodel.
H(j, j);
1471 qpresults.
info.objValue +=
1472 qpresults.
x(j) * T(qpmodel.
H.col(j)
1473 .tail(qpmodel.
dim - j - 1)
1474 .dot(qpresults.
x.tail(qpmodel.
dim - j - 1)));
1476 qpresults.
info.objValue += (qpmodel.
g).dot(qpresults.
x);
1478 std::cout <<
"\033[1;32m[outer iteration " << iter + 1 <<
"]\033[0m"
1480 std::cout << std::scientific << std::setw(2) << std::setprecision(2)
1481 <<
"| primal residual=" << qpresults.
info.pri_res
1482 <<
" | dual residual=" << qpresults.
info.dua_res
1483 <<
" | duality gap=" << qpresults.
info.duality_gap
1484 <<
" | mu_in=" << qpresults.
info.mu_in
1485 <<
" | rho=" << qpresults.
info.rho << std::endl;
1490 if (box_constraints) {
1495 if (is_primal_feasible && is_dual_feasible) {
1497 if (std::fabs(qpresults.
info.duality_gap) <=
1501 qpresults.
info.status ==
1503 qpresults.
info.status =
1515 qpresults.
info.iter_ext += 1;
1527 if (box_constraints) {
1535 qpresults.
info.mu_in;
1547 qpresults.
si.head(qpmodel.
n_in) -=
1549 if (box_constraints) {
1557 qpresults.
si.tail(qpmodel.
dim) -=
1576 qpresults.
x = qpwork.
dw_aug.head(qpmodel.
dim);
1578 qpresults.
z = qpwork.
dw_aug.tail(n_constraints);
1581 if (scaled_eps == qpsettings.
eps_abs &&
1586 qpwork.
rhs.head(qpmodel.
dim).noalias() =
1587 qpmodel.
A.transpose() * qpwork.
rhs.segment(qpmodel.
dim, qpmodel.
n_eq) +
1588 qpmodel.
C.transpose() *
1590 if (box_constraints) {
1594 infty_norm(qpwork.
rhs.head(qpmodel.
dim)) * qpsettings.
eps_abs;
1596 T primal_feasibility_lhs_new(primal_feasibility_lhs);
1604 primal_feasibility_lhs_new,
1605 primal_feasibility_eq_rhs_0,
1606 primal_feasibility_in_rhs_0,
1607 primal_feasibility_eq_lhs,
1608 primal_feasibility_in_lhs);
1610 is_primal_feasible =
1611 primal_feasibility_lhs_new <=
1612 (scaled_eps + qpsettings.
eps_rel * std::max(primal_feasibility_eq_rhs_0,
1613 primal_feasibility_in_rhs_0));
1614 qpresults.
info.pri_res = primal_feasibility_lhs_new;
1615 if (is_primal_feasible) {
1616 T dual_feasibility_lhs_new(dual_feasibility_lhs);
1623 dual_feasibility_lhs_new,
1624 dual_feasibility_rhs_0,
1625 dual_feasibility_rhs_1,
1626 dual_feasibility_rhs_3,
1630 qpresults.
info.dua_res = dual_feasibility_lhs_new;
1631 qpresults.
info.duality_gap = duality_gap;
1634 dual_feasibility_lhs_new <=
1638 std::max(dual_feasibility_rhs_3, dual_feasibility_rhs_0),
1641 if (is_dual_feasible) {
1643 if (std::fabs(qpresults.
info.duality_gap) <=
1647 qpresults.
info.status ==
1649 qpresults.
info.status =
1657 qpresults.
info.status ==
1659 qpresults.
info.status =
1671 primal_feasibility_lhs_new,
1684 primal_feasibility_lhs_new,
1685 primal_feasibility_lhs,
1695 T dual_feasibility_lhs_new(dual_feasibility_lhs);
1702 dual_feasibility_lhs_new,
1703 dual_feasibility_rhs_0,
1704 dual_feasibility_rhs_1,
1705 dual_feasibility_rhs_3,
1709 qpresults.
info.dua_res = dual_feasibility_lhs_new;
1710 qpresults.
info.duality_gap = duality_gap;
1712 if (primal_feasibility_lhs_new >= primal_feasibility_lhs &&
1713 dual_feasibility_lhs_new >= dual_feasibility_lhs &&
1714 qpresults.
info.mu_in <= T(1e-5)) {
1729 if (qpresults.
info.mu_in != new_bcl_mu_in ||
1730 qpresults.
info.mu_eq != new_bcl_mu_eq) {
1732 ++qpresults.
info.mu_updates;
1743 qpresults.
info.mu_eq = new_bcl_mu_eq;
1744 qpresults.
info.mu_in = new_bcl_mu_in;
1745 qpresults.
info.mu_eq_inv = new_bcl_mu_eq_inv;
1746 qpresults.
info.mu_in_inv = new_bcl_mu_in_inv;
1753 if (box_constraints) {
1763 if (box_constraints) {
1771 qpresults.
info.objValue = 0;
1772 for (Eigen::Index j = 0; j < qpmodel.
dim; ++j) {
1773 qpresults.
info.objValue +=
1774 0.5 * (qpresults.
x(j) * qpresults.
x(j)) * qpmodel.
H(j, j);
1775 qpresults.
info.objValue +=
1776 qpresults.
x(j) * T(qpmodel.
H.col(j)
1777 .tail(qpmodel.
dim - j - 1)
1778 .dot(qpresults.
x.tail(qpmodel.
dim - j - 1)));
1780 qpresults.
info.objValue += (qpmodel.
g).dot(qpresults.
x);
1784 qpresults.
info.solve_time = qpwork.
timer.elapsed().user;
1785 qpresults.
info.run_time =
1786 qpresults.
info.solve_time + qpresults.
info.setup_time;
1790 std::cout <<
"-------------------SOLVER STATISTICS-------------------"
1792 std::cout <<
"outer iter: " << qpresults.
info.iter_ext << std::endl;
1793 std::cout <<
"total iter: " << qpresults.
info.iter << std::endl;
1794 std::cout <<
"mu updates: " << qpresults.
info.mu_updates << std::endl;
1795 std::cout <<
"rho updates: " << qpresults.
info.rho_updates << std::endl;
1796 std::cout <<
"objective: " << qpresults.
info.objValue << std::endl;
1797 switch (qpresults.
info.status) {
1799 std::cout <<
"status: "
1800 <<
"Solved" << std::endl;
1804 std::cout <<
"status: "
1805 <<
"Maximum number of iterations reached" << std::endl;
1809 std::cout <<
"status: "
1810 <<
"Primal infeasible" << std::endl;
1814 std::cout <<
"status: "
1815 <<
"Dual infeasible" << std::endl;
1819 std::cout <<
"status: "
1820 <<
"Solved closest primal feasible" << std::endl;
1824 std::cout <<
"status: "
1825 <<
"Solver not run" << std::endl;
1831 std::cout <<
"run time [μs]: " << qpresults.
info.solve_time << std::endl;
1832 std::cout <<
"--------------------------------------------------------"
1835 qpwork.
dirty =
true;
1838 assert(!std::isnan(qpresults.
info.pri_res));
1839 assert(!std::isnan(qpresults.
info.dua_res));
1840 assert(!std::isnan(qpresults.
info.duality_gap));