Simulated Annealing ABC implemented in MLX C++.
Project description
sabc
Simulated Annealing ABC with multiple summary statistics, with the core algorithm implemented in MLX C++ and a thin, MLX-native Python API.
sabc performs likelihood-free Bayesian inference (Approximate Bayesian
Computation) via simulated annealing. The annealing loop — empirical-CDF
distance transform, importance resampling, epsilon schedule, and a
Differential-Evolution MCMC kernel — runs in a compiled nanobind extension
(sabc._core), while models, priors, and the entry point live in Python and
exchange mlx.core.arrays with the C++ core zero-copy via DLPack.
It implements the thermodynamic, multiple-summary-statistics SABC of
C. Albert, S. Ulzega, S. Dirmeier, A. Scheidegger, A. Bassi, A. Mira. A thermodynamic approach to Approximate Bayesian Computation with multiple summary statistics. arXiv:2505.23261 (2025).
building on the original SABC of Albert, Künsch & Scheidegger, Statistics and Computing 25 (2015).
Installation
Requires Python ≥ 3.11 and uv. MLX targets Apple
Silicon (Metal); Linux support is experimental.
uv sync --all-extras # creates the venv and compiles sabc._core
Or, into an existing environment:
pip install .
Quickstart
Infer the location of a 2-D model whose summary statistics are observed at
[1, -1]:
import mlx.core as mx
import sabc
from sabc import distributions as dist
observed = mx.array([1.0, -1.0])
def simulator(theta): # theta: (B, n_para) -> data (B, ...)
return theta + mx.random.normal(theta.shape) * 0.1
prior = dist.JointDistributionNamed(
dict(theta=dist.Normal(mx.zeros(2), mx.ones(2) * 3.0))
)
post = sabc.run(
simulator,
prior=prior,
observed=observed,
n_particles=2000,
n_simulation=200_000,
schedule=sabc.SingleEps(v=1.0),
proposal=sabc.DiffEvolution(),
distance="abs",
key=mx.random.key(0),
)
print(post.samples.mean(axis=0)) # ~ [1, -1]
sabc.run returns a Posterior with samples, u, rho, and the
epsilon_history / u_history traces.
Priors
Priors are built from MLX-native, TFP-style distributions. JointDistributionNamed
supports both independent factors and conditional factors p(b | a) (a factor
may be a callable whose argument names refer to preceding factors):
prior = dist.JointDistributionNamed(dict(
a=dist.Normal(mx.zeros(1), mx.ones(1)),
b=lambda a: dist.Normal(a, mx.ones(1)), # p(b | a)
))
Project layout
src/
sabc/ Python package (public API + co-located *_test.py)
csrc/ C++ sources for the sabc._core nanobind extension
examples/ runnable examples (gaussian.py)
CMakeLists.txt scikit-build-core + nanobind build of sabc._core
The split follows nanobind's recommended src/ layout: the importable package
and the C++ translation units live under src/; only the package (with the
compiled _core installed into it) ships in the wheel.
Development
The project uses uv, scikit-build-core (CMake/C++23), ruff for Python, and
clang-format + cpplint for C++. Common tasks are in the Makefile:
make build # editable rebuild of the extension
make tests # uv run pytest
make lints # ruff (Python) + cpplint (C++)
make format # ruff format/import-sort + clang-format
make check # cppcheck static analysis (requires cppcheck)
make docs # Doxygen API docs -> build/doxygen
make example # run examples/gaussian.py
Install the git hooks once:
uv run pre-commit install
pre-commit runs ruff, clang-format, cpplint, and assorted hygiene checks,
and blocks direct commits to main.
Contributing
- Branch off
main(direct commits tomainare blocked by a pre-commit hook). - Make your change. Python lives in
src/sabc, C++ insrc/csrc.- Python: 2-space indent, 80 columns, Google-style docstrings (enforced by
ruff). - C++: 2-space indent, 80 columns, Google
clang-format; document public declarations with Doxygen@brief/@param/@return. The algorithm code insrc/csrc/*.{hpp,cpp}stays free ofnanobind; all Python interop is isolated inbindings.cppand theconv.hppDLPack helpers.
- Python: 2-space indent, 80 columns, Google-style docstrings (enforced by
- Validate locally:
make format && make lints && make tests. - Commit with Conventional Commits
(
feat:,fix:,refactor:,build:,docs:,chore:);gitlintenforces the subject. Keep subjects ≤ 72 characters. - Open a PR. CI runs the pre-commit hooks and the build/test suite on macOS (Apple Silicon) and, best-effort, on Linux x64/arm64.
Correctness is validated through self-contained generative examples (running the full inference on a model with a known posterior), not an external reference.
License
Apache-2.0. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sabc-0.1.0.tar.gz.
File metadata
- Download URL: sabc-0.1.0.tar.gz
- Upload date:
- Size: 77.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fdcf575c93492a3aec291a629665266582b925a0b4a09b11d8e82be4e331b201
|
|
| MD5 |
bbdb9746cca4722afc6a43657626a1b6
|
|
| BLAKE2b-256 |
3ace303f3d88f6b2cd85f50559426b879ba4af9059d40cba9a987c1f83b52bad
|
File details
Details for the file sabc-0.1.0-cp313-cp313-macosx_26_0_arm64.whl.
File metadata
- Download URL: sabc-0.1.0-cp313-cp313-macosx_26_0_arm64.whl
- Upload date:
- Size: 99.4 kB
- Tags: CPython 3.13, macOS 26.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ae060f250768506b26b8f21cc0bed90f0263488d2736fc6069e993c184d1bad
|
|
| MD5 |
b702efd10cc6bbe966fe168b908b7de0
|
|
| BLAKE2b-256 |
0e7fe657a3fee5856394758f2493ddafbbd244c600a91b591e3b64256ef64099
|