pyfiltersqp
Open-source SQP (Sequential Quadratic Programming) solver in Python with L-BFGS Hessian approximation, l₁-merit and filter line searches, and first-class warm-starting. Faster than IPOPT on most CUTEst problems we've benchmarked.
Why
The open-source NLP ecosystem is dominated by interior-point methods (IPOPT, ECOS, Clarabel). For SQP there's no modern, MIT-licensed, Python-friendly option with sparse Jacobians and warm-starting baked in. This fills that gap.
Headline benchmarks
vs cyipopt IPOPT on the classical CUTEst deck (47 problems, n up to 5000):
| problem | n | pyfiltersqp | IPOPT | speedup |
|---|---|---|---|---|
| ARWHEAD | 5000 | 1.9 ms | 132 ms | 70× |
| EXTROSNB | 1000 | 9.4 ms | 402 ms | 43× |
| HS25 | 3 | 0.1 ms | (fails) | wins outright |
| TQUARTIC | 5000 | 23 ms | 277 ms | 12× |
| ROSENBR | 2 | 3.4 ms | 35 ms | 10× |
| HS71 | 4 | 1.3 ms | 4.9 ms | 3.7× |
41 of 45 successfully-solved problems beat IPOPT, by 1.3× – 70×.
See scripts/bench_cutest.py for the harness.
Install
pip install pyfiltersqp # core
pip install "pyfiltersqp[numba]" # +Numba JIT (2× faster L-BFGS recursion)
pip install "pyfiltersqp[dev]" # +pytest for development
Requires Python ≥ 3.11. Core deps: numpy, scipy, osqp.
Quick start
import numpy as np
from pyfiltersqp import NLPProblem, solve
# HS71 — the classic 4-var SQP demo problem.
problem = NLPProblem(
n=4, m_eq=1, m_ineq=1,
xl=np.ones(4), xu=5 * np.ones(4),
objective = lambda x: x[0]*x[3]*(x[0]+x[1]+x[2]) + x[2],
gradient = lambda x: np.array([
x[3]*(2*x[0]+x[1]+x[2]),
x[0]*x[3],
x[0]*x[3] + 1,
x[0]*(x[0]+x[1]+x[2]),
]),
eq_constraints = lambda x: np.array([x[0]**2+x[1]**2+x[2]**2+x[3]**2 - 40]),
eq_jacobian = lambda x: np.array([[2*x[0], 2*x[1], 2*x[2], 2*x[3]]]),
ineq_constraints = lambda x: np.array([25 - x[0]*x[1]*x[2]*x[3]]),
ineq_jacobian = lambda x: np.array([[
-x[1]*x[2]*x[3], -x[0]*x[2]*x[3],
-x[0]*x[1]*x[3], -x[0]*x[1]*x[2],
]]),
)
result = solve(problem, x0=np.array([1., 5., 5., 1.]))
print(result.success, result.obj) # True, 17.014017...
Algorithm
- Outer: Sequential Quadratic Programming with l₁-merit Armijo line search; filter line search opt-in (Fletcher & Leyffer, 2002) for degenerate problems.
- Hessian: L-BFGS with Powell damping. Optional Numba JIT for the forward recursion. Compact (Byrd-Lu-Nocedal-Zhu) representation under the hood.
- QP backend (auto-selected by problem shape):
ImplicitLBFGSQP— primal-dual active-set + Schur complement, appliesB⁻¹via the L-BFGS two-loop recursion in O(n·m) without ever forming the densen×nHessian. Best for small-to-medium n with few active constraints.WoodburyADMM— Woodbury-identity ADMM on the compact L-BFGS factors, polished via a Schur solve on the inferred active set. Cost per ADMM step is O(n·m) and independent of the active set. Best for large n or many constraints.OSQP— the original v0.1 path. Retained as a deprecated fallback; every benchmark we've run is faster on the implicit / Woodbury paths.
- Robustness: second-order correction on Maratos-class line search collapse, mid-solve fallback to filter on stagnation, anti-cycling (Bland's rule + one-step tabu) in active-set, watchdog reset of L-BFGS on tiny-α streaks.
See DESIGN.md for the full algorithm specification.
Warm-starting
Designed for iterative MPCC strategies and homotopy methods where the constraint set changes slightly between solves:
result1 = solve(problem_v1, x0)
result2 = solve(problem_v2,
x0=result1.x,
lam_eq0=result1.lam_eq,
lam_ineq0=result1.lam_ineq)
Roadmap
See ROADMAP.md and CHANGELOG.md. The next
real-engineering items are PyPI publish (this commit), Woodbury custom KKT
solver inside OSQP for the n > 1000 range, and a projected-CG QP path for
n > 10 000.
References
- Nocedal & Wright, Numerical Optimization, 2nd ed. (2006) — chapters 18 (SQP), 7 (L-BFGS)
- Fletcher & Leyffer (2002), "Nonlinear programming without a penalty function" — filter line search
- Byrd, Lu, Nocedal & Zhu (1994), "Representations of quasi-Newton matrices and their use in limited memory methods" — compact L-BFGS
- Powell (1978), "A fast algorithm for nonlinearly constrained optimization calculations" — damped BFGS
- Stellato et al. (2020), OSQP
License
MIT — see LICENSE.
Metadata
Release files for pyfiltersqp 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pyfiltersqp-0.3.0.tar.gz | 65.0 kB | Without provenance | Details for pyfiltersqp-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pyfiltersqp-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for pyfiltersqp-0.3.0-py3-none-any.whl |
Total release size: 110.1 kB
Release files / pyfiltersqp-0.3.0.tar.gz
| Download URL | pyfiltersqp-0.3.0.tar.gz |
|---|---|
| Size | 65.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ac88e1ff025b21ab66de527c25fb0eb054b47bfd671e4a4099d81560918db3f0
|
|
BLAKE2b-256 checksum How to use checksums |
46ad23a960e373c0fe1c0e659f7510ca694f03f98566377bb02346e73981a5e7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / pyfiltersqp-0.3.0-py3-none-any.whl
| Download URL | pyfiltersqp-0.3.0-py3-none-any.whl |
|---|---|
| Size | 45.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d38140c528cef8e2a57edd49efacc94a35a37aadf3e2824914c73b8d9da3a1e7
|
|
BLAKE2b-256 checksum How to use checksums |
264398300f2b7dfb28f7369e39269d04bfd8ddf8d819534a76ec7d040c5a0fc6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for pyfiltersqp 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.