Skip to content

Resolve Clippy lints, replace rand::rngs::mock::StepRng #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion distr_test/tests/cdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ fn geometric() {
#[test]
fn hypergeometric() {
fn cdf(x: i64, n: u64, k: u64, n_: u64) -> f64 {
let min = if n_ + k > n { n_ + k - n } else { 0 };
let min = (n_ + k).saturating_sub(n);
let max = k.min(n_);
if x < min as i64 {
return 0.0;
Expand Down
8 changes: 4 additions & 4 deletions distr_test/tests/ks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ pub fn test_continuous(seed: u64, dist: impl Distribution<f64>, cdf: impl Fn(f64

let critical_value = critical_value();

println!("KS statistic: {}", ks_statistic);
println!("Critical value: {}", critical_value);
println!("KS statistic: {ks_statistic}");
println!("Critical value: {critical_value}");
assert!(ks_statistic < critical_value);
}

Expand All @@ -131,7 +131,7 @@ where
// This critical value is bigger than it could be for discrete distributions, but because of large sample sizes this should not matter too much
let critical_value = critical_value();

println!("KS statistic: {}", ks_statistic);
println!("Critical value: {}", critical_value);
println!("KS statistic: {ks_statistic}");
println!("Critical value: {critical_value}");
assert!(ks_statistic < critical_value);
}
3 changes: 3 additions & 0 deletions distr_test/tests/skew_normal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ fn owen_t(h: f64, a: f64) -> f64 {
}

fn normal_cdf(x: f64, mean: f64, std_dev: f64) -> f64 {
// f64::erfc from feature `float_erf` may be used over special::Primitive::erfc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this is a reproducibility hazard.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is, but if I add #![feature(float_erf)] to the module then the test still passes (with a warning that special::Primitive is unused).

#![allow(unstable_name_collisions)]

0.5 * ((mean - x) / (std_dev * core::f64::consts::SQRT_2)).erfc()
}

Expand Down
2 changes: 1 addition & 1 deletion src/beta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ mod test {
let beta = Beta::<f64>::new(1e-3, 1e-3).unwrap();
let mut rng = crate::test::rng(206);
for i in 0..1000 {
assert!(!beta.sample(&mut rng).is_nan(), "failed at i={}", i);
assert!(!beta.sample(&mut rng).is_nan(), "failed at i={i}");
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/cauchy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,11 @@ mod test {
}
let median = median(&mut numbers);
#[cfg(feature = "std")]
std::println!("Cauchy median: {}", median);
std::println!("Cauchy median: {median}");
assert!((median - 10.0).abs() < 0.4); // not 100% certain, but probable enough
let mean = sum / 1000.0;
#[cfg(feature = "std")]
std::println!("Cauchy mean: {}", mean);
std::println!("Cauchy mean: {mean}");
// for a Cauchy distribution the mean should not converge
assert!((mean - 10.0).abs() > 0.4); // not 100% certain, but probable enough
}
Expand Down
7 changes: 4 additions & 3 deletions src/triangular.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,12 @@ where
#[cfg(test)]
mod test {
use super::*;
use rand::{rngs::mock, Rng};
use crate::utils::ConstRng;
use rand::Rng;

#[test]
fn test_triangular() {
let mut half_rng = mock::StepRng::new(0x8000_0000_0000_0000, 0);
let mut half_rng = ConstRng(0x8000_0000_0000_0000);
assert_eq!(half_rng.random::<f64>(), 0.5);
for &(min, max, mode, median) in &[
(-1., 1., 0., 0.),
Expand All @@ -128,7 +129,7 @@ mod test {
(-4., -0.5, -2., -4.0 + 3.5f64.sqrt()),
] {
#[cfg(feature = "std")]
std::println!("{} {} {} {}", min, max, mode, median);
std::println!("{min} {max} {mode} {median}");
let distr = Triangular::new(min, max, mode).unwrap();
// Test correct value at median:
assert_eq!(distr.sample(&mut half_rng), median);
Expand Down
20 changes: 19 additions & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ use num_traits::Float; // Used for `no_std` to get `f64::abs()` working before `
use rand::distr::hidden_export::IntoFloat;
use rand::Rng;

/// An RNG yielding a constant value
#[cfg(test)]
pub(crate) struct ConstRng(pub(crate) u64);
#[cfg(test)]
impl rand::RngCore for ConstRng {
fn next_u32(&mut self) -> u32 {
self.next_u64() as u32
}

fn next_u64(&mut self) -> u64 {
self.0
}

fn fill_bytes(&mut self, _: &mut [u8]) {
unimplemented!()
}
}

/// Sample a random number using the Ziggurat method (specifically the
/// ZIGNOR variant from Doornik 2005). Most of the arguments are
/// directly from the paper:
Expand All @@ -25,7 +43,7 @@ use rand::Rng;
/// * `F_DIFF`: precomputed values of $f(x_i) - f(x_{i+1})$
/// * `pdf`: the probability density function
/// * `zero_case`: manual sampling from the tail when we chose the
/// bottom box (i.e. i == 0)
/// bottom box (i.e. i == 0)
#[inline(always)] // Forced inlining improves the perf by 25-50%
pub(crate) fn ziggurat<R: Rng + ?Sized, P, Z>(
rng: &mut R,
Expand Down