Skip to content

Commit 6cf6510

Browse files
authored
Merge pull request #36 from Bambade/devel
Remove sparse sparse overload for dense backend
2 parents 690cae4 + 03e1f1e commit 6cf6510

22 files changed

+66
-491
lines changed

bindings/python/src/expose-qpobject.hpp

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -71,39 +71,6 @@ exposeQpObjectDense(pybind11::module_ m)
7171
"mu_eq", std::nullopt, "dual equality constraint proximal parameter"),
7272
pybind11::arg_v(
7373
"mu_in", std::nullopt, "dual inequality constraint proximal parameter"))
74-
75-
.def(
76-
"init",
77-
static_cast<void (dense::QP<T>::*)(std::optional<dense::SparseMat<T>>,
78-
std::optional<dense::VecRef<T>>,
79-
std::optional<dense::SparseMat<T>>,
80-
std::optional<dense::VecRef<T>>,
81-
std::optional<dense::SparseMat<T>>,
82-
std::optional<dense::VecRef<T>>,
83-
std::optional<dense::VecRef<T>>,
84-
bool compute_preconditioner,
85-
std::optional<T>,
86-
std::optional<T>,
87-
std::optional<T>)>(
88-
&dense::QP<T>::init),
89-
"function for initialize the QP model.",
90-
pybind11::arg_v("H", std::nullopt, "quadratic cost"),
91-
pybind11::arg_v("g", std::nullopt, "linear cost"),
92-
pybind11::arg_v("A", std::nullopt, "equality constraint matrix"),
93-
pybind11::arg_v("b", std::nullopt, "equality constraint vector"),
94-
pybind11::arg_v("C", std::nullopt, "inequality constraint matrix"),
95-
pybind11::arg_v("u", std::nullopt, "upper inequality constraint vector"),
96-
pybind11::arg_v("l", std::nullopt, "lower inequality constraint vector"),
97-
pybind11::arg_v("compute_preconditioner",
98-
true,
99-
"execute the preconditioner for reducing "
100-
"ill-conditioning and speeding up solver execution."),
101-
pybind11::arg_v("rho", std::nullopt, "primal proximal parameter"),
102-
pybind11::arg_v(
103-
"mu_eq", std::nullopt, "dual equality constraint proximal parameter"),
104-
pybind11::arg_v(
105-
"mu_in", std::nullopt, "dual inequality constraint proximal parameter"))
106-
10774
.def("solve",
10875
static_cast<void (dense::QP<T>::*)()>(&dense::QP<T>::solve),
10976
"function used for solving the QP problem, using default parameters.")
@@ -148,40 +115,6 @@ exposeQpObjectDense(pybind11::module_ m)
148115
"mu_eq", std::nullopt, "dual equality constraint proximal parameter"),
149116
pybind11::arg_v(
150117
"mu_in", std::nullopt, "dual inequality constraint proximal parameter"))
151-
.def(
152-
"update",
153-
static_cast<void (dense::QP<T>::*)(
154-
const std::optional<dense::SparseMat<T>>,
155-
std::optional<dense::Vec<T>>,
156-
const std::optional<dense::SparseMat<T>>,
157-
std::optional<dense::Vec<T>>,
158-
const std::optional<dense::SparseMat<T>>,
159-
std::optional<dense::Vec<T>>,
160-
std::optional<dense::Vec<T>>,
161-
bool update_preconditioner,
162-
std::optional<T>,
163-
std::optional<T>,
164-
std::optional<T>)>(&dense::QP<T>::update),
165-
"function used for updating matrix or vector entry of the model using "
166-
"sparse matrix entries.",
167-
pybind11::arg_v("H", std::nullopt, "quadratic cost"),
168-
pybind11::arg_v("g", std::nullopt, "linear cost"),
169-
pybind11::arg_v("A", std::nullopt, "equality constraint matrix"),
170-
pybind11::arg_v("b", std::nullopt, "equality constraint vector"),
171-
pybind11::arg_v("C", std::nullopt, "inequality constraint matrix"),
172-
pybind11::arg_v("u", std::nullopt, "upper inequality constraint vector"),
173-
pybind11::arg_v("l", std::nullopt, "lower inequality constraint vector"),
174-
pybind11::arg_v(
175-
"update_preconditioner",
176-
true,
177-
"update the preconditioner considering new matrices entries for "
178-
"reducing ill-conditioning and speeding up solver execution. If set up "
179-
"to false, use previous derived preconditioner."),
180-
pybind11::arg_v("rho", std::nullopt, "primal proximal parameter"),
181-
pybind11::arg_v(
182-
"mu_eq", std::nullopt, "dual equality constraint proximal parameter"),
183-
pybind11::arg_v(
184-
"mu_in", std::nullopt, "dual inequality constraint proximal parameter"))
185118
.def("cleanup",
186119
&dense::QP<T>::cleanup,
187120
"function used for cleaning the workspace and result "

bindings/python/src/expose-solve.hpp

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -84,72 +84,6 @@ solveDenseQp(pybind11::module_ m)
8484
"initial_guess",
8585
proxsuite::proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS,
8686
"maximum number of iteration."));
87-
m.def(
88-
"solve",
89-
pybind11::overload_cast<std::optional<dense::SparseMat<T>>,
90-
std::optional<dense::VecRef<T>>,
91-
std::optional<dense::SparseMat<T>>,
92-
std::optional<dense::VecRef<T>>,
93-
std::optional<dense::SparseMat<T>>,
94-
std::optional<dense::VecRef<T>>,
95-
std::optional<dense::VecRef<T>>,
96-
std::optional<VecRef<T>>,
97-
std::optional<VecRef<T>>,
98-
std::optional<VecRef<T>>,
99-
std::optional<T>,
100-
std::optional<T>,
101-
std::optional<T>,
102-
std::optional<T>,
103-
std::optional<T>,
104-
std::optional<bool>,
105-
bool,
106-
bool,
107-
std::optional<isize>,
108-
proxsuite::proxqp::InitialGuessStatus>(
109-
&dense::solve<T>),
110-
"Function for solving a QP problem using PROXQP dense backend directly "
111-
"without defining a QP object. It is possible to set up some of the solver "
112-
"parameters (warm start, initial guess option, proximal step sizes, "
113-
"absolute and relative accuracies, maximum number of iterations, "
114-
"preconditioner execution).",
115-
pybind11::arg_v("H", std::nullopt, "quadratic cost with dense format."),
116-
pybind11::arg_v("g", std::nullopt, "linear cost"),
117-
pybind11::arg_v(
118-
"A", std::nullopt, "equality constraint matrix with dense format."),
119-
pybind11::arg_v("b", std::nullopt, "equality constraint vector"),
120-
pybind11::arg_v(
121-
"C", std::nullopt, "inequality constraint matrix with dense format."),
122-
pybind11::arg_v("u", std::nullopt, "upper inequality constraint vector"),
123-
pybind11::arg_v("l", std::nullopt, "lower inequality constraint vector"),
124-
pybind11::arg_v("x", std::nullopt, "primal warm start"),
125-
pybind11::arg_v("y", std::nullopt, "dual equality warm start"),
126-
pybind11::arg_v("z", std::nullopt, "dual inequality warm start"),
127-
pybind11::arg_v(
128-
"eps_abs",
129-
std::nullopt,
130-
"absolute accuracy level used for the solver stopping criterion."),
131-
pybind11::arg_v("eps_rel",
132-
std::nullopt,
133-
"relative accuracy level used for the solver stopping "
134-
"criterion. Deactivated in standard settings."),
135-
pybind11::arg_v("rho", std::nullopt, "primal proximal parameter"),
136-
pybind11::arg_v(
137-
"mu_eq", std::nullopt, "dual equality constraint proximal parameter"),
138-
pybind11::arg_v(
139-
"mu_in", std::nullopt, "dual inequality constraint proximal parameter"),
140-
pybind11::arg_v("verbose",
141-
std::nullopt,
142-
"verbose option to print information at each iteration."),
143-
pybind11::arg_v("compute_preconditioner",
144-
true,
145-
"executes the default preconditioner for reducing ill "
146-
"conditioning and speeding up the solver."),
147-
pybind11::arg_v("compute_timings", true, "compute solver's timings."),
148-
pybind11::arg_v("max_iter", std::nullopt, "maximum number of iteration."),
149-
pybind11::arg_v(
150-
"initial_guess",
151-
proxsuite::proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS,
152-
"maximum number of iteration."));
15387
}
15488

