quadprog: Quadratic Programming Solver
quadprog is a Python wrapper for a C++ library that efficiently solves quadratic programming problems. It minimizes `0.5 * x^T G x + a^T x` subject to `C^T x >= b` and an optional number of equality constraints (`meq`). The library is currently at version 0.1.13 and receives active, though somewhat irregular, maintenance.
Warnings
- breaking Version 0.1.10 is explicitly marked as 'not recommended for use' due to a bug related to Lagrange multipliers for equality constraints.
- gotcha The matrix `G` must be symmetric and positive definite. If `G` is not positive definite, the solver may fail or return incorrect results. Ensure numerical stability for your problem.
- gotcha The `C` matrix requires constraint vectors as its columns. If you define constraints as `A x >= b`, then `C` in `solve_qp` should be `A.T`.
- gotcha The `meq` parameter specifies the number of *equality* constraints, and these constraints *must* be the first `meq` rows in both `C` and `b`. Mixing equality and inequality constraints out of order will lead to incorrect solutions.
- gotcha The `factorized` parameter (default `False`) determines if `G` is expected as the Cholesky factor `R` (such that `R^T R = G`). Setting it to `True` when `G` is the original quadratic matrix will lead to incorrect results.
Install
-
pip install quadprog
Imports
- solve_qp
from quadprog import solve_qp
Quickstart
import numpy as np
from quadprog import solve_qp
# Define the quadratic program:
# Minimize 0.5 * x^T G x + a^T x
# Subject to C^T x >= b
# Example: Minimize x^2 + y^2 - x - y
# This means G = [[2, 0], [0, 2]] and a = [-1, -1]
G = np.array([[2., 0.], [0., 2.]])
a = np.array([-1., -1.])
# Constraints: x >= 0, y >= 0, x + y >= 1
# In quadprog, C's columns are the normal vectors of the constraints.
# C^T x >= b => [[1, 0, 1], [0, 1, 1]]^T x >= [0, 0, 1]^T
# Which means:
# 1*x + 0*y >= 0
# 0*x + 1*y >= 0
# 1*x + 1*y >= 1
C = np.array([[1., 0., 1.],
[0., 1., 1.]])
b = np.array([0., 0., 1.])
# Number of equality constraints (first 'meq' rows of C and b)
meq = 0
# Solve the QP. It returns (x, fval, xu, l)
# x: solution vector
# fval: objective function value at x
# xu: unconstrained solution (unused in this example)
# l: Lagrange multipliers (unused in this example)
solution, _, _, _ = solve_qp(G, a, C, b, meq)
print(f"Optimal solution x: {solution}")
# Expected output for this problem: Optimal solution x: [0.5 0.5]