8#ifndef PROXSUITE_PROXQP_DENSE_COMPUTE_ECJ_HPP
9#define PROXSUITE_PROXQP_DENSE_COMPUTE_ECJ_HPP
42 std::invalid_argument,
43 "the QP problem is not feasible, so computing the derivatives "
44 "is not valid in this setting. Try enabling infeasible solving if "
45 "the problem is only primally infeasible.");
47 solved_qp.
model.backward_data.initialize(
51 solved_qp.
work.CTz.noalias() =
53 solved_qp.
work.active_set_up.array() =
54 (solved_qp.
work.CTz - solved_qp.
model.u).array() >= 0.;
55 solved_qp.
work.active_set_low.array() =
56 (solved_qp.
work.CTz - solved_qp.
model.l).array() <= 0.;
57 solved_qp.
work.active_inequalities =
58 solved_qp.
work.active_set_up || solved_qp.
work.active_set_low;
59 isize numactive_inequalities = solved_qp.
work.active_inequalities.count();
61 solved_qp.
model.dim + solved_qp.
model.n_eq + numactive_inequalities;
62 solved_qp.
work.rhs.setZero();
64 solved_qp.
results.info.rho = rho_new;
65 solved_qp.
results.info.mu_eq = mu_new;
66 solved_qp.
results.info.mu_in = mu_new;
78 solved_qp.
work.n_c = 0;
79 for (isize i = 0; i < solved_qp.
model.n_in; i++) {
80 solved_qp.
work.current_bijection_map(i) = i;
81 solved_qp.
work.new_bijection_map(i) = i;
88 solved_qp.
work.constraints_changed =
false;
90 solved_qp.
work.rhs = -loss_derivative;
92 from_eigen, solved_qp.
work.rhs.head(solved_qp.
model.dim) });
93 if (!solved_qp.
work.rhs.segment(solved_qp.
model.dim, solved_qp.
model.n_eq)
95 solved_qp.
work.rhs.segment(solved_qp.
model.dim, solved_qp.
model.n_eq) =
96 -loss_derivative.segment(solved_qp.
model.dim, solved_qp.
model.n_eq);
97 solved_qp.
ruiz.scale_primal_residual_in_place_eq(
99 solved_qp.
work.rhs.segment(solved_qp.
model.dim,
100 solved_qp.
model.n_eq) });
102 if (!solved_qp.
work.rhs.tail(solved_qp.
model.n_in).isZero()) {
103 for (isize i = 0; i < solved_qp.
model.n_in; i++) {
104 isize j = solved_qp.
work.current_bijection_map(i);
105 if (j < solved_qp.
work.n_c) {
106 solved_qp.
work.rhs(j + solved_qp.
model.dim + solved_qp.
model.n_eq) =
107 -loss_derivative(i + solved_qp.
model.dim + solved_qp.
model.n_eq);
110 from_eigen, solved_qp.
work.rhs.tail(solved_qp.
model.n_in) });
118 solved_qp.
model.n_in,
132 solved_qp.
work.active_part_z.setZero();
133 for (isize j = 0; j < solved_qp.
model.n_in; ++j) {
134 isize i = solved_qp.
work.current_bijection_map(j);
135 if (i < solved_qp.
work.n_c) {
136 solved_qp.
work.active_part_z(j) =
137 solved_qp.
work.dw_aug(solved_qp.
model.dim + solved_qp.
model.n_eq + i);
139 solved_qp.
work.active_part_z(j) =
140 loss_derivative(solved_qp.
model.dim + solved_qp.
model.n_eq + i);
143 solved_qp.
work.dw_aug.tail(solved_qp.
model.n_in) =
144 solved_qp.
work.active_part_z;
146 from_eigen, solved_qp.
work.dw_aug.head(solved_qp.
model.dim) });
149 solved_qp.
work.dw_aug.segment(solved_qp.
model.dim, solved_qp.
model.n_eq) });
151 from_eigen, solved_qp.
work.dw_aug.tail(solved_qp.
model.n_in) });
154 solved_qp.
model.backward_data.dL_dC.noalias() =
155 solved_qp.
work.dw_aug.tail(solved_qp.
model.n_in) *
156 solved_qp.
results.x.transpose();
157 solved_qp.
model.backward_data.dL_dC.noalias() +=
159 solved_qp.
work.dw_aug.head(solved_qp.
model.dim).transpose();
161 solved_qp.
model.backward_data.dL_du =
162 (solved_qp.
work.active_set_up)
163 .select(-solved_qp.
work.dw_aug.tail(solved_qp.
model.n_in),
164 Eigen::Matrix<T, Eigen::Dynamic, 1>::Zero(solved_qp.
model.n_in));
166 solved_qp.
model.backward_data.dL_dl =
167 (solved_qp.
work.active_set_low)
168 .select(-solved_qp.
work.dw_aug.tail(solved_qp.
model.n_in),
169 Eigen::Matrix<T, Eigen::Dynamic, 1>::Zero(solved_qp.
model.n_in));
171 solved_qp.
model.backward_data.dL_dA.noalias() =
172 solved_qp.
work.dw_aug.segment(solved_qp.
model.dim, solved_qp.
model.n_eq) *
173 solved_qp.
results.x.transpose();
174 solved_qp.
model.backward_data.dL_dA.noalias() +=
176 solved_qp.
work.dw_aug.head(solved_qp.
model.dim).transpose();
178 solved_qp.
model.backward_data.dL_db =
179 -solved_qp.
work.dw_aug.segment(solved_qp.
model.dim, solved_qp.
model.n_eq);
180 solved_qp.
model.backward_data.dL_dH.noalias() =
181 0.5 * (solved_qp.
work.dw_aug.head(solved_qp.
model.dim) *
182 solved_qp.
results.x.transpose() +
184 solved_qp.
work.dw_aug.head(solved_qp.
model.dim).transpose());
186 solved_qp.
model.backward_data.dL_dg =
187 solved_qp.
work.dw_aug.head(solved_qp.
model.dim);
#define PROXSUITE_THROW_PRETTY(condition, exception, message)
void active_set_change(const Model< T > &qpmodel, Results< T > &qpresults, const DenseBackend &dense_backend, const isize n_constraints, Workspace< T > &qpwork)
void setup_factorization(Workspace< T > &qpwork, const Model< T > &qpmodel, Results< T > &qpresults, const DenseBackend &dense_backend, const HessianType &hessian_type)
void iterative_solve_with_permut_fact(const Settings< T > &qpsettings, const Model< T > &qpmodel, Results< T > &qpresults, Workspace< T > &qpwork, const isize n_constraints, const DenseBackend &dense_backend, const HessianType &hessian_type, T eps, isize inner_pb_dim)
void compute_backward_loss_ESG(dense::QP< T > &solved_qp, VecRef< T > loss_derivative)
void compute_backward(dense::QP< T > &solved_qp, VecRef< T > loss_derivative, T eps=1.E-4, T rho_new=1.E-6, T mu_new=1.E-6)
Eigen::Ref< Vec< T > const > VecRef
HessianType which_hessian_type() const
DenseBackend which_dense_backend() const
preconditioner::RuizEquilibration< T > ruiz