8#ifndef PROXSUITE_PROXQP_DENSE_WRAPPER_HPP
9#define PROXSUITE_PROXQP_DENSE_WRAPPER_HPP
90 isize n_constraints(n_in);
91 if (box_constraints) {
96 T PrimalDualLDLTCost =
97 0.5 * std::pow(T(n_eq) / T(dim), 2) +
98 0.17 * (std::pow(T(n_eq) / T(dim), 3) +
99 std::pow(T(n_constraints) / T(dim), 3)) +
100 frequence * std::pow(T(n_eq + n_constraints) / T(dim), 2) / T(dim);
103 ((0.5 * T(n_eq) + T(n_constraints)) / T(dim) + frequence / T(dim));
104 bool choice = PrimalDualLDLTCost > PrimalLDLTCost;
111 return _dense_backend;
121 bool box_constraints;
143 bool _box_constraints,
151 , box_constraints(_box_constraints)
152 , hessian_type(_hessian_type)
153 ,
results(_dim, _n_eq, _n_in, _box_constraints, dense_backend)
155 ,
model(_dim, _n_eq, _n_in, _box_constraints)
156 ,
work(_dim, _n_eq, _n_in, _box_constraints, dense_backend)
157 ,
ruiz(preconditioner::RuizEquilibration<T>{ _dim,
176 bool _box_constraints,
184 , box_constraints(_box_constraints)
185 , hessian_type(_hessian_type)
186 ,
results(_dim, _n_eq, _n_in, _box_constraints, dense_backend)
188 ,
model(_dim, _n_eq, _n_in, _box_constraints)
189 ,
work(_dim, _n_eq, _n_in, _box_constraints, dense_backend)
190 ,
ruiz(preconditioner::RuizEquilibration<T>{ _dim,
208 bool _box_constraints,
215 , box_constraints(_box_constraints)
216 , hessian_type(_hessian_type)
217 ,
results(_dim, _n_eq, _n_in, _box_constraints, dense_backend)
219 ,
model(_dim, _n_eq, _n_in, _box_constraints)
220 ,
work(_dim, _n_eq, _n_in, _box_constraints, dense_backend)
221 ,
ruiz(preconditioner::RuizEquilibration<T>{ _dim,
240 bool _box_constraints,
247 , box_constraints(_box_constraints)
249 ,
results(_dim, _n_eq, _n_in, _box_constraints, dense_backend)
251 ,
model(_dim, _n_eq, _n_in, _box_constraints)
252 ,
work(_dim, _n_eq, _n_in, _box_constraints, dense_backend)
253 ,
ruiz(preconditioner::RuizEquilibration<T>{ _dim,
267 QP(isize _dim, isize _n_eq, isize _n_in,
bool _box_constraints)
273 , box_constraints(_box_constraints)
275 ,
results(_dim, _n_eq, _n_in, _box_constraints, dense_backend)
277 ,
model(_dim, _n_eq, _n_in, _box_constraints)
278 ,
work(_dim, _n_eq, _n_in, _box_constraints, dense_backend)
279 ,
ruiz(preconditioner::RuizEquilibration<T>{ _dim,
302 , box_constraints(false)
303 , hessian_type(_hessian_type)
304 ,
results(_dim, _n_eq, _n_in, false, dense_backend)
306 ,
model(_dim, _n_eq, _n_in, false)
307 ,
work(_dim, _n_eq, _n_in, false, dense_backend)
308 ,
ruiz(preconditioner::RuizEquilibration<T>{ _dim, _n_eq, _n_in,
false })
318 QP(isize _dim, isize _n_eq, isize _n_in)
324 , box_constraints(false)
326 ,
results(_dim, _n_eq, _n_in, false, dense_backend)
328 ,
model(_dim, _n_eq, _n_in, false)
329 ,
work(_dim, _n_eq, _n_in, false, dense_backend)
330 ,
ruiz(preconditioner::RuizEquilibration<T>{ _dim, _n_eq, _n_in,
false })
361 bool compute_preconditioner =
true,
368 box_constraints ==
true,
369 std::invalid_argument,
370 "wrong model setup: the QP object is designed with box "
371 "constraints, but is initialized without lower or upper box "
378 settings.compute_preconditioner = compute_preconditioner;
380 if (g !=
nullopt && g.value().size() != 0) {
384 "the dimension wrt the primal variable x variable for initializing g "
389 if (b !=
nullopt && b.value().size() != 0) {
393 "the dimension wrt equality constrained variables for initializing b "
398 if (u !=
nullopt && u.value().size() != 0) {
402 "the dimension wrt inequality constrained variables for initializing u "
407 if (l !=
nullopt && l.value().size() != 0) {
411 "the dimension wrt inequality constrained variables for initializing l "
416 if (H !=
nullopt && H.value().size() != 0) {
420 "the row dimension for initializing H is not valid.");
424 "the column dimension for initializing H is not valid.");
428 if (A !=
nullopt && A.value().size() != 0) {
432 "the row dimension for initializing A is not valid.");
436 "the column dimension for initializing A is not valid.");
440 if (C !=
nullopt && C.value().size() != 0) {
444 "the row dimension for initializing C is not valid.");
448 "the column dimension for initializing C is not valid.");
458 work.refactorize =
false;
460 work.proximal_parameter_update =
false;
466 if (compute_preconditioner) {
492 preconditioner_status,
494 work.is_initialized =
true;
496 results.info.setup_time =
work.timer.elapsed().user;
529 bool compute_preconditioner =
true,
541 settings.compute_preconditioner = compute_preconditioner;
543 box_constraints ==
false && (l_box !=
nullopt || u_box !=
nullopt),
544 std::invalid_argument,
545 "wrong model setup: the QP object is designed without box "
546 "constraints, but is initialized with lower or upper box inequalities.");
547 if (l_box !=
nullopt && l_box.value().size() != 0) {
550 "the dimension wrt the primal variable x "
551 "variable for initializing l_box "
556 if (u_box !=
nullopt && u_box.value().size() != 0) {
559 "the dimension wrt the primal variable x "
560 "variable for initializing u_box "
566 if (g !=
nullopt && g.value().size() != 0) {
570 "the dimension wrt the primal variable x variable for initializing g "
575 if (b !=
nullopt && b.value().size() != 0) {
579 "the dimension wrt equality constrained variables for initializing b "
584 if (u !=
nullopt && u.value().size() != 0) {
588 "the dimension wrt inequality constrained variables for initializing u "
593 if (u_box !=
nullopt && u_box.value().size() != 0) {
595 u_box.value().size(),
597 "the dimension wrt box inequality constrained variables for "
598 "initializing u_box "
603 if (l !=
nullopt && l.value().size() != 0) {
607 "the dimension wrt inequality constrained variables for initializing l "
612 if (l_box !=
nullopt && l_box.value().size() != 0) {
614 l_box.value().size(),
616 "the dimension wrt box inequality constrained variables for "
617 "initializing l_box "
622 if (H !=
nullopt && H.value().size() != 0) {
626 "the row dimension for initializing H is not valid.");
630 "the column dimension for initializing H is not valid.");
634 if (A !=
nullopt && A.value().size() != 0) {
638 "the row dimension for initializing A is not valid.");
642 "the column dimension for initializing A is not valid.");
646 if (C !=
nullopt && C.value().size() != 0) {
650 "the row dimension for initializing C is not valid.");
654 "the column dimension for initializing C is not valid.");
664 work.refactorize =
false;
666 work.proximal_parameter_update =
false;
672 if (compute_preconditioner) {
697 preconditioner_status,
699 work.is_initialized =
true;
701 results.info.setup_time =
work.timer.elapsed().user;
730 bool update_preconditioner =
false,
737 box_constraints ==
true,
738 std::invalid_argument,
739 "wrong model setup: the QP object is designed without box "
740 "constraints, but the update does not include lower or upper box "
742 settings.update_preconditioner = update_preconditioner;
743 if (!
work.is_initialized) {
744 init(H, g, A, b, C, l, u, update_preconditioner, rho, mu_eq, mu_in);
748 work.refactorize =
false;
749 work.proximal_parameter_update =
false;
755 if (update_preconditioner) {
760 const bool matrix_update =
801 preconditioner_status,
805 results.info.setup_time =
work.timer.elapsed().user;
840 bool update_preconditioner =
false,
847 box_constraints ==
false && (l_box !=
nullopt || u_box !=
nullopt),
848 std::invalid_argument,
849 "wrong model setup: the QP object is designed without box "
850 "constraints, but the update includes lower or upper box inequalities.");
851 settings.update_preconditioner = update_preconditioner;
852 if (!
work.is_initialized) {
862 update_preconditioner,
869 work.refactorize =
false;
870 work.proximal_parameter_update =
false;
876 if (update_preconditioner) {
881 const bool matrix_update =
887 H, g, A, b, C, l, u, l_box, u_box,
model,
work, box_constraints);
912 preconditioner_status,
916 results.info.setup_time =
work.timer.elapsed().user;
961 work.cleanup(box_constraints);
1019 bool compute_preconditioner =
true,
1020 bool compute_timings =
false,
1024 bool check_duality_gap =
false,
1027 bool primal_infeasibility_solving =
false,
1034 n = H.value().rows();
1037 n_eq = A.value().rows();
1040 n_in = C.value().rows();
1045 Qp.
settings.check_duality_gap = check_duality_gap;
1048 Qp.
settings.eps_abs = eps_abs.value();
1051 Qp.
settings.eps_rel = eps_rel.value();
1054 Qp.
settings.verbose = verbose.value();
1057 Qp.
settings.max_iter = max_iter.value();
1059 if (eps_duality_gap_abs !=
nullopt) {
1060 Qp.
settings.eps_duality_gap_abs = eps_duality_gap_abs.value();
1062 if (eps_duality_gap_rel !=
nullopt) {
1063 Qp.
settings.eps_duality_gap_rel = eps_duality_gap_rel.value();
1065 Qp.
settings.compute_timings = compute_timings;
1066 Qp.
settings.primal_infeasibility_solving = primal_infeasibility_solving;
1067 if (manual_minimal_H_eigenvalue !=
nullopt) {
1075 compute_preconditioner,
1079 manual_minimal_H_eigenvalue.value());
1082 H, g, A, b, C, l, u, compute_preconditioner, rho, mu_eq, mu_in,
nullopt);
1151 bool compute_preconditioner =
true,
1152 bool compute_timings =
false,
1156 bool check_duality_gap =
false,
1159 bool primal_infeasibility_solving =
false,
1166 n = H.value().rows();
1169 n_eq = A.value().rows();
1172 n_in = C.value().rows();
1177 Qp.
settings.check_duality_gap = check_duality_gap;
1180 Qp.
settings.eps_abs = eps_abs.value();
1183 Qp.
settings.eps_rel = eps_rel.value();
1186 Qp.
settings.verbose = verbose.value();
1189 Qp.
settings.max_iter = max_iter.value();
1191 if (eps_duality_gap_abs !=
nullopt) {
1192 Qp.
settings.eps_duality_gap_abs = eps_duality_gap_abs.value();
1194 if (eps_duality_gap_rel !=
nullopt) {
1195 Qp.
settings.eps_duality_gap_rel = eps_duality_gap_rel.value();
1197 Qp.
settings.compute_timings = compute_timings;
1198 Qp.
settings.primal_infeasibility_solving = primal_infeasibility_solving;
1199 if (manual_minimal_H_eigenvalue !=
nullopt) {
1209 compute_preconditioner,
1213 manual_minimal_H_eigenvalue.value());
1224 compute_preconditioner,
1249 return !(qp1 == qp2);
1265 if (
qp_vector.max_size() != batch_size) {
1279 qp_vector.emplace_back(dim, n_eq, n_in);
#define PROXSUITE_CHECK_ARGUMENT_SIZE(size, expected_size, message)
#define PROXSUITE_THROW_PRETTY(condition, exception, message)
void warm_start(optional< VecRef< T > > x_wm, optional< VecRef< T > > y_wm, optional< VecRef< T > > z_wm, Results< T > &results, Settings< T > &settings, Model< T > &model)
void initial_guess(Workspace< T > &qpwork, Settings< T > &qpsettings, Model< T > &qpmodel, Results< T > &qpresults)
Eigen::Ref< Mat< T, l > const > MatRef
DenseBackend dense_backend_choice(DenseBackend _dense_backend, isize dim, isize n_eq, isize n_in, bool box_constraints)
This class defines the API of PROXQP solver with dense backend.
bool operator==(const Model< T > &model1, const Model< T > &model2)
proxqp::Results< T > solve(optional< MatRef< T > > H, optional< VecRef< T > > g, optional< MatRef< T > > A, optional< VecRef< T > > b, optional< MatRef< T > > C, optional< VecRef< T > > l, optional< VecRef< T > > u, optional< VecRef< T > > x=nullopt, optional< VecRef< T > > y=nullopt, optional< VecRef< T > > z=nullopt, optional< T > eps_abs=nullopt, optional< T > eps_rel=nullopt, optional< T > rho=nullopt, optional< T > mu_eq=nullopt, optional< T > mu_in=nullopt, optional< bool > verbose=nullopt, bool compute_preconditioner=true, bool compute_timings=false, optional< isize > max_iter=nullopt, proxsuite::proxqp::InitialGuessStatus initial_guess=proxsuite::proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS, bool check_duality_gap=false, optional< T > eps_duality_gap_abs=nullopt, optional< T > eps_duality_gap_rel=nullopt, bool primal_infeasibility_solving=false, optional< T > manual_minimal_H_eigenvalue=nullopt)
void qp_solve(const Settings< T > &qpsettings, const Model< T > &qpmodel, Results< T > &qpresults, Workspace< T > &qpwork, const bool box_constraints, const DenseBackend &dense_backend, const HessianType &hessian_type, preconditioner::RuizEquilibration< T > &ruiz)
void update_proximal_parameters(Settings< T > &settings, Results< T > &results, Workspace< T > &work, optional< T > rho_new, optional< T > mu_eq_new, optional< T > mu_in_new)
void update_default_rho_with_minimal_Hessian_eigen_value(optional< T > manual_minimal_H_eigenvalue, Results< T > &results, Settings< T > &settings)
void setup(optional< MatRef< T > > H, optional< VecRef< T > > g, optional< MatRef< T > > A, optional< VecRef< T > > b, optional< MatRef< T > > C, optional< VecRef< T > > l, optional< VecRef< T > > u, optional< VecRef< T > > l_box, optional< VecRef< T > > u_box, Settings< T > &qpsettings, Model< T > &qpmodel, Workspace< T > &qpwork, Results< T > &qpresults, const bool box_constraints, preconditioner::RuizEquilibration< T > &ruiz, PreconditionerStatus preconditioner_status, const HessianType hessian_type)
void update(optional< MatRef< T > > H, optional< VecRef< T > > g, optional< MatRef< T > > A, optional< VecRef< T > > b, optional< MatRef< T > > C, optional< VecRef< T > > l, optional< VecRef< T > > u, optional< VecRef< T > > l_box, optional< VecRef< T > > u_box, Model< T > &model, Workspace< T > &work, const bool box_constraints)
Eigen::Ref< Vec< T > const > VecRef
bool operator!=(const Model< T > &model1, const Model< T > &model2)
@ EQUALITY_CONSTRAINED_INITIAL_GUESS
@ WARM_START_WITH_PREVIOUS_RESULT
constexpr nullopt_t nullopt
This class stores all the results of PROXQP solvers with sparse and dense backends.
This class defines the settings of PROXQP solvers with sparse and dense backends.
QP< T > & init_qp_in_place(dense::isize dim, dense::isize n_eq, dense::isize n_in)
std::vector< QP< T > > qp_vector
const QP< T > & operator[](isize i) const
BatchQP(size_t batch_size)
void insert(const QP< T > &qp)
QP< T > & operator[](isize i)
const QP< T > & get(isize i) const
This class stores the model of the QP problem.
HessianType which_hessian_type() const
DenseBackend which_dense_backend() const
QP(isize _dim, isize _n_eq, isize _n_in, bool _box_constraints)
void update(optional< MatRef< T > > H, optional< VecRef< T > > g, optional< MatRef< T > > A, optional< VecRef< T > > b, optional< MatRef< T > > C, optional< VecRef< T > > l, optional< VecRef< T > > u, optional< VecRef< T > > l_box, optional< VecRef< T > > u_box, bool update_preconditioner=false, optional< T > rho=nullopt, optional< T > mu_eq=nullopt, optional< T > mu_in=nullopt, optional< T > manual_minimal_H_eigenvalue=nullopt)
QP(isize _dim, isize _n_eq, isize _n_in, bool _box_constraints, proxsuite::proxqp::HessianType _hessian_type, DenseBackend _dense_backend)
void solve(optional< VecRef< T > > x, optional< VecRef< T > > y, optional< VecRef< T > > z)
QP(isize _dim, isize _n_eq, isize _n_in, bool _box_constraints, DenseBackend _dense_backend, proxsuite::proxqp::HessianType _hessian_type)
QP(isize _dim, isize _n_eq, isize _n_in, bool _box_constraints, proxsuite::proxqp::HessianType _hessian_type)
void update(optional< MatRef< T > > H, optional< VecRef< T > > g, optional< MatRef< T > > A, optional< VecRef< T > > b, optional< MatRef< T > > C, optional< VecRef< T > > l, optional< VecRef< T > > u, bool update_preconditioner=false, optional< T > rho=nullopt, optional< T > mu_eq=nullopt, optional< T > mu_in=nullopt, optional< T > manual_minimal_H_eigenvalue=nullopt)
QP(isize _dim, isize _n_eq, isize _n_in)
QP(isize _dim, isize _n_eq, isize _n_in, bool _box_constraints, DenseBackend _dense_backend)
bool is_box_constrained() const
void init(optional< MatRef< T > > H, optional< VecRef< T > > g, optional< MatRef< T > > A, optional< VecRef< T > > b, optional< MatRef< T > > C, optional< VecRef< T > > l, optional< VecRef< T > > u, optional< VecRef< T > > l_box, optional< VecRef< T > > u_box, bool compute_preconditioner=true, optional< T > rho=nullopt, optional< T > mu_eq=nullopt, optional< T > mu_in=nullopt, optional< T > manual_minimal_H_eigenvalue=nullopt)
QP(isize _dim, isize _n_eq, isize _n_in, proxsuite::proxqp::HessianType _hessian_type)
preconditioner::RuizEquilibration< T > ruiz
void init(optional< MatRef< T > > H, optional< VecRef< T > > g, optional< MatRef< T > > A, optional< VecRef< T > > b, optional< MatRef< T > > C, optional< VecRef< T > > l, optional< VecRef< T > > u, bool compute_preconditioner=true, optional< T > rho=nullopt, optional< T > mu_eq=nullopt, optional< T > mu_in=nullopt, optional< T > manual_minimal_H_eigenvalue=nullopt)
This class defines the workspace of the dense solver.