15589
} // namespace python

doc/2-PROXQP_API/2-ProxQP_api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ Once you have defined a Qp object, the init method enables you setting up the QP
139139
</tr>
140140
</table>
141141

142-
Note that with its dense backend, ProxQP solver can manipulate both matrices in dense and sparse representations (in the example above the matrices are in sparse format). Note that if some elements of your QP model are not defined (for example a QP without linear cost or inequality constraints), you can either pass a None argument, or a matrix with zero shape for specifying it. We provide an example below in cpp and python (for the dense case, it is similar with sparse backend).
142+
Note that with its dense backend, ProxQP solver manipulates matrices in dense representations (in the same spirit, the solver with sparse backend manipulates entries in sparse format). In the example above the matrices are originally in sparse format, and eventually converted into dense format. Note that if some elements of your QP model are not defined (for example a QP without linear cost or inequality constraints), you can either pass a None argument, or a matrix with zero shape for specifying it. We provide an example below in cpp and python (for the dense case, it is similar with sparse backend).
143143

144144
<table class="manual">
145145
<tr>

doc/3-ProxQP_solve.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ $$\begin{equation}\label{eq:approx_qp_sol_relative_criterion}
6767

6868
If if you don't want to pass through [ProxQP API](2-ProxQP_api.md), it is also possible to use one single solve function. We will show how to do so with examples.
6969

