From c60f2705fa1df4443fa9cc48bfa5fce1b62a3bbb Mon Sep 17 00:00:00 2001 From: Sebastien Rousseau Date: Sat, 9 Mar 2024 09:25:50 +0000 Subject: [PATCH] style(vrd): :lipstick: code formatting --- src/macros.rs | 44 ++++++------- src/mersenne_twister.rs | 16 ++++- src/random.rs | 5 +- tests/test_macros.rs | 142 ++++++++++++++++++++++++++-------------- 4 files changed, 133 insertions(+), 74 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 08e7694..573e2b3 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -251,15 +251,13 @@ macro_rules! rand_string { /// * `slice` - A mutable reference to the slice to be shuffled. #[macro_export] macro_rules! rand_shuffle { - ($rng:expr, $slice:expr) => { - { - let len = $slice.len(); - for i in (1..len).rev() { - let j = $rng.random_range(0, (i + 1) as u32) as usize; - $slice.swap(i, j); - } + ($rng:expr, $slice:expr) => {{ + let len = $slice.len(); + for i in (1..len).rev() { + let j = $rng.random_range(0, (i + 1) as u32) as usize; + $slice.swap(i, j); } - }; + }}; } /// Selects a random element from a slice based on the provided weights. @@ -292,7 +290,11 @@ macro_rules! rand_shuffle { #[macro_export] macro_rules! rand_weighted_choice { ($rng:expr, $choices:expr, $weights:expr) => {{ - assert_eq!($choices.len(), $weights.len(), "Choices and weights must have the same length"); + assert_eq!( + $choices.len(), + $weights.len(), + "Choices and weights must have the same length" + ); let total_weight: u32 = $weights.iter().sum(); let mut rnd = $rng.random_range(0, total_weight); let mut selected_choice = None; @@ -378,19 +380,17 @@ macro_rules! rand_exponential { /// An `u64` representing a random number from a Poisson distribution. #[macro_export] macro_rules! rand_poisson { - ($rng:expr, $mean:expr) => { - { - let mut k = 0; - let mut p = 1.0; - let l = f64::exp(-$mean); - loop { - k += 1; - p *= $rng.f64(); - if p < l { - break; - } + ($rng:expr, $mean:expr) => {{ + let mut k = 0; + let mut p = 1.0; + let l = f64::exp(-$mean); + loop { + k += 1; + p *= $rng.f64(); + if p < l { + break; } - k - 1 } - }; + k - 1 + }}; } diff --git a/src/mersenne_twister.rs b/src/mersenne_twister.rs index c6f184b..9e96af5 100644 --- a/src/mersenne_twister.rs +++ b/src/mersenne_twister.rs @@ -3,9 +3,21 @@ // This file is part of the `Random (VRD)` library, a Rust implementation of the Mersenne Twister RNG. // See LICENSE-APACHE.md and LICENSE-MIT.md in the repository root for full license information. -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; -#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] +#[derive( + Clone, + Copy, + Debug, + Default, + Deserialize, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + Serialize, +)] /// Configuration for the Mersenne Twister algorithm. pub struct MersenneTwisterConfig { /// The number of elements in the array used for the Mersenne Twister algorithm. diff --git a/src/random.rs b/src/random.rs index f2c0bd7..4032137 100644 --- a/src/random.rs +++ b/src/random.rs @@ -385,7 +385,10 @@ impl Random { /// # Notes /// - This method offers a convenient way to specify the range for random number generation. pub fn random_range(&mut self, min: u32, max: u32) -> u32 { - assert!(max > min, "max must be greater than min for random_range"); + assert!( + max > min, + "max must be greater than min for random_range" + ); let mut rng = rand::thread_rng(); // Get a thread-local RNG rng.gen_range(min..max) // Use the gen_range method for uniform distribution } diff --git a/tests/test_macros.rs b/tests/test_macros.rs index 2764f3f..dc06354 100644 --- a/tests/test_macros.rs +++ b/tests/test_macros.rs @@ -14,14 +14,20 @@ mod tests { let min = 10; let max = 20; let num = random_range!(rng, min, max); - assert!(num >= min && num <= max, "Number should be within the given range."); + assert!( + num >= min && num <= max, + "Number should be within the given range." + ); } #[test] fn test_rand_bool_macro_always_true() { let mut rng = Random::new(); let b = rand_bool!(rng, 1.0); - assert!(b, "rand_bool should always return true with probability 1.0."); + assert!( + b, + "rand_bool should always return true with probability 1.0." + ); } #[test] @@ -36,7 +42,11 @@ mod tests { let mut rng = Random::new(); let len = 10; let bytes = rand_bytes!(rng, len); - assert_eq!(bytes.len(), len, "Length of bytes should be equal to the specified length."); + assert_eq!( + bytes.len(), + len, + "Length of bytes should be equal to the specified length." + ); } #[test] @@ -54,14 +64,20 @@ mod tests { let mut rng = Random::new(); let values = vec![1, 2, 3, 4, 5]; let chosen = rand_choose!(rng, &values).unwrap(); - assert!(values.contains(chosen), "Chosen value should be in the provided slice."); + assert!( + values.contains(chosen), + "Chosen value should be in the provided slice." + ); } #[test] fn test_rand_float_macro_within_bounds() { let mut rng = Random::new(); let f = rand_float!(rng); - assert!((0.0..1.0).contains(&f), "Generated float should be within 0.0 and 1.0."); + assert!( + (0.0..1.0).contains(&f), + "Generated float should be within 0.0 and 1.0." + ); } #[test] @@ -70,7 +86,10 @@ mod tests { let min = 10; let max = 20; let num = rand_int!(rng, min, max); - assert!(num >= min && num <= max, "Generated integer should be within the specified range."); + assert!( + num >= min && num <= max, + "Generated integer should be within the specified range." + ); } #[test] @@ -111,7 +130,10 @@ mod tests { let min = 10; let max = 20; let num = random_range!(rng, min, max); - assert!(num >= min && num < max, "Number should be within the given range."); + assert!( + num >= min && num < max, + "Number should be within the given range." + ); } #[test] @@ -127,7 +149,10 @@ mod tests { let mut rng = Random::new(); let p = 0.0; // Set p to 0.0 to always generate false let b = rand_bool!(rng, p); - assert!(!b, "The probability of 0.0 should always return false."); + assert!( + !b, + "The probability of 0.0 should always return false." + ); } #[test] @@ -136,7 +161,10 @@ mod tests { let min = 10; let max = 20; let num = rand_int!(rng, min, max); - assert!(num >= min && num <= max, "Number should be within the given range."); + assert!( + num >= min && num <= max, + "Number should be within the given range." + ); } #[test] @@ -154,7 +182,9 @@ mod tests { let length = 20; let random_string = rand_string!(rng, length); assert_eq!(random_string.len(), length); - assert!(random_string.chars().all(|c| c.is_ascii_alphanumeric())); + assert!(random_string + .chars() + .all(|c| c.is_ascii_alphanumeric())); } #[test] @@ -169,51 +199,60 @@ mod tests { assert!(numbers.iter().all(|&x| original_numbers.contains(&x))); } -/// Test the `rand_weighted_choice!` macro for correct weighted choice distribution. -#[test] -fn test_rand_weighted_choice() { - // Create a new Random instance - let mut rng = Random::new(); - - // Define choices and their corresponding weights - let choices = ["A", "B", "C"]; - let weights = [20, 30, 50]; // Weights implying a 2:3:5 ratio - - // Initialize counters for each choice - let mut counts = [0; 3]; - let num_iterations = 10_000; // Number of iterations to simulate - - // Simulate weighted choice selection - for _ in 0..num_iterations { - let selected = rand_weighted_choice!(rng, &choices, &weights); - match *selected { - "A" => counts[0] += 1, - "B" => counts[1] += 1, - "C" => counts[2] += 1, - _ => panic!("Unexpected choice"), + /// Test the `rand_weighted_choice!` macro for correct weighted choice distribution. + #[test] + fn test_rand_weighted_choice() { + // Create a new Random instance + let mut rng = Random::new(); + + // Define choices and their corresponding weights + let choices = ["A", "B", "C"]; + let weights = [20, 30, 50]; // Weights implying a 2:3:5 ratio + + // Initialize counters for each choice + let mut counts = [0; 3]; + let num_iterations = 10_000; // Number of iterations to simulate + + // Simulate weighted choice selection + for _ in 0..num_iterations { + let selected = + rand_weighted_choice!(rng, &choices, &weights); + match *selected { + "A" => counts[0] += 1, + "B" => counts[1] += 1, + "C" => counts[2] += 1, + _ => panic!("Unexpected choice"), + } } - } - // Calculate the observed distribution ratios - let total_counts: i32 = counts.iter().sum(); - let observed_ratios: Vec = counts.iter().map(|&count| count as f64 / total_counts as f64).collect(); + // Calculate the observed distribution ratios + let total_counts: i32 = counts.iter().sum(); + let observed_ratios: Vec = counts + .iter() + .map(|&count| count as f64 / total_counts as f64) + .collect(); - // Expected distribution ratios based on weights - let total_weight: u32 = weights.iter().sum(); - let expected_ratios: Vec = weights.iter().map(|&weight| weight as f64 / total_weight as f64).collect(); + // Expected distribution ratios based on weights + let total_weight: u32 = weights.iter().sum(); + let expected_ratios: Vec = weights + .iter() + .map(|&weight| weight as f64 / total_weight as f64) + .collect(); - // Check if the observed ratios are close to the expected ratios within a tolerance - let tolerance = 0.05; // 5% tolerance for distribution accuracy - for (observed, expected) in observed_ratios.iter().zip(expected_ratios.iter()) { - assert!( + // Check if the observed ratios are close to the expected ratios within a tolerance + let tolerance = 0.05; // 5% tolerance for distribution accuracy + for (observed, expected) in + observed_ratios.iter().zip(expected_ratios.iter()) + { + assert!( (observed - expected).abs() <= tolerance, "Distribution does not match expected ratios within tolerance: observed {:?}, expected {:?}", observed_ratios, expected_ratios ); + } } -} -#[test] + #[test] fn test_rand_normal() { let mut rng = Random::new(); // Assuming `Random::new()` provides the necessary `f64()` method. let mu = 0.0; // Expected mean @@ -227,8 +266,13 @@ fn test_rand_weighted_choice() { } // Calculate the sample mean and sample standard deviation - let sample_mean: f64 = samples.iter().sum::() / num_samples as f64; - let sample_variance: f64 = samples.iter().map(|&x| (x - sample_mean).powi(2)).sum::() / (num_samples - 1) as f64; + let sample_mean: f64 = + samples.iter().sum::() / num_samples as f64; + let sample_variance: f64 = samples + .iter() + .map(|&x| (x - sample_mean).powi(2)) + .sum::() + / (num_samples - 1) as f64; let sample_std_dev = sample_variance.sqrt(); // Define tolerances for the mean and standard deviation @@ -260,7 +304,8 @@ fn test_rand_weighted_choice() { .map(|_| rand_exponential!(rng, rate)) .collect(); - let sample_mean: f64 = samples.iter().sum::() / samples.len() as f64; + let sample_mean: f64 = + samples.iter().sum::() / samples.len() as f64; // Tolerance for the difference between the sample mean and the expected mean. let tolerance = 0.1; @@ -292,4 +337,3 @@ fn test_rand_weighted_choice() { assert!((sample_mean - expected_mean).abs() < 0.1); } } -