Skip to content

Commit

Permalink
Poisson distribution falls into an infinite loop for parameter λ=∞ (r…
Browse files Browse the repository at this point in the history
  • Loading branch information
Thopic committed Feb 27, 2023
1 parent 17c8b26 commit 0f3eced
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
1 change: 1 addition & 0 deletions rand_distr/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
This breaks serialization compatibility with older versions.
- Upgrade Rand
- Fix Knuth's method so `Poisson` doesn't return -1.0 for small lambda
- Fix `Poisson` distribution instantiation so it return an error if lambda is infinite

## [0.4.3] - 2021-12-30
- Fix `no_std` build (#1208)
Expand Down
18 changes: 15 additions & 3 deletions rand_distr/src/poisson.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,17 @@ where F: Float + FloatConst, Standard: Distribution<F>
/// Error type returned from `Poisson::new`.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Error {
/// `lambda <= 0` or `nan`.
/// `lambda <= 0`
ShapeTooSmall,
/// `lambda = ∞` or `lambda = nan`
NonFinite,
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Error::ShapeTooSmall => "lambda is not positive in Poisson distribution",
Error::NonFinite => "lambda is infinite or nan in Poisson distribution",
})
}
}
Expand All @@ -66,6 +69,9 @@ where F: Float + FloatConst, Standard: Distribution<F>
/// Construct a new `Poisson` with the given shape parameter
/// `lambda`.
pub fn new(lambda: F) -> Result<Poisson<F>, Error> {
if !lambda.is_finite() {
return Err(Error::NonFinite);
}
if !(lambda > F::zero()) {
return Err(Error::ShapeTooSmall);
}
Expand Down Expand Up @@ -163,7 +169,7 @@ mod test {
fn test_poisson_avg() {
test_poisson_avg_gen::<f64>(10.0, 0.1);
test_poisson_avg_gen::<f64>(15.0, 0.1);

test_poisson_avg_gen::<f32>(10.0, 0.1);
test_poisson_avg_gen::<f32>(15.0, 0.1);

Expand All @@ -178,6 +184,12 @@ mod test {
Poisson::new(0.0).unwrap();
}

#[test]
#[should_panic]
fn test_poisson_invalid_lambda_infinity() {
Poisson::new(f64::INFINITY).unwrap();
}

#[test]
#[should_panic]
fn test_poisson_invalid_lambda_neg() {
Expand All @@ -188,4 +200,4 @@ mod test {
fn poisson_distributions_can_be_compared() {
assert_eq!(Poisson::new(1.0), Poisson::new(1.0));
}
}
}

0 comments on commit 0f3eced

Please sign in to comment.