proxsuite 0.6.4
The Advanced Proximal Optimization Toolbox
Loading...
Searching...
No Matches
proxsuite

Proxsuite Logo

What is ProxSuite?

ProxSuite is a library which provides efficient solvers for solving constrained programs encountered in robotics using dedicated proximal point based algorithms. ProxSuite is open-source, written in C++ with Python bindings, and distributed under the BSD2 licence. Contributions are welcome.

For the moment, the library offers ProxQP solver, which is a C++ implementation of the ProxQP algorithm for solving convex QPs. It is planned to release soon an extension for dealing with non linear inequality constraints as well.

In this doc, you will find the usual description of the library functionalities and a quick tutorial with examples on how to use the API.

How to install ProxSuite?

The full installation procedure can be found here.

If you just need the Python bindings, you can directly have access to them through Conda. On systems for which binaries are not provided, installation from source should be straightforward. Every release is validated in main Linux, Mac OS X and Windows distributions.

Simplest ProxQP example with compilation command

We start with a simple program to load ProxQP and use ProxQP solver in order to solve a random generated QP problem. It is given in both C++ and Python cases.

examples/cpp/overview-simple.cpp examples/python/overview-simple.py
#include <iostream>
#include <proxsuite/proxqp/utils/random_qp_problems.hpp> // used for generating a random convex qp
using namespace proxsuite::proxqp;
using T = double;
int
{
// generate a QP problem
T sparsity_factor = 0.15;
dense::isize dim = 10;
dense::isize n_eq(dim / 4);
dense::isize n_in(dim / 4);
// we generate a qp, so the function used from helpers.hpp is
// in proxqp namespace. The qp is in dense eigen format and
// you can control its sparsity ratio and strong convexity factor.
dense::Model<T> qp_random = utils::dense_strongly_convex_qp(
// load PROXQP solver with dense backend and solve the problem
dense::QP<T> qp(dim, n_eq, n_in);
qp.init(qp_random.H,
qp.solve();
// print an optimal solution x,y and z
std::cout << "optimal x: " << qp.results.x << std::endl;
std::cout << "optimal y: " << qp.results.y << std::endl;
std::cout << "optimal z: " << qp.results.z << std::endl;
}
This class stores the model of the QP problem.
Definition model.hpp:24
import proxsuite
import numpy as np
import scipy.sparse as spa
def generate_mixed_qp(n, seed=1):
# A function for generating sparse random convex qps in dense format
np.random.seed(seed)
n_eq = int(n / 4)
n_in = int(n / 4)
m = n_eq + n_in
P = spa.random(
n, n, density=0.075, data_rvs=np.random.randn, format="csc"
).toarray()
P = (P + P.T) / 2.0
s = max(np.absolute(np.linalg.eigvals(P)))
P += (abs(s) + 1e-02) * spa.eye(n)
P = spa.coo_matrix(P)
q = np.random.randn(n)
A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray()
v = np.random.randn(n) # Fictitious solution
delta = np.random.rand(m) # To get inequality
u = A @ v
l = -1.0e20 * np.ones(m)
return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:]
# generate a qp problem
n = 10
H, g, A, b, C, u, l = generate_mixed_qp(n)
n_eq = A.shape[0]
n_in = C.shape[0]
# solve it
qp = proxsuite.proxqp.dense.QP(n, n_eq, n_in)
qp.init(H, g, A, b, C, l, u)
qp.solve()
# print an optimal solution
print("optimal x: {}".format(qp.results.x))
print("optimal y: {}".format(qp.results.y))
print("optimal z: {}".format(qp.results.z))

Compiling and running your program

You can compile the C++ version by including ProxSuite and Eigen header directories

g++ -std=c++17 examples/cpp/overview-simple.cpp -o overview-simple $(pkg-config --cflags proxsuite)

If you are looking for the fastest performance, use the following flags to use SIMDE in proxsuite and tell your compiler to use the corresponding cpu instruction set

g++ -O3 -march=native -DNDEBUG -DPROXSUITE_VECTORIZE -std=c++17 examples/cpp/overview-simple.cpp -o overview-simple $(pkg-config --cflags proxsuite)

Once your code is compiled, you might then run it using

./overview-simple

In Python, just run it:

python examples/python/overview-simple.py

Explanation of the program

This program generates a random convex QP problem and loads ProxQP solver with dense backend for solving it.

We first include the proper files. In C++, we have to include the dense backend API imported from "dense.hpp" file, and a header file "util.hpp" for generating a random QP problem (from test directory as it is used for unit testing the solver). In Python, the library is included by just importing proxsuite_pywrap, and we propose a little function generated_mixed_qp for generating convex QP with equality and inequality constraints.

The first paragraph generates the QP problem. In the second paragraph, we first define the object Qp, using the dimensions of the problem (i.e., n is the dimension of primal variable x, n_eq the number of equality constraints, and n_in the number of inequality constraints). We then define some settings for the solver: the accuracy threshold is set to 1.E-9, and the verbose option is set to false (so no intermediary printings will be displayed). The solver is initialized with the previously generated QP problem with the method init. Finally, we call the solve method. All the results are stored in Qp.results.

About Python wrappings

ProxSuite is written in C++, with a full template-based C++ API, for efficiency purposes. All the functionalities are available in C++. Extension of the library should be preferably in C++.

However, C++ efficiency comes with a higher work cost, especially for newcomers. For this reason, all the interface is exposed in Python. We tried to build the Python API as much as possible as a mirror of the C++ interface. The greatest difference is that the C++ interface is proposed using Eigen objects for matrices and vectors, that are exposed as NumPy matrices in Python.

How to cite ProxSuite?

Happy with ProxSuite? Please cite us with the following format.

@inproceedings{bambade:hal-03683733,
TITLE = {{PROX-QP: Yet another Quadratic Programming Solver for Robotics and beyond}},
AUTHOR = {Antoine Bambade, Sarah El-Kazdadi, Adrien Taylor, Justin Carpentier},
URL = {https://hal.inria.fr/hal-03683733},
BOOKTITLE = {{RSS 2022 - Robotics: Science and Systems}},
ADDRESS = {New York, United States},
YEAR = {2022},
MONTH = June,
PDF = {https://hal.inria.fr/hal-03683733/file/Yet_another_QP_solver_for_robotics_and_beyond.pdf},
HAL_ID = {hal-03683733},
HAL_VERSION = {v1},
}

The paper is publicly available in HAL (ref 03683733).

Where to go from here?

This documentation is mostly composed of several examples, along with a technical documentation. In the next sections you will find illustrated with examples in C++ and python, (i) ProxQP API methods (with dense and sparse backends) ; the lists of solver's settings and results subclasses ; some recommandation about which backend using according to your needs ; some important remarks about timings (and compilation options for speeding up ProxQP considering your OS architecture); and finally (ii) some examples for using ProxQP without passing by the API (but only through a unique solve function).

The last parts of the documentation describes the differents namespaces, classes and files of the C++ project.