solver-osqp
A OSQP wrapper for Python that ships prebuilt
binaries. It exposes OSQP's first-order ADMM solver through a thin,
numpy-friendly, MATLAB-quadprog-like interface, in the C++ namespace
marinholab::solvers::osqp and the Python package marinholab.solvers.osqp.
pip install marinholab-solvers-osqp
Overview
Given a symmetric matrix H, a vector f, and (optionally) inequality and
equality constraint matrices, the solver solves the quadratic program
min_x 0.5 * x' H x + f' x
s.t. A x <= b
Aeq x = beq
Internally the inequality and equality rows are stacked into OSQP's single
l <= A x <= u form. Once a problem has been solved once, subsequent solves on
the same Solver instance reuse the OSQP solver and update its data in place
by default (Configuration.use_hotstart = True), which is the main performance
benefit for repeated, related QPs. OSQP additionally warm-starts from the
previous iterate between osqp_solve() calls
(Configuration.warm_starting = 1).
Quickstart
import numpy as np
from marinholab.solvers import osqp
solver = osqp.Solver()
H = np.eye(2) # positive definite Hessian
f = np.array([-1.0, -1.0]) # linear term
A = np.array([[1.0, 0.0]]) # x[0] <= 0.2
b = np.array([0.2])
x = solver.solve_quadratic_program(H, f, A, b,
Aeq=np.zeros((1, 2)),
beq=np.zeros((1,)))
# x ≈ [0.2, 1.0]
Omitting constraints
Any of the four constraint arguments (A, b, Aeq, beq) can be None,
meaning "no such constraint". The matrix and its right-hand side must be
omitted (or provided) together:
# Unconstrained
x = solver.solve_quadratic_program(H, f, None, None, None, None)
# Equality constraints only
x = solver.solve_quadratic_program(H, f, None, None, Aeq, beq)
Warm-starting
solve_quadratic_program accepts optional x0 and y0 warm-starts for the
primal and dual variables. The dual solution returned by get_info() can be
used to warm-start the next solve:
x = solver.solve_quadratic_program(H, f, A, b, None, None)
y0 = solver.get_info().dual_solution
x = solver.solve_quadratic_program(H, f, A, b, None, None, x0=x, y0=y0)
Solution information
solver.get_info() returns an Info with the objective and dual-objective
values, the primal and dual residual norms, and the dual solution
(dual_solution):
solver.solve_quadratic_program(H, f, A, b, Aeq, beq)
info = solver.get_info()
info.obj_val, info.dual_obj_val, info.prim_res, info.dual_res, info.dual_solution
C++ API
The same solver is available directly in C++ (the Python wrapper is a thin pybind11 layer over it). It is built with Eigen and OSQP:
#include <marinholab/solvers/osqp.h>
namespace osqp = marinholab::solvers::osqp;
osqp::Configuration config;
config.eps_abs = 1.0e-9; // the rest keeps its defaults
config.polishing = 1;
osqp::Solver solver(config);
Eigen::MatrixXd H = Eigen::MatrixXd::Identity(2, 2);
Eigen::VectorXd f(2);
f << -1.0, -1.0;
Eigen::MatrixXd A(1, 2);
A << 1.0, 0.0; // x[0] <= 0.2
Eigen::VectorXd b(1);
b << 0.2;
Eigen::MatrixXd Aeq = Eigen::MatrixXd::Zero(1, 2);
Eigen::VectorXd beq = Eigen::VectorXd::Zero(1);
Eigen::VectorXd x = solver.solve_quadratic_program(H, f, A, b, Aeq, beq);
// x ≈ [0.2, 1.0]
osqp::Solver::Info info = solver.get_info(); // obj_val, prim_res, dual_solution, ...
The API mirrors the Python one: solve_quadratic_program(H, f, A, b, Aeq, beq, x0, y0) solves the QP above and get_info() reports the solution quality.
Configuration exposes the same fields documented below.
A standalone, self-contained C++ program using this API lives in
example/example.cpp (target example_osqp). It is
built only when BUILD_EXAMPLES=ON so it does not affect pip install .:
cmake -B build -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON
cmake --build build --target example_osqp
./build/example/example_osqp # prints x ≈ [0.2, 1.0] and the residuals
Type checking (Pyright)
The Python wrapper is fully type-annotated and ships a PEP 561 py.typed
marker plus a _core.pyi type stub for the compiled _core extension, so
downstream projects can be checked against it. To type-check the package:
pyright # configuration in pyrightconfig.json (python 3.9, mode basic)
This must pass with 0 errors / 0 warnings. Keep _core.pyi in sync with
the pybind11 surface in src/core.cpp.
Configuration
All of OSQP's OSQPSettings fields are exposed, plus one wrapper-specific
setting. Create a Configuration, tweak the fields you need, and pass it to
the solver:
config = osqp.Configuration()
config.eps_abs = 1.0e-9 # tighter absolute tolerance
config.eps_rel = 1.0e-9 # tighter relative tolerance
config.max_iter = 20000 # more ADMM iterations
config.polishing = 1 # polish the ADMM solution
solver = osqp.Solver(config)
The enum types are re-exported for convenience: osqp.LinsysSolverType,
osqp.PreconditionerType, and osqp.Status.
Wrapper-specific option
| Option | Default | Type | Description |
|---|---|---|---|
use_hotstart |
True |
bool |
Reuse the existing OSQP solver and update its data in place instead of re-running osqp_setup() when the problem shape is unchanged. |
OSQP options (linear algebra & control)
These map 1:1 onto OSQP's OSQPSettings fields. Defaults match OSQP's own
defaults for a standard double-precision, direct-solver build (see
osqp_set_default_settings()), except verbose, which defaults to off so the
solver is quiet by default. See the
OSQP documentation for a full description of each
option.
| Option | Default | Type | Description |
|---|---|---|---|
device |
0 |
int |
Device identifier; currently used for CUDA devices. |
linsys_solver |
OSQP_DIRECT_SOLVER |
LinsysSolverType |
Linear system solver to use. |
allocate_solution |
1 |
int |
Whether the solution is allocated during osqp_setup(). |
verbose |
0 |
int |
Whether solver progress is written out (quiet by default). |
profiler_level |
0 |
int |
Level of detail for profiler annotations. |
warm_starting |
1 |
int |
Warm-start from the previous solution between consecutive solves. |
scaling |
10 |
int |
Heuristic data-scaling iterations; 0 disables scaling. |
polishing |
0 |
int |
Whether the ADMM solution is polished to improve accuracy. |
OSQP options (ADMM parameters)
| Option | Default | Type | Description |
|---|---|---|---|
rho |
0.1 |
float |
ADMM penalty parameter (scalar). |
rho_is_vec |
1 |
int |
Whether rho is a scalar or a vector. |
sigma |
1e-06 |
float |
ADMM regularization parameter (improves conditioning). |
alpha |
1.6 |
float |
ADMM relaxation parameter. |
OSQP options (CG settings)
| Option | Default | Type | Description |
|---|---|---|---|
cg_max_iter |
20 |
int |
Maximum number of CG iterations per solve. |
cg_tol_reduction |
10 |
int |
Consecutive zero CG iterations before the tolerance is halved. |
cg_tol_fraction |
0.15 |
float |
CG tolerance, as a fraction of the ADMM residuals. |
cg_precond |
OSQP_DIAGONAL_PRECONDITIONER |
PreconditionerType |
Preconditioner used by the CG method. |
OSQP options (adaptive rho)
| Option | Default | Type | Description |
|---|---|---|---|
adaptive_rho |
1 (..._ITERATIONS) |
int |
rho stepsize adaptation method (0 disabled, 1 iterations, 2 time, 3 KKT error). |
adaptive_rho_interval |
50 |
int |
Interval between rho adaptations (iterations-based method). |
adaptive_rho_fraction |
0.4 |
float |
Fraction controlling when non-fixed rho adaptations occur. |
adaptive_rho_tolerance |
5.0 |
float |
Min ratio between new and current rho for it to be adopted. |
OSQP options (termination)
| Option | Default | Type | Description |
|---|---|---|---|
max_iter |
4000 |
int |
Maximum number of ADMM iterations. |
eps_abs |
1e-3 |
float |
Absolute solution tolerance. |
eps_rel |
1e-3 |
float |
Relative solution tolerance. |
eps_prim_inf |
1e-4 |
float |
Primal infeasibility detection tolerance. |
eps_dual_inf |
1e-4 |
float |
Dual infeasibility detection tolerance. |
scaled_termination |
0 |
int |
Whether the scaled termination criteria are used. |
check_termination |
25 |
int |
Interval at which termination is checked; 0 disables the periodic check. |
check_dualgap |
1 |
int |
Whether the duality-gap termination criteria are used. |
time_limit |
1e10 |
float |
Maximum solve time, in seconds. |
OSQP options (polishing)
| Option | Default | Type | Description |
|---|---|---|---|
delta |
1e-6 |
float |
Regularization parameter used by polishing. |
polish_refine_iter |
3 |
int |
Number of iterative refinement steps during polishing. |
Enums
Linear system solvers (LinsysSolverType): OSQP_UNKNOWN_SOLVER,
OSQP_DIRECT_SOLVER, OSQP_INDIRECT_SOLVER.
CG preconditioners (PreconditionerType): OSQP_NO_PRECONDITIONER,
OSQP_DIAGONAL_PRECONDITIONER.
Solver status (Status): OSQP_SOLVED, OSQP_SOLVED_INACCURATE,
OSQP_PRIMAL_INFEASIBLE, OSQP_PRIMAL_INFEASIBLE_INACCURATE,
OSQP_DUAL_INFEASIBLE, OSQP_DUAL_INFEASIBLE_INACCURATE,
OSQP_MAX_ITER_REACHED, OSQP_TIME_LIMIT_REACHED, OSQP_NON_CVX,
OSQP_SIGINT, OSQP_UNSOLVED.
Examples
marinholab/solvers/osqp/example.py— positive-definite solves, theNone-constraint path, warm-starting, a hierarchical (task-priority) example, andget_info(). Run it withosqp_example(installed as a console script).marinholab/solvers/osqp/example_kinematics.py— an optional example showing the solver used in a hierarchical (task-priority) controller for a kinematically redundant robot, built ondqrobotics. It requires the optional dependenciesdqroboticsanddqrobotics-pyplot(pip install --pre dqrobotics dqrobotics-pyplot).
Building from source
The package builds a C++ extension (via CMake + pybind11) and vendors OSQP and pybind11 as git submodules.
git clone --recurse-submodules <repo>
pip install .
Prerequisites: a C++23 compiler, CMake, an Eigen3 installation, and Python.
On Ubuntu: sudo apt-get install cmake libeigen3-dev.
License
The wrapper is under the GNU Lesser General Public License v2.1 (see the
included LICENSE file); the bundled
OSQP library is Apache-2.0.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file marinholab_solvers_osqp-26.7.0.14-cp313-cp313-manylinux2014_x86_64.whl.
File metadata
- Download URL: marinholab_solvers_osqp-26.7.0.14-cp313-cp313-manylinux2014_x86_64.whl
- Upload date:
- Size: 239.8 kB
- Tags: CPython 3.13
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5959d2772d584d5a467546dff06b4b4f351f770b7722e51eb9ca3ac4ba850965
|
|
| MD5 |
843d35d4474caa8827cae92c271b5993
|
|
| BLAKE2b-256 |
1954edee7e9086dffb1989b777d280d7eb64db087105ba7c3cb0a77b8d3b99cb
|
Provenance
The following attestation bundles were made for marinholab_solvers_osqp-26.7.0.14-cp313-cp313-manylinux2014_x86_64.whl:
Publisher:
python-publish.yml on MarinhoLab/solver-osqp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
marinholab_solvers_osqp-26.7.0.14-cp313-cp313-manylinux2014_x86_64.whl -
Subject digest:
5959d2772d584d5a467546dff06b4b4f351f770b7722e51eb9ca3ac4ba850965 - Sigstore transparency entry: 2709034117
- Sigstore integration time:
-
Permalink:
MarinhoLab/solver-osqp@7877f7826ae9aaff1197c4eb8801d5349baf1cfc -
Branch / Tag:
refs/pull/1/merge - Owner: https://github.com/MarinhoLab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@7877f7826ae9aaff1197c4eb8801d5349baf1cfc -
Trigger Event:
pull_request
-
Statement type:
File details
Details for the file marinholab_solvers_osqp-26.7.0.14-cp313-cp313-manylinux2014_aarch64.whl.
File metadata
- Download URL: marinholab_solvers_osqp-26.7.0.14-cp313-cp313-manylinux2014_aarch64.whl
- Upload date:
- Size: 216.0 kB
- Tags: CPython 3.13
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac5ca53c825e15de08fbaa8aaf6d8758835b9b7b654c5b29aaab443ff6d54dba
|
|
| MD5 |
4b546749bddeed98e92a673b79bdbb71
|
|
| BLAKE2b-256 |
ff1a53cdf112a63e8f44afb990f841338ff1fa5dc5839c39669d4f52412ce6ed
|
Provenance
The following attestation bundles were made for marinholab_solvers_osqp-26.7.0.14-cp313-cp313-manylinux2014_aarch64.whl:
Publisher:
python-publish.yml on MarinhoLab/solver-osqp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
marinholab_solvers_osqp-26.7.0.14-cp313-cp313-manylinux2014_aarch64.whl -
Subject digest:
ac5ca53c825e15de08fbaa8aaf6d8758835b9b7b654c5b29aaab443ff6d54dba - Sigstore transparency entry: 2709034179
- Sigstore integration time:
-
Permalink:
MarinhoLab/solver-osqp@7877f7826ae9aaff1197c4eb8801d5349baf1cfc -
Branch / Tag:
refs/pull/1/merge - Owner: https://github.com/MarinhoLab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@7877f7826ae9aaff1197c4eb8801d5349baf1cfc -
Trigger Event:
pull_request
-
Statement type:
File details
Details for the file marinholab_solvers_osqp-26.7.0.14-cp312-cp312-manylinux2014_x86_64.whl.
File metadata
- Download URL: marinholab_solvers_osqp-26.7.0.14-cp312-cp312-manylinux2014_x86_64.whl
- Upload date:
- Size: 240.0 kB
- Tags: CPython 3.12
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e7d38d41020ab4069699e20777583217defa9525a6067293e81801cc45922d5f
|
|
| MD5 |
191c76e2bd14c3af3e2e85279cdbbb72
|
|
| BLAKE2b-256 |
a55c754285a2601f944e0b5f997e96c24b0ac3aa92125e80cdc814d1782e00ed
|
Provenance
The following attestation bundles were made for marinholab_solvers_osqp-26.7.0.14-cp312-cp312-manylinux2014_x86_64.whl:
Publisher:
python-publish.yml on MarinhoLab/solver-osqp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
marinholab_solvers_osqp-26.7.0.14-cp312-cp312-manylinux2014_x86_64.whl -
Subject digest:
e7d38d41020ab4069699e20777583217defa9525a6067293e81801cc45922d5f - Sigstore transparency entry: 2709034092
- Sigstore integration time:
-
Permalink:
MarinhoLab/solver-osqp@7877f7826ae9aaff1197c4eb8801d5349baf1cfc -
Branch / Tag:
refs/pull/1/merge - Owner: https://github.com/MarinhoLab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@7877f7826ae9aaff1197c4eb8801d5349baf1cfc -
Trigger Event:
pull_request
-
Statement type:
File details
Details for the file marinholab_solvers_osqp-26.7.0.14-cp312-cp312-manylinux2014_aarch64.whl.
File metadata
- Download URL: marinholab_solvers_osqp-26.7.0.14-cp312-cp312-manylinux2014_aarch64.whl
- Upload date:
- Size: 216.0 kB
- Tags: CPython 3.12
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca6e0a6aecc7bd0a135988f1904e71216ab0b5f81a542fc1d4f7278120ecf2ac
|
|
| MD5 |
a65c58528a52a6461e7fc74f9056fd24
|
|
| BLAKE2b-256 |
fe194652aa4155d24b9a9e3cbea5765e439bc82bd14cddc7df9656976801ad96
|
Provenance
The following attestation bundles were made for marinholab_solvers_osqp-26.7.0.14-cp312-cp312-manylinux2014_aarch64.whl:
Publisher:
python-publish.yml on MarinhoLab/solver-osqp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
marinholab_solvers_osqp-26.7.0.14-cp312-cp312-manylinux2014_aarch64.whl -
Subject digest:
ca6e0a6aecc7bd0a135988f1904e71216ab0b5f81a542fc1d4f7278120ecf2ac - Sigstore transparency entry: 2709034144
- Sigstore integration time:
-
Permalink:
MarinhoLab/solver-osqp@7877f7826ae9aaff1197c4eb8801d5349baf1cfc -
Branch / Tag:
refs/pull/1/merge - Owner: https://github.com/MarinhoLab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@7877f7826ae9aaff1197c4eb8801d5349baf1cfc -
Trigger Event:
pull_request
-
Statement type: