8#ifndef PROXSUITE_PROXQP_SPARSE_WRAPPER_HPP
9#define PROXSUITE_PROXQP_SPARSE_WRAPPER_HPP
89template<
typename T,
typename I>
103 QP(isize dim, isize n_eq, isize n_in)
106 ,
model(dim, n_eq, n_in)
108 ,
ruiz(dim, n_eq + n_in, 1e-3, 10, preconditioner::
Symmetry::UPPER)
111 work.internal.do_symbolic_fact =
true;
112 work.internal.is_initialized =
false;
125 :
QP(H.rows(), A.rows(), C.rows())
143 work.setup_symbolic_factorizaton(
144 model, Href.symbolic(), ATref.symbolic(), CTref.symbolic());
146 results.info.setup_time =
work.timer.elapsed().user;
172 bool compute_preconditioner_ =
true,
182 if (g !=
nullopt && g.value().size() != 0) {
186 "the dimension wrt the primal variable x variable for initializing g "
191 if (b !=
nullopt && b.value().size() != 0) {
195 "the dimension wrt equality constrained variables for initializing b "
200 if (u !=
nullopt && u.value().size() != 0) {
204 "the dimension wrt inequality constrained variables for initializing u "
209 if (l !=
nullopt && l.value().size() != 0) {
213 "the dimension wrt inequality constrained variables for initializing l "
218 if (H !=
nullopt && H.value().size() != 0) {
222 "the row dimension for initializing H is not valid.");
226 "the column dimension for initializing H is not valid.");
230 if (A !=
nullopt && A.value().size() != 0) {
234 "the row dimension for initializing A is not valid.");
238 "the column dimension for initializing A is not valid.");
242 if (C !=
nullopt && C.value().size() != 0) {
246 "the row dimension for initializing C is not valid.");
250 "the column dimension for initializing C is not valid.");
254 work.internal.proximal_parameter_update =
false;
256 if (compute_preconditioner_) {
284 AT = (A.value()).transpose();
290 CT = (C.value()).transpose();
296 (H.value()).
template triangularView<Eigen::Upper>();
314 H_triu = (H.value()).
template triangularView<Eigen::Upper>();
326 work.internal.is_initialized =
true;
329 results.info.setup_time +=
work.timer.elapsed().user;
359 bool update_preconditioner =
false,
365 if (!
work.internal.is_initialized) {
366 init(H, g, A, b, C, l, u, update_preconditioner, rho, mu_eq, mu_in);
373 work.internal.dirty =
false;
374 work.internal.proximal_parameter_update =
false;
376 if (update_preconditioner) {
382 isize n_eq =
model.n_eq;
383 isize n_in =
model.n_in;
385 model.kkt_mut_unscaled();
388 proxsuite::linalg::veg::unsafe, kkt_unscaled, n);
403 "the dimension wrt the primal variable x "
404 "variable for updating g is not valid.");
409 "the dimension wrt equality constrained "
410 "variables for updating b is not valid.");
415 "the dimension wrt inequality constrained "
416 "variables for updating u is not valid.");
421 "the dimension wrt inequality constrained "
422 "variables for updating l is not valid.");
428 "the row dimension for updating H is not valid.");
432 "the column dimension for updating H is not valid.");
438 "the row dimension for updating A is not valid.");
442 "the column dimension for updating A is not valid.");
448 "the row dimension for updating C is not valid.");
452 "the column dimension for updating C is not valid.");
471 H.value().template triangularView<Eigen::Upper>();
476 H_unscaled.as_const(),
477 { proxsuite::linalg::sparse::from_eigen, H_triu }) &&
479 { proxsuite::linalg::sparse::from_eigen,
480 SparseMat<T, I>(A.value().transpose()) }) &&
482 { proxsuite::linalg::sparse::from_eigen,
483 SparseMat<T, I>(C.value().transpose()) });
503 H_unscaled.as_const(),
504 { proxsuite::linalg::sparse::from_eigen, H_triu }) &&
506 { proxsuite::linalg::sparse::from_eigen,
507 SparseMat<T, I>(A.value().transpose()) });
524 H_unscaled.as_const(),
525 { proxsuite::linalg::sparse::from_eigen, H_triu }) &&
527 { proxsuite::linalg::sparse::from_eigen,
528 SparseMat<T, I>(C.value().transpose()) });
543 H_unscaled.as_const(),
544 { proxsuite::linalg::sparse::from_eigen, H_triu });
558 { proxsuite::linalg::sparse::from_eigen,
559 SparseMat<T, I>(A.value().transpose()) }) &&
561 { proxsuite::linalg::sparse::from_eigen,
562 SparseMat<T, I>(C.value().transpose()) });
577 { proxsuite::linalg::sparse::from_eigen,
578 SparseMat<T, I>(A.value().transpose()) });
591 { proxsuite::linalg::sparse::from_eigen,
592 SparseMat<T, I>(C.value().transpose()) });
604 H_unscaled.to_eigen().template triangularView<Eigen::Upper>();
622 preconditioner_status);
630 results.info.setup_time =
work.timer.elapsed().user;
705template<
typename T,
typename I>
724 bool compute_preconditioner =
true,
725 bool compute_timings =
false,
731 bool check_duality_gap =
false,
734 bool primal_infeasibility_solving =
false,
742 n = H.value().rows();
745 n_eq = A.value().rows();
748 n_in = C.value().rows();
752 Qp.
settings.initial_guess = initial_guess;
753 Qp.
settings.check_duality_gap = check_duality_gap;
756 Qp.
settings.eps_abs = eps_abs.value();
759 Qp.
settings.eps_rel = eps_rel.value();
762 Qp.
settings.verbose = verbose.value();
765 Qp.
settings.max_iter = max_iter.value();
767 if (eps_duality_gap_abs !=
nullopt) {
768 Qp.
settings.eps_duality_gap_abs = eps_duality_gap_abs.value();
770 if (eps_duality_gap_rel !=
nullopt) {
771 Qp.
settings.eps_duality_gap_rel = eps_duality_gap_rel.value();
773 Qp.
settings.compute_timings = compute_timings;
774 Qp.
settings.sparse_backend = sparse_backend;
775 Qp.
settings.primal_infeasibility_solving = primal_infeasibility_solving;
776 if (manual_minimal_H_eigenvalue !=
nullopt) {
784 compute_preconditioner,
788 manual_minimal_H_eigenvalue.value());
791 H, g, A, b, C, l, u, compute_preconditioner, rho, mu_eq, mu_in,
nullopt);
799template<
typename T,
typename I>
#define PROXSUITE_CHECK_ARGUMENT_SIZE(size, expected_size, message)
auto middle_cols_mut(proxsuite::linalg::sparse::MatMut< T, I > mat, isize start, isize ncols, isize nnz) -> proxsuite::linalg::sparse::MatMut< T, I >
auto top_rows_mut_unchecked(proxsuite::linalg::veg::Unsafe, proxsuite::linalg::sparse::MatMut< T, I > mat, isize nrows) -> proxsuite::linalg::sparse::MatMut< T, I >
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, I > &model)
void update_proximal_parameters(Settings< T > &settings, Results< T > &results, Workspace< T, I > &work, optional< T > rho_new, optional< T > mu_eq_new, optional< T > mu_in_new)
void qp_solve(Results< T > &results, Model< T, I > &data, const Settings< T > &settings, Workspace< T, I > &work, P &precond)
Eigen::SparseMatrix< T, Eigen::ColMajor, I > SparseMat
proxqp::Results< T > solve(optional< SparseMat< T, I > > H, optional< VecRef< T > > g, optional< SparseMat< T, I > > A, optional< VecRef< T > > b, optional< SparseMat< T, I > > 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, proxsuite::proxqp::SparseBackend sparse_backend=proxsuite::proxqp::SparseBackend::Automatic, 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 copy(proxsuite::linalg::sparse::MatMut< T, I > a, proxsuite::linalg::sparse::MatRef< T, I > b)
Eigen::Ref< Eigen::Matrix< T, DYN, 1 > const > VecRef
auto have_same_structure(proxsuite::linalg::sparse::MatRef< T, I > a, proxsuite::linalg::sparse::MatRef< T, I > b) -> bool
void qp_setup(QpView< T, I > qp, Results< T > &results, Model< T, I > &data, Workspace< T, I > &work, Settings< T > &settings, P &precond, PreconditionerStatus &preconditioner_status)
void update_default_rho_with_minimal_Hessian_eigen_value(optional< T > manual_minimal_H_eigenvalue, Results< T > &results, Settings< T > &settings)
@ EQUALITY_CONSTRAINED_INITIAL_GUESS
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.
std::vector< QP< T, I > > qp_vector
void insert(QP< T, I > &qp)
QP< T, I > & operator[](isize i)
QP< T, I > & init_qp_in_place(sparse::isize dim, sparse::isize n_eq, sparse::isize n_in)
QP< T, I > & get(isize i)
const QP< T, I > & operator[](isize i) const
const QP< T, I > & get(isize i) const
BatchQP(long unsigned int batchSize)
This class stores the model of the QP problem.
This class defines the API of PROXQP solver with sparse backend.
QP(const SparseMat< bool, I > &H, const SparseMat< bool, I > &A, const SparseMat< bool, I > &C)
void solve(optional< VecRef< T > > x, optional< VecRef< T > > y, optional< VecRef< T > > z)
void update(const optional< SparseMat< T, I > > H, optional< VecRef< T > > g, const optional< SparseMat< T, I > > A, optional< VecRef< T > > b, const optional< SparseMat< T, I > > 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)
void init(optional< SparseMat< T, I > > H, optional< VecRef< T > > g, optional< SparseMat< T, I > > A, optional< VecRef< T > > b, optional< SparseMat< T, I > > 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)
QP(isize dim, isize n_eq, isize n_in)
preconditioner::RuizEquilibration< T, I > ruiz
This class defines the workspace of the sparse solver.