diff --git a/benches/benches/distr.rs b/benches/benches/distr.rs index 63d6a1034ee..ec43e7e61cc 100644 --- a/benches/benches/distr.rs +++ b/benches/benches/distr.rs @@ -159,7 +159,7 @@ fn bench(c: &mut Criterion) { g.finish(); let mut g = c.benchmark_group("zipf"); - distr_float!(g, "zipf", f64, Zipf::new(10, 1.5).unwrap()); + distr_float!(g, "zipf", f64, Zipf::new(10.0, 1.5).unwrap()); distr_float!(g, "zeta", f64, Zeta::new(1.5).unwrap()); g.finish(); diff --git a/rand_distr/CHANGELOG.md b/rand_distr/CHANGELOG.md index 8e6cfff686b..fc597d47763 100644 --- a/rand_distr/CHANGELOG.md +++ b/rand_distr/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Mark `WeightError`, `PoissonError`, `BinomialError` as `#[non_exhaustive]` (#1480). - Remove support for generating `isize` and `usize` values with `Standard`, `Uniform` and `Fill` and usage as a `WeightedAliasIndex` weight (#1487) - Limit the maximal acceptable lambda for `Poisson` to solve (#1312) (#1498) +- Change parameter type of `Zipf::new`: `n` is now floating-point (#1518) ### Added - Add plots for `rand_distr` distributions to documentation (#1434) diff --git a/rand_distr/src/zipf.rs b/rand_distr/src/zipf.rs index 9d98458db08..45a8bf2b5cb 100644 --- a/rand_distr/src/zipf.rs +++ b/rand_distr/src/zipf.rs @@ -35,7 +35,7 @@ use rand::Rng; /// use rand::prelude::*; /// use rand_distr::Zipf; /// -/// let val: f64 = rand::rng().sample(Zipf::new(10, 1.5).unwrap()); +/// let val: f64 = rand::rng().sample(Zipf::new(10.0, 1.5).unwrap()); /// println!("{}", val); /// ``` /// @@ -92,16 +92,17 @@ where /// Construct a new `Zipf` distribution for a set with `n` elements and a /// frequency rank exponent `s`. /// - /// For large `n`, rounding may occur to fit the number into the float type. + /// The parameter `n` is typically integral, however we use type + ///
F: [Float]
in order to permit very large values + /// and since our implementation requires a floating-point type. #[inline] - pub fn new(n: u64, s: F) -> Result, Error> { + pub fn new(n: F, s: F) -> Result, Error> { if !(s >= F::zero()) { return Err(Error::STooSmall); } - if n < 1 { + if n < F::one() { return Err(Error::NTooSmall); } - let n = F::from(n).unwrap(); // This does not fail. let q = if s != F::one() { // Make sure to calculate the division only once. F::one() / (F::one() - s) @@ -173,24 +174,24 @@ mod tests { #[test] #[should_panic] fn zipf_s_too_small() { - Zipf::new(10, -1.).unwrap(); + Zipf::new(10., -1.).unwrap(); } #[test] #[should_panic] fn zipf_n_too_small() { - Zipf::new(0, 1.).unwrap(); + Zipf::new(0., 1.).unwrap(); } #[test] #[should_panic] fn zipf_nan() { - Zipf::new(10, f64::NAN).unwrap(); + Zipf::new(10., f64::NAN).unwrap(); } #[test] fn zipf_sample() { - let d = Zipf::new(10, 0.5).unwrap(); + let d = Zipf::new(10., 0.5).unwrap(); let mut rng = crate::test::rng(2); for _ in 0..1000 { let r = d.sample(&mut rng); @@ -200,7 +201,7 @@ mod tests { #[test] fn zipf_sample_s_1() { - let d = Zipf::new(10, 1.).unwrap(); + let d = Zipf::new(10., 1.).unwrap(); let mut rng = crate::test::rng(2); for _ in 0..1000 { let r = d.sample(&mut rng); @@ -210,7 +211,7 @@ mod tests { #[test] fn zipf_sample_s_0() { - let d = Zipf::new(10, 0.).unwrap(); + let d = Zipf::new(10., 0.).unwrap(); let mut rng = crate::test::rng(2); for _ in 0..1000 { let r = d.sample(&mut rng); @@ -221,7 +222,7 @@ mod tests { #[test] fn zipf_sample_large_n() { - let d = Zipf::new(u64::MAX, 1.5).unwrap(); + let d = Zipf::new(f64::MAX, 1.5).unwrap(); let mut rng = crate::test::rng(2); for _ in 0..1000 { let r = d.sample(&mut rng); @@ -232,12 +233,12 @@ mod tests { #[test] fn zipf_value_stability() { - test_samples(Zipf::new(10, 0.5).unwrap(), 0f32, &[10.0, 2.0, 6.0, 7.0]); - test_samples(Zipf::new(10, 2.0).unwrap(), 0f64, &[1.0, 2.0, 3.0, 2.0]); + test_samples(Zipf::new(10., 0.5).unwrap(), 0f32, &[10.0, 2.0, 6.0, 7.0]); + test_samples(Zipf::new(10., 2.0).unwrap(), 0f64, &[1.0, 2.0, 3.0, 2.0]); } #[test] fn zipf_distributions_can_be_compared() { - assert_eq!(Zipf::new(1, 2.0), Zipf::new(1, 2.0)); + assert_eq!(Zipf::new(1.0, 2.0), Zipf::new(1.0, 2.0)); } } diff --git a/rand_distr/tests/cdf.rs b/rand_distr/tests/cdf.rs index 8eb22740e2b..86e926af00e 100644 --- a/rand_distr/tests/cdf.rs +++ b/rand_distr/tests/cdf.rs @@ -385,7 +385,7 @@ fn zipf() { let parameters = [(1000, 1.0), (500, 2.0), (1000, 0.5)]; for (seed, (n, x)) in parameters.into_iter().enumerate() { - let dist = rand_distr::Zipf::new(n, x).unwrap(); + let dist = rand_distr::Zipf::new(n as f64, x).unwrap(); test_discrete(seed as u64, dist, |k| cdf(k, n, x)); } }