70-
You just need to call a "solve" function with in entry the model of the convex QP you want to solve. We show you below examples in C++ and python for ProxQP sparse and dense backends.
70+
You just need to call a "solve" function with in entry the model of the convex QP you want to solve. We show you below examples in C++ and python for ProxQP sparse and dense backends. Note that the sparse and dense solvers take respectivaly entries in sparse and dense formats.
7171

7272
<table class="manual">
7373
<tr>

examples/cpp/solve_without_api.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ main()
3232
std::cout << "optimal z from sparse solver: " << results_sparse_solver.z
3333
<< std::endl;
3434
// Solve the problem using the dense backend
35-
Results<T> results_dense_solver = dense::solve<T>(H, g, A, b, C, u, l);
35+
Results<T> results_dense_solver = dense::solve<T>(
36+
dense::Mat<T>(H), g, dense::Mat<T>(A), b, dense::Mat<T>(C), u, l);
3637
// print an optimal solution x,y and z
3738
std::cout << "optimal x from dense solver: " << results_dense_solver.x
3839
<< std::endl;

examples/cpp/solve_without_api_and_option.cpp

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,21 @@ main()
1212
isize n = 10;
1313
isize n_eq(n / 4);
1414
isize n_in(n / 4);
15-
16-
T p = 0.15; // level of sparsity
17-
T conditioning = 10.0; // conditioning level for H
18-
auto H = ::proxsuite::proxqp::utils::rand::sparse_positive_definite_rand(
19-
n, conditioning, p);
20-
auto g = ::proxsuite::proxqp::utils::rand::vector_rand<T>(n);
21-
auto A = ::proxsuite::proxqp::utils::rand::sparse_matrix_rand<T>(n_eq, n, p);
22-
auto C = ::proxsuite::proxqp::utils::rand::sparse_matrix_rand<T>(n_in, n, p);
23-
auto x_sol = ::proxsuite::proxqp::utils::rand::vector_rand<T>(n);
24-
auto b = A * x_sol;
25-
auto l = C * x_sol;
26-
auto u = (l.array() + 10).matrix().eval();
15+
T sparsity_factor(0.15);
16+
T strong_convexity_factor(1.e-2);
17+
dense::Model<T> qp_random = utils::dense_strongly_convex_qp(
18+
n, n_eq, n_in, sparsity_factor, strong_convexity_factor);
2719
// Solve the problem using the dense backend
2820
// and suppose you want to change the accuracy to 1.E-9 and rho initial value
2921
// to 1.E-7
3022
proxsuite::proxqp::Results<T> results =
31-
proxsuite::proxqp::dense::solve<T>(H,
32-
g,
33-
A,
34-
b,
35-
C,
36-
u,
37-
l,
23+
proxsuite::proxqp::dense::solve<T>(qp_random.H,
24+
qp_random.g,
25+
qp_random.A,
26+
qp_random.b,
27+
qp_random.C,
28+
qp_random.u,
29+
qp_random.l,
3830
std::nullopt,
3931
std::nullopt,
4032
std::nullopt,

examples/julia/overview-simple.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function generate_mixed_qp(n, seed=1)
3232
u = A * v
3333
l = -1.0e20 * np.ones(m)
3434

35-
return P, q, get(A, slice(0, n_eq)), get(u, slice(0, n_eq)), get(A, slice(n_in, m)), get(u, slice(n_in, m, )), l[n_in+1:end]
35+
return P.toarray(), q, get(A, slice(0, n_eq)), get(u, slice(0, n_eq)), get(A, slice(n_in, m)), get(u, slice(n_in, m, )), l[n_in+1:end]
3636
end
3737

3838
# generate a qp problem
@@ -44,7 +44,7 @@ n_in = C.shape[1]
4444
# solve it
4545
qp = proxsuite.proxqp.dense.QP(n, n_eq, n_in)
4646
qp.settings.eps_abs = EPS
47-
qp.init(H, g, A, b, C, u, l)
47+
qp.init(H, g, A.toarray(), b, C.toarray(), u, l)
4848
qp.solve()
4949

5050
x_res = qp.results.x

examples/python/init_dense_qp.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ def generate_mixed_qp(n, seed=1):
2020
P += (abs(s) + 1e-02) * spa.eye(n)
2121
P = spa.coo_matrix(P)
2222
q = np.random.randn(n)
23-
A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc")
23+
A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray()
2424
v = np.random.randn(n) # Fictitious solution
2525
delta = np.random.rand(m) # To get inequality
2626
u = A @ v
2727
l = -1.0e20 * np.ones(m)
2828

29-
return P, q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:]
29+
return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:]
3030

