glmm
Standalone f64 GLM(M) fit kernels — OLS → GLM → LMM → GLMM — in pure Rust on faer.
Fits fixed-effect and mixed (random-intercept/random-slope) models for Gaussian, Binomial (logit/probit), Poisson, Gamma, and Negative-Binomial outcomes, validated against R/lme4 and Julia/MixedModels.jl goldens.
New to the crate? Start with tutorial-rust.md — a
single-page, three-layer walkthrough (cold fit → warm fit → advanced loop)
plus a short section on parsing an R-style formula string instead of building
inputs by hand. Python and R packages are also available — see
Python and R below.
One crate, one fit
A single entry point covers the whole linear-regression family. fit reads
ModelSpec and routes on family × random effects × weights:
flowchart LR
F["fit(x, y, ModelSpec)"] --> RE{"re?"}
RE -- "None" --> FAM1{"family?"}
FAM1 -- "Gaussian" --> OLS["OLS - WLS with weights"]
FAM1 -- "other" --> GLM["GLM - IRLS"]
RE -- "Some" --> FAM2{"family?"}
FAM2 -- "Gaussian" --> LMM["LMM - profiled REML"]
FAM2 -- "other" --> GLMM["GLMM - PIRLS, Laplace/AGQ"]
This is the pitch view. Every branch point, solver path, and tuning knob is
traced to code in the full algorithm map:
documentation/algorithms.md, with the LMM
and GLMM legs detailed in
documentation/algorithms-lmm.md and
documentation/algorithms-glmm.md.
Documentation
The fuller map — entry point, tutorials, examples, migration guides, reference,
and internals, all in one tiered table — lives in
documentation/index.md. The table below is this
README's own copy of the essentials, not the whole set.
| File | Purpose |
|---|---|
documentation/tutorial-rust.md |
Three-layer Rust walkthrough: cold fit → warm fit → advanced loop, plus the formula frontend |
documentation/tutorial-python.md |
The Python package (glmm) walkthrough |
documentation/tutorial-r.md |
The R package (fastglmm) walkthrough |
documentation/supported_families.md |
Family × link support matrix, canonical-link notes, dispersion conventions |
documentation/algorithms.md |
Algorithm map entry point: full dispatch graph, knob index, OLS/GLM paths |
documentation/algorithms-lmm.md |
LMM: θ-Cholesky, profiled REML, closed-form shortcut, BOBYQA, boundary handling |
documentation/algorithms-glmm.md |
GLMM: PIRLS, Laplace vs AGQ, dense vs sparse Z, NB outer loop, warm starts |
documentation/glmm-design.md |
Algorithmic design rationale: the differences from lme4/MixedModels.jl and why each one is faster |
documentation/installation.md |
Installing the Rust crate, Python package, and R package |
documentation/formula.md |
What the formula parser accepts and rejects, with workarounds |
documentation/conventions.md |
Estimation, standard-error, dispersion, and variance-component conventions, and the flags on a fit result |
documentation/validation.md |
How glmm is validated against lme4 and MixedModels.jl, what's covered, and known tolerances/exemptions |
documentation/coming-from-lme4.md |
Call mapping from lme4, what's deliberately missing, and behavioral differences to watch (covers both the R and Python surface) |
documentation/coming-from-statsmodels.md |
Migrating from statsmodels MixedLM/GLM to glmm.fit (Python only) |
documentation/troubleshooting.md |
Fixes for singular fits, non-convergence, NotImplementedError, and rejected formulas |
Scope and stability (0.2.x)
The semver-covered surface is fit_cold/fit_warm + ModelSpec + GroupIds.
| Model | Fixed-only (re: None) |
Mixed (re: Some) |
|---|---|---|
| Gaussian | OLS | LMM — dense, or sparse-Z when an extra grouping carries a random slope |
| Binomial (logit/probit) | GLM | GLMM — dense, or sparse-Z over-envelope |
| Poisson (log) | GLM | GLMM — dense, or sparse-Z over-envelope |
| Gamma (log/inverse) | GLM | GLMM — dense, or sparse-Z over-envelope |
| Negative-Binomial (log) | GLM | GLMM — dense, or sparse-Z over-envelope |
Every wired family fits through both routes — there is no reachable panic for
falling outside the dense solver's envelope (too many extra groupings, or an
extra grouping too wide); classification just routes to the sparse-Z solver
instead. See tutorial-rust.md and
documentation/algorithms-glmm.md for the
dense/sparse routing envelope.
The loop_advanced cargo feature (off by default) exposes an unstable
scratch-explicit hot-path surface for warm-start callers like MCPower's
simulation loop — no semver guarantees; do not depend on it outside a
pinned revision.
The orchestrate cargo feature (off by default) exposes the string-typed fit
orchestration the Python and R packages are built on — one definition of the
family/link string vocabulary, the formula-and-data lowering, and the
flattened result both ports publish. No semver guarantees, for the same
reason as loop_advanced: its shape follows the ports' needs.
The parallel cargo feature (off by default, experimental) enables
in-fit parallelism — the AGQ cluster loop and the FD-Hessian SE grid — via
rayon, and is additionally gated at runtime by FitOptions::parallel_inner
(also off by default): both the feature and the flag must be on for any
thread to spawn. Parallel results are bit-identical to serial ones, but the
kernels are new and their performance envelope isn't characterized yet —
treat as opt-in only. A no-op on wasm32 (compile-time excluded, rayon never
pulled in).
Quick example
use ;
// y ~ x + (1 | group), Gaussian — a random-intercept LMM.
let model = ModelSpec ;
let ids = GroupIds ;
// target_indices = which coefficients get a standard error; here, both.
let opts = FitOptions ;
let fit = fit_cold;
assert!;
See tutorial-rust.md for the full walkthrough: warm
starts, the advanced hot-loop surface, and building x/ModelSpec/GroupIds
from a formula string with glmm::formula (the formula feature, on by default)
instead of by hand.
Python and R
The same kernel ships as a Python package and an R package. Both take a data table and an R-style formula — no design matrices by hand.
Python (glmm on PyPI; Python 3.10+, NumPy is the only dependency):
= # data: dict / pandas / polars
The public surface is six names: glmm.fit, glmm.Fit, and the four warning
categories the diagnostics channel raises. See the
Python README and
tutorial-python.md.
R (fastglmm, via r-universe):
fit <-
# plus fixef, ranef, fitted, vcov, VarCorr, confint, logLik, isSingular
Deliberately scoped to fast fitting — anything the engine cannot compute
honestly (predict, residuals) errors with the reason instead of guessing.
See the R README and
tutorial-r.md.
Design
| Property | Detail |
|---|---|
No unsafe |
zero unsafe (workspace baseline unsafe_code = "warn") |
| Deterministic | no RNG, no global state, no I/O in the fit path |
| Linear algebra | faer 0.24, pinned |
| MSRV | Rust 1.85 (floor set by the bobyqa dep) |
Origin
glmm was carved out of MCPower's
simulation engine — the numerics here are the same validation-pinned kernels that
power MCPower's Monte Carlo fits, split out so they're usable standalone. The
loop_advanced feature above exists specifically to serve MCPower's
warm-start hot loop as a consumer of this crate.
License
GPL-3.0-or-later (coupled to the GPL-3 MCPower flagship).
Paweł Lenartowicz — Freestyler Scientist · GitHub · ORCID