1#[cfg(not(feature = "std"))] use core::time::Duration;
107#[cfg(feature = "std")] use std::time::Duration;
108use core::ops::{Range, RangeInclusive};
109
110use crate::distributions::float::IntoFloat;
111use crate::distributions::utils::{BoolAsSIMD, FloatAsSIMD, FloatSIMDUtils, WideningMultiply};
112use crate::distributions::Distribution;
113use crate::{Rng, RngCore};
114
115#[cfg(not(feature = "std"))]
116#[allow(unused_imports)] use crate::distributions::utils::Float;
118
119#[cfg(feature = "simd_support")] use packed_simd::*;
120
121#[cfg(feature = "serde1")]
122use serde::{Serialize, Deserialize};
123
124#[derive(Clone, Copy, Debug)]
174#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
175pub struct Uniform<X: SampleUniform>(X::Sampler);
176
177impl<X: SampleUniform> Uniform<X> {
178 pub fn new<B1, B2>(low: B1, high: B2) -> Uniform<X>
181 where
182 B1: SampleBorrow<X> + Sized,
183 B2: SampleBorrow<X> + Sized,
184 {
185 Uniform(X::Sampler::new(low, high))
186 }
187
188 pub fn new_inclusive<B1, B2>(low: B1, high: B2) -> Uniform<X>
191 where
192 B1: SampleBorrow<X> + Sized,
193 B2: SampleBorrow<X> + Sized,
194 {
195 Uniform(X::Sampler::new_inclusive(low, high))
196 }
197}
198
199impl<X: SampleUniform> Distribution<X> for Uniform<X> {
200 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> X {
201 self.0.sample(rng)
202 }
203}
204
205pub trait SampleUniform: Sized {
213 type Sampler: UniformSampler<X = Self>;
215}
216
217pub trait UniformSampler: Sized {
228 type X;
230
231 fn new<B1, B2>(low: B1, high: B2) -> Self
237 where
238 B1: SampleBorrow<Self::X> + Sized,
239 B2: SampleBorrow<Self::X> + Sized;
240
241 fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
247 where
248 B1: SampleBorrow<Self::X> + Sized,
249 B2: SampleBorrow<Self::X> + Sized;
250
251 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X;
253
254 fn sample_single<R: Rng + ?Sized, B1, B2>(low: B1, high: B2, rng: &mut R) -> Self::X
274 where
275 B1: SampleBorrow<Self::X> + Sized,
276 B2: SampleBorrow<Self::X> + Sized,
277 {
278 let uniform: Self = UniformSampler::new(low, high);
279 uniform.sample(rng)
280 }
281
282 fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(low: B1, high: B2, rng: &mut R)
291 -> Self::X
292 where B1: SampleBorrow<Self::X> + Sized,
293 B2: SampleBorrow<Self::X> + Sized
294 {
295 let uniform: Self = UniformSampler::new_inclusive(low, high);
296 uniform.sample(rng)
297 }
298}
299
300impl<X: SampleUniform> From<Range<X>> for Uniform<X> {
301 fn from(r: ::core::ops::Range<X>) -> Uniform<X> {
302 Uniform::new(r.start, r.end)
303 }
304}
305
306impl<X: SampleUniform> From<RangeInclusive<X>> for Uniform<X> {
307 fn from(r: ::core::ops::RangeInclusive<X>) -> Uniform<X> {
308 Uniform::new_inclusive(r.start(), r.end())
309 }
310}
311
312
313pub trait SampleBorrow<Borrowed> {
319 fn borrow(&self) -> &Borrowed;
323}
324impl<Borrowed> SampleBorrow<Borrowed> for Borrowed
325where Borrowed: SampleUniform
326{
327 #[inline(always)]
328 fn borrow(&self) -> &Borrowed {
329 self
330 }
331}
332impl<'a, Borrowed> SampleBorrow<Borrowed> for &'a Borrowed
333where Borrowed: SampleUniform
334{
335 #[inline(always)]
336 fn borrow(&self) -> &Borrowed {
337 *self
338 }
339}
340
341pub trait SampleRange<T> {
346 fn sample_single<R: RngCore + ?Sized>(self, rng: &mut R) -> T;
348
349 fn is_empty(&self) -> bool;
351}
352
353impl<T: SampleUniform + PartialOrd> SampleRange<T> for Range<T> {
354 #[inline]
355 fn sample_single<R: RngCore + ?Sized>(self, rng: &mut R) -> T {
356 T::Sampler::sample_single(self.start, self.end, rng)
357 }
358
359 #[inline]
360 fn is_empty(&self) -> bool {
361 !(self.start < self.end)
362 }
363}
364
365impl<T: SampleUniform + PartialOrd> SampleRange<T> for RangeInclusive<T> {
366 #[inline]
367 fn sample_single<R: RngCore + ?Sized>(self, rng: &mut R) -> T {
368 T::Sampler::sample_single_inclusive(self.start(), self.end(), rng)
369 }
370
371 #[inline]
372 fn is_empty(&self) -> bool {
373 !(self.start() <= self.end())
374 }
375}
376
377
378#[derive(Clone, Copy, Debug)]
418#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
419pub struct UniformInt<X> {
420 low: X,
421 range: X,
422 z: X, }
424
425macro_rules! uniform_int_impl {
426 ($ty:ty, $unsigned:ident, $u_large:ident) => {
427 impl SampleUniform for $ty {
428 type Sampler = UniformInt<$ty>;
429 }
430
431 impl UniformSampler for UniformInt<$ty> {
432 type X = $ty;
438
439 #[inline] fn new<B1, B2>(low_b: B1, high_b: B2) -> Self
442 where
443 B1: SampleBorrow<Self::X> + Sized,
444 B2: SampleBorrow<Self::X> + Sized,
445 {
446 let low = *low_b.borrow();
447 let high = *high_b.borrow();
448 assert!(low < high, "Uniform::new called with `low >= high`");
449 UniformSampler::new_inclusive(low, high - 1)
450 }
451
452 #[inline] fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Self
455 where
456 B1: SampleBorrow<Self::X> + Sized,
457 B2: SampleBorrow<Self::X> + Sized,
458 {
459 let low = *low_b.borrow();
460 let high = *high_b.borrow();
461 assert!(
462 low <= high,
463 "Uniform::new_inclusive called with `low > high`"
464 );
465 let unsigned_max = ::core::$u_large::MAX;
466
467 let range = high.wrapping_sub(low).wrapping_add(1) as $unsigned;
468 let ints_to_reject = if range > 0 {
469 let range = $u_large::from(range);
470 (unsigned_max - range + 1) % range
471 } else {
472 0
473 };
474
475 UniformInt {
476 low,
477 range: range as $ty,
479 z: ints_to_reject as $unsigned as $ty,
480 }
481 }
482
483 #[inline]
484 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
485 let range = self.range as $unsigned as $u_large;
486 if range > 0 {
487 let unsigned_max = ::core::$u_large::MAX;
488 let zone = unsigned_max - (self.z as $unsigned as $u_large);
489 loop {
490 let v: $u_large = rng.gen();
491 let (hi, lo) = v.wmul(range);
492 if lo <= zone {
493 return self.low.wrapping_add(hi as $ty);
494 }
495 }
496 } else {
497 rng.gen()
499 }
500 }
501
502 #[inline]
503 fn sample_single<R: Rng + ?Sized, B1, B2>(low_b: B1, high_b: B2, rng: &mut R) -> Self::X
504 where
505 B1: SampleBorrow<Self::X> + Sized,
506 B2: SampleBorrow<Self::X> + Sized,
507 {
508 let low = *low_b.borrow();
509 let high = *high_b.borrow();
510 assert!(low < high, "UniformSampler::sample_single: low >= high");
511 Self::sample_single_inclusive(low, high - 1, rng)
512 }
513
514 #[inline]
515 fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(low_b: B1, high_b: B2, rng: &mut R) -> Self::X
516 where
517 B1: SampleBorrow<Self::X> + Sized,
518 B2: SampleBorrow<Self::X> + Sized,
519 {
520 let low = *low_b.borrow();
521 let high = *high_b.borrow();
522 assert!(low <= high, "UniformSampler::sample_single_inclusive: low > high");
523 let range = high.wrapping_sub(low).wrapping_add(1) as $unsigned as $u_large;
524 if range == 0 {
527 return rng.gen();
528 }
529
530 let zone = if ::core::$unsigned::MAX <= ::core::u16::MAX as $unsigned {
531 let unsigned_max: $u_large = ::core::$u_large::MAX;
535 let ints_to_reject = (unsigned_max - range + 1) % range;
536 unsigned_max - ints_to_reject
537 } else {
538 (range << range.leading_zeros()).wrapping_sub(1)
541 };
542
543 loop {
544 let v: $u_large = rng.gen();
545 let (hi, lo) = v.wmul(range);
546 if lo <= zone {
547 return low.wrapping_add(hi as $ty);
548 }
549 }
550 }
551 }
552 };
553}
554
555uniform_int_impl! { i8, u8, u32 }
556uniform_int_impl! { i16, u16, u32 }
557uniform_int_impl! { i32, u32, u32 }
558uniform_int_impl! { i64, u64, u64 }
559#[cfg(not(target_os = "emscripten"))]
560uniform_int_impl! { i128, u128, u128 }
561uniform_int_impl! { isize, usize, usize }
562uniform_int_impl! { u8, u8, u32 }
563uniform_int_impl! { u16, u16, u32 }
564uniform_int_impl! { u32, u32, u32 }
565uniform_int_impl! { u64, u64, u64 }
566uniform_int_impl! { usize, usize, usize }
567#[cfg(not(target_os = "emscripten"))]
568uniform_int_impl! { u128, u128, u128 }
569
570#[cfg(feature = "simd_support")]
571macro_rules! uniform_simd_int_impl {
572 ($ty:ident, $unsigned:ident, $u_scalar:ident) => {
573 impl SampleUniform for $ty {
582 type Sampler = UniformInt<$ty>;
583 }
584
585 impl UniformSampler for UniformInt<$ty> {
586 type X = $ty;
587
588 #[inline] fn new<B1, B2>(low_b: B1, high_b: B2) -> Self
591 where B1: SampleBorrow<Self::X> + Sized,
592 B2: SampleBorrow<Self::X> + Sized
593 {
594 let low = *low_b.borrow();
595 let high = *high_b.borrow();
596 assert!(low.lt(high).all(), "Uniform::new called with `low >= high`");
597 UniformSampler::new_inclusive(low, high - 1)
598 }
599
600 #[inline] fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Self
603 where B1: SampleBorrow<Self::X> + Sized,
604 B2: SampleBorrow<Self::X> + Sized
605 {
606 let low = *low_b.borrow();
607 let high = *high_b.borrow();
608 assert!(low.le(high).all(),
609 "Uniform::new_inclusive called with `low > high`");
610 let unsigned_max = ::core::$u_scalar::MAX;
611
612 let range: $unsigned = ((high - low) + 1).cast();
615 let not_full_range = range.gt($unsigned::splat(0));
617 let modulo = not_full_range.select(range, $unsigned::splat(unsigned_max));
620 let ints_to_reject = (unsigned_max - range + 1) % modulo;
622 let zone = unsigned_max - ints_to_reject;
625
626 UniformInt {
627 low,
628 range: range.cast(),
630 z: zone.cast(),
631 }
632 }
633
634 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
635 let range: $unsigned = self.range.cast();
636 let zone: $unsigned = self.z.cast();
637
638 let mut v: $unsigned = rng.gen();
648 loop {
649 let (hi, lo) = v.wmul(range);
650 let mask = lo.le(zone);
651 if mask.all() {
652 let hi: $ty = hi.cast();
653 let result = self.low + hi;
655 let v: $ty = v.cast();
659 return range.gt($unsigned::splat(0)).select(result, v);
660 }
661 v = mask.select(v, rng.gen());
663 }
664 }
665 }
666 };
667
668 ($(($unsigned:ident, $signed:ident),)+ $u_scalar:ident) => {
670 $(
671 uniform_simd_int_impl!($unsigned, $unsigned, $u_scalar);
672 uniform_simd_int_impl!($signed, $unsigned, $u_scalar);
673 )+
674 };
675}
676
677#[cfg(feature = "simd_support")]
678uniform_simd_int_impl! {
679 (u64x2, i64x2),
680 (u64x4, i64x4),
681 (u64x8, i64x8),
682 u64
683}
684
685#[cfg(feature = "simd_support")]
686uniform_simd_int_impl! {
687 (u32x2, i32x2),
688 (u32x4, i32x4),
689 (u32x8, i32x8),
690 (u32x16, i32x16),
691 u32
692}
693
694#[cfg(feature = "simd_support")]
695uniform_simd_int_impl! {
696 (u16x2, i16x2),
697 (u16x4, i16x4),
698 (u16x8, i16x8),
699 (u16x16, i16x16),
700 (u16x32, i16x32),
701 u16
702}
703
704#[cfg(feature = "simd_support")]
705uniform_simd_int_impl! {
706 (u8x2, i8x2),
707 (u8x4, i8x4),
708 (u8x8, i8x8),
709 (u8x16, i8x16),
710 (u8x32, i8x32),
711 (u8x64, i8x64),
712 u8
713}
714
715impl SampleUniform for char {
716 type Sampler = UniformChar;
717}
718
719#[derive(Clone, Copy, Debug)]
729#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
730pub struct UniformChar {
731 sampler: UniformInt<u32>,
732}
733
734const CHAR_SURROGATE_START: u32 = 0xD800;
736const CHAR_SURROGATE_LEN: u32 = 0xE000 - CHAR_SURROGATE_START;
738
739fn char_to_comp_u32(c: char) -> u32 {
741 match c as u32 {
742 c if c >= CHAR_SURROGATE_START => c - CHAR_SURROGATE_LEN,
743 c => c,
744 }
745}
746
747impl UniformSampler for UniformChar {
748 type X = char;
749
750 #[inline] fn new<B1, B2>(low_b: B1, high_b: B2) -> Self
753 where
754 B1: SampleBorrow<Self::X> + Sized,
755 B2: SampleBorrow<Self::X> + Sized,
756 {
757 let low = char_to_comp_u32(*low_b.borrow());
758 let high = char_to_comp_u32(*high_b.borrow());
759 let sampler = UniformInt::<u32>::new(low, high);
760 UniformChar { sampler }
761 }
762
763 #[inline] fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Self
766 where
767 B1: SampleBorrow<Self::X> + Sized,
768 B2: SampleBorrow<Self::X> + Sized,
769 {
770 let low = char_to_comp_u32(*low_b.borrow());
771 let high = char_to_comp_u32(*high_b.borrow());
772 let sampler = UniformInt::<u32>::new_inclusive(low, high);
773 UniformChar { sampler }
774 }
775
776 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
777 let mut x = self.sampler.sample(rng);
778 if x >= CHAR_SURROGATE_START {
779 x += CHAR_SURROGATE_LEN;
780 }
781 unsafe { core::char::from_u32_unchecked(x) }
785 }
786}
787
788#[derive(Clone, Copy, Debug)]
808#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
809pub struct UniformFloat<X> {
810 low: X,
811 scale: X,
812}
813
814macro_rules! uniform_float_impl {
815 ($ty:ty, $uty:ident, $f_scalar:ident, $u_scalar:ident, $bits_to_discard:expr) => {
816 impl SampleUniform for $ty {
817 type Sampler = UniformFloat<$ty>;
818 }
819
820 impl UniformSampler for UniformFloat<$ty> {
821 type X = $ty;
822
823 fn new<B1, B2>(low_b: B1, high_b: B2) -> Self
824 where
825 B1: SampleBorrow<Self::X> + Sized,
826 B2: SampleBorrow<Self::X> + Sized,
827 {
828 let low = *low_b.borrow();
829 let high = *high_b.borrow();
830 debug_assert!(
831 low.all_finite(),
832 "Uniform::new called with `low` non-finite."
833 );
834 debug_assert!(
835 high.all_finite(),
836 "Uniform::new called with `high` non-finite."
837 );
838 assert!(low.all_lt(high), "Uniform::new called with `low >= high`");
839 let max_rand = <$ty>::splat(
840 (::core::$u_scalar::MAX >> $bits_to_discard).into_float_with_exponent(0) - 1.0,
841 );
842
843 let mut scale = high - low;
844 assert!(scale.all_finite(), "Uniform::new: range overflow");
845
846 loop {
847 let mask = (scale * max_rand + low).ge_mask(high);
848 if mask.none() {
849 break;
850 }
851 scale = scale.decrease_masked(mask);
852 }
853
854 debug_assert!(<$ty>::splat(0.0).all_le(scale));
855
856 UniformFloat { low, scale }
857 }
858
859 fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Self
860 where
861 B1: SampleBorrow<Self::X> + Sized,
862 B2: SampleBorrow<Self::X> + Sized,
863 {
864 let low = *low_b.borrow();
865 let high = *high_b.borrow();
866 debug_assert!(
867 low.all_finite(),
868 "Uniform::new_inclusive called with `low` non-finite."
869 );
870 debug_assert!(
871 high.all_finite(),
872 "Uniform::new_inclusive called with `high` non-finite."
873 );
874 assert!(
875 low.all_le(high),
876 "Uniform::new_inclusive called with `low > high`"
877 );
878 let max_rand = <$ty>::splat(
879 (::core::$u_scalar::MAX >> $bits_to_discard).into_float_with_exponent(0) - 1.0,
880 );
881
882 let mut scale = (high - low) / max_rand;
883 assert!(scale.all_finite(), "Uniform::new_inclusive: range overflow");
884
885 loop {
886 let mask = (scale * max_rand + low).gt_mask(high);
887 if mask.none() {
888 break;
889 }
890 scale = scale.decrease_masked(mask);
891 }
892
893 debug_assert!(<$ty>::splat(0.0).all_le(scale));
894
895 UniformFloat { low, scale }
896 }
897
898 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
899 let value1_2 = (rng.gen::<$uty>() >> $bits_to_discard).into_float_with_exponent(0);
901
902 let value0_1 = value1_2 - 1.0;
905
906 value0_1 * self.scale + self.low
912 }
913
914 #[inline]
915 fn sample_single<R: Rng + ?Sized, B1, B2>(low_b: B1, high_b: B2, rng: &mut R) -> Self::X
916 where
917 B1: SampleBorrow<Self::X> + Sized,
918 B2: SampleBorrow<Self::X> + Sized,
919 {
920 let low = *low_b.borrow();
921 let high = *high_b.borrow();
922 debug_assert!(
923 low.all_finite(),
924 "UniformSampler::sample_single called with `low` non-finite."
925 );
926 debug_assert!(
927 high.all_finite(),
928 "UniformSampler::sample_single called with `high` non-finite."
929 );
930 assert!(
931 low.all_lt(high),
932 "UniformSampler::sample_single: low >= high"
933 );
934 let mut scale = high - low;
935 assert!(scale.all_finite(), "UniformSampler::sample_single: range overflow");
936
937 loop {
938 let value1_2 =
940 (rng.gen::<$uty>() >> $bits_to_discard).into_float_with_exponent(0);
941
942 let value0_1 = value1_2 - 1.0;
945
946 let res = value0_1 * scale + low;
949
950 debug_assert!(low.all_le(res) || !scale.all_finite());
951 if res.all_lt(high) {
952 return res;
953 }
954
955 let mask = !scale.finite_mask();
983 if mask.any() {
984 assert!(
985 low.all_finite() && high.all_finite(),
986 "Uniform::sample_single: low and high must be finite"
987 );
988 scale = scale.decrease_masked(mask);
989 }
990 }
991 }
992 }
993 };
994}
995
996uniform_float_impl! { f32, u32, f32, u32, 32 - 23 }
997uniform_float_impl! { f64, u64, f64, u64, 64 - 52 }
998
999#[cfg(feature = "simd_support")]
1000uniform_float_impl! { f32x2, u32x2, f32, u32, 32 - 23 }
1001#[cfg(feature = "simd_support")]
1002uniform_float_impl! { f32x4, u32x4, f32, u32, 32 - 23 }
1003#[cfg(feature = "simd_support")]
1004uniform_float_impl! { f32x8, u32x8, f32, u32, 32 - 23 }
1005#[cfg(feature = "simd_support")]
1006uniform_float_impl! { f32x16, u32x16, f32, u32, 32 - 23 }
1007
1008#[cfg(feature = "simd_support")]
1009uniform_float_impl! { f64x2, u64x2, f64, u64, 64 - 52 }
1010#[cfg(feature = "simd_support")]
1011uniform_float_impl! { f64x4, u64x4, f64, u64, 64 - 52 }
1012#[cfg(feature = "simd_support")]
1013uniform_float_impl! { f64x8, u64x8, f64, u64, 64 - 52 }
1014
1015
1016#[derive(Clone, Copy, Debug)]
1021#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
1022pub struct UniformDuration {
1023 mode: UniformDurationMode,
1024 offset: u32,
1025}
1026
1027#[derive(Debug, Copy, Clone)]
1028#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
1029enum UniformDurationMode {
1030 Small {
1031 secs: u64,
1032 nanos: Uniform<u32>,
1033 },
1034 Medium {
1035 nanos: Uniform<u64>,
1036 },
1037 Large {
1038 max_secs: u64,
1039 max_nanos: u32,
1040 secs: Uniform<u64>,
1041 },
1042}
1043
1044impl SampleUniform for Duration {
1045 type Sampler = UniformDuration;
1046}
1047
1048impl UniformSampler for UniformDuration {
1049 type X = Duration;
1050
1051 #[inline]
1052 fn new<B1, B2>(low_b: B1, high_b: B2) -> Self
1053 where
1054 B1: SampleBorrow<Self::X> + Sized,
1055 B2: SampleBorrow<Self::X> + Sized,
1056 {
1057 let low = *low_b.borrow();
1058 let high = *high_b.borrow();
1059 assert!(low < high, "Uniform::new called with `low >= high`");
1060 UniformDuration::new_inclusive(low, high - Duration::new(0, 1))
1061 }
1062
1063 #[inline]
1064 fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Self
1065 where
1066 B1: SampleBorrow<Self::X> + Sized,
1067 B2: SampleBorrow<Self::X> + Sized,
1068 {
1069 let low = *low_b.borrow();
1070 let high = *high_b.borrow();
1071 assert!(
1072 low <= high,
1073 "Uniform::new_inclusive called with `low > high`"
1074 );
1075
1076 let low_s = low.as_secs();
1077 let low_n = low.subsec_nanos();
1078 let mut high_s = high.as_secs();
1079 let mut high_n = high.subsec_nanos();
1080
1081 if high_n < low_n {
1082 high_s -= 1;
1083 high_n += 1_000_000_000;
1084 }
1085
1086 let mode = if low_s == high_s {
1087 UniformDurationMode::Small {
1088 secs: low_s,
1089 nanos: Uniform::new_inclusive(low_n, high_n),
1090 }
1091 } else {
1092 let max = high_s
1093 .checked_mul(1_000_000_000)
1094 .and_then(|n| n.checked_add(u64::from(high_n)));
1095
1096 if let Some(higher_bound) = max {
1097 let lower_bound = low_s * 1_000_000_000 + u64::from(low_n);
1098 UniformDurationMode::Medium {
1099 nanos: Uniform::new_inclusive(lower_bound, higher_bound),
1100 }
1101 } else {
1102 let max_nanos = high_n - low_n;
1104 UniformDurationMode::Large {
1105 max_secs: high_s,
1106 max_nanos,
1107 secs: Uniform::new_inclusive(low_s, high_s),
1108 }
1109 }
1110 };
1111 UniformDuration {
1112 mode,
1113 offset: low_n,
1114 }
1115 }
1116
1117 #[inline]
1118 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Duration {
1119 match self.mode {
1120 UniformDurationMode::Small { secs, nanos } => {
1121 let n = nanos.sample(rng);
1122 Duration::new(secs, n)
1123 }
1124 UniformDurationMode::Medium { nanos } => {
1125 let nanos = nanos.sample(rng);
1126 Duration::new(nanos / 1_000_000_000, (nanos % 1_000_000_000) as u32)
1127 }
1128 UniformDurationMode::Large {
1129 max_secs,
1130 max_nanos,
1131 secs,
1132 } => {
1133 let nano_range = Uniform::new(0, 1_000_000_000);
1135 loop {
1136 let s = secs.sample(rng);
1137 let n = nano_range.sample(rng);
1138 if !(s == max_secs && n > max_nanos) {
1139 let sum = n + self.offset;
1140 break Duration::new(s, sum);
1141 }
1142 }
1143 }
1144 }
1145 }
1146}
1147
1148#[cfg(test)]
1149mod tests {
1150 use super::*;
1151 use crate::rngs::mock::StepRng;
1152
1153 #[test]
1154 #[cfg(feature = "serde1")]
1155 fn test_serialization_uniform_duration() {
1156 let distr = UniformDuration::new(std::time::Duration::from_secs(10), std::time::Duration::from_secs(60));
1157 let de_distr: UniformDuration = bincode::deserialize(&bincode::serialize(&distr).unwrap()).unwrap();
1158 assert_eq!(
1159 distr.offset, de_distr.offset
1160 );
1161 match (distr.mode, de_distr.mode) {
1162 (UniformDurationMode::Small {secs: a_secs, nanos: a_nanos}, UniformDurationMode::Small {secs, nanos}) => {
1163 assert_eq!(a_secs, secs);
1164
1165 assert_eq!(a_nanos.0.low, nanos.0.low);
1166 assert_eq!(a_nanos.0.range, nanos.0.range);
1167 assert_eq!(a_nanos.0.z, nanos.0.z);
1168 }
1169 (UniformDurationMode::Medium {nanos: a_nanos} , UniformDurationMode::Medium {nanos}) => {
1170 assert_eq!(a_nanos.0.low, nanos.0.low);
1171 assert_eq!(a_nanos.0.range, nanos.0.range);
1172 assert_eq!(a_nanos.0.z, nanos.0.z);
1173 }
1174 (UniformDurationMode::Large {max_secs:a_max_secs, max_nanos:a_max_nanos, secs:a_secs}, UniformDurationMode::Large {max_secs, max_nanos, secs} ) => {
1175 assert_eq!(a_max_secs, max_secs);
1176 assert_eq!(a_max_nanos, max_nanos);
1177
1178 assert_eq!(a_secs.0.low, secs.0.low);
1179 assert_eq!(a_secs.0.range, secs.0.range);
1180 assert_eq!(a_secs.0.z, secs.0.z);
1181 }
1182 _ => panic!("`UniformDurationMode` was not serialized/deserialized correctly")
1183 }
1184 }
1185
1186 #[test]
1187 #[cfg(feature = "serde1")]
1188 fn test_uniform_serialization() {
1189 let unit_box: Uniform<i32> = Uniform::new(-1, 1);
1190 let de_unit_box: Uniform<i32> = bincode::deserialize(&bincode::serialize(&unit_box).unwrap()).unwrap();
1191
1192 assert_eq!(unit_box.0.low, de_unit_box.0.low);
1193 assert_eq!(unit_box.0.range, de_unit_box.0.range);
1194 assert_eq!(unit_box.0.z, de_unit_box.0.z);
1195
1196 let unit_box: Uniform<f32> = Uniform::new(-1., 1.);
1197 let de_unit_box: Uniform<f32> = bincode::deserialize(&bincode::serialize(&unit_box).unwrap()).unwrap();
1198
1199 assert_eq!(unit_box.0.low, de_unit_box.0.low);
1200 assert_eq!(unit_box.0.scale, de_unit_box.0.scale);
1201 }
1202
1203 #[should_panic]
1204 #[test]
1205 fn test_uniform_bad_limits_equal_int() {
1206 Uniform::new(10, 10);
1207 }
1208
1209 #[test]
1210 fn test_uniform_good_limits_equal_int() {
1211 let mut rng = crate::test::rng(804);
1212 let dist = Uniform::new_inclusive(10, 10);
1213 for _ in 0..20 {
1214 assert_eq!(rng.sample(dist), 10);
1215 }
1216 }
1217
1218 #[should_panic]
1219 #[test]
1220 fn test_uniform_bad_limits_flipped_int() {
1221 Uniform::new(10, 5);
1222 }
1223
1224 #[test]
1225 #[cfg_attr(miri, ignore)] fn test_integers() {
1227 #[cfg(not(target_os = "emscripten"))] use core::{i128, u128};
1228 use core::{i16, i32, i64, i8, isize};
1229 use core::{u16, u32, u64, u8, usize};
1230
1231 let mut rng = crate::test::rng(251);
1232 macro_rules! t {
1233 ($ty:ident, $v:expr, $le:expr, $lt:expr) => {{
1234 for &(low, high) in $v.iter() {
1235 let my_uniform = Uniform::new(low, high);
1236 for _ in 0..1000 {
1237 let v: $ty = rng.sample(my_uniform);
1238 assert!($le(low, v) && $lt(v, high));
1239 }
1240
1241 let my_uniform = Uniform::new_inclusive(low, high);
1242 for _ in 0..1000 {
1243 let v: $ty = rng.sample(my_uniform);
1244 assert!($le(low, v) && $le(v, high));
1245 }
1246
1247 let my_uniform = Uniform::new(&low, high);
1248 for _ in 0..1000 {
1249 let v: $ty = rng.sample(my_uniform);
1250 assert!($le(low, v) && $lt(v, high));
1251 }
1252
1253 let my_uniform = Uniform::new_inclusive(&low, &high);
1254 for _ in 0..1000 {
1255 let v: $ty = rng.sample(my_uniform);
1256 assert!($le(low, v) && $le(v, high));
1257 }
1258
1259 for _ in 0..1000 {
1260 let v = <$ty as SampleUniform>::Sampler::sample_single(low, high, &mut rng);
1261 assert!($le(low, v) && $lt(v, high));
1262 }
1263
1264 for _ in 0..1000 {
1265 let v = <$ty as SampleUniform>::Sampler::sample_single_inclusive(low, high, &mut rng);
1266 assert!($le(low, v) && $le(v, high));
1267 }
1268 }
1269 }};
1270
1271 ($($ty:ident),*) => {{
1273 $(t!(
1274 $ty,
1275 [(0, 10), (10, 127), ($ty::MIN, $ty::MAX)],
1276 |x, y| x <= y,
1277 |x, y| x < y
1278 );)*
1279 }};
1280
1281 ($($ty:ident),* => $scalar:ident) => {{
1283 $(t!(
1284 $ty,
1285 [
1286 ($ty::splat(0), $ty::splat(10)),
1287 ($ty::splat(10), $ty::splat(127)),
1288 ($ty::splat($scalar::MIN), $ty::splat($scalar::MAX)),
1289 ],
1290 |x: $ty, y| x.le(y).all(),
1291 |x: $ty, y| x.lt(y).all()
1292 );)*
1293 }};
1294 }
1295 t!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
1296 #[cfg(not(target_os = "emscripten"))]
1297 t!(i128, u128);
1298
1299 #[cfg(feature = "simd_support")]
1300 {
1301 t!(u8x2, u8x4, u8x8, u8x16, u8x32, u8x64 => u8);
1302 t!(i8x2, i8x4, i8x8, i8x16, i8x32, i8x64 => i8);
1303 t!(u16x2, u16x4, u16x8, u16x16, u16x32 => u16);
1304 t!(i16x2, i16x4, i16x8, i16x16, i16x32 => i16);
1305 t!(u32x2, u32x4, u32x8, u32x16 => u32);
1306 t!(i32x2, i32x4, i32x8, i32x16 => i32);
1307 t!(u64x2, u64x4, u64x8 => u64);
1308 t!(i64x2, i64x4, i64x8 => i64);
1309 }
1310 }
1311
1312 #[test]
1313 #[cfg_attr(miri, ignore)] fn test_char() {
1315 let mut rng = crate::test::rng(891);
1316 let mut max = core::char::from_u32(0).unwrap();
1317 for _ in 0..100 {
1318 let c = rng.gen_range('A'..='Z');
1319 assert!(('A'..='Z').contains(&c));
1320 max = max.max(c);
1321 }
1322 assert_eq!(max, 'Z');
1323 let d = Uniform::new(
1324 core::char::from_u32(0xD7F0).unwrap(),
1325 core::char::from_u32(0xE010).unwrap(),
1326 );
1327 for _ in 0..100 {
1328 let c = d.sample(&mut rng);
1329 assert!((c as u32) < 0xD800 || (c as u32) > 0xDFFF);
1330 }
1331 }
1332
1333 #[test]
1334 #[cfg_attr(miri, ignore)] fn test_floats() {
1336 let mut rng = crate::test::rng(252);
1337 let mut zero_rng = StepRng::new(0, 0);
1338 let mut max_rng = StepRng::new(0xffff_ffff_ffff_ffff, 0);
1339 macro_rules! t {
1340 ($ty:ty, $f_scalar:ident, $bits_shifted:expr) => {{
1341 let v: &[($f_scalar, $f_scalar)] = &[
1342 (0.0, 100.0),
1343 (-1e35, -1e25),
1344 (1e-35, 1e-25),
1345 (-1e35, 1e35),
1346 (<$f_scalar>::from_bits(0), <$f_scalar>::from_bits(3)),
1347 (-<$f_scalar>::from_bits(10), -<$f_scalar>::from_bits(1)),
1348 (-<$f_scalar>::from_bits(5), 0.0),
1349 (-<$f_scalar>::from_bits(7), -0.0),
1350 (0.1 * ::core::$f_scalar::MAX, ::core::$f_scalar::MAX),
1351 (-::core::$f_scalar::MAX * 0.2, ::core::$f_scalar::MAX * 0.7),
1352 ];
1353 for &(low_scalar, high_scalar) in v.iter() {
1354 for lane in 0..<$ty>::lanes() {
1355 let low = <$ty>::splat(0.0 as $f_scalar).replace(lane, low_scalar);
1356 let high = <$ty>::splat(1.0 as $f_scalar).replace(lane, high_scalar);
1357 let my_uniform = Uniform::new(low, high);
1358 let my_incl_uniform = Uniform::new_inclusive(low, high);
1359 for _ in 0..100 {
1360 let v = rng.sample(my_uniform).extract(lane);
1361 assert!(low_scalar <= v && v < high_scalar);
1362 let v = rng.sample(my_incl_uniform).extract(lane);
1363 assert!(low_scalar <= v && v <= high_scalar);
1364 let v = <$ty as SampleUniform>::Sampler
1365 ::sample_single(low, high, &mut rng).extract(lane);
1366 assert!(low_scalar <= v && v < high_scalar);
1367 }
1368
1369 assert_eq!(
1370 rng.sample(Uniform::new_inclusive(low, low)).extract(lane),
1371 low_scalar
1372 );
1373
1374 assert_eq!(zero_rng.sample(my_uniform).extract(lane), low_scalar);
1375 assert_eq!(zero_rng.sample(my_incl_uniform).extract(lane), low_scalar);
1376 assert_eq!(<$ty as SampleUniform>::Sampler
1377 ::sample_single(low, high, &mut zero_rng)
1378 .extract(lane), low_scalar);
1379 assert!(max_rng.sample(my_uniform).extract(lane) < high_scalar);
1380 assert!(max_rng.sample(my_incl_uniform).extract(lane) <= high_scalar);
1381
1382 if (high_scalar - low_scalar) > 0.0001 {
1386 let mut lowering_max_rng = StepRng::new(
1387 0xffff_ffff_ffff_ffff,
1388 (-1i64 << $bits_shifted) as u64,
1389 );
1390 assert!(
1391 <$ty as SampleUniform>::Sampler
1392 ::sample_single(low, high, &mut lowering_max_rng)
1393 .extract(lane) < high_scalar
1394 );
1395 }
1396 }
1397 }
1398
1399 assert_eq!(
1400 rng.sample(Uniform::new_inclusive(
1401 ::core::$f_scalar::MAX,
1402 ::core::$f_scalar::MAX
1403 )),
1404 ::core::$f_scalar::MAX
1405 );
1406 assert_eq!(
1407 rng.sample(Uniform::new_inclusive(
1408 -::core::$f_scalar::MAX,
1409 -::core::$f_scalar::MAX
1410 )),
1411 -::core::$f_scalar::MAX
1412 );
1413 }};
1414 }
1415
1416 t!(f32, f32, 32 - 23);
1417 t!(f64, f64, 64 - 52);
1418 #[cfg(feature = "simd_support")]
1419 {
1420 t!(f32x2, f32, 32 - 23);
1421 t!(f32x4, f32, 32 - 23);
1422 t!(f32x8, f32, 32 - 23);
1423 t!(f32x16, f32, 32 - 23);
1424 t!(f64x2, f64, 64 - 52);
1425 t!(f64x4, f64, 64 - 52);
1426 t!(f64x8, f64, 64 - 52);
1427 }
1428 }
1429
1430 #[test]
1431 #[should_panic]
1432 fn test_float_overflow() {
1433 Uniform::from(::core::f64::MIN..::core::f64::MAX);
1434 }
1435
1436 #[test]
1437 #[should_panic]
1438 fn test_float_overflow_single() {
1439 let mut rng = crate::test::rng(252);
1440 rng.gen_range(::core::f64::MIN..::core::f64::MAX);
1441 }
1442
1443 #[test]
1444 #[cfg(all(
1445 feature = "std",
1446 not(target_arch = "wasm32"),
1447 not(target_arch = "asmjs")
1448 ))]
1449 fn test_float_assertions() {
1450 use super::SampleUniform;
1451 use std::panic::catch_unwind;
1452 fn range<T: SampleUniform>(low: T, high: T) {
1453 let mut rng = crate::test::rng(253);
1454 T::Sampler::sample_single(low, high, &mut rng);
1455 }
1456
1457 macro_rules! t {
1458 ($ty:ident, $f_scalar:ident) => {{
1459 let v: &[($f_scalar, $f_scalar)] = &[
1460 (::std::$f_scalar::NAN, 0.0),
1461 (1.0, ::std::$f_scalar::NAN),
1462 (::std::$f_scalar::NAN, ::std::$f_scalar::NAN),
1463 (1.0, 0.5),
1464 (::std::$f_scalar::MAX, -::std::$f_scalar::MAX),
1465 (::std::$f_scalar::INFINITY, ::std::$f_scalar::INFINITY),
1466 (
1467 ::std::$f_scalar::NEG_INFINITY,
1468 ::std::$f_scalar::NEG_INFINITY,
1469 ),
1470 (::std::$f_scalar::NEG_INFINITY, 5.0),
1471 (5.0, ::std::$f_scalar::INFINITY),
1472 (::std::$f_scalar::NAN, ::std::$f_scalar::INFINITY),
1473 (::std::$f_scalar::NEG_INFINITY, ::std::$f_scalar::NAN),
1474 (::std::$f_scalar::NEG_INFINITY, ::std::$f_scalar::INFINITY),
1475 ];
1476 for &(low_scalar, high_scalar) in v.iter() {
1477 for lane in 0..<$ty>::lanes() {
1478 let low = <$ty>::splat(0.0 as $f_scalar).replace(lane, low_scalar);
1479 let high = <$ty>::splat(1.0 as $f_scalar).replace(lane, high_scalar);
1480 assert!(catch_unwind(|| range(low, high)).is_err());
1481 assert!(catch_unwind(|| Uniform::new(low, high)).is_err());
1482 assert!(catch_unwind(|| Uniform::new_inclusive(low, high)).is_err());
1483 assert!(catch_unwind(|| range(low, low)).is_err());
1484 assert!(catch_unwind(|| Uniform::new(low, low)).is_err());
1485 }
1486 }
1487 }};
1488 }
1489
1490 t!(f32, f32);
1491 t!(f64, f64);
1492 #[cfg(feature = "simd_support")]
1493 {
1494 t!(f32x2, f32);
1495 t!(f32x4, f32);
1496 t!(f32x8, f32);
1497 t!(f32x16, f32);
1498 t!(f64x2, f64);
1499 t!(f64x4, f64);
1500 t!(f64x8, f64);
1501 }
1502 }
1503
1504
1505 #[test]
1506 #[cfg_attr(miri, ignore)] fn test_durations() {
1508 #[cfg(not(feature = "std"))] use core::time::Duration;
1509 #[cfg(feature = "std")] use std::time::Duration;
1510
1511 let mut rng = crate::test::rng(253);
1512
1513 let v = &[
1514 (Duration::new(10, 50000), Duration::new(100, 1234)),
1515 (Duration::new(0, 100), Duration::new(1, 50)),
1516 (
1517 Duration::new(0, 0),
1518 Duration::new(u64::max_value(), 999_999_999),
1519 ),
1520 ];
1521 for &(low, high) in v.iter() {
1522 let my_uniform = Uniform::new(low, high);
1523 for _ in 0..1000 {
1524 let v = rng.sample(my_uniform);
1525 assert!(low <= v && v < high);
1526 }
1527 }
1528 }
1529
1530 #[test]
1531 fn test_custom_uniform() {
1532 use crate::distributions::uniform::{
1533 SampleBorrow, SampleUniform, UniformFloat, UniformSampler,
1534 };
1535 #[derive(Clone, Copy, PartialEq, PartialOrd)]
1536 struct MyF32 {
1537 x: f32,
1538 }
1539 #[derive(Clone, Copy, Debug)]
1540 struct UniformMyF32(UniformFloat<f32>);
1541 impl UniformSampler for UniformMyF32 {
1542 type X = MyF32;
1543
1544 fn new<B1, B2>(low: B1, high: B2) -> Self
1545 where
1546 B1: SampleBorrow<Self::X> + Sized,
1547 B2: SampleBorrow<Self::X> + Sized,
1548 {
1549 UniformMyF32(UniformFloat::<f32>::new(low.borrow().x, high.borrow().x))
1550 }
1551
1552 fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
1553 where
1554 B1: SampleBorrow<Self::X> + Sized,
1555 B2: SampleBorrow<Self::X> + Sized,
1556 {
1557 UniformSampler::new(low, high)
1558 }
1559
1560 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
1561 MyF32 {
1562 x: self.0.sample(rng),
1563 }
1564 }
1565 }
1566 impl SampleUniform for MyF32 {
1567 type Sampler = UniformMyF32;
1568 }
1569
1570 let (low, high) = (MyF32 { x: 17.0f32 }, MyF32 { x: 22.0f32 });
1571 let uniform = Uniform::new(low, high);
1572 let mut rng = crate::test::rng(804);
1573 for _ in 0..100 {
1574 let x: MyF32 = rng.sample(uniform);
1575 assert!(low <= x && x < high);
1576 }
1577 }
1578
1579 #[test]
1580 fn test_uniform_from_std_range() {
1581 let r = Uniform::from(2u32..7);
1582 assert_eq!(r.0.low, 2);
1583 assert_eq!(r.0.range, 5);
1584 let r = Uniform::from(2.0f64..7.0);
1585 assert_eq!(r.0.low, 2.0);
1586 assert_eq!(r.0.scale, 5.0);
1587 }
1588
1589 #[test]
1590 fn test_uniform_from_std_range_inclusive() {
1591 let r = Uniform::from(2u32..=6);
1592 assert_eq!(r.0.low, 2);
1593 assert_eq!(r.0.range, 5);
1594 let r = Uniform::from(2.0f64..=7.0);
1595 assert_eq!(r.0.low, 2.0);
1596 assert!(r.0.scale > 5.0);
1597 assert!(r.0.scale < 5.0 + 1e-14);
1598 }
1599
1600 #[test]
1601 fn value_stability() {
1602 fn test_samples<T: SampleUniform + Copy + core::fmt::Debug + PartialEq>(
1603 lb: T, ub: T, expected_single: &[T], expected_multiple: &[T],
1604 ) where Uniform<T>: Distribution<T> {
1605 let mut rng = crate::test::rng(897);
1606 let mut buf = [lb; 3];
1607
1608 for x in &mut buf {
1609 *x = T::Sampler::sample_single(lb, ub, &mut rng);
1610 }
1611 assert_eq!(&buf, expected_single);
1612
1613 let distr = Uniform::new(lb, ub);
1614 for x in &mut buf {
1615 *x = rng.sample(&distr);
1616 }
1617 assert_eq!(&buf, expected_multiple);
1618 }
1619
1620 test_samples(11u8, 219, &[17, 66, 214], &[181, 93, 165]);
1624 test_samples(11u32, 219, &[17, 66, 214], &[181, 93, 165]);
1625
1626 test_samples(0f32, 1e-2f32, &[0.0003070104, 0.0026630748, 0.00979833], &[
1627 0.008194133,
1628 0.00398172,
1629 0.007428536,
1630 ]);
1631 test_samples(
1632 -1e10f64,
1633 1e10f64,
1634 &[-4673848682.871551, 6388267422.932352, 4857075081.198343],
1635 &[1173375212.1808167, 1917642852.109581, 2365076174.3153973],
1636 );
1637
1638 test_samples(
1639 Duration::new(2, 0),
1640 Duration::new(4, 0),
1641 &[
1642 Duration::new(2, 532615131),
1643 Duration::new(3, 638826742),
1644 Duration::new(3, 485707508),
1645 ],
1646 &[
1647 Duration::new(3, 117337521),
1648 Duration::new(3, 191764285),
1649 Duration::new(3, 236507617),
1650 ],
1651 );
1652 }
1653}