3131

3232
# load a qp object using qp problem dimensions

examples/python/init_dense_qp_with_other_options.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ def generate_mixed_qp(n, seed=1):
2020
P += (abs(s) + 1e-02) * spa.eye(n)
2121
P = spa.coo_matrix(P)
2222
q = np.random.randn(n)
23-
A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc")
23+
A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray()
2424
v = np.random.randn(n) # Fictitious solution
2525
delta = np.random.rand(m) # To get inequality
2626
u = A @ v
2727
l = -1.0e20 * np.ones(m)
2828

29-
return P, q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:]
29+
return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:]
3030

3131

3232
# load a qp object using qp problem dimensions

examples/python/init_dense_qp_with_timings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ def generate_mixed_qp(n, seed=1):
2020
P += (abs(s) + 1e-02) * spa.eye(n)
2121
P = spa.coo_matrix(P)
2222
q = np.random.randn(n)
23-
A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc")
23+
A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray()
2424
v = np.random.randn(n) # Fictitious solution
2525
delta = np.random.rand(m) # To get inequality
2626
u = A @ v
2727
l = -1.0e20 * np.ones(m)
2828

29-
return P, q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:]
29+
return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:]
3030

3131

3232
# load a qp object using qp problem dimensions

0 commit comments

Comments
 (0)