@@ -35,9 +35,9 @@ pub trait Distrib: Clone {
3535 /// ```
3636 /// use retrofire_core::math::rand::*;
3737 ///
38- /// // Simulate rolling a six-sided die
38+ /// // Simulate rolling a six-sided die three times
3939 /// let rng = &mut DefaultRng::default();
40- /// let mut iter = Uniform(1 ..7).samples(rng);
40+ /// let mut iter = Uniform(1u32 ..7).samples(rng);
4141 ///
4242 /// assert_eq!(iter.next(), Some(3));
4343 /// assert_eq!(iter.next(), Some(2));
@@ -217,7 +217,7 @@ impl Default for Xorshift64 {
217217// Local trait impls
218218//
219219
220- /// Uniformly distributed integers.
220+ /// Uniformly distributed signed integers.
221221impl Distrib for Uniform < i32 > {
222222 type Sample = i32 ;
223223
@@ -228,18 +228,70 @@ impl Distrib for Uniform<i32> {
228228 /// use retrofire_core::math::rand::*;
229229 /// let rng = &mut DefaultRng::default();
230230 ///
231- /// // Simulate rolling a six-sided die
232- /// let mut iter = Uniform(1..7).samples(rng);
233- /// assert_eq!(iter.next(), Some(3));
234- /// assert_eq!(iter.next(), Some(2));
231+ ///
232+ /// let mut iter = Uniform(-5i32..6).samples(rng);
233+ /// assert_eq!(iter.next(), Some(0));
235234 /// assert_eq!(iter.next(), Some(4));
235+ /// assert_eq!(iter.next(), Some(5));
236236 /// ```
237237 fn sample ( & self , rng : & mut DefaultRng ) -> i32 {
238238 let bits = rng. next_bits ( ) as i32 ;
239239 // TODO rem introduces slight bias
240240 bits. rem_euclid ( self . 0 . end - self . 0 . start ) + self . 0 . start
241241 }
242242}
243+ /// Uniformly distributed unsigned integers.
244+ impl Distrib for Uniform < u32 > {
245+ type Sample = u32 ;
246+
247+ /// Returns a uniformly distributed `u32` in the range.
248+ ///
249+ /// # Examples
250+ /// ```
251+ /// use retrofire_core::math::rand::*;
252+ /// let rng = &mut DefaultRng::from_seed(1234);
253+ ///
254+ /// // Simulate rolling a six-sided die
255+ /// let mut rolls: Vec<_> = Uniform(1u32..7)
256+ /// .samples(rng)
257+ /// .take(6)
258+ /// .collect();
259+ /// assert_eq!(rolls, [2, 4, 6, 6, 3, 1]);
260+ /// ```
261+ fn sample ( & self , rng : & mut DefaultRng ) -> u32 {
262+ let bits = rng. next_bits ( ) as u32 ;
263+ // TODO rem introduces slight bias
264+ bits. rem_euclid ( self . 0 . end - self . 0 . start ) + self . 0 . start
265+ }
266+ }
267+
268+ /// Uniformly distributed indices.
269+ impl Distrib for Uniform < usize > {
270+ type Sample = usize ;
271+
272+ /// Returns a uniformly distributed `usize` in the range.
273+ ///
274+ /// # Examples
275+ /// ```
276+ /// use retrofire_core::math::rand::*;
277+ /// let rng = &mut DefaultRng::default();
278+ ///
279+ /// // Randomly sample elements from a list (with replacement)
280+ /// let beverages = ["water", "tea", "coffee", "Coke", "Red Bull"];
281+ /// let mut x: Vec<_> = Uniform(0..beverages.len())
282+ /// .samples(rng)
283+ /// .take(3)
284+ /// .map(|i| beverages[i])
285+ /// .collect();
286+ ///
287+ /// assert_eq!(x, ["water", "tea", "Red Bull"]);
288+ /// ```
289+ fn sample ( & self , rng : & mut DefaultRng ) -> usize {
290+ let bits = rng. next_bits ( ) as usize ;
291+ // TODO rem introduces slight bias
292+ bits. rem_euclid ( self . 0 . end - self . 0 . start ) + self . 0 . start
293+ }
294+ }
243295
244296/// Uniformly distributed floats.
245297impl Distrib for Uniform < f32 > {
@@ -491,7 +543,7 @@ mod tests {
491543
492544 #[ test]
493545 fn uniform_i32 ( ) {
494- let dist = Uniform ( -123 ..456 ) ;
546+ let dist = Uniform ( -123i32 ..456 ) ;
495547 for r in dist. samples ( & mut rng ( ) ) . take ( COUNT ) {
496548 assert ! ( -123 <= r && r < 456 ) ;
497549 }
0 commit comments