NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #4232 most downloaded on PyPI
Quadratic programming solvers in Python with a unified API.
Last release 2 months ago
19 Jul 2026
Release timing varies
gaps range from 2 weeks to 5 months
Nearly every release is documented
notes for 59 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
8 years old
71 releases · first in 2018
This release updates the SIP solver interface to bring bug fixes and improvements, contributed by @joaospinto :+1: It also improves dev tools and the
This release updates the SIP solver interface to bring bug fixes and improvements, contributed by @joaospinto :+1: It also improves dev tools and the OSQP interface.
Thanks to @ahoarau, @joaospinto and @vincentvaroquauxads for contributing to this release 👍
raise_error keyword argument to the solve function (thanks to @vincentvaroquauxads)sip-qp-python v0.0.2 QP frontend (thanks to @joaospinto)This release adds qpmad, a C++ implementation of the Goldfarb-Idnani active-set dual method. Thanks to @ahoarau for implementing this interface 👍
This release adds qpmad, a C++ implementation of the Goldfarb-Idnani active-set dual method. Thanks to @ahoarau for implementing this interface 👍
This release also enables warm starting for DAQP, thanks to @darnstrom :+1:
One column per quarter.
This release adds PDHCG, a primal-dual hybrid gradient method that is GPU-accelerated and designed for large-scale QPs. Thanks to @Lhongpei for implem
This release adds PDHCG, a primal-dual hybrid gradient method that is GPU-accelerated and designed for large-scale QPs. Thanks to @Lhongpei for implementing this interface 👍
The primal-dual hybrid gradient algorithm is also known as the Chambolle–Pock algorithm. PDHCG-II extends it with a conjugate gradient inner solver, Halpern acceleration, and PID-controlled primal-dual weight updates, among other improvements. See the research paper for details.
This release adds COPT, a commercial sparse interior point solver that targets modern CPU/GPU architectures and multi-core processors. Thanks to @Sala
This release adds COPT, a commercial sparse interior point solver that targets modern CPU/GPU architectures and multi-core processors. Thanks to @Salancelot for implementing this interface 👍
This release adds QTQP, a primal-dual interior point method for solving convex QPs. It is implemented in pure Python and allows users to select the ba
This release adds QTQP, a primal-dual interior point method for solving convex QPs. It is implemented in pure Python and allows users to select the backend linear solver (called internally to solve KKT systems).
This release also brings a number of bug fixes, bumps the minimum Python version to 3.10 and improves continuous integration of the project by switching to pixi.
unpack_as_dense function to problems__solve_sparse_ls functionconcatenate_boundlinear_from_box_inequalities__solve_dense_ls functionsolve_qp variant of the interfacePrevent deprecation warnings from OSQP related to solver status (thanks to @jkeust)
This patch release provides OSQP warning fixes contributed by @jkeust. Thanks! :+1:
This patch release makes the Calarabel interface warn properly when forwarding an unconstrained problem to lsqr, like the other interfaces already do.
This patch release makes the Calarabel interface warn properly when forwarding an unconstrained problem to lsqr, like the other interfaces already do. Thanks to @proyan for this patch :+1:
lsqrlsqr (thanks to @proyan)This release adds support for the new API of PIQP v0.6.0, as well as macOS unit testing for KVXOPT.
This release adds support for the new API of PIQP v0.6.0, as well as macOS unit testing for KVXOPT.
Thanks to @RSchwan and @sanurielf for contributing to this release :+1:
This patch release adds a py.typed file to be used by tools like Mypy. Thanks to @ValerianRey for taking care of this :+1:
This patch release adds a py.typed file to be used by tools like Mypy. Thanks to @ValerianRey for taking care of this :+1:
py.typed file to indicate tools like mypy to use type annotationspy.typed file to indicate tools like mypy to use type annotations (thanks to @ValerianRey)This release adds SIP, a sparse interior point solver implemented in C++. Thanks to @joaospinto for implementing this interface 👍
This release adds SIP, a sparse interior point solver implemented in C++. Thanks to @joaospinto for implementing this interface 👍
Additionally, this new version adds warning filters and clears out the OSQP version pin.
SparseConversionWarning to filter the corresponding warningQPWarning for all qpsolvers-related warningsensure_sparse_matrices functionThis release adds KVXOPT, a fork from CVXOPT including more SuiteSparse functions and KLU sparse matrix solver. Thanks to @agroudiev for implementing
This release adds KVXOPT, a fork from CVXOPT including more SuiteSparse functions and KLU sparse matrix solver. Thanks to @agroudiev for implementing this interface 👍
Additionally, this new version extends support to JAX arrays when using the jaxopt.OSQP solver.
This patch release adds a workaround to handle OSQP infeasibility certificates with both pre-1.0 and 1.0.3 versions of the solver.
This patch release adds a workaround to handle OSQP infeasibility certificates with both pre-1.0 and 1.0.3 versions of the solver.
This release adds jaxopt.OSQP, an implementation of the OSQP algorithm in JAX.
This release adds jaxopt.OSQP, an implementation of the OSQP algorithm in JAX.
tol_dual_gap parameterSolution.primal_residualtol_dual_gap parameterSolution.primal_residualThis release adds qpax, a primal-dual interior-point solver implemented in JAX. Thanks to @lvjonok for implementing this interface :thumbsup:
This patch release follows a NumPy update, avoids unnecessary matrix conversions with PIQP and catches some exceptions from Clarabel.
This patch release follows a NumPy update, avoids unnecessary matrix conversions with PIQP and catches some exceptions from Clarabel.
Thanks to @itsahmedkhalil for contributing to this release :+1:
None rather than empty listnp.infty to np.infThis patch release updates the wheels_only optional dependency to work on more systems.
This patch release updates the wheels_only optional dependency to work on more systems.
wheels_only for solvers with pre-compiled binariesThis patch release fixes the sign of dual multipliers in the Gurobi interface, and adds corresponding unit tests. Thanks @563925743 for finding this :
This patch release fixes the sign of dual multipliers in the Gurobi interface, and adds corresponding unit tests. Thanks @563925743 for finding this :+1:
This release moves all QP solvers to optional dependencies (#268), along with a healthy batch of corrections to the documentation.
This release moves all QP solvers to optional dependencies (#268), along with a healthy batch of corrections to the documentation.
Thanks to @ogencoglu and @ottapav for contributing to this release :+1:
solve_ls documentation (thanks to @ogencoglu)solve_ls documentation (thanks to @ogencoglu)This release adds the ability to load and save problems from/to files.
This release adds the ability to load and save problems from/to files.
Problem.load functionProblem.save functionProblem.load functionProblem.save functionThis patch release marks QPALM as a sparse solver only to reflect its API.
This patch release marks QPALM as a sparse solver only to reflect its API.
This release adds QPALM, a proximal augmented Lagrangian based solver for (possibly nonconvex) quadratic programs. Check it out!
This release adds QPALM, a proximal augmented Lagrangian based solver for (possibly nonconvex) quadratic programs. Check it out!
master to mainThis minor release adds the ability to install specific solvers from PyPI, *e.g.* pip install qpsolvers[clarabel,daqp,proxqp,scs].
This minor release adds the ability to install specific solvers from PyPI, e.g. pip install qpsolvers[clarabel,daqp,proxqp,scs].
Thanks to @sandeep026 for suggesting this in https://github.com/qpsolvers/qpsolvers/discussions/247 :+1:
This release ships an API-breaking change in the condition number `Problem.cond`, which now requires an active set. Thanks to @aescande for bringing t…
This release adds PIQP, a proximal interior point solver suited to both dense and sparse problems. Thanks to @shaoanlu for implementing this interface 👍
This release ships an API-breaking change in the condition number Problem.cond, which now requires an active set. Thanks to @aescande for bringing this up in https://github.com/qpsolvers/qpsolvers/issues/220 :+1:
This release adds HPIPM, an interior point solver suited to small to medium-size problems arising in model predictive control and embedded optmization
This release adds HPIPM, an interior point solver suited to small to medium-size problems arising in model predictive control and embedded optmization. Thanks to @adamheins for implementing this interface :+1:
This release adds support for MOSEK, fixes corner-case residual computations, and has ECOS raise errors on problems its interface does not handle.
This release adds support for MOSEK, fixes corner-case residual computations, and has ECOS raise errors on problems its interface does not handle.
Thanks to @aszekMosek for helping with MOSEK integration and @uricohen for bringing up this point :+1:
This release updates DAQP to 0.5.1 to address an installation issue with arm64 wheels.
This release updates DAQP to 0.5.1 to address an installation issue with arm64 wheels.
Thanks @darnstrom for the swift fix :+1:
This release adds DAQP, a dual active-set solver suited to small/medium-scale dense problems. It also introduces the Solution.found boolean, which is
This release adds DAQP, a dual active-set solver suited to small/medium-scale dense problems. It also introduces the Solution.found boolean, which is now used rather than Solution.x is not None to check if a call to solve_problem was successful. Solvers can then return a non-empty Solution.x even when the optimal solution was not found (e.g. an intermediate value reached after a maximum number of iterations).
Thanks to @darnstrom for implementing the DAQP interface, and @rxian for suggesting the switch to Solution.found :+1:
qpsolvers.problemsSolution.found as success signal rather than Solution.x is Noneqpsolvers.problemsSolution.found as solver success status (thanks to @rxian)This release adds a second LS-to-QP conversion strategy to solve_ls that's better suited to sparse problems. It is used by default when input matrices
This release adds a second LS-to-QP conversion strategy to solve_ls that's better suited to sparse problems. It is used by default when input matrices are sparse. We can also specify which conversion to use explicitly using the sparse_conversion argument, for example solve_ls(..., sparse_conversion=False).
Thanks to @bodono for pointing out this strategy in https://github.com/qpsolvers/qpsolvers/issues/192 :+1:
problems submodule to collect sample test problemsproblems submodule to collect sample test problemsThis release adds an interface for the NPPro solver, and refactors solver interfaces into supported (open source, unit tested) and unsupported categor
This release adds an interface for the NPPro solver, and refactors solver interfaces into supported (open source, unit tested) and unsupported categories. It also makes CVXOPT and quadprog dependencies optional as they don't distribute arm64 wheels yet.
Here comes the new major version of qpsolvers! To be as underwhelming as possible, this release is feature-equivalent to v2.8.1. It only ships the ann
Here comes the new major version of qpsolvers! To be as underwhelming as possible, this release is feature-equivalent to v2.8.1. It only ships the announced API changes:
QPError base exception.solve_safer_qp function has been removed.sym_proj parameter has been removed.__init__.py at the root of the repository has been removed.These changes unload some legacy weight from the API to keep the project manageable while moving forward.
ParamError for incorrect solver parametersSolverError for solver failuresValueError as either ProblemError or SolverErrorSolution.is_empty becomes not Solution.foundsolve_safer_qpsym_proj parameterThis minor version improves the README FAQ on non-convex problems and fixes the handling of unconstrained problems with Clarabel.
This minor version improves the README FAQ on non-convex problems and fixes the handling of unconstrained problems with Clarabel.
Thanks to @nrontsis for contributing the FAQ update :+1:
solve_unconstrained function from main moduleThis minor release handles non-flat input problem vectors, either flattening them or raising an exception when there is ambiguity.
This minor release handles non-flat input problem vectors, either flattening them or raising an exception when there is ambiguity.
Thanks to @microprediction for the feedback :thumbsup:
This release fixes edge cases for CVXOPT and qpOASES when problems have infinite linear or box bounds, as well as a segmentation fault that occurred w
This release fixes edge cases for CVXOPT and qpOASES when problems have infinite linear or box bounds, as well as a segmentation fault that occurred when using qpOASES from conda-forge.
This patch release fixes an edge case dense conversion for sparse problems with only box inequalities. It also introduces the ProblemError exception,
This patch release fixes an edge case dense conversion for sparse problems with only box inequalities. It also introduces the ProblemError exception, and brings minor improvements to the qpOASES, qpSWIFT and quadprog interfaces.
use_sparse argument to internal linear-from-box conversionProblemError for problem formulation errorsQPError as a base class for exceptionsuse_sparse argument to internal linear-from-box conversionThis release fixes the duality gap computation when some box bounds are disabled (lb=-np.inf or ub=+np.inf). It also brings minor improvements to the
This release fixes the duality gap computation when some box bounds are disabled (lb=-np.inf or ub=+np.inf). It also brings minor improvements to the ECOS and quadprog interfaces.
split_dual_linear_box conversion functionsplit_dual_linear_box conversion functionThis release introduces the `solve_problem` function, and with it the ability to get dual multipliers (yes, finally!) at the solution for all wrapped
This release introduces the solve_problem function, and with it the ability to get dual multipliers (yes, finally!) at the solution for all wrapped QP solvers:
import numpy as np
from qpsolvers import Problem, solve_problem
M = np.array([[1., 2., 0.], [-8., 3., 2.], [0., 1., 1.]])
P = M.T.dot(M) # quick way to build a symmetric matrix
q = np.array([3., 2., 3.]).dot(M).reshape((3,))
G = np.array([[1., 2., 1.], [2., 0., 1.], [-1., 2., -1.]])
h = np.array([3., 2., -2.]).reshape((3,))
A = np.array([1., 1., 1.])
b = np.array([1.])
lb = -0.6 * np.ones(3)
ub = +0.7 * np.ones(3)
problem = Problem(P, q, G, h, A, b, lb, ub)
solution = solve_problem(problem, solver="proxqp")
print(f"Primal: x = {solution.x}")
print(f"Dual (Gx <= h): z = {solution.z}")
print(f"Dual (Ax == b): y = {solution.y}")
print(f"Dual (lb <= x <= ub): z_box = {solution.z_box}")
Depending on the solver, solutions may also contain extra information such as the value of the objective at the solution.
solve_safer_qp to a separate source fileDeprecate solve_safer_qp and warn about future removal
This version improves support for box inequalities in Gurobi, ProxQP, qpOASES and OSQP. It also improves least squares for sparse problems.
solve_safer_qp and warn about future removalSOLVED_INACCURATE is now considered a failuresolve_ls with sparse matricesRET_INIT_FAILED* return codesThis release wires in all solver tolerance and time-limit parameters properly. It is accompanied by a blog post on :spiral_notepad: Optimality conditi
This release wires in all solver tolerance and time-limit parameters properly. It is accompanied by a blog post on :spiral_notepad: Optimality conditions and numerical tolerances in QP solvers. Check it our for a primer on the primal residual, dual residual, duality gap, and how solvers use (ideally all three of) them to decide whether they have converged to a solution.
Here is an overview of what tolerances solvers allow us to check as of this release:
| Solver | Version | Primal residual | Dual residual | Duality gap |
|---|---|---|---|---|
| CVXOPT | 1.3.0 | ✔️ | ✔️ | ✔️ |
| ECOS | 2.0.10 | ✔️ | ✔️ | ✔️ |
| HiGHS | 1.1.2.dev3 | ✔️ | ✔️ | ❌ |
| OSQP | 0.6.2.post0 | ✔️ | ✔️ | ❌ |
| ProxQP | 0.2.2 | ✔️ | ✔️ | ❌ |
| qpSWIFT | 1.0.0 | ✔️ | ✔️ | ✔️ |
| quadprog | 0.1.11 | ❌ | ❌ | ❌ |
| SCS | 3.2.0 | ✔️ | ✔️ | ✔️ |
This release includes one API change: solver tolerance settings for OSQP and SCS, which had been so far overridden (to match the average solver accuracy of all unit tests), are now back to the solvers' respective defaults. If you were relying on the previous behavior, you can pass the additional keyword arguments:
eps_abs=1e-4 and eps_rel=1e-4eps_abs=1e-7 and eps_rel=1e-7From this release onward, the library will adhere to the gateway principle: qpsolvers only acts as a gateway to QP solvers. All default settings are decided by the solvers themselves. Except verbosity :wink:
This release updates ProxQP to v0.2.2. This upstream update removes a parameter conversion overhead that was adding ~0.4 ms to computation time on den
This release updates ProxQP to v0.2.2. This upstream update removes a parameter conversion overhead that was adding ~0.4 ms to computation time on dense problems.
This release adds support for HiGHS, an open-source solver tailored to large-scale sparse problems. Check it out!
This release adds support for HiGHS, an open-source solver tailored to large-scale sparse problems. Check it out!
starter_solvers optional deps to open_source_solversR argument to solve_ls. Thanks to @ansetou for pointing this out.This release adds support for ProxQP, a new solver based on revisited primal-dual proximal algorithms. Check it out!
This release adds support for ProxQP, a new solver based on revisited primal-dual proximal algorithms. Check it out!
tox-gh-actions for Python 3.7USING_COVERAGE in GitHub workflow configurationtest_all_shapesThis release adds lb and ub box-inequality arguments to all _solve_qp functions.
This release adds lb and ub box-inequality arguments to all <solver>_solve_qp functions.
If your code calls a solver-specific <solver>_solve_qp function with initvals as a positional keyword argument, it should be updated to either:
None values for lb and ub bounds, which now come before initvals.qpsolvers.solvers.conversions submodulelb and ub arguments to all <solver>_solve_qp functionsconcatenate_bounds to internal conversions submoduleconvert_to_socp to internal conversions submoduleconcatenate_bounds to linear_from_box_inequalitiesconvert_to_socp function to socp_from_qplb and ub arguments to all <solver>_solve_qp functionsconversions submoduleconcatenate_bounds to internal conversions submoduleconvert_to_socp to internal conversions submoduleconcatenate_bounds to linear_from_box_inequalitiesconvert_to_socp function to socp_from_qpThis release adds support for the SCS box cone API.
This release adds support for the SCS box cone API.
Thanks to @bodono for his feedback in https://github.com/bodono/scs-python/issues/63.
lb XOR ub is setThis major release makes the solver keyword argument mandatory. (Meanwhile, quadprog is not the default QP solver any more.)
This major release makes the solver keyword argument mandatory. (Meanwhile, quadprog is not the default QP solver any more.)
See https://github.com/stephane-caron/qpsolvers/issues/62 for the discussion that lead to this decision.
Thanks to @AntoineD for bringing up and helping with this release :+1:
NoSolverSelected raised when the solver kwarg is missingsolve_ls and solve_qpThis minor release gives qpSWIFT the same keyword argument passing API as the other solvers (e.g. quadprog or OSQP).
This minor release gives qpSWIFT the same keyword argument passing API as the other solvers (e.g. quadprog or OSQP).
This minor release fixes OSQP keyword argument passing. Thanks to @urob for pointing out this bug :+1:
This minor release fixes OSQP keyword argument passing. Thanks to @urob for pointing out this bug :+1:
This release adds an interface to the qpSWIFT solver.
This release adds an interface to the qpSWIFT solver.
The benchmark has been updated accordingly. qpSWIFT is one of the top-performing solvers there, on both dense and sparse problems. Thanks to @abhishek-pandala for support and feedback in https://github.com/qpSWIFT/qpSWIFT/issues/3 :+1:
The main change of this release is that ECOS now raises a ValueError (like other solvers) when the matrix *P* is not positive definite.
The main change of this release is that ECOS now raises a ValueError (like other solvers) when the matrix P is not positive definite.
Thanks to @bodono for pointing out https://github.com/stephane-caron/qpsolvers/issues/51 which lead to more unit tests and fixing this inconsistency. :construction_worker_man:
The major update of this release is the switch to SCS 3.0. Thanks to @bodono for his help in https://github.com/stephane-caron/qpsolvers/pull/50 :+1:
The major update of this release is the switch to SCS 3.0. Thanks to @bodono for his help in https://github.com/stephane-caron/qpsolvers/pull/50 :+1:
The small solver benchmark in the README has been updated accordingly.
requirements2.txt and update Python 2 installation instructionsprint_matrix_vector__all__ in model and top-level __init__.pyRemoved deprecated requirements.txt installation file
This release reduces required dependencies to numpy, quadprog and scipy (with a lower required version number for the latter). This should help with installing on older systems.
requirements.txt installation filesolvers optional dependencies to all_pypi_solversThis release fixes https://github.com/stephane-caron/qpsolvers/issues/46. Thanks to @adamoppenheimer for reporting it.
This release fixes https://github.com/stephane-caron/qpsolvers/issues/46. Thanks to @adamoppenheimer for reporting it.
Example script corresponding exactly to the README
sw parameter of solve_safer_qp to sr for "slack repulsion"initvals is not None is now verboseAdd quadprog dependency properly in pyproject.toml
pyproject.tomlThe major update of this release is the significant performance improvement to the Gurobi interface brought by @DKenefake in https://github.com/stepha
The major update of this release is the significant performance improvement to the Gurobi interface brought by @DKenefake in https://github.com/stephane-caron/qpsolvers/pull/38 :+1:
This release also fixes major solver interface inconsistencies on CVXPY, ECOS, OSQP and quadprog when given unfeasible problems. Now all solvers diligently return None over unfeasible problems, as per the documentation of solve_qp. Thanks a lot to @DKenefake for pointing this out on quadprog, which triggered the whole hunt for inconsistencies via unit testing.
On the packaging side, the project leveled up (linting, static type checking, test coverage, GitHub Actions) thanks to the articles How to make an awesome Python package in 2021 and Python in GitHub Actions. Thanks @nalgeon and @hynek for sharing your experience in such a clear and actionable format! :grinning:
__version__ to main moduleNone on unfeasible problemsinitvals is passed but ignored by solver interfaceNone on unfeasible problemsNone case in solve_safer_qp (found by static type checking)__init__.pyNone on unfeasible problemssolve_qp via a module-level solve-function indexNone on unfeasible problems (thanks to @DKenefake)Upgrade to Python 3 and deprecate Python 2
The major update of this release is the switch to Python 3 and a corresponding upgrade to newer versions of the related solvers in requirements.txt. Users who need Python 2 are now encouraged to install the package via:
# Python 2
sudo apt install python-dev
pip2 install -r requirements2.txt
Thanks to @gmazzamuto and @samuelstjean for proposing patches to CVXPY warnings!
solve_ls function to solve linear Least Squares problemsrequirements2.txtprint in PyPI descriptionNew solve_ls function to solve linear Least Squares problems
solve_ls function to solve linear Least Squares problemsprint in PyPI descriptionThanks to @Neotriple for contributing to the OSQP update in this release.
Thanks to @Neotriple for contributing to the OSQP update in this release.
solve_qp as keyword argumentsverbose an explicit keyword argument of all internal functionsEquation of quadratic program on PyPI page
Nothing published for this version
Thanks to @abhishek-pandala, @dmeoli, @juanjqo, @nikolaif399 and @samuelstjean for reporting and discussing issues that contributed to this release!
Thanks to @abhishek-pandala, @dmeoli, @juanjqo, @nikolaif399 and @samuelstjean for reporting and discussing issues that contributed to this release!
verbose=True available for all solvers except quadprogYour coding agent can read these notes before it upgrades. Set up the MCP server →