Skip to main content

rustmc

Bayesian inference powered by Rust, with a Python API.

Project status: alpha. rustmc is suitable for research, evaluation, and controlled internal workflows. Its supported modeling surface is useful but still intentionally smaller than mature probabilistic programming systems. Validate every model on representative data before using its output for consequential decisions.

rustmc is a practical, general-purpose Bayesian toolkit. It combines graph-based automatic differentiation and NUTS/HMC with reusable compiled models, exact conjugate inference, and specialized state-space algorithms. A generic sampler is available when a model needs one, while focused methods can be added when a research or production problem benefits from them.

rustmc complements PyMC and Stan rather than trying to replace them. Its practical distinction is native Rust execution and Rayon-powered parallelism across chains and repeated-model workloads. That foundation can support fast forecasting, regression, and domain-specific models in biomedical research, engineering, science, finance, and other fields. The project aims to keep those implementations understandable enough to inspect, adapt, and extend for real work.

Why rustmc

  • General and specialized inference in one runtime. The model builder uses reverse-mode automatic differentiation with NUTS or HMC. Local-level, seasonal, and trend models use FFBS/Gibbs, while Gaussian AR(p) uses an exact Normal-Inverse-Gamma posterior.
  • Compile once, bind many. ModelBuilder.compile() separates immutable model structure from validated datasets, including datasets with different row counts.
  • Native execution. Sampling, state-space operations, and chain coordination execute in Rust outside the Python hot path.
  • Deterministic parallelism. Chains and repeated-model workloads use Rayon with stable per-chain seed derivation and ordered results.
  • A focused scope. General inference and specialized model implementations share a native core, so domain methods can be added without pursuing feature parity with a mature probabilistic-programming language. The Python binding surface still needs the modularization described in the roadmap before that extension path is as simple as it should be.
  • Bayesian workflow support. Prior predictive checks, posterior predictive draws, pointwise log likelihood, convergence diagnostics, and ArviZ export are available for the generic inference path.
  • Coherent uncertainty. Specialized forecasting APIs retain complete (chain, draw, horizon) paths so derived totals and other nonlinear quantities can be calculated draw by draw.

These are implementation capabilities, not a universal speed or accuracy claim. Performance and statistical quality depend on the model, data, tuning, and hardware.

Installation

Install the latest published Python package with:

pip install rustmc

To build the current source instead of installing a published wheel:

git clone https://github.com/tbosier/rustmc.git
cd rustmc
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip maturin numpy
maturin develop --manifest-path python_bindings/Cargo.toml --release

Python 3.9 through 3.13 are covered by source-install and wheel-install CI. NumPy is the only required Python runtime dependency. ArviZ and Matplotlib are optional:

pip install "rustmc[viz]"

The Python extension is the supported public package today. rustmc_core contains the Rust implementation, but its public API should still be considered unstable.

Quick start

This example fits a Bayesian linear regression with NUTS:

import numpy as np
import rustmc as rmc

rng = np.random.default_rng(42)
x = rng.normal(size=1_000)
y = 2.5 * x + rng.normal(size=1_000)

builder = rmc.ModelBuilder()
beta = builder.normal_prior("beta", mu=0.0, sigma=1.0)
builder.normal_likelihood(
    "obs",
    mu_expr=beta * "x",
    sigma=1.0,
    observed_key="y",
)

fit = rmc.sample(
    model_spec=builder.build(),
    data={"x": x, "y": y},
    chains=4,
    warmup=1_000,
    draws=1_000,
    seed=42,
)
print(fit.summary())

The same modeling surface supports scalar hierarchical priors, GLM-style expressions, and a vectorized beta @ "X" path backed by faer.

Reuse one model structure

When the structure is shared across datasets, compile it once and bind new data:

builder = rmc.ModelBuilder()
intercept = builder.normal_prior("intercept", mu=0.0, sigma=5.0)
slope = builder.normal_prior("slope", mu=0.0, sigma=2.0)
builder.normal_likelihood(
    "obs",
    mu_expr=intercept + slope * "x",
    sigma=1.0,
    observed_key="y",
)

compiled = builder.compile()
batch = compiled.sample_batch(
    [
        {"x": x_a, "y": y_a},
        {"x": x_b, "y": y_b},
    ],
    ids=["dataset-a", "dataset-b"],
    chains=4,
    warmup=500,
    draws=1_000,
    seed=42,
)

CompiledModel validates each binding against the same structural schema. The legacy sample() and batch_sample() entry points remain available.

Forecasting as an application

Forecasting is one application of rustmc's structure-aware inference rather than the definition of the library. Current specialized models include a joint hierarchical mean for ragged related series, Bayesian local level, seasonal local level, local linear trend, and directly observed Gaussian AR(p), plus fixed-parameter linear Gaussian state-space filtering, smoothing, and a sum-to-zero seasonal constructor.

For many short program series, fit one population → group → program posterior instead of independently batching models:

model = rmc.BayesianHierarchicalMean(
    group_variance_prior=rmc.InverseGammaPrior(3.0, 20.0),
    program_variance_prior=rmc.InverseGammaPrior(3.0, 10.0),
    observation_variance_prior=rmc.InverseGammaPrior(3.0, 25.0),
    population_mean_prior=100.0,
    population_variance_prior=400.0,
)
fit = model.fit(
    [program_a, program_b, program_c],       # unequal lengths are native
    group_index=[0, 0, 1],
    program_names=["a", "b", "c"],
    group_names=["division-a", "division-b"],
)
forecast = fit.forecast(steps=12)

# (chain, draw, program, step); chain/draw alignment preserves dependence.
company_draws = forecast.observation_samples.sum(axis=2)
division_draws = forecast.group_observation_samples

This MVP pools a static Gaussian intercept/mean; it is not a dynamic local-level model. Its conjugate Gibbs kernel samples the joint hierarchy directly and avoids requiring HMC to navigate a funnel. Centered Gibbs can still mix slowly near zero variance, so inspect fit.summary()/fit.diagnostics(); explicit priors remain important for sparse groups.

values = np.asarray(
    [101, 98, 103, 105, 102, 108, 111, 109, 114, 116, 113, 119,
     121, 118, 123, 126, 124, 129, 131, 128, 134, 136, 133, 139],
    dtype=float,
)

model = rmc.BayesianLocalLevel(
    process_variance_prior=rmc.InverseGammaPrior(shape=3.0, scale=20.0),
    observation_variance_prior=rmc.InverseGammaPrior(shape=3.0, scale=50.0),
    initial_mean=float(values[0]),
    initial_variance=100.0,
)
fit = model.fit(values, chains=4, warmup=500, draws=1_000, seed=42)
forecast = fit.forecast(steps=12, seed=43)

predictive_lower, predictive_upper = forecast.interval(0.95)
level_lower, level_upper = forecast.state_interval(0.95)

# Derived quantities are summarized after calculation within each joint draw.
six_period_totals = forecast.observation_samples[:, :, :6].sum(axis=2)
total_mean = six_period_totals.mean()
total_interval = np.quantile(six_period_totals, [0.025, 0.975])

The observation interval is posterior predictive; the latent-level interval is a credible interval for the expected level. Applications include demand, operations, sensor data, and financial series such as rebate accruals. Rebate payments are only an example: choose a model for settlement timing, zeros, contract drivers, and positive support, with priors matched to observation units.

The fitted Gaussian models support joint Bayesian regressors and Fourier calendar terms, including known future design rows. Calendar coefficients, structural states, and variance parameters remain aligned in posterior forecast paths. Native independent batches fit ragged cells with stable IDs, explicit worker limits, per-cell diagnostics, and collected errors. Annual seasonal models accept histories shorter than two full cycles under proper priors.

For sparse nonnegative amounts, BayesianHurdleLogNormal combines a learned zero probability with dynamic positive severity and bounded log variances. DirichletMultinomialRunoff models payment-event counts by cohort and lag, including unknown ultimate counts and an explicit unscheduled tail. Runoff count inputs represent events; currency amounts need an amount model.

Forecasting examples:

Implemented surface

Area Current support
Generic inference NUTS with configurable target_accept, fixed-trajectory HMC, transformed continuous parameters, parallel chains
Continuous priors Normal, Student-t, HalfNormal, Exponential, LogNormal, Gamma, Beta, Uniform
Likelihoods Normal, Bernoulli-logit, Poisson-log, Exponential, LogNormal, Negative Binomial
Model structure Joint ragged hierarchical means, scalar hierarchical priors, scalar/vector regression expressions, automatic non-centering for supported generic scalar hierarchies
Diagnostics Rank-normalized folded split R-hat, bulk/tail ESS, MCSE and HDIs on generic and specialized fits; sampler-specific divergence/acceptance metadata
Predictive workflow Prior predictive, posterior predictive, pointwise log likelihood, ArviZ export
Repeated models In-memory compile/bind reuse, generic batch sampling, and independent forecasting batches with stable cell IDs
Fixed state space Constant transitions and time-varying observation rows, Kalman filter, RTS smoother, missing observations, joint and cumulative conditional forecasts
Specialized inference Bayesian level/trend/seasonal regression, Fourier calendar features, Gaussian AR(p), sparse hurdle lognormal, and payment-count runoff

Bernoulli and Poisson are exposed for prior-predictive use, but discrete latent parameters are not suitable for the current gradient-based samplers. Fitted AR(p) coefficient draws are not constrained to the stationary region; explosive draws are possible and are not silently discarded.

Validation and benchmarks

The repository includes finite-difference autodiff checks, analytic and synthetic posterior recovery, state-space reference tests, cross-thread determinism checks, Python API tests, and clean-wheel verification.

Run the core verification with:

cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace --release
python -m pytest -q

Run python examples/run_benchmarks.py --help for the benchmark harness. This README does not publish a numeric cross-engine result because the repository does not retain a complete raw output, environment, and revision for one. Use benchmarks/RESULTS_TEMPLATE.md when publishing a result, and report statistical quality together with wall time.

