sabc
Simulated Annealing ABC in MLX
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.
Quickstart
All you provide is a prior, the observed data, and a distance
function f_dist(theta, observed). The distance function is yours to write —
it folds simulation, summary statistics, and the metric into one place — and it
returns either one distance per particle (scalar) or one per summary statistic
(vector). Here we infer the location of a 2-D model observed at [1, -1]:
import mlx.core as mx
import sabc
from sabc import distributions as dist
observed = mx.array([1.0, -1.0])
prior = dist.JointDistributionNamed(
dict(theta=dist.Normal(mx.zeros(2), mx.ones(2) * 3.0))
)
def f_dist(theta, observed):
# theta: (n_particles, n_para). Simulate, then return the distance(s).
y = theta + mx.random.normal(theta.shape) * 0.1
return mx.abs(y - observed) # per-dimension (vector) distance
posterior = sabc.run(
f_dist,
prior=prior,
observed=observed,
n_particles=2000,
n_simulation=200_000,
schedule=sabc.SingleEps(v=1.0),
key=mx.random.key(0),
)
print(posterior.samples.mean(axis=0)) # ~ [1, -1]
sabc.run returns a Posterior with samples, u, rho, and the
epsilon_history / u_history traces.
Scalar vs vector distances, single vs multiple epsilon
The shape of what f_dist returns chooses the inference flavour, independently
of the epsilon schedule:
- return
(n_particles,)/(n_particles, 1)for a single scalar distance, - return
(n_particles, n_stats)to keep one distance per summary statistic.
A per-statistic distance pairs naturally with MultiEps, which anneals one
temperature per statistic (SingleEps uses one shared temperature):
def f_dist(theta, observed):
y = simulate(theta)
return mx.abs(summary(y) - observed) # (n_particles, n_stats)
posterior = sabc.run(
f_dist, prior=prior, observed=observed,
schedule=sabc.MultiEps(v=1.0), # one epsilon per statistic
)
Priors
Priors are built from MLX-native, TFP-style distributions:
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)
))
Examples
Self-contained examples are in examples.
Installation
sabc targets Apple Silicon (Metal); Linux support is experimental. It requires
Python ≥ 3.11. Install the released package from PyPI:
pip install sabc
For a development checkout, use uv:
git clone https://github.com/dirmeier/sabc && cd sabc
uv sync --all-extras
Development
The project uses uv, scikit-build-core (CMake/C++23), ruff for Python, and
clang-format + cpplint for C++. The Makefile wraps the common tasks:
make check # cpp checks
make tests # run the tests
make format # autoformat
make lints # lint
Install the git hooks once (the commit-msg type is needed for gitlint):
uv run pre-commit install --hook-type pre-commit --hook-type commit-msg
The hooks then run automatically on changed files at commit time. To run every hook against the whole repository (useful after adding a hook or before a PR):
uv run pre-commit run --all-files
Linux build (Docker)
The CI builds the C++/MLX extension under gcc on Linux. Apple clang accepts
some MLX overloads that gcc rejects, so a dev container is provided to
reproduce and verify the Linux build locally without GitHub Actions:
docker build -t sabc-linux -f .devcontainer/Dockerfile .
docker run --rm -v "$PWD":/work -w /work sabc-linux \
bash -lc "uv sync --all-extras && make tests"
Citing SABC
If you find this package relevant to your research, please consider citing:
@article{albert2025simulated,
title={Simulated Annealing ABC with multiple summary statistics},
author={Albert, Carlo and Ulzega, Simone and Dirmeier, Simon and Scheidegger, Andreas and Bassi, Alberto and Mira, Antonietta},
journal={arXiv preprint arXiv:2505.23261},
year={2025}
}
Metadata
Release files for sabc 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 | |
|---|---|---|---|---|
| sabc-0.3.0.tar.gz | 131.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sabc-0.3.0-cp313-cp313-macosx_26_0_arm64.whl | CPython 3.13 | CPython 3.13 | macOS 26.0+ ARM64 | Details |
Total release size: 234.9 kB
Release files / sabc-0.3.0.tar.gz
| Download URL | sabc-0.3.0.tar.gz |
|---|---|
| Size | 131.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
884f8a86e0ddf8dc6a239b25cd1f119bbe50629970b91f4597eca25f1060fef2
|
|
BLAKE2b-256 checksum How to use checksums |
579ab1eb0e7c074c08e3e3505ba7b67e4829f0ef9f456080db98ba0c4f21ecf8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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}
|
Release files / sabc-0.3.0-cp313-cp313-macosx_26_0_arm64.whl
| Download URL | sabc-0.3.0-cp313-cp313-macosx_26_0_arm64.whl |
|---|---|
| Size | 103.4 kB |
| Tags | CPython 3.13 macOS 26.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
fc89da0de314f4e03cb4798ca55aa36f26e19534a4daeffd8257f1e12c9e189e
|
|
BLAKE2b-256 checksum How to use checksums |
e872b9237526a5bbf3ee981f755496eb2b384e24f7328fe783bd50c163d6ca9d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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}
|
Security for sabc 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.