diff --git a/src/distribution/geometric.rs b/src/distribution/geometric.rs index e794fdf9..3d3b37c9 100644 --- a/src/distribution/geometric.rs +++ b/src/distribution/geometric.rs @@ -153,6 +153,23 @@ impl DiscreteCDF for Geometric { ((-self.p).ln_1p() * (x as f64)).exp() } } + + /// Calculates the inverse cumulative distribution function (quantile) for the + /// geometric distribution using its closed-form expression. Keeps behavior + /// consistent across platforms without relying on bisection. + fn inverse_cdf(&self, p: f64) -> u64 { + assert!((0.0..=1.0).contains(&p), "p must be on [0,1]"); + if p <= 0.0 || prec::ulps_eq!(self.p, 1.0) { + return 1; + } + if p >= 1.0 { + return u64::MAX; + } + + // k = ceil(log(1 - p) / log(1 - self.p)), clamped to domain ≥ 1. + let k = ((-p).ln_1p() / (-self.p).ln_1p()).ceil().max(1.0); + if k.is_finite() { k as u64 } else { u64::MAX } + } } impl Min for Geometric { diff --git a/src/distribution/inverse_gamma.rs b/src/distribution/inverse_gamma.rs index 9b029e43..21a576ee 100644 --- a/src/distribution/inverse_gamma.rs +++ b/src/distribution/inverse_gamma.rs @@ -344,7 +344,6 @@ impl Continuous for InverseGamma { mod tests { use super::*; use crate::distribution::internal::density_util; - use crate::distribution::internal::testing_boiler; testing_boiler!(shape: f64, rate: f64; InverseGamma; InverseGammaError); diff --git a/src/distribution/laplace.rs b/src/distribution/laplace.rs index 12c4da36..9284e2ad 100644 --- a/src/distribution/laplace.rs +++ b/src/distribution/laplace.rs @@ -323,7 +323,6 @@ mod tests { use super::*; use crate::prec; - use crate::distribution::internal::testing_boiler; testing_boiler!(location: f64, scale: f64; Laplace; LaplaceError); diff --git a/src/distribution/log_normal.rs b/src/distribution/log_normal.rs index 4e937124..0b39af1c 100644 --- a/src/distribution/log_normal.rs +++ b/src/distribution/log_normal.rs @@ -364,7 +364,6 @@ impl Continuous for LogNormal { mod tests { use super::*; use crate::distribution::internal::density_util; - use crate::distribution::internal::testing_boiler; testing_boiler!(location: f64, scale: f64; LogNormal; LogNormalError); diff --git a/src/distribution/negative_binomial.rs b/src/distribution/negative_binomial.rs index 3e15ff48..7d9ba846 100644 --- a/src/distribution/negative_binomial.rs +++ b/src/distribution/negative_binomial.rs @@ -323,7 +323,6 @@ impl Discrete for NegativeBinomial { mod tests { use super::*; use crate::distribution::internal::density_util; - use crate::distribution::internal::testing_boiler; testing_boiler!(r: f64, p: f64; NegativeBinomial; NegativeBinomialError); diff --git a/src/distribution/poisson.rs b/src/distribution/poisson.rs index 78e06da2..5d04d379 100644 --- a/src/distribution/poisson.rs +++ b/src/distribution/poisson.rs @@ -342,7 +342,6 @@ pub fn sample_unchecked(rng: &mut R, lambda: f64) -> f6 mod tests { use super::*; use crate::distribution::internal::density_util; - use crate::distribution::internal::testing_boiler; testing_boiler!(lambda: f64; Poisson; PoissonError); #[test] diff --git a/src/distribution/triangular.rs b/src/distribution/triangular.rs index c8954901..e24fe110 100644 --- a/src/distribution/triangular.rs +++ b/src/distribution/triangular.rs @@ -438,7 +438,6 @@ fn sample_unchecked(rng: &mut R, min: f64, max: f64, mo mod tests { use super::*; use crate::distribution::internal::density_util; - use crate::distribution::internal::testing_boiler; testing_boiler!(min: f64, max: f64, mode: f64; Triangular; TriangularError); diff --git a/src/distribution/uniform.rs b/src/distribution/uniform.rs index bdb87444..9b26ef23 100644 --- a/src/distribution/uniform.rs +++ b/src/distribution/uniform.rs @@ -348,7 +348,6 @@ mod tests { use super::*; use crate::prec; use crate::distribution::internal::density_util; - use crate::distribution::internal::testing_boiler; testing_boiler!(min: f64, max: f64; Uniform; UniformError); diff --git a/src/distribution/weibull.rs b/src/distribution/weibull.rs index d3cc8748..3a563849 100644 --- a/src/distribution/weibull.rs +++ b/src/distribution/weibull.rs @@ -381,7 +381,6 @@ impl Continuous for Weibull { mod tests { use super::*; use crate::distribution::internal::density_util; - use crate::distribution::internal::testing_boiler; testing_boiler!(shape: f64, scale: f64; Weibull; WeibullError);