The separate demo-docs synthetic forecasting study retains its generated data, model-selection code, raw outputs, RustMC plots, comparison timings, and negative results. It is a diagnostic example, not a general product benchmark.

Tests establish behavior on their stated reference cases. They do not prove that a new model is appropriate for a user's data or that its intervals are calibrated under misspecification.

Current limitations

  • The expression and distribution surface is deliberately finite; arbitrary user-defined probability functions and broad tensor algebra are not yet supported.
  • Vector-valued hierarchical priors, group indexing, named dimensions, and coordinates are incomplete.
  • Compile/bind artifacts are in-memory only and are not portable or versioned.
  • Initialization controls remain limited; BFMI and explicit termination reasons are not yet reported.
  • The generic state-space API accepts fixed system matrices rather than inferring them.
  • Specialized forecasting lacks covariates/calendar interventions, multiple seasonalities, positive/robust observations, hierarchical pooling, dated outputs, and rolling backtests.
  • Performance has not been established on a representative, retained benchmark corpus.

See ROADMAP.md for the ordered engineering plan and differentiated capability ideas.

Contributing

See CONTRIBUTING.md for development and evidence requirements. Bug reports are most useful when they include a minimal model, seed, environment, diagnostics, and expected result.

License

MIT

Release files for rustmc 0.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rustmc 0.11.0
File Size Uploaded
rustmc-0.11.0.tar.gz 201.3 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for rustmc 0.11.0
File
rustmc-0.11.0-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
rustmc-0.11.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
rustmc-0.11.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details
rustmc-0.11.0-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details
rustmc-0.11.0-cp39-abi3-macosx_10_12_x86_64.whl CPython 3.9 abi3 macOS 10.12+ x86-64 Details

Total release size: 7.4 MB

Release files / rustmc-0.11.0.tar.gz

Download URL rustmc-0.11.0.tar.gz
Size 201.3 kB
Tags Source
SHA-256 checksum
How to use checksums
020cb22827e07b9e77db9d93aeb7cd41703e8d68664ab751b2b93cb2e0690b5c
BLAKE2b-256 checksum
How to use checksums
2976f124d4b66995c57a3e67623f9fe41e819eba6bbe12ce2c01b7e29f406807
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 8, 2026.

Transparency log

Release files / rustmc-0.11.0-cp39-abi3-win_amd64.whl

Download URL rustmc-0.11.0-cp39-abi3-win_amd64.whl
Size 1.3 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
56198e48782cdda3f8b36f1e1dd6273827031b43ca7021c6e0c7208f1eb86f4f
BLAKE2b-256 checksum
How to use checksums
d5490dd0cb0a322ce959465a3ba5309a0b5234cdd1e6df5581aceed5ba2ca012
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 8, 2026.

Transparency log

Release files / rustmc-0.11.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL rustmc-0.11.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 1.6 MB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
b2148a2ebd82213c8f84c75ab7f0fb3e7fd19506a636010652ad6d591558b581
BLAKE2b-256 checksum
How to use checksums
ff86c89674c5f0fa11f6f43d89ddcd0b7149670ed99512b1a54a64270db74242
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 8, 2026.

Transparency log

Release files / rustmc-0.11.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL rustmc-0.11.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 1.5 MB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
1ede1017717e4757cb8c8577b14aad8b9991e1baa3d9ba76e65b3d32b092284a
BLAKE2b-256 checksum
How to use checksums
02541f73504c13ffaf6cdcc8196d43e31763707cec254fd3bc8257884ef81843
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 8, 2026.

Transparency log

Release files / rustmc-0.11.0-cp39-abi3-macosx_11_0_arm64.whl

Download URL rustmc-0.11.0-cp39-abi3-macosx_11_0_arm64.whl
Size 1.4 MB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
3236f8fe2eb889d185ddb458f0ad944eae561b1d8bd2087fa2226de154647c2b
BLAKE2b-256 checksum
How to use checksums
bd54720c6f472d929535f768bd4a1957822f7fb008ccc1456cdefdfbdcb3d0df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 8, 2026.

Transparency log

Release files / rustmc-0.11.0-cp39-abi3-macosx_10_12_x86_64.whl

Download URL rustmc-0.11.0-cp39-abi3-macosx_10_12_x86_64.whl
Size 1.4 MB
Tags CPython 3.9 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
20b3e5a9f0fd848c8520ce7ec5f3b1510f84196cbc91b012fdc769c6f47d7f5c
BLAKE2b-256 checksum
How to use checksums
a50b08d826d269110008b0ab55c7b1f8c0ff842d74f0a9143f726662ed9645f7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 8, 2026.

Transparency log

Release history Release notifications | RSS feed

0.13.0

6 release files

0.12.0

6 release files

This release

0.11.0 This release

6 release files

0.9.0

6 release files

0.8.0

6 release files

0.7.0

6 release files

0.6.0

6 release files

0.5.1

6 release files

0.4.0

5 release files

0.3.1

5 release files

0.3.0

5 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page