blr-core 0.1.0

Bayesian Linear Regression with Automatic Relevance Determination for interpretable, sparse modeling in embedded and WASM environments
Documentation

blr-core: Bayesian Linear Regression (BLR) with Automatic Relevance Detection (ARD)

Pure-Rust BLR+ARD curve fitting for interpretable, sparse modeling at the edge.

Crates.io Docs License

What Is blr-core?

blr-core is a production-ready Bayesian Linear Regression (BLR) engine with Automatic Relevance Determination (ARD) — a statistically principled approach to sparse, interpretable curve fitting with automatic hyperparameter tuning.

Why BLR?

Standard least-squares regression gives point estimates, not calibrated uncertainty. BLR inverts this:

  • Uncertainty propagation — every prediction includes epistemic (model) and aleatoric (measurement noise) uncertainty bounds
  • Principled regularization — Bayesian priors naturally prevent overfitting without manual hyperparameter tuning
  • Interpretability — posterior weights and their covariance tell you exactly what the model learned
  • Empirical Bayes — noise level is estimated from data, not guessed
  • Single-model inference — marginalizes over weight uncertainty for well-calibrated predictions, avoiding ensemble complexity

Why ARD?

Traditional regression requires manual feature selection and hyperparameter tuning. ARD eliminates both by learning which input features are truly relevant to your problem, automatically driving irrelevant ones to zero. You get:

  • Automatic sparse models — only the features that matter remain active
  • Calibrated uncertainty — each prediction includes epistemic and aleatoric uncertainty bounds
  • Interpretability — understand exactly why the model makes decisions
  • Zero manual tuning — the EM algorithm learns hyperparameters from data

Industrial Curve Fitting & Sensor Calibration

blr-core is purpose-built for Industry 4.0 regression tasks:

  • Sensor calibration — fit physics-based models to sensor data; quantify measurement uncertainty
  • Anomaly detection — ARD automatically flags broken or misconfigured sensors
  • Real-time inference — predict on new data with propagated uncertainty in milliseconds
  • Edge deployment — runs on embedded controllers, IoT devices, and WebAssembly runtimes

Designed for Integration

blr-core is intentionally lightweight and composable:

  • Minimal dependencies — pure Rust + faer for linear algebra
  • WASM-first — compiles to wasm32-wasip2 with no unsafe code in core logic
  • Embeddable — integrate directly or wrap as a service/component in larger systems

Features

  • Sparse Feature Selection: ARD automatically discovers and deactivates irrelevant features
  • Uncertainty Quantification: Epistemic and aleatoric uncertainty decomposition
  • Noise Estimation: Automated residual analysis and noise floor detection
  • Physics-Aware Basis Functions: Polynomial, RBF, and sensor-specific feature maps
  • WASM-Ready: Compiles to wasm32-wasip2 with no unsafe code in core logic
  • Production-Ready: Extensive test coverage, benchmark harness, zero panics on valid inputs
  • No external runtime: Pure CPU math via faer

Installation

Add to your Cargo.toml:

[dependencies]
blr-core = "0.1"

Quick Start

use blr_core::{features, fit, ArdConfig};

// Fit a sparse model to a synthetic dataset
// True model: y = 2·x + 0.5·x² + noise
let n = 30;
let x: Vec<f64> = (0..n)
    .map(|i| -3.0 + 6.0 * (i as f64) / (n as f64 - 1.0))
    .collect();
let y: Vec<f64> = x.iter()
    .map(|xi| 2.0 * xi + 0.5 * xi * xi + 0.2 * xi.sin())
    .collect();

// Polynomial feature basis: [1, x, x², x³]
let (phi, d) = features::polynomial(&x, 3);

// Fit with ARD — automatically discovers irrelevant features
let config = ArdConfig {
    max_iter: 200,
    tol: 1e-6,
    ..ArdConfig::default()
};
let fitted = fit(&phi, &y, n, d, &config)?;

// Inspect results
println!("Noise std:        {:.4}", fitted.noise_std());
println!("Relevant features: {}/{}", 
    fitted.relevant_features(None).iter().filter(|&&x| x).count(), d);
println!("Active weights:   {:?}", &fitted.posterior.mean[..d]);

// Predict with uncertainty on new data
let x_test = vec![-1.0, 0.0, 1.0];
let (phi_test, _) = features::polynomial(&x_test, 3);
let pred = fitted.predict(&phi_test, 3, d);
println!("Predictions (mean ± std):");
for (i, &mu) in pred.mean.iter().enumerate() {
    println!("  x={:5.1}:  {: .3} ± {:.3}", x_test[i], mu, pred.total_std[i]);
}
# Ok::<(), blr_core::BLRError>(())

How It Works

BLR assumes a Gaussian likelihood over observations: each target y_n equals the dot product of a feature vector φ_n with a weight vector w, plus Gaussian noise with precision β.

ARD places an independent Gaussian prior on each weight w_d with its own precision hyperparameter α_d. The EM algorithm iteratively updates both the posterior over weights and the hyperparameters. Features with low signal drive α_d → ∞, effectively removing those weights from the model.

The result is a sparse, interpretable model with calibrated uncertainty estimates — ideal for sensor calibration where only a few physics-based features truly explain the sensor's behaviour.

Core Modules

Module Purpose
gaussian Multivariate Gaussian utilities
ard BLR+ARD fitting, predictions, evidence computation
noise_estimation Automated noise characterisation
features Polynomial, RBF, and custom basis functions
synthetic_data Benchmark datasets and physics simulators

Examples

Run examples directly:

cargo run --example quick_start -p blr-core
cargo run --example noise_estimation_workflow -p blr-core
cargo run --example hall_sensor -p blr-core

Performance

Quick reference on a single core (Intel i7-12700K, --release):

N (obs) D (features) Fit time
30 6 ~3 ms
60 11 ~12 ms
500 30 ~240 ms

See BENCHMARK_GUIDE.md for detailed benchmarks, hardware requirements, and how to reproduce and interpret results.

Running Benchmarks

# Run all benchmarks (~2 minutes)
cargo bench -p blr-core

# Run a specific benchmark
cargo bench -p blr-core -- "fit_medium"

WASM Deployment

cargo build -p blr-core --target wasm32-wasip2 --release

See PYTHON_BINDINGS.md for integration with Python via Wasmtime.

When NOT to Use blr-core

  • High-dimensional features: Covariance matrix inversion scales O(D³); becomes prohibitive for D > ~30–50.
  • Deep non-linear functions: BLR is a linear model in the feature space.
  • Multi-output regression: Current implementation is single-output only.
  • Hard real-time deadlines: EM convergence is iterative; worst-case runtime is bounded by max_iter but not cycle-exact.

Compatibility

  • Rust: 1.70+
  • Platforms: Linux, macOS, Windows, WebAssembly (WASI Preview 2)
  • License: Apache 2.0
  • Key dependency: faer — pure-Rust linear algebra

References

  • Tipping, M. E. (2001). "Sparse Bayesian learning and the relevance vector machine." Journal of Machine Learning Research, 1, 211–244.
  • Bishop, C. M. (2006). Pattern Recognition and Machine Learning. Springer.
  • Hennig, P. (2025). Probabilistic Machine Learning | 2025 . University of Tübingen.
  • MacKay, D. J. C. (1992). "Bayesian Interpolation." Neural Computation, 4(3), 415–447.

License

Licensed under the Apache License, Version 2.0. See LICENSE for details.

Acknowledgments

Part of the Wamli initiative - WAMLI - "WASM Machine Learning Inference". Special thanks to the ByteCode Alliance for WASI standardisation and the Wasmtime project for runtime support.