GAM core (Rust) with sklearn-style Python bindings — alpha
Project description
gamrs
Generalised Additive Models in Rust — a clean-room reimplementation built on
six composable trait layers (Basis, BasisTransform, Loss/Link/VarianceFn,
InnerSolver, ScoreDerivatives, OuterSolver). Designed for parity with
R's mgcv and the sibling mgcv_rust crate.
Status: alpha. Multi-smooth additive (y ~ s(x0) + s(x1)) and tensor
products (te(x0, x1)) both ship in this release — the latter leap-frogs
mgcv_rust. Shape-aware families (scat, NegBin, Tweedie, Ocat, ELF) are
still single-smooth-only; production users with multi-smooth shape-aware
models should stay on mgcv-rust for now.
What's in this alpha
Families (all 1-D parity, 10 families)
| Family | Link | Inner solver | Outer Newton | Parity (μ rel-err) |
|---|---|---|---|---|
| Gaussian | identity | one-Cholesky | 1-D Newton | ~3e-6 |
| Bernoulli | logit | PIRLS | 1-D Newton | ~1e-3 |
| Poisson | log | PIRLS | 1-D Newton | ~8e-5 |
| QuasiPoisson | log | PIRLS | 1-D Newton (prof φ) | ~2e-4 |
| QuasiBinomial | logit | PIRLS | 1-D Newton (prof φ) | ~7e-5 |
| Gamma | log | PIRLS | 1-D Newton (prof φ) | ~2e-2 |
| InverseGaussian | log | PIRLS | 1-D Newton (prof φ) | ~3e-4 |
| NegBin | log | PIRLS | 2-D joint Newton | ~9e-7 |
| Tweedie | log | PIRLS | 3-D joint Newton | ~2e-1 |
| TDist (scat) | identity | PIRLS | 3-D joint Newton | ~2e-2 |
| Ocat | logit | gam.fit5 | joint β + threshold | smoke |
| Quantile (ELF) | identity | Armijo BT | 1-D Newton | smoke |
Bases
Cr— cubic regression splines (default for 1-D smooths)Re— random effects (bs="re")Tensor<A, B>— anisotropic tensor product (te(x0, x1))
Smooth strategies
- Single 1-D smooth —
y ~ s(x0) - Additive multi-smooth —
y ~ s(x0) + s(x1) + s(x2)(parity with mgcv_rust on Gaussian/Bernoulli/Poisson/Gamma/InvGauss/QuasiPoisson/QuasiBinomial) - Tensor product —
y ~ te(x0, x1)(leap-frogs mgcv_rust; v0.x doesn't have this)
Python API
PyO3 bindings + numpy. sklearn-like with vcov, predict_ci, predict_diff,
serialize/deserialize, GamPredictor for inference-only deployment.
Not in this alpha (follow-ups)
- Multi-smooth shape-aware families — scat/TDist, NegBin, Tweedie, Ocat,
ELF/quantile gated at single-smooth via runtime error. Lifting θ packing
from
[ρ, shape…]to[ρ_0, …, ρ_{T-1}, shape…]is tracked. s(x0, x1)TPRS — isotropic thin-plate; separate basis kind fromte().- 3+ margin tensor products
te(x0, x1, x2)— mechanical generalization. ti(x0, x1)centred tensor interaction — needs main-effect orthogonalisation.
Use (Rust)
use gamrs::{TermSpec, MarginKind, DesignStrategy};
use ndarray::Array2;
let x: Array2<f64> = /* (n, n_input_dims) */;
let y = /* Array1<f64> */;
// Single 1-D smooth
let fit = gamrs::fit(gamrs::family::gaussian_identity(), x.view(), y.view(), None, 10)?;
// Multi-smooth additive
let fit = gamrs::fit_with_design(
gamrs::family::gaussian_identity(),
DesignStrategy::Additive { terms: vec![
TermSpec::Cr { col: 0, k: 10 },
TermSpec::Cr { col: 1, k: 15 },
]},
x.view(), y.view(), None,
)?;
// Tensor product
let fit = gamrs::fit_with_design(
gamrs::family::gaussian_identity(),
DesignStrategy::Additive { terms: vec![
TermSpec::Tensor { col_a: 0, col_b: 1, k_a: 5, k_b: 5, bs_a: MarginKind::Cr, bs_b: MarginKind::Cr },
]},
x.view(), y.view(), None,
)?;
let mu = fit.predict(x.view())?;
Use (Python)
from gamrs import Gam, CrTerm, ReTerm, TeTerm
# Additive multi-smooth
g = Gam(terms=[CrTerm("x0", k=10), CrTerm("x1", k=15)])
g.fit(df, "y")
mu = g.predict(df)
# Tensor product
g = Gam(terms=[TeTerm(cols=("x0", "x1"), k=(5, 5))])
g.fit(df, "y")
Architecture
See architecture-assumptions.md in the repo root and the v2 plan note in
~/ObsidianVault/Projects/mgcv_rust/plans/mgcv_rust - v2 Architecture Plan 2026-05-22.md.
The trait layering (src/traits.rs):
Layer 1 Basis ← CrBasis, RandomEffectsBasis, TensorProductBasis<A, B>
Layer 1.5 BasisTransform ← SumToZero, StableReparam
Layer 2 Loss/Link/Variance ← 10 families (see table above)
Layer 3 InnerSolver ← GaussianClosedFormInner, PirlsInner, GamFit5Inner, ArmijoInner
Layer 4 ScoreDerivatives ← EnvelopeScore, ShapeAwareEnvelopeScore
Layer 5 OuterSolver ← NewtonWithHalving (ρ-dim generic)
Layer 6 FittedGam ← predict, predict_ci, predict_diff, vcov, serialize
Versioning
0.1.0-alpha.x indicates pre-stable. Breaking changes are expected on every
minor bump until shape-aware multi-smooth lands.
License
MIT.
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 gamrs-0.1.0a5.tar.gz.
File metadata
- Download URL: gamrs-0.1.0a5.tar.gz
- Upload date:
- Size: 827.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7381b1f357688274c22f06a3d78b9f7e596689589dfb7a0ae5ecc8a517549435
|
|
| MD5 |
8c8b80af1ff9db685cf2b5a7c706c05d
|
|
| BLAKE2b-256 |
345da0686f1cbf6f92c731e8ffb9e7edd40dd64302dbd863530a20c41bb7478f
|
File details
Details for the file gamrs-0.1.0a5-cp310-cp310-manylinux_2_38_x86_64.whl.
File metadata
- Download URL: gamrs-0.1.0a5-cp310-cp310-manylinux_2_38_x86_64.whl
- Upload date:
- Size: 12.7 MB
- Tags: CPython 3.10, manylinux: glibc 2.38+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74ec55620fc4a29595e6a360e6b0821e16c8af3a57b88291a0cfdf728950bf06
|
|
| MD5 |
f4e26ed163869bd1f90ee119c69249ef
|
|
| BLAKE2b-256 |
23b642ad8ba9b70eb24579c0df5168f6ca5534b9d92039871cf3a49dc99b4857
|