use rand::prelude::StdRng;
use rand::Rng;
use rand::SeedableRng;
use crate::zipf::Zipf;
const DEFAULT_SEED: u64 = 666;
#[derive(Debug, Clone)]
pub struct ZipfIterator {
zipf: Zipf,
rng: StdRng,
}
impl ZipfIterator {
pub fn new(zipf: Zipf) -> Self {
Self {
zipf,
rng: StdRng::seed_from_u64(DEFAULT_SEED),
}
}
pub fn with_rng(self, rng: StdRng) -> Self {
Self {
zipf: self.zipf,
rng,
}
}
pub fn with_seed(zipf: Zipf, seed: u64) -> Self {
Self::new(zipf).with_rng(StdRng::seed_from_u64(seed))
}
}
impl Iterator for ZipfIterator {
type Item = f64;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let u = self.rng.r#gen::<f64>();
Some(self.zipf.sample(u))
}
}
#[cfg(test)]
mod tests {
use rand::rngs::StdRng;
use rand::SeedableRng;
use crate::zipf::*;
#[test]
fn test_zipf_iterator_rng_consistency() {
let zipf = Zipf::new(1.0..10.0, 1.5).unwrap();
let iter1 = ZipfIterator::with_seed(zipf, 42);
let iter2 = ZipfIterator::with_seed(zipf, 42);
let seq1: Vec<f64> = iter1.take(10).collect();
let seq2: Vec<f64> = iter2.take(10).collect();
assert_eq!(seq1, seq2, "Same seed should produce identical sequences");
}
#[test]
fn test_zipf_iterator_different_rngs() {
let zipf = Zipf::new(1.0..5.0, 1.2).unwrap();
let mut iter = ZipfIterator::with_seed(zipf, 123);
let seq1: Vec<f64> = (&mut iter).take(5).collect();
iter = ZipfIterator::with_seed(zipf, 456);
let seq2: Vec<f64> = (&mut iter).take(5).collect();
assert_ne!(
seq1, seq2,
"Different seeds should produce different sequences"
);
}
#[test]
fn test_zipf_iterator_rng_reproducibility() {
let zipf = Zipf::new(2.0..8.0, 0.9).unwrap();
let mut iter = zipf.iter().with_rng(StdRng::seed_from_u64(789));
let seq1: Vec<f64> = (&mut iter).take(8).collect();
iter = zipf.iter().with_rng(StdRng::seed_from_u64(789));
let seq2: Vec<f64> = (&mut iter).take(8).collect();
assert_eq!(seq1, seq2, "Same seed should reproduce identical sequence");
}
}