Quadratic Programming Solvers
qpsolvers is a Python library that provides a unified API to various quadratic programming (QP) solvers. It simplifies the process of solving convex QPs by abstracting away solver-specific APIs and matrix format requirements. Currently at version 4.11.0, the library maintains an active development pace with frequent minor releases to integrate new solvers and provide updates for existing ones.
Warnings
- breaking The `solver` keyword argument became mandatory for `solve_qp` and `solve_ls` functions in v2.0.
- breaking The minimum required Python version was bumped to 3.10.
- breaking The Gurobi interface was updated to a newer Gurobi API.
- breaking The PIQP interface was updated to support the new PIQP v0.6.0 API.
- gotcha Starting from v4.3.0, `pip install qpsolvers` no longer installs any default QP solvers alongside the library. Solvers must be installed separately.
- gotcha The cost matrix `P` in a QP problem should always be symmetric. Many solvers assume this property and may return incorrect results if it's not. Some solvers also require `P` to be positive definite.
- gotcha OSQP solver may issue deprecation warnings related to solver status or matrix conversion, particularly with certain versions of OSQP.
Install
-
pip install qpsolvers -
pip install qpsolvers[open_source_solvers] -
pip install qpsolvers[clarabel,osqp,proxqp]
Imports
- solve_qp
from qpsolvers import solve_qp
- solve_problem
from qpsolvers import solve_problem
- available_solvers
from qpsolvers import available_solvers
Quickstart
import numpy as np
from qpsolvers import solve_qp, available_solvers
# Define the QP problem in standard form: minimize 0.5 * x.T * P * x + q.T * x
# subject to G * x <= h, A * x == b, lb <= x <= ub
M = np.array([[1., 2., 0.], [-8., 3., 2.], [0., 1., 1.]])
P = M.T @ M # This results in a positive definite matrix
q = np.array([3., 2., 3.]) @ M
G = np.array([[1., 2., 1.], [2., 0., 1.], [-1., 2., -1.]])
h = np.array([3., 2., -2.])
A = np.array([1., 1., 1.])
b = np.array([1.])
# Try to use a common open-source solver, or fallback if not available
solver_to_use = "proxqp" if "proxqp" in available_solvers else available_solvers[0] if available_solvers else None
if solver_to_use:
print(f"Using solver: {solver_to_use}")
x = solve_qp(P, q, G, h, A, b, solver=solver_to_use)
print(f"QP solution: {x = }")
else:
print("No QP solvers found. Please install one, e.g., pip install qpsolvers[proxqp]")