Skip to content

feat: add BernoulliDistribution and ErlangDistribution — delegation wrappers over Binomial and Gamma #55

Description

@OldCrow

Summary

Add two distributions that are thin delegation wrappers over existing implementations, requiring no new mathematical primitives.

BernoulliDistribution

Bernoulli(p) is Binomial(n=1, p). All PDF/CDF/quantile/sample operations delegate to the existing BinomialDistribution.

  • PMF: P(X=1) = p, P(X=0) = 1-p
  • Mean = p, Variance = p(1-p), Skewness = (1-2p)/√(p(1-p))
  • MLE: p̂ = x̄ (sample proportion)
  • Rationale for explicit class: Bernoulli is a named distribution that users will search for by name; it also provides a natural base for composition (Beta-Bernoulli, Bernoulli trials). scipy and Boost.Math both expose it separately despite the Binomial relationship.
  • Implementation: kDistributionType = BERNOULLI; all methods call BinomialDistribution(1, p_) equivalents; is_delegation_wrapper = true in kDistributionMeta

ErlangDistribution

Erlang(k, λ) is Gamma(α=k, β=λ) with the constraint that k is a positive integer. All operations delegate to GammaDistribution.

  • Mean = k/λ, Variance = k/λ², Skewness = 2/√k
  • MLE: k̂ estimated via method of moments (k̂ = x̄²/s²) then rounded to nearest integer; λ̂ = k̂/x̄
  • Use cases: queuing theory (sum of k exponential waiting times), network packet delays, reliability of k-of-n systems
  • Named separately from Gamma because Erlang is the standard name in queuing and telecoms contexts; integer shape constraint enables MLE simplification
  • Implementation: store k (int) and λ (double); validate k ≥ 1; delegate to GammaDistribution(k, 1.0/λ) — note the rate vs scale parameterisation

Implementation notes

  • Both follow the full 6-step registration checklist in include/core/distribution_meta.h
  • Append BERNOULLI and ERLANG enum values to include/core/distribution_type.h
  • Dispatch thresholds: copy from Binomial (BERNOULLI) and Gamma (ERLANG) respectively — the delegate's thresholds apply directly
  • is_delegation_wrapper = true for both in the metadata table
  • getDistributionName() returns "BernoulliDistribution" / "ErlangDistribution" for clarity in output

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions