Skip to main content

Rust-backed SLSQP optimiser with Python bindings

Project description

rslsqp logo

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 replacementfrom rslsqp import minimize works exactly like scipy.optimize.minimize(method='SLSQP').
  • 🐍 Pythonic OO interfaceSlsqpSolver with 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).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rslsqp-0.1.1.tar.gz (393.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rslsqp-0.1.1-cp39-abi3-win_amd64.whl (248.1 kB view details)

Uploaded CPython 3.9+Windows x86-64

rslsqp-0.1.1-cp39-abi3-manylinux_2_34_aarch64.whl (7.9 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.34+ ARM64

rslsqp-0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (10.9 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

rslsqp-0.1.1-cp39-abi3-macosx_11_0_arm64.whl (333.4 kB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

rslsqp-0.1.1-cp39-abi3-macosx_10_12_x86_64.whl (348.5 kB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file rslsqp-0.1.1.tar.gz.

File metadata

  • Download URL: rslsqp-0.1.1.tar.gz
  • Upload date:
  • Size: 393.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rslsqp-0.1.1.tar.gz
Algorithm Hash digest
SHA256 86c0df8386f7985fa965ad1ab05dc39d9c71100008458d6a04096883a4007d3e
MD5 b1279fcd54a93772c6d7c6b1b97f6f8a
BLAKE2b-256 8e4de6926fb13c95aa0809755cf0f45a8345b534ee4bbe599c38d920ae686a1d

See more details on using hashes here.

Provenance

The following attestation bundles were made for rslsqp-0.1.1.tar.gz:

Publisher: release.yml on oberbichler/rslsqp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rslsqp-0.1.1-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: rslsqp-0.1.1-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 248.1 kB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rslsqp-0.1.1-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 8111370c957c1ed23457fff0e59a4e8a7ba45af30307bc79ea15f2296ec079d4
MD5 e82144ece801dd05d3cab9619c224e76
BLAKE2b-256 2964b84f036e00dbce4a23c6b79de27c32a490bcc9b8cb95eb80b64bff44854f

See more details on using hashes here.

Provenance

The following attestation bundles were made for rslsqp-0.1.1-cp39-abi3-win_amd64.whl:

Publisher: release.yml on oberbichler/rslsqp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rslsqp-0.1.1-cp39-abi3-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for rslsqp-0.1.1-cp39-abi3-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 e195b34d43f1bb22e9a7e9fbac01fc7cbba25799786cc682fdb4563e99d55208
MD5 014687ada3f7609d32d86035de29fcde
BLAKE2b-256 070a56e29ed127e7b51b52d5f1a7eb8ffb0cb04715689de75cb748ef6621c96c

See more details on using hashes here.

Provenance

The following attestation bundles were made for rslsqp-0.1.1-cp39-abi3-manylinux_2_34_aarch64.whl:

Publisher: release.yml on oberbichler/rslsqp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rslsqp-0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rslsqp-0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0ac47502e822b43e4568370e3e8120357ec3c3c887148395ffac7b21638e7a79
MD5 27855c2a84e23a775c87070098e2f32c
BLAKE2b-256 8740edcce3824ef27a7a35a9014386528dd19e67d8e6112aeb2491fd792ef585

See more details on using hashes here.

Provenance

The following attestation bundles were made for rslsqp-0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on oberbichler/rslsqp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rslsqp-0.1.1-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

  • Download URL: rslsqp-0.1.1-cp39-abi3-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 333.4 kB
  • Tags: CPython 3.9+, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rslsqp-0.1.1-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 22c77874ff7b8e487ee0753f9677f2f8a16925806e1b73fdc7014cf0ad3ea6b4
MD5 d1ee5993f0b3cdcea9eae5cdd8f93182
BLAKE2b-256 3ddcfc9f8c72b156c1a71fd2050810eed55b0a4eb1031f3b31a7539b93aa0128

See more details on using hashes here.

Provenance

The following attestation bundles were made for rslsqp-0.1.1-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on oberbichler/rslsqp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rslsqp-0.1.1-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rslsqp-0.1.1-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 00e8db2ea1ba852dbe4111de093eb3320296f0e450a138fa53ac5d5e38ac10f1
MD5 1f669292fb39adee58fca9e175ed1748
BLAKE2b-256 1b4790b0085d2d9c65fafe1afc36be8a4dacb668f90f977fec04ca785183bcbe

See more details on using hashes here.

Provenance

The following attestation bundles were made for rslsqp-0.1.1-cp39-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on oberbichler/rslsqp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page