Skip to content

Commit

Permalink
Allow lambda zero for parametrization in Exp distribution. (#972)
Browse files Browse the repository at this point in the history
* Allow lambda zero for parametrization in Exp distribution.

* Inaccurate — "or NaN"

Updated description of LambdaTooSmall error.

* Update CHANGELOG.md
  • Loading branch information
saona-raimundo committed Jul 3, 2020
1 parent fddcac1 commit c9f485a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
1 change: 1 addition & 0 deletions rand_distr/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
- All error types now implement `std::error::Error` (#919)
- Re-exported `rand::distributions::BernoulliError` (#919)
- Add case `lambda = 0` in the parametrixation of `Exp` (#972)

## [0.2.2] - 2019-09-10
- Fix version requirement on rand lib (#847)
Expand Down
26 changes: 19 additions & 7 deletions rand_distr/src/exponential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl Distribution<f64> for Exp1 {
/// The exponential distribution `Exp(lambda)`.
///
/// This distribution has density function: `f(x) = lambda * exp(-lambda * x)`
/// for `x > 0`.
/// for `x > 0`, when `lambda > 0`. For `lambda = 0`, all samples yield infinity.
///
/// Note that [`Exp1`](crate::Exp1) is an optimised implementation for `lambda = 1`.
///
Expand All @@ -98,14 +98,14 @@ pub struct Exp<N> {
/// Error type returned from `Exp::new`.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Error {
/// `lambda <= 0` or `nan`.
/// `lambda < 0` or `nan`.
LambdaTooSmall,
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Error::LambdaTooSmall => "lambda is not positive in exponential distribution",
Error::LambdaTooSmall => "lambda is negative or NaN in exponential distribution",
})
}
}
Expand All @@ -117,9 +117,16 @@ where Exp1: Distribution<N>
{
/// Construct a new `Exp` with the given shape parameter
/// `lambda`.
///
/// # Remarks
///
/// For custom types `N` implementing the [`Float`](crate::Float) trait,
/// the case `lambda = 0` is handled as follows: each sample corresponds
/// to a sample from an `Exp1` multiplied by `1 / 0`. Primitive types
/// yield infinity, since `1 / 0 = infinity`.
#[inline]
pub fn new(lambda: N) -> Result<Exp<N>, Error> {
if !(lambda > N::from(0.0)) {
if !(lambda >= N::from(0.0)) {
return Err(Error::LambdaTooSmall);
}
Ok(Exp {
Expand Down Expand Up @@ -149,15 +156,20 @@ mod test {
}
}
#[test]
#[should_panic]
fn test_exp_invalid_lambda_zero() {
Exp::new(0.0).unwrap();
fn test_zero() {
let d = Exp::new(0.0).unwrap();
assert_eq!(d.sample(&mut crate::test::rng(21)), std::f64::INFINITY);
}
#[test]
#[should_panic]
fn test_exp_invalid_lambda_neg() {
Exp::new(-10.0).unwrap();
}
#[test]
#[should_panic]
fn test_exp_invalid_lambda_nan() {
Exp::new(std::f64::NAN).unwrap();
}

#[test]
fn value_stability() {
Expand Down

0 comments on commit c9f485a

Please sign in to comment.