Skip to main content

pyfiltersqp

PyPI Python License: MIT CI

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, applies B⁻¹ via the L-BFGS two-loop recursion in O(n·m) without ever forming the dense n×n Hessian. 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)

Source distribution for pyfiltersqp 0.3.0
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)

Table of built distributions (wheels) for pyfiltersqp 0.3.0
File Interpreter ABI Platform Actions
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.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page