363 proxsuite::linalg::veg::unsafe, kkt_unscaled, data.
dim);
376 H_unscaled.to_eigen().template triangularView<Eigen::Upper>();
396 precond.scale_primal_in_place(
397 { proxsuite::proxqp::from_eigen, results.
x });
398 precond.scale_dual_in_place_eq(
399 { proxsuite::proxqp::from_eigen, results.
y });
400 precond.scale_dual_in_place_in(
401 { proxsuite::proxqp::from_eigen, results.
z });
411 precond.scale_primal_in_place(
412 { proxsuite::proxqp::from_eigen,
414 precond.scale_dual_in_place_eq(
415 { proxsuite::proxqp::from_eigen, results.
y });
416 precond.scale_dual_in_place_in(
417 { proxsuite::proxqp::from_eigen, results.
z });
423 precond.scale_primal_in_place(
424 { proxsuite::proxqp::from_eigen, results.
x });
425 precond.scale_dual_in_place_eq(
426 { proxsuite::proxqp::from_eigen, results.
y });
427 precond.scale_dual_in_place_in(
428 { proxsuite::proxqp::from_eigen, results.
z });
438 P::scale_qp_in_place_req(
449 precond.scale_primal_in_place(
450 { proxsuite::proxqp::from_eigen,
453 precond.scale_dual_in_place_eq(
454 { proxsuite::proxqp::from_eigen, results.
y });
455 precond.scale_dual_in_place_in(
456 { proxsuite::proxqp::from_eigen, results.
z });
463 precond.scale_primal_in_place(
464 { proxsuite::proxqp::from_eigen, results.
x });
465 precond.scale_dual_in_place_eq(
466 { proxsuite::proxqp::from_eigen, results.
y });
467 precond.scale_dual_in_place_in(
468 { proxsuite::proxqp::from_eigen, results.
z });
472 precond.scale_primal_in_place(
473 { proxsuite::proxqp::from_eigen,
476 precond.scale_dual_in_place_eq(
477 { proxsuite::proxqp::from_eigen, results.
y });
478 precond.scale_dual_in_place_in(
479 { proxsuite::proxqp::from_eigen, results.
z });
490 auto zx = util::zero_extend;
495 isize n_eq = data.
n_eq;
496 isize n_in = data.
n_in;
497 isize
n_tot = n + n_eq + n_in;
532 T
const dual_feasibility_rhs_2 = infty_norm(data.
g);
535 auto ldl_col_ptrs = work.
internal.
ldl.col_ptrs.ptr_mut();
545 I* perm_inv = work.
internal.
ldl.perm_inv.ptr_mut();
546 I* perm =
_perm.ptr_mut();
551 perm[isize(
zx(perm_inv[
i]))] = I(
i);
562 for (usize
j = 0;
j <
usize(n + n_eq); ++
j) {
563 kkt_nnz_counts[isize(
j)] = I(kkt.col_end(
j) - kkt.col_start(
j));
566 for (isize
j = 0;
j < n_in; ++
j) {
567 kkt_nnz_counts[n + n_eq +
j] = 0;
577 for (usize
j = 0;
j <
usize(n + n_eq); ++
j) {
578 kkt_nnz_counts[isize(
j)] = I(kkt.col_end(
j) - kkt.col_start(
j));
581 for (isize
j = 0;
j < n_in; ++
j) {
582 if (results.
z(
j) != 0) {
583 kkt_nnz_counts[n + n_eq +
j] = I(kkt.col_end(usize(n + n_eq +
j)) -
584 kkt.col_start(usize(n + n_eq +
j)));
588 kkt_nnz_counts[n + n_eq +
j] = 0;
597 for (usize
j = 0;
j <
usize(n + n_eq); ++
j) {
598 kkt_nnz_counts[isize(
j)] = I(kkt.col_end(
j) - kkt.col_start(
j));
601 for (isize
j = 0;
j < n_in; ++
j) {
602 kkt_nnz_counts[n + n_eq +
j] = 0;
611 for (usize
j = 0;
j <
usize(n + n_eq); ++
j) {
612 kkt_nnz_counts[isize(
j)] = I(kkt.col_end(
j) - kkt.col_start(
j));
615 for (isize
j = 0;
j < n_in; ++
j) {
616 if (results.
z(
j) != 0) {
617 kkt_nnz_counts[n + n_eq +
j] = I(kkt.col_end(usize(n + n_eq +
j)) -
618 kkt.col_start(usize(n + n_eq +
j)));
623 kkt_nnz_counts[n + n_eq +
j] = 0;
632 for (usize
j = 0;
j <
usize(n + n_eq); ++
j) {
633 kkt_nnz_counts[isize(
j)] = I(kkt.col_end(
j) - kkt.col_start(
j));
636 for (isize
j = 0;
j < n_in; ++
j) {
637 if (results.
z(
j) != 0) {
638 kkt_nnz_counts[n + n_eq +
j] = I(kkt.col_end(usize(n + n_eq +
j)) -
639 kkt.col_start(usize(n + n_eq +
j)));
643 kkt_nnz_counts[n + n_eq +
j] = 0;
652 proxsuite::linalg::sparse::from_raw_parts,
658 kkt.row_indices_mut(),
670 proxsuite::linalg::sparse::from_raw_parts,
685 auto x_e = x.to_eigen();
686 auto y_e = y.to_eigen();
687 auto z_e = z.to_eigen();
689 work, results, settings, kkt_active, active_constraints, data, stack,
xtag);
697 rhs.segment(n + n_eq, n_in).setZero();
716 y_e = rhs.segment(n, n_eq);
717 z_e = rhs.segment(n + n_eq, n_in);
740 for (isize iter = 0; iter < settings.
max_iter; ++iter) {
742 results.
info.iter_ext += 1;
781 dual_feasibility_rhs_2,
798 primal_residual_in_scaled_up,
799 dual_residual_scaled,
831 precond.unscale_dual_residual_in_place({ proxqp::from_eigen,
tmp });
833 precond.unscale_primal_in_place({ proxqp::from_eigen,
x_e });
834 precond.unscale_dual_in_place_eq({ proxqp::from_eigen,
y_e });
835 precond.unscale_dual_in_place_in({ proxqp::from_eigen,
z_e });
839 std::cout <<
"\033[1;32m[outer iteration " << iter + 1 <<
"]\033[0m"
841 std::cout << std::scientific << std::setw(2) << std::setprecision(2)
844 <<
" | duality gap=" << results.
info.duality_gap
845 <<
" | mu_in=" << results.
info.mu_in
846 <<
" | rho=" << results.
info.rho << std::endl;
856 if (std::fabs(results.
info.duality_gap) <=
862 results.
info.status =
873 results.
info.status =
892 primal_residual_in_scaled_up += results.
info.mu_in *
z_prev_e;
910 auto primal_dual_newton_semi_smooth = [&]() ->
void {
928 primal_residual_in_scaled_up.array() >= 0;
936 for (isize
i = 0;
i < n_in; ++
i) {
940 isize idx = n + n_eq +
i;
943 zx(kkt.col_end(usize(idx))) -
zx(kkt.col_start(usize(idx)));
948 kkt_active.nnz_per_col_mut()[idx] = I(
col_nnz);
949 kkt_active._set_nnz(kkt_active.nnz() + isize(
col_nnz));
953 proxsuite::linalg::sparse::from_raw_parts,
956 kkt.row_indices() +
zx(kkt.col_start(usize(idx))),
957 kkt.values() +
zx(kkt.col_start(usize(idx))),
976 kkt_active.nnz_per_col_mut()[idx] = 0;
977 kkt_active._set_nnz(kkt_active.nnz() - isize(
col_nnz));
980 ldl, etree, perm_inv, idx, stack);
1000 rhs.head(n) = -dual_residual_scaled;
1002 for (isize
i = 0;
i < n_in; ++
i) {
1005 results.
info.mu_in *
z_e(
i) - primal_residual_in_scaled_up(
i);
1010 rhs(n + n_eq +
i) = -
z_e(
i);
1047 { proxqp::from_eigen, rhs },
1048 { proxqp::from_eigen,
1064 active_constraints);
1067 auto dx =
dw.head(n);
1068 auto dy =
dw.segment(n, n_eq);
1069 auto dz =
dw.segment(n + n_eq, n_in);
1099 auto zero = Eigen::Matrix<T, Eigen::Dynamic, 1>::Zero(n_in);
1105 active_part_z = (
tmp_lo.array() < 0)
1108 .select(primal_residual_in_scaled_up,
zero);
1112 results.
info.rho *
dx.squaredNorm() +
1113 results.
info.mu_eq_inv * Adx.squaredNorm() +
1115 results.
info.nu * results.
info.mu_eq *
1117 results.
info.nu * results.
info.mu_in *
1127 results.
info.mu_eq_inv * Adx -
dy) +
1129 (active_part_z - results.
info.mu_in *
z_e)
1192 const T
machine_eps = std::numeric_limits<T>::epsilon();
1194 for (isize
i = 0;
i < n_in; ++
i) {
1207 std::sort(alphas.data(), alphas.data() +
alphas_count);
1209 std::unique(alphas.data(), alphas.data() +
alphas_count) -
1212 auto infty = std::numeric_limits<T>::infinity();
1299 dual_residual_scaled +=
1303 primal_residual_in_scaled_up += alpha * Cdx;
1310 (infty_norm(dual_residual_scaled)),
1344 std::cout <<
"\033[1;34m[inner iteration " <<
iter_inner + 1
1345 <<
"]\033[0m" << std::endl;
1346 std::cout << std::scientific << std::setw(2) << std::setprecision(2)
1347 <<
"| inner residual=" <<
err_in <<
" | alpha=" << alpha
1396 primal_dual_newton_semi_smooth();
1431 primal_residual_in_scaled_up,
1432 dual_residual_scaled,
1450 if (std::fabs(results.
info.duality_gap) <=
1456 results.
info.status ==
1458 results.
info.status =
1470 results.
info.status =
1480 auto bcl_update = [&]() ->
void {
1516 primal_residual_in_scaled_up,
1517 dual_residual_scaled,
1531 proxsuite::linalg::veg::unused(_);
1535 results.
info.mu_in <= T(1.E-5)) {
1545 ++results.
info.mu_updates;
1560 for (isize
j = 0;
j < n_eq + n_in; ++
j) {
1582 proxsuite::linalg::veg::from_raw_parts,
1588 ldl = rank1_update(ldl, etree, perm_inv,
w, alpha, stack);
1610 precond.unscale_dual_residual_in_place({ proxqp::from_eigen,
tmp });
1612 precond.unscale_primal_in_place({ proxqp::from_eigen,
x_e });
1613 precond.unscale_dual_in_place_eq({ proxqp::from_eigen,
y_e });
1614 precond.unscale_dual_in_place_in({ proxqp::from_eigen,
z_e });
1620 results.
info.solve_time = work.
timer.elapsed().user;
1621 results.
info.run_time = results.
info.solve_time + results.
info.setup_time;
1624 std::cout <<
"-------------------SOLVER STATISTICS-------------------"
1626 std::cout <<
"outer iter: " << results.
info.iter_ext << std::endl;
1627 std::cout <<
"total iter: " << results.
info.iter << std::endl;
1628 std::cout <<
"mu updates: " << results.
info.mu_updates << std::endl;
1629 std::cout <<
"rho updates: " << results.
info.rho_updates << std::endl;
1630 std::cout <<
"objective: " << results.
info.objValue << std::endl;
1631 switch (results.
info.status) {
1633 std::cout <<
"status: "
1634 <<
"Solved" << std::endl;
1638 std::cout <<
"status: "
1639 <<
"Maximum number of iterations reached" << std::endl;
1643 std::cout <<
"status: "
1644 <<
"Primal infeasible" << std::endl;
1648 std::cout <<
"status: "
1649 <<
"Dual infeasible" << std::endl;
1653 std::cout <<
"status: "
1654 <<
"Solved closest primal feasible" << std::endl;
1658 std::cout <<
"status: "
1659 <<
"Solver not run" << std::endl;
1664 std::cout <<
"run time [μs]: " << results.
info.solve_time << std::endl;
1665 std::cout <<
"--------------------------------------------------------"
1671 assert(!std::isnan(results.
info.duality_gap));
auto unscaled_primal_dual_residual(Workspace< T, I > &work, Results< T > &results, const Settings< T > &settings, VecMapMut< T > primal_residual_eq_scaled, VecMapMut< T > primal_residual_in_scaled_lo, VecMapMut< T > primal_residual_in_scaled_up, VecMapMut< T > dual_residual_scaled, T &primal_feasibility_eq_rhs_0, T &primal_feasibility_in_rhs_0, T &dual_feasibility_rhs_0, T &dual_feasibility_rhs_1, T &dual_feasibility_rhs_3, T &rhs_duality_gap, const P &precond, Model< T, I > const &data, const QpView< T, I > qp_scaled, VecMapMut< T > x_e, VecMapMut< T > y_e, VecMapMut< T > z_e, proxsuite::linalg::veg::dynstack::DynStackMut stack) -> proxsuite::linalg::veg::Tuple< T, T >
void ldl_iter_solve_noalias(VectorViewMut< T > sol, VectorView< T > rhs, VectorView< T > init_guess, Results< T > const &results, Model< T, I > const &data, isize n_tot, proxsuite::linalg::sparse::MatMut< T, I > ldl, Eigen::MINRES< detail::AugmentedKkt< T, I >, Eigen::Upper|Eigen::Lower, Eigen::IdentityPreconditioner > &iterative_solver, bool do_ldlt, proxsuite::linalg::veg::dynstack::DynStackMut stack, T *ldl_values, I *perm, I *ldl_col_ptrs, I const *perm_inv, Settings< T > const &settings, proxsuite::linalg::sparse::MatMut< T, I > kkt_active, proxsuite::linalg::veg::SliceMut< bool > active_constraints)
void ldl_solve_in_place(VectorViewMut< T > rhs, VectorView< T > init_guess, Results< T > const &results, Model< T, I > const &data, isize n_tot, proxsuite::linalg::sparse::MatMut< T, I > ldl, Eigen::MINRES< detail::AugmentedKkt< T, I >, Eigen::Upper|Eigen::Lower, Eigen::IdentityPreconditioner > &iterative_solver, bool do_ldlt, proxsuite::linalg::veg::dynstack::DynStackMut stack, T *ldl_values, I *perm, I *ldl_col_ptrs, I const *perm_inv, Settings< T > const &settings, proxsuite::linalg::sparse::MatMut< T, I > kkt_active, proxsuite::linalg::veg::SliceMut< bool > active_constraints)