State-space inference in JAX: Kalman and particle filters, tempered SMC, and SMC2 across CPU and accelerators
Project description
smcx
smcx is a JAX library for state-space inference: exact linear-Gaussian filtering and smoothing, extended and unscented nonlinear Gaussian filtering, particle filters, adaptive tempered SMC, and SMC² with a small, function-oriented API. It runs on CPU, CUDA, and TPU through JAX, and on Apple-silicon GPUs through the optional jax-mps backend.
Features include:
- exact linear-Gaussian Kalman filtering and RTS smoothing;
- extended and scaled unscented Kalman filtering with shared mean callbacks;
- bootstrap, auxiliary, guided, and Liu–West particle filters;
- a public runner for caller-owned particle-filter kernels;
- adaptive tempered SMC and nested SMC² parameter inference;
- systematic, stratified, multinomial, and residual resampling;
- filtering diagnostics, scoring rules, trajectory reconstruction, and ArviZ export; and
- structured latent-state PyTrees and explicit time-varying inputs.
smcx supplies inference algorithms, not model or distribution classes.
Its catalog covers core families rather than every named variant; additions
need concrete user or research demand and an independent validator.
Linear-Gaussian models use dense arrays. The EKF and UKF share mean callbacks;
the EKF alone adds explicit Jacobians. Particle models use JAX callbacks,
and run_particle_filter lets research code own the filter kernel. Typed
posteriors keep filtering and smoothing composable without a class hierarchy.
Installation
smcx requires Python 3.11 or later.
pip install smcx
Install the optional extras for Apple-silicon GPU execution or ArviZ reporting with:
pip install "smcx[metal]"
pip install "smcx[arviz]"
The metal extra uses jax-mps and is available on macOS 14 or later on
arm64. Metal is float32-only; releases are tested on a physical M-series
GPU as well as on CPU.
Documentation
The documentation includes a quickstart, guides for custom models and custom particle filters and ArviZ reporting, and the complete API reference.
Quick example
import jax.numpy as jnp
import jax.random as jr
import smcx
a, q, r = 0.9, 0.5, 0.3
def initial_sampler(key, num_particles):
return jr.normal(key, (num_particles, 1))
def transition_sampler(key, state):
return a * state + jnp.sqrt(q) * jr.normal(key, state.shape)
def log_observation(y, state):
error = y[0] - state[0]
return -0.5 * (jnp.log(2 * jnp.pi * r) + error**2 / r)
observations = jnp.array([0.2, -0.1, 0.4, 0.7, 0.3])[:, None]
posterior = smcx.bootstrap_filter(
jr.key(0),
initial_sampler,
transition_sampler,
log_observation,
observations,
num_particles=10_000,
)
posterior.marginal_loglik
smcx.weighted_mean(posterior)
smcx.diagnose(posterior)
Callbacks describe one particle; smcx vectorizes them over the cloud. Every stochastic operation takes an explicit PRNG key, and posterior containers are JAX PyTrees.
Citation
If smcx contributes to academic work, cite the release used. The
repository's Cite this repository menu uses the base metadata in
CITATION.cff
to provide BibTeX and APA entries. Include the release tag or version and
release date in the final citation.
Sources and attribution
The broader Feynman–Kac architecture follows Chopin and Papaspiliopoulos's An Introduction to Sequential Monte Carlo. The caller-owned particle-filter runner and dependency-free tempering mutation boundary were informed by BlackJAX's functional state/information protocol and pinned SMC-from-MCMC split, and by the separation of orchestration from history in particles 0.4. These are design credits; no code was copied or translated. The implemented methods draw on these primary sources:
- Exact linear-Gaussian state estimation: Kalman (1960) and Rauch, Tung, and Striebel (1965).
- Nonlinear Gaussian filtering: Schmidt (1966) and Julier (2002).
- Particle filters: Gordon, Salmond, and Smith (1993), Pitt and Shephard (1999), Doucet, Godsill, and Andrieu (2000), and Liu and West (2001).
- Static and parameter inference: Del Moral, Doucet, and Jasra (2006) and Chopin, Jacob, and Papaspiliopoulos (2013).
- Resampling and diagnostics: Douc, Cappé, and Moulines (2005), Lee and Whiteley (2018), Zhang and Stephens (2009), and Vehtari et al. (2024).
- Scoring rules: Matheson and Winkler (1976) and Gneiting and Raftery (2007).
- Reporting: ArviZ.
Numerical validation references
The linear Kalman and RTS outputs are independently validated against Dynamax 1.0.2 and statsmodels 0.14.6; the details are recorded with the frozen linear fixture.
The extended and unscented Kalman outputs are independently validated against Stone Soup 1.9.1, cross-checked with Dynamax 1.0.2, and checked against SciPy 1.18.0 innovation log densities. Exact commits, environments, licenses, and observed differences are recorded with the frozen extended and unscented fixtures.
The auxiliary-guided runner recipe is distributionally cross-checked against
particles 0.4's pinned
AuxiliaryPF composition
and SMC bookkeeping.
These projects are numerical comparison implementations, not code lineage; no implementation code was copied or translated.
Contributing
Contributions are welcome. See
CONTRIBUTING.md
for the development setup and pull-request conventions.
License
smcx is distributed under the Apache License 2.0.
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 smcx-1.14.13.tar.gz.
File metadata
- Download URL: smcx-1.14.13.tar.gz
- Upload date:
- Size: 88.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad33b328998ae8d5d026971fc07257690ebd9583487a15e376d3f57a995e4dee
|
|
| MD5 |
80a8205c29c3f9b35155978d1980ce21
|
|
| BLAKE2b-256 |
9f1b36c3c23148b9aed4c2bec808507133d5a500f141f4d57a2c472a52609ad9
|
Provenance
The following attestation bundles were made for smcx-1.14.13.tar.gz:
Publisher:
release.yml on michaelellis003/smcx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smcx-1.14.13.tar.gz -
Subject digest:
ad33b328998ae8d5d026971fc07257690ebd9583487a15e376d3f57a995e4dee - Sigstore transparency entry: 2256619394
- Sigstore integration time:
-
Permalink:
michaelellis003/smcx@7ede487692f2adc2a41cc8ba3fe6c991e335c333 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/michaelellis003
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7ede487692f2adc2a41cc8ba3fe6c991e335c333 -
Trigger Event:
workflow_run
-
Statement type:
File details
Details for the file smcx-1.14.13-py3-none-any.whl.
File metadata
- Download URL: smcx-1.14.13-py3-none-any.whl
- Upload date:
- Size: 103.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23da3f1d6254ce588be638bbc37cdfd99a17ed0aa2a460f92936ede9d9650861
|
|
| MD5 |
acf75892949ce1bca232c4e4050d58f3
|
|
| BLAKE2b-256 |
9b715b1d781450e8c52cab8586f34a3b5e86c8c74d86e46c528e1d9972039b14
|
Provenance
The following attestation bundles were made for smcx-1.14.13-py3-none-any.whl:
Publisher:
release.yml on michaelellis003/smcx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smcx-1.14.13-py3-none-any.whl -
Subject digest:
23da3f1d6254ce588be638bbc37cdfd99a17ed0aa2a460f92936ede9d9650861 - Sigstore transparency entry: 2256619400
- Sigstore integration time:
-
Permalink:
michaelellis003/smcx@7ede487692f2adc2a41cc8ba3fe6c991e335c333 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/michaelellis003
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7ede487692f2adc2a41cc8ba3fe6c991e335c333 -
Trigger Event:
workflow_run
-
Statement type: