Skip to content

Commit ad67294

Browse files
authored
Zipf: let n have type F (#1518)
1 parent 585b29f commit ad67294

File tree

4 files changed

+19
-17
lines changed

4 files changed

+19
-17
lines changed

benches/benches/distr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ fn bench(c: &mut Criterion<CyclesPerByte>) {
159159
g.finish();
160160

161161
let mut g = c.benchmark_group("zipf");
162-
distr_float!(g, "zipf", f64, Zipf::new(10, 1.5).unwrap());
162+
distr_float!(g, "zipf", f64, Zipf::new(10.0, 1.5).unwrap());
163163
distr_float!(g, "zeta", f64, Zeta::new(1.5).unwrap());
164164
g.finish();
165165

rand_distr/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
- Mark `WeightError`, `PoissonError`, `BinomialError` as `#[non_exhaustive]` (#1480).
1414
- Remove support for generating `isize` and `usize` values with `Standard`, `Uniform` and `Fill` and usage as a `WeightedAliasIndex` weight (#1487)
1515
- Limit the maximal acceptable lambda for `Poisson` to solve (#1312) (#1498)
16+
- Change parameter type of `Zipf::new`: `n` is now floating-point (#1518)
1617

1718
### Added
1819
- Add plots for `rand_distr` distributions to documentation (#1434)

rand_distr/src/zipf.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use rand::Rng;
3535
/// use rand::prelude::*;
3636
/// use rand_distr::Zipf;
3737
///
38-
/// let val: f64 = rand::rng().sample(Zipf::new(10, 1.5).unwrap());
38+
/// let val: f64 = rand::rng().sample(Zipf::new(10.0, 1.5).unwrap());
3939
/// println!("{}", val);
4040
/// ```
4141
///
@@ -92,16 +92,17 @@ where
9292
/// Construct a new `Zipf` distribution for a set with `n` elements and a
9393
/// frequency rank exponent `s`.
9494
///
95-
/// For large `n`, rounding may occur to fit the number into the float type.
95+
/// The parameter `n` is typically integral, however we use type
96+
/// <pre><code>F: [Float]</code></pre> in order to permit very large values
97+
/// and since our implementation requires a floating-point type.
9698
#[inline]
97-
pub fn new(n: u64, s: F) -> Result<Zipf<F>, Error> {
99+
pub fn new(n: F, s: F) -> Result<Zipf<F>, Error> {
98100
if !(s >= F::zero()) {
99101
return Err(Error::STooSmall);
100102
}
101-
if n < 1 {
103+
if n < F::one() {
102104
return Err(Error::NTooSmall);
103105
}
104-
let n = F::from(n).unwrap(); // This does not fail.
105106
let q = if s != F::one() {
106107
// Make sure to calculate the division only once.
107108
F::one() / (F::one() - s)
@@ -173,24 +174,24 @@ mod tests {
173174
#[test]
174175
#[should_panic]
175176
fn zipf_s_too_small() {
176-
Zipf::new(10, -1.).unwrap();
177+
Zipf::new(10., -1.).unwrap();
177178
}
178179

179180
#[test]
180181
#[should_panic]
181182
fn zipf_n_too_small() {
182-
Zipf::new(0, 1.).unwrap();
183+
Zipf::new(0., 1.).unwrap();
183184
}
184185

185186
#[test]
186187
#[should_panic]
187188
fn zipf_nan() {
188-
Zipf::new(10, f64::NAN).unwrap();
189+
Zipf::new(10., f64::NAN).unwrap();
189190
}
190191

191192
#[test]
192193
fn zipf_sample() {
193-
let d = Zipf::new(10, 0.5).unwrap();
194+
let d = Zipf::new(10., 0.5).unwrap();
194195
let mut rng = crate::test::rng(2);
195196
for _ in 0..1000 {
196197
let r = d.sample(&mut rng);
@@ -200,7 +201,7 @@ mod tests {
200201

201202
#[test]
202203
fn zipf_sample_s_1() {
203-
let d = Zipf::new(10, 1.).unwrap();
204+
let d = Zipf::new(10., 1.).unwrap();
204205
let mut rng = crate::test::rng(2);
205206
for _ in 0..1000 {
206207
let r = d.sample(&mut rng);
@@ -210,7 +211,7 @@ mod tests {
210211

211212
#[test]
212213
fn zipf_sample_s_0() {
213-
let d = Zipf::new(10, 0.).unwrap();
214+
let d = Zipf::new(10., 0.).unwrap();
214215
let mut rng = crate::test::rng(2);
215216
for _ in 0..1000 {
216217
let r = d.sample(&mut rng);
@@ -221,7 +222,7 @@ mod tests {
221222

222223
#[test]
223224
fn zipf_sample_large_n() {
224-
let d = Zipf::new(u64::MAX, 1.5).unwrap();
225+
let d = Zipf::new(f64::MAX, 1.5).unwrap();
225226
let mut rng = crate::test::rng(2);
226227
for _ in 0..1000 {
227228
let r = d.sample(&mut rng);
@@ -232,12 +233,12 @@ mod tests {
232233

233234
#[test]
234235
fn zipf_value_stability() {
235-
test_samples(Zipf::new(10, 0.5).unwrap(), 0f32, &[10.0, 2.0, 6.0, 7.0]);
236-
test_samples(Zipf::new(10, 2.0).unwrap(), 0f64, &[1.0, 2.0, 3.0, 2.0]);
236+
test_samples(Zipf::new(10., 0.5).unwrap(), 0f32, &[10.0, 2.0, 6.0, 7.0]);
237+
test_samples(Zipf::new(10., 2.0).unwrap(), 0f64, &[1.0, 2.0, 3.0, 2.0]);
237238
}
238239

239240
#[test]
240241
fn zipf_distributions_can_be_compared() {
241-
assert_eq!(Zipf::new(1, 2.0), Zipf::new(1, 2.0));
242+
assert_eq!(Zipf::new(1.0, 2.0), Zipf::new(1.0, 2.0));
242243
}
243244
}

rand_distr/tests/cdf.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ fn zipf() {
385385
let parameters = [(1000, 1.0), (500, 2.0), (1000, 0.5)];
386386

387387
for (seed, (n, x)) in parameters.into_iter().enumerate() {
388-
let dist = rand_distr::Zipf::new(n, x).unwrap();
388+
let dist = rand_distr::Zipf::new(n as f64, x).unwrap();
389389
test_discrete(seed as u64, dist, |k| cdf(k, n, x));
390390
}
391391
}

0 commit comments

Comments
 (0)