1use core::time::Duration;
110use core::ops::{Range, RangeInclusive};
111
112use crate::distributions::float::IntoFloat;
113use crate::distributions::utils::{BoolAsSIMD, FloatAsSIMD, FloatSIMDUtils, WideningMultiply};
114use crate::distributions::Distribution;
115use crate::{Rng, RngCore};
116
117#[cfg(not(feature = "std"))]
118#[allow(unused_imports)] use crate::distributions::utils::Float;
120
121#[cfg(feature = "serde1")]
122use serde::{Serialize, Deserialize};
123
124#[derive(Clone, Copy, Debug, PartialEq)]
174#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
175#[cfg_attr(feature = "serde1", serde(bound(serialize = "X::Sampler: Serialize")))]
176#[cfg_attr(feature = "serde1", serde(bound(deserialize = "X::Sampler: Deserialize<'de>")))]
177pub struct Uniform<X: SampleUniform>(X::Sampler);
178
179impl<X: SampleUniform> Uniform<X> {
180 pub fn new<B1, B2>(low: B1, high: B2) -> Uniform<X>
183 where
184 B1: SampleBorrow<X> + Sized,
185 B2: SampleBorrow<X> + Sized,
186 {
187 Uniform(X::Sampler::new(low, high))
188 }
189
190 pub fn new_inclusive<B1, B2>(low: B1, high: B2) -> Uniform<X>
193 where
194 B1: SampleBorrow<X> + Sized,
195 B2: SampleBorrow<X> + Sized,
196 {
197 Uniform(X::Sampler::new_inclusive(low, high))
198 }
199}
200
201impl<X: SampleUniform> Distribution<X> for Uniform<X> {
202 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> X {
203 self.0.sample(rng)
204 }
205}
206
207pub trait SampleUniform: Sized {
215 type Sampler: UniformSampler<X = Self>;
217}
218
219pub trait UniformSampler: Sized {
230 type X;
232
233 fn new<B1, B2>(low: B1, high: B2) -> Self
239 where
240 B1: SampleBorrow<Self::X> + Sized,
241 B2: SampleBorrow<Self::X> + Sized;
242
243 fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
249 where
250 B1: SampleBorrow<Self::X> + Sized,
251 B2: SampleBorrow<Self::X> + Sized;
252
253 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X;
255
256 fn sample_single<R: Rng + ?Sized, B1, B2>(low: B1, high: B2, rng: &mut R) -> Self::X
276 where
277 B1: SampleBorrow<Self::X> + Sized,
278 B2: SampleBorrow<Self::X> + Sized,
279 {
280 let uniform: Self = UniformSampler::new(low, high);
281 uniform.sample(rng)
282 }
283
284 fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(low: B1, high: B2, rng: &mut R)
293 -> Self::X
294 where B1: SampleBorrow<Self::X> + Sized,
295 B2: SampleBorrow<Self::X> + Sized
296 {
297 let uniform: Self = UniformSampler::new_inclusive(low, high);
298 uniform.sample(rng)
299 }
300}
301
302impl<X: SampleUniform> From<Range<X>> for Uniform<X> {
303 fn from(r: ::core::ops::Range<X>) -> Uniform<X> {
304 Uniform::new(r.start, r.end)
305 }
306}
307
308impl<X: SampleUniform> From<RangeInclusive<X>> for Uniform<X> {
309 fn from(r: ::core::ops::RangeInclusive<X>) -> Uniform<X> {
310 Uniform::new_inclusive(r.start(), r.end())
311 }
312}
313
314
315pub trait SampleBorrow<Borrowed> {
321 fn borrow(&self) -> &Borrowed;
325}
326impl<Borrowed> SampleBorrow<Borrowed> for Borrowed
327where Borrowed: SampleUniform
328{
329 #[inline(always)]
330 fn borrow(&self) -> &Borrowed {
331 self
332 }
333}
334impl<'a, Borrowed> SampleBorrow<Borrowed> for &'a Borrowed
335where Borrowed: SampleUniform
336{
337 #[inline(always)]
338 fn borrow(&self) -> &Borrowed {
339 *self
340 }
341}
342
343pub trait SampleRange<T> {
348 fn sample_single<R: RngCore + ?Sized>(self, rng: &mut R) -> T;
350
351 fn is_empty(&self) -> bool;
353}
354
355impl<T: SampleUniform + PartialOrd> SampleRange<T> for Range<T> {
356 #[inline]
357 fn sample_single<R: RngCore + ?Sized>(self, rng: &mut R) -> T {
358 T::Sampler::sample_single(self.start, self.end, rng)
359 }
360
361 #[inline]
362 fn is_empty(&self) -> bool {
363 !(self.start < self.end)
364 }
365}
366
367impl<T: SampleUniform + PartialOrd> SampleRange<T> for RangeInclusive<T> {
368 #[inline]
369 fn sample_single<R: RngCore + ?Sized>(self, rng: &mut R) -> T {
370 T::Sampler::sample_single_inclusive(self.start(), self.end(), rng)
371 }
372
373 #[inline]
374 fn is_empty(&self) -> bool {
375 !(self.start() <= self.end())
376 }
377}
378
379
380#[derive(Clone, Copy, Debug, PartialEq)]
420#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
421pub struct UniformInt<X> {
422 low: X,
423 range: X,
424 z: X, }
426
427macro_rules! uniform_int_impl {
428 ($ty:ty, $unsigned:ident, $u_large:ident) => {
429 impl SampleUniform for $ty {
430 type Sampler = UniformInt<$ty>;
431 }
432
433 impl UniformSampler for UniformInt<$ty> {
434 type X = $ty;
440
441 #[inline] fn new<B1, B2>(low_b: B1, high_b: B2) -> Self
444 where
445 B1: SampleBorrow<Self::X> + Sized,
446 B2: SampleBorrow<Self::X> + Sized,
447 {
448 let low = *low_b.borrow();
449 let high = *high_b.borrow();
450 assert!(low < high, "Uniform::new called with `low >= high`");
451 UniformSampler::new_inclusive(low, high - 1)
452 }
453
454 #[inline] fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Self
457 where
458 B1: SampleBorrow<Self::X> + Sized,
459 B2: SampleBorrow<Self::X> + Sized,
460 {
461 let low = *low_b.borrow();
462 let high = *high_b.borrow();
463 assert!(
464 low <= high,
465 "Uniform::new_inclusive called with `low > high`"
466 );
467 let unsigned_max = ::core::$u_large::MAX;
468
469 let range = high.wrapping_sub(low).wrapping_add(1) as $unsigned;
470 let ints_to_reject = if range > 0 {
471 let range = $u_large::from(range);
472 (unsigned_max - range + 1) % range
473 } else {
474 0
475 };
476
477 UniformInt {
478 low,
479 range: range as $ty,
481 z: ints_to_reject as $unsigned as $ty,
482 }
483 }
484
485 #[inline]
486 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
487 let range = self.range as $unsigned as $u_large;
488 if range > 0 {
489 let unsigned_max = ::core::$u_large::MAX;
490 let zone = unsigned_max - (self.z as $unsigned as $u_large);
491 loop {
492 let v: $u_large = rng.gen();
493 let (hi, lo) = v.wmul(range);
494 if lo <= zone {
495 return self.low.wrapping_add(hi as $ty);
496 }
497 }
498 } else {
499 rng.gen()
501 }
502 }
503
504 #[inline]
505 fn sample_single<R: Rng + ?Sized, B1, B2>(low_b: B1, high_b: B2, rng: &mut R) -> Self::X
506 where
507 B1: SampleBorrow<Self::X> + Sized,
508 B2: SampleBorrow<Self::X> + Sized,
509 {
510 let low = *low_b.borrow();
511 let high = *high_b.borrow();
512 assert!(low < high, "UniformSampler::sample_single: low >= high");
513 Self::sample_single_inclusive(low, high - 1, rng)
514 }
515
516 #[inline]
517 fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(low_b: B1, high_b: B2, rng: &mut R) -> Self::X
518 where
519 B1: SampleBorrow<Self::X> + Sized,
520 B2: SampleBorrow<Self::X> + Sized,
521 {
522 let low = *low_b.borrow();
523 let high = *high_b.borrow();
524 assert!(low <= high, "UniformSampler::sample_single_inclusive: low > high");
525 let range = high.wrapping_sub(low).wrapping_add(1) as $unsigned as $u_large;
526 if range == 0 {
529 return rng.gen();
530 }
531
532 let zone = if ::core::$unsigned::MAX <= ::core::u16::MAX as $unsigned {
533 let unsigned_max: $u_large = ::core::$u_large::MAX;
537 let ints_to_reject = (unsigned_max - range + 1) % range;
538 unsigned_max - ints_to_reject
539 } else {
540 (range << range.leading_zeros()).wrapping_sub(1)
543 };
544
545 loop {
546 let v: $u_large = rng.gen();
547 let (hi, lo) = v.wmul(range);
548 if lo <= zone {
549 return low.wrapping_add(hi as $ty);
550 }
551 }
552 }
553 }
554 };
555}
556
557uniform_int_impl! { i8, u8, u32 }
558uniform_int_impl! { i16, u16, u32 }
559uniform_int_impl! { i32, u32, u32 }
560uniform_int_impl! { i64, u64, u64 }
561uniform_int_impl! { i128, u128, u128 }
562uniform_int_impl! { isize, usize, usize }
563uniform_int_impl! { u8, u8, u32 }
564uniform_int_impl! { u16, u16, u32 }
565uniform_int_impl! { u32, u32, u32 }
566uniform_int_impl! { u64, u64, u64 }
567uniform_int_impl! { usize, usize, usize }
568uniform_int_impl! { u128, u128, u128 }
569
570impl SampleUniform for char {
571 type Sampler = UniformChar;
572}
573
574#[derive(Clone, Copy, Debug)]
584#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
585pub struct UniformChar {
586 sampler: UniformInt<u32>,
587}
588
589const CHAR_SURROGATE_START: u32 = 0xD800;
591const CHAR_SURROGATE_LEN: u32 = 0xE000 - CHAR_SURROGATE_START;
593
594fn char_to_comp_u32(c: char) -> u32 {
596 match c as u32 {
597 c if c >= CHAR_SURROGATE_START => c - CHAR_SURROGATE_LEN,
598 c => c,
599 }
600}
601
602impl UniformSampler for UniformChar {
603 type X = char;
604
605 #[inline] fn new<B1, B2>(low_b: B1, high_b: B2) -> Self
608 where
609 B1: SampleBorrow<Self::X> + Sized,
610 B2: SampleBorrow<Self::X> + Sized,
611 {
612 let low = char_to_comp_u32(*low_b.borrow());
613 let high = char_to_comp_u32(*high_b.borrow());
614 let sampler = UniformInt::<u32>::new(low, high);
615 UniformChar { sampler }
616 }
617
618 #[inline] fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Self
621 where
622 B1: SampleBorrow<Self::X> + Sized,
623 B2: SampleBorrow<Self::X> + Sized,
624 {
625 let low = char_to_comp_u32(*low_b.borrow());
626 let high = char_to_comp_u32(*high_b.borrow());
627 let sampler = UniformInt::<u32>::new_inclusive(low, high);
628 UniformChar { sampler }
629 }
630
631 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
632 let mut x = self.sampler.sample(rng);
633 if x >= CHAR_SURROGATE_START {
634 x += CHAR_SURROGATE_LEN;
635 }
636 unsafe { core::char::from_u32_unchecked(x) }
640 }
641}
642
643#[derive(Clone, Copy, Debug, PartialEq)]
663#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
664pub struct UniformFloat<X> {
665 low: X,
666 scale: X,
667}
668
669macro_rules! uniform_float_impl {
670 ($ty:ty, $uty:ident, $f_scalar:ident, $u_scalar:ident, $bits_to_discard:expr) => {
671 impl SampleUniform for $ty {
672 type Sampler = UniformFloat<$ty>;
673 }
674
675 impl UniformSampler for UniformFloat<$ty> {
676 type X = $ty;
677
678 fn new<B1, B2>(low_b: B1, high_b: B2) -> Self
679 where
680 B1: SampleBorrow<Self::X> + Sized,
681 B2: SampleBorrow<Self::X> + Sized,
682 {
683 let low = *low_b.borrow();
684 let high = *high_b.borrow();
685 debug_assert!(
686 low.all_finite(),
687 "Uniform::new called with `low` non-finite."
688 );
689 debug_assert!(
690 high.all_finite(),
691 "Uniform::new called with `high` non-finite."
692 );
693 assert!(low.all_lt(high), "Uniform::new called with `low >= high`");
694 let max_rand = <$ty>::splat(
695 (::core::$u_scalar::MAX >> $bits_to_discard).into_float_with_exponent(0) - 1.0,
696 );
697
698 let mut scale = high - low;
699 assert!(scale.all_finite(), "Uniform::new: range overflow");
700
701 loop {
702 let mask = (scale * max_rand + low).ge_mask(high);
703 if mask.none() {
704 break;
705 }
706 scale = scale.decrease_masked(mask);
707 }
708
709 debug_assert!(<$ty>::splat(0.0).all_le(scale));
710
711 UniformFloat { low, scale }
712 }
713
714 fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Self
715 where
716 B1: SampleBorrow<Self::X> + Sized,
717 B2: SampleBorrow<Self::X> + Sized,
718 {
719 let low = *low_b.borrow();
720 let high = *high_b.borrow();
721 debug_assert!(
722 low.all_finite(),
723 "Uniform::new_inclusive called with `low` non-finite."
724 );
725 debug_assert!(
726 high.all_finite(),
727 "Uniform::new_inclusive called with `high` non-finite."
728 );
729 assert!(
730 low.all_le(high),
731 "Uniform::new_inclusive called with `low > high`"
732 );
733 let max_rand = <$ty>::splat(
734 (::core::$u_scalar::MAX >> $bits_to_discard).into_float_with_exponent(0) - 1.0,
735 );
736
737 let mut scale = (high - low) / max_rand;
738 assert!(scale.all_finite(), "Uniform::new_inclusive: range overflow");
739
740 loop {
741 let mask = (scale * max_rand + low).gt_mask(high);
742 if mask.none() {
743 break;
744 }
745 scale = scale.decrease_masked(mask);
746 }
747
748 debug_assert!(<$ty>::splat(0.0).all_le(scale));
749
750 UniformFloat { low, scale }
751 }
752
753 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
754 let value1_2 = (rng.gen::<$uty>() >> $bits_to_discard).into_float_with_exponent(0);
756
757 let value0_1 = value1_2 - 1.0;
760
761 value0_1 * self.scale + self.low
767 }
768
769 #[inline]
770 fn sample_single<R: Rng + ?Sized, B1, B2>(low_b: B1, high_b: B2, rng: &mut R) -> Self::X
771 where
772 B1: SampleBorrow<Self::X> + Sized,
773 B2: SampleBorrow<Self::X> + Sized,
774 {
775 let low = *low_b.borrow();
776 let high = *high_b.borrow();
777 debug_assert!(
778 low.all_finite(),
779 "UniformSampler::sample_single called with `low` non-finite."
780 );
781 debug_assert!(
782 high.all_finite(),
783 "UniformSampler::sample_single called with `high` non-finite."
784 );
785 assert!(
786 low.all_lt(high),
787 "UniformSampler::sample_single: low >= high"
788 );
789 let mut scale = high - low;
790 assert!(scale.all_finite(), "UniformSampler::sample_single: range overflow");
791
792 loop {
793 let value1_2 =
795 (rng.gen::<$uty>() >> $bits_to_discard).into_float_with_exponent(0);
796
797 let value0_1 = value1_2 - 1.0;
800
801 let res = value0_1 * scale + low;
804
805 debug_assert!(low.all_le(res) || !scale.all_finite());
806 if res.all_lt(high) {
807 return res;
808 }
809
810 let mask = !scale.finite_mask();
838 if mask.any() {
839 assert!(
840 low.all_finite() && high.all_finite(),
841 "Uniform::sample_single: low and high must be finite"
842 );
843 scale = scale.decrease_masked(mask);
844 }
845 }
846 }
847 }
848 };
849}
850
851uniform_float_impl! { f32, u32, f32, u32, 32 - 23 }
852uniform_float_impl! { f64, u64, f64, u64, 64 - 52 }
853
854#[derive(Clone, Copy, Debug)]
859#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
860pub struct UniformDuration {
861 mode: UniformDurationMode,
862 offset: u32,
863}
864
865#[derive(Debug, Copy, Clone)]
866#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
867enum UniformDurationMode {
868 Small {
869 secs: u64,
870 nanos: Uniform<u32>,
871 },
872 Medium {
873 nanos: Uniform<u64>,
874 },
875 Large {
876 max_secs: u64,
877 max_nanos: u32,
878 secs: Uniform<u64>,
879 },
880}
881
882impl SampleUniform for Duration {
883 type Sampler = UniformDuration;
884}
885
886impl UniformSampler for UniformDuration {
887 type X = Duration;
888
889 #[inline]
890 fn new<B1, B2>(low_b: B1, high_b: B2) -> Self
891 where
892 B1: SampleBorrow<Self::X> + Sized,
893 B2: SampleBorrow<Self::X> + Sized,
894 {
895 let low = *low_b.borrow();
896 let high = *high_b.borrow();
897 assert!(low < high, "Uniform::new called with `low >= high`");
898 UniformDuration::new_inclusive(low, high - Duration::new(0, 1))
899 }
900
901 #[inline]
902 fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Self
903 where
904 B1: SampleBorrow<Self::X> + Sized,
905 B2: SampleBorrow<Self::X> + Sized,
906 {
907 let low = *low_b.borrow();
908 let high = *high_b.borrow();
909 assert!(
910 low <= high,
911 "Uniform::new_inclusive called with `low > high`"
912 );
913
914 let low_s = low.as_secs();
915 let low_n = low.subsec_nanos();
916 let mut high_s = high.as_secs();
917 let mut high_n = high.subsec_nanos();
918
919 if high_n < low_n {
920 high_s -= 1;
921 high_n += 1_000_000_000;
922 }
923
924 let mode = if low_s == high_s {
925 UniformDurationMode::Small {
926 secs: low_s,
927 nanos: Uniform::new_inclusive(low_n, high_n),
928 }
929 } else {
930 let max = high_s
931 .checked_mul(1_000_000_000)
932 .and_then(|n| n.checked_add(u64::from(high_n)));
933
934 if let Some(higher_bound) = max {
935 let lower_bound = low_s * 1_000_000_000 + u64::from(low_n);
936 UniformDurationMode::Medium {
937 nanos: Uniform::new_inclusive(lower_bound, higher_bound),
938 }
939 } else {
940 let max_nanos = high_n - low_n;
942 UniformDurationMode::Large {
943 max_secs: high_s,
944 max_nanos,
945 secs: Uniform::new_inclusive(low_s, high_s),
946 }
947 }
948 };
949 UniformDuration {
950 mode,
951 offset: low_n,
952 }
953 }
954
955 #[inline]
956 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Duration {
957 match self.mode {
958 UniformDurationMode::Small { secs, nanos } => {
959 let n = nanos.sample(rng);
960 Duration::new(secs, n)
961 }
962 UniformDurationMode::Medium { nanos } => {
963 let nanos = nanos.sample(rng);
964 Duration::new(nanos / 1_000_000_000, (nanos % 1_000_000_000) as u32)
965 }
966 UniformDurationMode::Large {
967 max_secs,
968 max_nanos,
969 secs,
970 } => {
971 let nano_range = Uniform::new(0, 1_000_000_000);
973 loop {
974 let s = secs.sample(rng);
975 let n = nano_range.sample(rng);
976 if !(s == max_secs && n > max_nanos) {
977 let sum = n + self.offset;
978 break Duration::new(s, sum);
979 }
980 }
981 }
982 }
983 }
984}
985
986#[cfg(test)]
987mod tests {
988 use super::*;
989 use crate::rngs::mock::StepRng;
990
991 #[test]
992 #[cfg(feature = "serde1")]
993 fn test_serialization_uniform_duration() {
994 let distr = UniformDuration::new(Duration::from_secs(10), Duration::from_secs(60));
995 let de_distr: UniformDuration = bincode::deserialize(&bincode::serialize(&distr).unwrap()).unwrap();
996 assert_eq!(
997 distr.offset, de_distr.offset
998 );
999 match (distr.mode, de_distr.mode) {
1000 (UniformDurationMode::Small {secs: a_secs, nanos: a_nanos}, UniformDurationMode::Small {secs, nanos}) => {
1001 assert_eq!(a_secs, secs);
1002
1003 assert_eq!(a_nanos.0.low, nanos.0.low);
1004 assert_eq!(a_nanos.0.range, nanos.0.range);
1005 assert_eq!(a_nanos.0.z, nanos.0.z);
1006 }
1007 (UniformDurationMode::Medium {nanos: a_nanos} , UniformDurationMode::Medium {nanos}) => {
1008 assert_eq!(a_nanos.0.low, nanos.0.low);
1009 assert_eq!(a_nanos.0.range, nanos.0.range);
1010 assert_eq!(a_nanos.0.z, nanos.0.z);
1011 }
1012 (UniformDurationMode::Large {max_secs:a_max_secs, max_nanos:a_max_nanos, secs:a_secs}, UniformDurationMode::Large {max_secs, max_nanos, secs} ) => {
1013 assert_eq!(a_max_secs, max_secs);
1014 assert_eq!(a_max_nanos, max_nanos);
1015
1016 assert_eq!(a_secs.0.low, secs.0.low);
1017 assert_eq!(a_secs.0.range, secs.0.range);
1018 assert_eq!(a_secs.0.z, secs.0.z);
1019 }
1020 _ => panic!("`UniformDurationMode` was not serialized/deserialized correctly")
1021 }
1022 }
1023
1024 #[test]
1025 #[cfg(feature = "serde1")]
1026 fn test_uniform_serialization() {
1027 let unit_box: Uniform<i32> = Uniform::new(-1, 1);
1028 let de_unit_box: Uniform<i32> = bincode::deserialize(&bincode::serialize(&unit_box).unwrap()).unwrap();
1029
1030 assert_eq!(unit_box.0.low, de_unit_box.0.low);
1031 assert_eq!(unit_box.0.range, de_unit_box.0.range);
1032 assert_eq!(unit_box.0.z, de_unit_box.0.z);
1033
1034 let unit_box: Uniform<f32> = Uniform::new(-1., 1.);
1035 let de_unit_box: Uniform<f32> = bincode::deserialize(&bincode::serialize(&unit_box).unwrap()).unwrap();
1036
1037 assert_eq!(unit_box.0.low, de_unit_box.0.low);
1038 assert_eq!(unit_box.0.scale, de_unit_box.0.scale);
1039 }
1040
1041 #[should_panic]
1042 #[test]
1043 fn test_uniform_bad_limits_equal_int() {
1044 Uniform::new(10, 10);
1045 }
1046
1047 #[test]
1048 fn test_uniform_good_limits_equal_int() {
1049 let mut rng = crate::test::rng(804);
1050 let dist = Uniform::new_inclusive(10, 10);
1051 for _ in 0..20 {
1052 assert_eq!(rng.sample(dist), 10);
1053 }
1054 }
1055
1056 #[should_panic]
1057 #[test]
1058 fn test_uniform_bad_limits_flipped_int() {
1059 Uniform::new(10, 5);
1060 }
1061
1062 #[test]
1063 #[cfg_attr(miri, ignore)] fn test_integers() {
1065 use core::{i128, u128};
1066 use core::{i16, i32, i64, i8, isize};
1067 use core::{u16, u32, u64, u8, usize};
1068
1069 let mut rng = crate::test::rng(251);
1070 macro_rules! t {
1071 ($ty:ident, $v:expr, $le:expr, $lt:expr) => {{
1072 for &(low, high) in $v.iter() {
1073 let my_uniform = Uniform::new(low, high);
1074 for _ in 0..1000 {
1075 let v: $ty = rng.sample(my_uniform);
1076 assert!($le(low, v) && $lt(v, high));
1077 }
1078
1079 let my_uniform = Uniform::new_inclusive(low, high);
1080 for _ in 0..1000 {
1081 let v: $ty = rng.sample(my_uniform);
1082 assert!($le(low, v) && $le(v, high));
1083 }
1084
1085 let my_uniform = Uniform::new(&low, high);
1086 for _ in 0..1000 {
1087 let v: $ty = rng.sample(my_uniform);
1088 assert!($le(low, v) && $lt(v, high));
1089 }
1090
1091 let my_uniform = Uniform::new_inclusive(&low, &high);
1092 for _ in 0..1000 {
1093 let v: $ty = rng.sample(my_uniform);
1094 assert!($le(low, v) && $le(v, high));
1095 }
1096
1097 for _ in 0..1000 {
1098 let v = <$ty as SampleUniform>::Sampler::sample_single(low, high, &mut rng);
1099 assert!($le(low, v) && $lt(v, high));
1100 }
1101
1102 for _ in 0..1000 {
1103 let v = <$ty as SampleUniform>::Sampler::sample_single_inclusive(low, high, &mut rng);
1104 assert!($le(low, v) && $le(v, high));
1105 }
1106 }
1107 }};
1108
1109 ($($ty:ident),*) => {{
1111 $(t!(
1112 $ty,
1113 [(0, 10), (10, 127), ($ty::MIN, $ty::MAX)],
1114 |x, y| x <= y,
1115 |x, y| x < y
1116 );)*
1117 }};
1118
1119 ($($ty:ident),* => $scalar:ident) => {{
1121 $(t!(
1122 $ty,
1123 [
1124 ($ty::splat(0), $ty::splat(10)),
1125 ($ty::splat(10), $ty::splat(127)),
1126 ($ty::splat($scalar::MIN), $ty::splat($scalar::MAX)),
1127 ],
1128 |x: $ty, y| x.le(y).all(),
1129 |x: $ty, y| x.lt(y).all()
1130 );)*
1131 }};
1132 }
1133 t!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, i128, u128);
1134 }
1135
1136 #[test]
1137 #[cfg_attr(miri, ignore)] fn test_char() {
1139 let mut rng = crate::test::rng(891);
1140 let mut max = core::char::from_u32(0).unwrap();
1141 for _ in 0..100 {
1142 let c = rng.gen_range('A'..='Z');
1143 assert!(('A'..='Z').contains(&c));
1144 max = max.max(c);
1145 }
1146 assert_eq!(max, 'Z');
1147 let d = Uniform::new(
1148 core::char::from_u32(0xD7F0).unwrap(),
1149 core::char::from_u32(0xE010).unwrap(),
1150 );
1151 for _ in 0..100 {
1152 let c = d.sample(&mut rng);
1153 assert!((c as u32) < 0xD800 || (c as u32) > 0xDFFF);
1154 }
1155 }
1156
1157 #[test]
1158 #[cfg_attr(miri, ignore)] fn test_floats() {
1160 let mut rng = crate::test::rng(252);
1161 let mut zero_rng = StepRng::new(0, 0);
1162 let mut max_rng = StepRng::new(0xffff_ffff_ffff_ffff, 0);
1163 macro_rules! t {
1164 ($ty:ty, $f_scalar:ident, $bits_shifted:expr) => {{
1165 let v: &[($f_scalar, $f_scalar)] = &[
1166 (0.0, 100.0),
1167 (-1e35, -1e25),
1168 (1e-35, 1e-25),
1169 (-1e35, 1e35),
1170 (<$f_scalar>::from_bits(0), <$f_scalar>::from_bits(3)),
1171 (-<$f_scalar>::from_bits(10), -<$f_scalar>::from_bits(1)),
1172 (-<$f_scalar>::from_bits(5), 0.0),
1173 (-<$f_scalar>::from_bits(7), -0.0),
1174 (0.1 * ::core::$f_scalar::MAX, ::core::$f_scalar::MAX),
1175 (-::core::$f_scalar::MAX * 0.2, ::core::$f_scalar::MAX * 0.7),
1176 ];
1177 for &(low_scalar, high_scalar) in v.iter() {
1178 for lane in 0..<$ty>::lanes() {
1179 let low = <$ty>::splat(0.0 as $f_scalar).replace(lane, low_scalar);
1180 let high = <$ty>::splat(1.0 as $f_scalar).replace(lane, high_scalar);
1181 let my_uniform = Uniform::new(low, high);
1182 let my_incl_uniform = Uniform::new_inclusive(low, high);
1183 for _ in 0..100 {
1184 let v = rng.sample(my_uniform).extract(lane);
1185 assert!(low_scalar <= v && v < high_scalar);
1186 let v = rng.sample(my_incl_uniform).extract(lane);
1187 assert!(low_scalar <= v && v <= high_scalar);
1188 let v = <$ty as SampleUniform>::Sampler
1189 ::sample_single(low, high, &mut rng).extract(lane);
1190 assert!(low_scalar <= v && v < high_scalar);
1191 }
1192
1193 assert_eq!(
1194 rng.sample(Uniform::new_inclusive(low, low)).extract(lane),
1195 low_scalar
1196 );
1197
1198 assert_eq!(zero_rng.sample(my_uniform).extract(lane), low_scalar);
1199 assert_eq!(zero_rng.sample(my_incl_uniform).extract(lane), low_scalar);
1200 assert_eq!(<$ty as SampleUniform>::Sampler
1201 ::sample_single(low, high, &mut zero_rng)
1202 .extract(lane), low_scalar);
1203 assert!(max_rng.sample(my_uniform).extract(lane) < high_scalar);
1204 assert!(max_rng.sample(my_incl_uniform).extract(lane) <= high_scalar);
1205
1206 if (high_scalar - low_scalar) > 0.0001 {
1210 let mut lowering_max_rng = StepRng::new(
1211 0xffff_ffff_ffff_ffff,
1212 (-1i64 << $bits_shifted) as u64,
1213 );
1214 assert!(
1215 <$ty as SampleUniform>::Sampler
1216 ::sample_single(low, high, &mut lowering_max_rng)
1217 .extract(lane) < high_scalar
1218 );
1219 }
1220 }
1221 }
1222
1223 assert_eq!(
1224 rng.sample(Uniform::new_inclusive(
1225 ::core::$f_scalar::MAX,
1226 ::core::$f_scalar::MAX
1227 )),
1228 ::core::$f_scalar::MAX
1229 );
1230 assert_eq!(
1231 rng.sample(Uniform::new_inclusive(
1232 -::core::$f_scalar::MAX,
1233 -::core::$f_scalar::MAX
1234 )),
1235 -::core::$f_scalar::MAX
1236 );
1237 }};
1238 }
1239
1240 t!(f32, f32, 32 - 23);
1241 t!(f64, f64, 64 - 52);
1242 }
1243
1244 #[test]
1245 #[should_panic]
1246 fn test_float_overflow() {
1247 let _ = Uniform::from(::core::f64::MIN..::core::f64::MAX);
1248 }
1249
1250 #[test]
1251 #[should_panic]
1252 fn test_float_overflow_single() {
1253 let mut rng = crate::test::rng(252);
1254 rng.gen_range(::core::f64::MIN..::core::f64::MAX);
1255 }
1256
1257 #[test]
1258 #[cfg(all(
1259 feature = "std",
1260 not(target_arch = "wasm32"),
1261 ))]
1262 fn test_float_assertions() {
1263 use super::SampleUniform;
1264 use std::panic::catch_unwind;
1265 fn range<T: SampleUniform>(low: T, high: T) {
1266 let mut rng = crate::test::rng(253);
1267 T::Sampler::sample_single(low, high, &mut rng);
1268 }
1269
1270 macro_rules! t {
1271 ($ty:ident, $f_scalar:ident) => {{
1272 let v: &[($f_scalar, $f_scalar)] = &[
1273 (::std::$f_scalar::NAN, 0.0),
1274 (1.0, ::std::$f_scalar::NAN),
1275 (::std::$f_scalar::NAN, ::std::$f_scalar::NAN),
1276 (1.0, 0.5),
1277 (::std::$f_scalar::MAX, -::std::$f_scalar::MAX),
1278 (::std::$f_scalar::INFINITY, ::std::$f_scalar::INFINITY),
1279 (
1280 ::std::$f_scalar::NEG_INFINITY,
1281 ::std::$f_scalar::NEG_INFINITY,
1282 ),
1283 (::std::$f_scalar::NEG_INFINITY, 5.0),
1284 (5.0, ::std::$f_scalar::INFINITY),
1285 (::std::$f_scalar::NAN, ::std::$f_scalar::INFINITY),
1286 (::std::$f_scalar::NEG_INFINITY, ::std::$f_scalar::NAN),
1287 (::std::$f_scalar::NEG_INFINITY, ::std::$f_scalar::INFINITY),
1288 ];
1289 for &(low_scalar, high_scalar) in v.iter() {
1290 for lane in 0..<$ty>::lanes() {
1291 let low = <$ty>::splat(0.0 as $f_scalar).replace(lane, low_scalar);
1292 let high = <$ty>::splat(1.0 as $f_scalar).replace(lane, high_scalar);
1293 assert!(catch_unwind(|| range(low, high)).is_err());
1294 assert!(catch_unwind(|| Uniform::new(low, high)).is_err());
1295 assert!(catch_unwind(|| Uniform::new_inclusive(low, high)).is_err());
1296 assert!(catch_unwind(|| range(low, low)).is_err());
1297 assert!(catch_unwind(|| Uniform::new(low, low)).is_err());
1298 }
1299 }
1300 }};
1301 }
1302
1303 t!(f32, f32);
1304 t!(f64, f64);
1305 }
1306
1307
1308 #[test]
1309 #[cfg_attr(miri, ignore)] fn test_durations() {
1311 let mut rng = crate::test::rng(253);
1312
1313 let v = &[
1314 (Duration::new(10, 50000), Duration::new(100, 1234)),
1315 (Duration::new(0, 100), Duration::new(1, 50)),
1316 (
1317 Duration::new(0, 0),
1318 Duration::new(u64::max_value(), 999_999_999),
1319 ),
1320 ];
1321 for &(low, high) in v.iter() {
1322 let my_uniform = Uniform::new(low, high);
1323 for _ in 0..1000 {
1324 let v = rng.sample(my_uniform);
1325 assert!(low <= v && v < high);
1326 }
1327 }
1328 }
1329
1330 #[test]
1331 fn test_custom_uniform() {
1332 use crate::distributions::uniform::{
1333 SampleBorrow, SampleUniform, UniformFloat, UniformSampler,
1334 };
1335 #[derive(Clone, Copy, PartialEq, PartialOrd)]
1336 struct MyF32 {
1337 x: f32,
1338 }
1339 #[derive(Clone, Copy, Debug)]
1340 struct UniformMyF32(UniformFloat<f32>);
1341 impl UniformSampler for UniformMyF32 {
1342 type X = MyF32;
1343
1344 fn new<B1, B2>(low: B1, high: B2) -> Self
1345 where
1346 B1: SampleBorrow<Self::X> + Sized,
1347 B2: SampleBorrow<Self::X> + Sized,
1348 {
1349 UniformMyF32(UniformFloat::<f32>::new(low.borrow().x, high.borrow().x))
1350 }
1351
1352 fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
1353 where
1354 B1: SampleBorrow<Self::X> + Sized,
1355 B2: SampleBorrow<Self::X> + Sized,
1356 {
1357 UniformSampler::new(low, high)
1358 }
1359
1360 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
1361 MyF32 {
1362 x: self.0.sample(rng),
1363 }
1364 }
1365 }
1366 impl SampleUniform for MyF32 {
1367 type Sampler = UniformMyF32;
1368 }
1369
1370 let (low, high) = (MyF32 { x: 17.0f32 }, MyF32 { x: 22.0f32 });
1371 let uniform = Uniform::new(low, high);
1372 let mut rng = crate::test::rng(804);
1373 for _ in 0..100 {
1374 let x: MyF32 = rng.sample(uniform);
1375 assert!(low <= x && x < high);
1376 }
1377 }
1378
1379 #[test]
1380 fn test_uniform_from_std_range() {
1381 let r = Uniform::from(2u32..7);
1382 assert_eq!(r.0.low, 2);
1383 assert_eq!(r.0.range, 5);
1384 let r = Uniform::from(2.0f64..7.0);
1385 assert_eq!(r.0.low, 2.0);
1386 assert_eq!(r.0.scale, 5.0);
1387 }
1388
1389 #[test]
1390 fn test_uniform_from_std_range_inclusive() {
1391 let r = Uniform::from(2u32..=6);
1392 assert_eq!(r.0.low, 2);
1393 assert_eq!(r.0.range, 5);
1394 let r = Uniform::from(2.0f64..=7.0);
1395 assert_eq!(r.0.low, 2.0);
1396 assert!(r.0.scale > 5.0);
1397 assert!(r.0.scale < 5.0 + 1e-14);
1398 }
1399
1400 #[test]
1401 fn value_stability() {
1402 fn test_samples<T: SampleUniform + Copy + core::fmt::Debug + PartialEq>(
1403 lb: T, ub: T, expected_single: &[T], expected_multiple: &[T],
1404 ) where Uniform<T>: Distribution<T> {
1405 let mut rng = crate::test::rng(897);
1406 let mut buf = [lb; 3];
1407
1408 for x in &mut buf {
1409 *x = T::Sampler::sample_single(lb, ub, &mut rng);
1410 }
1411 assert_eq!(&buf, expected_single);
1412
1413 let distr = Uniform::new(lb, ub);
1414 for x in &mut buf {
1415 *x = rng.sample(&distr);
1416 }
1417 assert_eq!(&buf, expected_multiple);
1418 }
1419
1420 test_samples(11u8, 219, &[17, 66, 214], &[181, 93, 165]);
1424 test_samples(11u32, 219, &[17, 66, 214], &[181, 93, 165]);
1425
1426 test_samples(0f32, 1e-2f32, &[0.0003070104, 0.0026630748, 0.00979833], &[
1427 0.008194133,
1428 0.00398172,
1429 0.007428536,
1430 ]);
1431 test_samples(
1432 -1e10f64,
1433 1e10f64,
1434 &[-4673848682.871551, 6388267422.932352, 4857075081.198343],
1435 &[1173375212.1808167, 1917642852.109581, 2365076174.3153973],
1436 );
1437
1438 test_samples(
1439 Duration::new(2, 0),
1440 Duration::new(4, 0),
1441 &[
1442 Duration::new(2, 532615131),
1443 Duration::new(3, 638826742),
1444 Duration::new(3, 485707508),
1445 ],
1446 &[
1447 Duration::new(3, 117337521),
1448 Duration::new(3, 191764285),
1449 Duration::new(3, 236507617),
1450 ],
1451 );
1452 }
1453
1454 #[test]
1455 fn uniform_distributions_can_be_compared() {
1456 assert_eq!(Uniform::new(1.0, 2.0), Uniform::new(1.0, 2.0));
1457
1458 assert_eq!(Uniform::new(1 as u32, 2 as u32), Uniform::new(1 as u32, 2 as u32));
1460 }
1461}