Expand description
Binomial maximum-likelihood numerics, for the
BinomialLikelihood.
§Model
N independent draws from Binomial(n_trials, p), observed as per-draw
success counts x ∈ {0, 1, …, n_trials} stored as f64. The single free
parameter is the success probability p ∈ (0, 1), so n_params() == 1. The
total log-likelihood is
ℓ(p; x) = Σᵢ [ ln C(n, xᵢ) + xᵢ ln p + (n − xᵢ) ln(1 − p) ]matching scipy.stats.binom.logpmf(x, n, p).sum().
§Design: where n_trials lives
The frozen LogLikelihood trait carries
no slot for the number of trials — its log_likelihood(params, data) sees
only the free parameter vector and the data. The
BinomialLikelihood struct, however, already carries a
number_of_trials field, so this
module attaches the numerics directly to that struct and reads n_trials
from it (rather than introducing a separate wrapper type). This keeps the
trait impl honest — n_trials is genuine model state owned by the model —
and lets fit_mle fit a &BinomialLikelihood
directly. Construct the model with the trials set, e.g.
BinomialLikelihood { number_of_trials: 10, ..Default::default() }.
§Examples
use stats_claw::likelihood::BinomialLikelihood;
use stats_claw::likelihood::LogLikelihood;
let model = BinomialLikelihood { number_of_trials: 10, ..Default::default() };
// scipy: binom.logpmf([3,5,2,4,6], 10, 0.4).sum() = -8.83278496896409
let ll = model.log_likelihood(&[0.4], &[3.0, 5.0, 2.0, 4.0, 6.0]);
assert!((ll - -8.832_784_968_964_091_4).abs() < 1e-10, "ll was {ll}");