rslsqp
A fast, pure-Rust reimplementation of the classic SLSQP (Sequential Least-Squares Quadratic Programming) optimiser — 1.5× faster than SciPy on average, up to 2.5× on constraint-heavy problems — with seamless Python bindings via PyO3.
Drop-in replacement for scipy.optimize.minimize(method='SLSQP'). Change one
import line — get a faster solver.
✨ Features
- 🚀 1.5× faster than SciPy — benchmarked across 12 problems (Rosenbrock, portfolio optimisation, constrained quadratics, nonlinear least-squares). Up to 2.5× faster on large, constraint-heavy problems.
- 🦀 Pure-Rust solver core — the entire iteration loop, BFGS update, QP sub-problem, and line-search run in compiled Rust; only objective/gradient callbacks cross the Python boundary.
- 🔌 Drop-in SciPy replacement —
from rslsqp import minimizeworks exactly likescipy.optimize.minimize(method='SLSQP'). - 🐍 Pythonic OO interface —
SlsqpSolverwith analytic or finite-difference gradients, iteration callbacks, and user-triggered abort. - 🧮 Optional BLAS acceleration — link against macOS Accelerate or Linux OpenBLAS for even faster Level-1 / LAPACK operations.
- ⚡ Zero-copy where possible — 1-D arrays are shared between NumPy and Rust without copying.
Installation
Requires Python ≥ 3.12, a Rust toolchain, and maturin.
# Clone and build
git clone https://github.com/<you>/rslsqp.git
cd rslsqp
uv sync
uv run maturin develop --release # pure-Rust build
# — or —
uv run maturin develop --release --features blas # with BLAS/Accelerate
Runtime dependency: NumPy ≥ 2.4. For tests and benchmarks: SciPy ≥ 1.17.
Quick start
import numpy as np
from rslsqp import SlsqpSolver, GradientMode
def func(x):
f = 100 * (x[1] - x[0]**2)**2 + (1 - x[0])**2
c = np.array([1 - x[0]**2 - x[1]**2]) # inequality: c >= 0
return f, c
def grad(x):
g = np.array([
-400 * (x[1] - x[0]**2) * x[0] - 2 * (1 - x[0]),
200 * (x[1] - x[0]**2),
])
a = np.array([[-2 * x[0], -2 * x[1]]])
return g, a
solver = SlsqpSolver(
func=func, grad=grad,
xl=np.array([-1.0, -1.0]),
xu=np.array([ 1.0, 1.0]),
m=1, meq=0,
)
result = solver.optimize(np.array([0.1, 0.1]))
print(result.x, result.fun, result.success)
SciPy-compatible interface
rslsqp.minimize is a drop-in replacement for
scipy.optimize.minimize(method='SLSQP'). It accepts the same arguments and
returns a compatible OptimizeResult:
from rslsqp import minimize
result = minimize(
fun, x0,
jac=jac, # callable, True, '2-point', '3-point'
bounds=bounds, # sequence of (lo, hi) or scipy.optimize.Bounds
constraints=constraints, # list of {'type': 'eq'/'ineq', 'fun': …, 'jac': …}
options={'maxiter': 200, 'ftol': 1e-10},
)
print(result.x, result.fun, result.nit, result.success)
Switching from SciPy requires changing only the import line:
- from scipy.optimize import minimize
+ from rslsqp import minimize
API overview
Enums
| Enum | Values | Description |
|---|---|---|
GradientMode |
USER, FORWARD, BACKWARD, CENTRAL |
How gradients are supplied or approximated |
LinesearchMode |
INEXACT, EXACT |
Line-search strategy |
NnlsMode |
NNLS, BVLS |
Non-negative least-squares sub-solver |
SlsqpStatus |
CONVERGED, MAX_ITERATIONS_REACHED, … |
Solver exit status |
Classes
| Class | Description |
|---|---|
SlsqpSolver |
OO interface — configure once, call optimize(x0) |
SlsqpResult |
Result of SlsqpSolver.optimize() (x, fun, constraints, status, iterations, success) |
OptimizeResult |
SciPy-compatible result from minimize() (x, fun, jac, nit, nfev, njev, success, message) |
Benchmark: rslsqp vs SciPy SLSQP
All benchmarks run with the blas feature enabled (macOS Accelerate on
Apple Silicon). Both solvers receive identical analytic gradients so the
comparison isolates solver-core overhead.
Environment: Python 3.12, NumPy 2.4, SciPy 1.17 — Apple Silicon (arm64), macOS — release build with
--features blas— 10 timed runs, 2 warm-up,maxiter=500,ftol=1e-10.
| Problem | n | Constraints | SciPy (ms) | rslsqp (ms) | Speedup |
|---|---|---|---|---|---|
| Rosenbrock unconstrained | 50 | 0 | 14.85 | 11.58 | 1.28× |
| Rosenbrock unconstrained | 100 | 0 | 62.71 | 54.14 | 1.16× |
| Rosenbrock unconstrained | 200 | 0 | 231.06 | 191.80 | 1.20× |
| Rosenbrock constrained | 50 | 2 | 11.87 | 8.67 | 1.37× |
| Rosenbrock constrained | 100 | 2 | 50.67 | 37.54 | 1.35× |
| Portfolio optimisation | 50 | 2 | 8.32 | 5.18 | 1.61× |
| Portfolio optimisation | 100 | 2 | 63.92 | 29.84 | 2.14× |
| Portfolio optimisation | 200 | 2 | 494.26 | 195.14 | 2.53× |
| Quadratic + 100 ineq | 50 | 100 | 33.15 | 16.33 | 2.03× |
| Quadratic + 200 ineq | 100 | 200 | 266.12 | 117.99 | 2.26× |
| Least-squares fitting | 20 | 1 | 1.35 | 1.34 | 1.00× |
| Least-squares fitting | 40 | 1 | 0.85 | 0.64 | 1.32× |
Geometric mean speedup: 1.54×
The advantage grows with problem size and constraint count — for constraint-heavy problems at n = 100–200 the Rust core is 2–2.5× faster than SciPy's Fortran-based SLSQP.
To reproduce:
uv run maturin develop --release --features blas
uv run python benchmarks/benchmark.py
BLAS acceleration (optional)
On macOS (Accelerate) or Linux (OpenBLAS), build with the blas feature
for faster BLAS Level 1 operations and LAPACK-accelerated QR:
uv run maturin develop --release --features blas
Development
# Install in editable mode (requires maturin + uv)
uv sync
uv run maturin develop --release
# Run tests
uv run pytest
# Run benchmarks
uv run python benchmarks/benchmark.py
A justfile is provided for common tasks:
just release # build in release mode
just release-blas # build with BLAS/Accelerate
just test # run Rust + Python tests
just benchmark-blas # benchmark with BLAS enabled
just lint # lint Rust + Python
just fmt # format all code
Licence
BSD-3-Clause — see LICENSE for details.
Based on the SLSQP algorithm by Dieter Kraft (1988), modernised in Fortran by Jacob Williams (slsqp, BSD-3-Clause).
Release files for rslsqp 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rslsqp-0.1.1.tar.gz | 393.8 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| rslsqp-0.1.1-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details |
| rslsqp-0.1.1-cp39-abi3-manylinux_2_34_aarch64.whl | CPython 3.9 | abi3 | Linux glibc 2.34+ ARM64 | Details |
| rslsqp-0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| rslsqp-0.1.1-cp39-abi3-macosx_11_0_arm64.whl | CPython 3.9 | abi3 | macOS 11.0+ ARM64 | Details |
| rslsqp-0.1.1-cp39-abi3-macosx_10_12_x86_64.whl | CPython 3.9 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 20.1 MB
Release files / rslsqp-0.1.1.tar.gz
| Download URL | rslsqp-0.1.1.tar.gz |
|---|---|
| Size | 393.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
86c0df8386f7985fa965ad1ab05dc39d9c71100008458d6a04096883a4007d3e
|
|
BLAKE2b-256 checksum How to use checksums |
8e4de6926fb13c95aa0809755cf0f45a8345b534ee4bbe599c38d920ae686a1d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 23, 2026.
Transparency logRelease files / rslsqp-0.1.1-cp39-abi3-win_amd64.whl
| Download URL | rslsqp-0.1.1-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 248.1 kB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
8111370c957c1ed23457fff0e59a4e8a7ba45af30307bc79ea15f2296ec079d4
|
|
BLAKE2b-256 checksum How to use checksums |
2964b84f036e00dbce4a23c6b79de27c32a490bcc9b8cb95eb80b64bff44854f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 23, 2026.
Transparency logRelease files / rslsqp-0.1.1-cp39-abi3-manylinux_2_34_aarch64.whl
| Download URL | rslsqp-0.1.1-cp39-abi3-manylinux_2_34_aarch64.whl |
|---|---|
| Size | 7.9 MB |
| Tags | CPython 3.9 Linux glibc 2.34+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
e195b34d43f1bb22e9a7e9fbac01fc7cbba25799786cc682fdb4563e99d55208
|
|
BLAKE2b-256 checksum How to use checksums |
070a56e29ed127e7b51b52d5f1a7eb8ffb0cb04715689de75cb748ef6621c96c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 23, 2026.
Transparency logRelease files / rslsqp-0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | rslsqp-0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 10.9 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
0ac47502e822b43e4568370e3e8120357ec3c3c887148395ffac7b21638e7a79
|
|
BLAKE2b-256 checksum How to use checksums |
8740edcce3824ef27a7a35a9014386528dd19e67d8e6112aeb2491fd792ef585
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 23, 2026.
Transparency logRelease files / rslsqp-0.1.1-cp39-abi3-macosx_11_0_arm64.whl
| Download URL | rslsqp-0.1.1-cp39-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 333.4 kB |
| Tags | CPython 3.9 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
22c77874ff7b8e487ee0753f9677f2f8a16925806e1b73fdc7014cf0ad3ea6b4
|
|
BLAKE2b-256 checksum How to use checksums |
3ddcfc9f8c72b156c1a71fd2050810eed55b0a4eb1031f3b31a7539b93aa0128
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 23, 2026.
Transparency logRelease files / rslsqp-0.1.1-cp39-abi3-macosx_10_12_x86_64.whl
| Download URL | rslsqp-0.1.1-cp39-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 348.5 kB |
| Tags | CPython 3.9 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
00e8db2ea1ba852dbe4111de093eb3320296f0e450a138fa53ac5d5e38ac10f1
|
|
BLAKE2b-256 checksum How to use checksums |
1b4790b0085d2d9c65fafe1afc36be8a4dacb668f90f977fec04ca785183bcbe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 23, 2026.
Transparency log