1#[path = "uniform_float.rs"]
98mod float;
99#[doc(inline)]
100pub use float::UniformFloat;
101
102#[path = "uniform_int.rs"]
103mod int;
104#[doc(inline)]
105pub use int::{UniformInt, UniformUsize};
106
107#[path = "uniform_other.rs"]
108mod other;
109#[doc(inline)]
110pub use other::{UniformChar, UniformDuration};
111
112use core::fmt;
113use core::ops::{Range, RangeInclusive, RangeTo, RangeToInclusive};
114
115use crate::Rng;
116use crate::distr::Distribution;
117
118#[cfg(doc)]
119use crate::RngExt;
120
121#[derive(#[automatically_derived]
impl ::core::clone::Clone for Error {
#[inline]
fn clone(&self) -> Error { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Error { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Error {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
Error::EmptyRange => "EmptyRange",
Error::NonFinite => "NonFinite",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Error {
#[inline]
fn eq(&self, other: &Error) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Error {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq)]
123pub enum Error {
124 EmptyRange,
126 NonFinite,
128}
129
130impl fmt::Display for Error {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 f.write_str(match self {
133 Error::EmptyRange => "low > high (or equal if exclusive) in uniform distribution",
134 Error::NonFinite => "Non-finite range in uniform distribution",
135 })
136 }
137}
138
139impl core::error::Error for Error {}
140
141#[cfg(feature = "serde")]
142use serde::{Deserialize, Serialize};
143
144#[derive(#[automatically_derived]
impl<X: ::core::clone::Clone + SampleUniform> ::core::clone::Clone for
Uniform<X> where X::Sampler: ::core::clone::Clone {
#[inline]
fn clone(&self) -> Uniform<X> {
Uniform(::core::clone::Clone::clone(&self.0))
}
}Clone, #[automatically_derived]
impl<X: ::core::marker::Copy + SampleUniform> ::core::marker::Copy for
Uniform<X> where X::Sampler: ::core::marker::Copy {
}Copy, #[automatically_derived]
impl<X: ::core::fmt::Debug + SampleUniform> ::core::fmt::Debug for Uniform<X>
where X::Sampler: ::core::fmt::Debug {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Uniform",
&&self.0)
}
}Debug, #[automatically_derived]
impl<X: ::core::cmp::PartialEq + SampleUniform> ::core::cmp::PartialEq for
Uniform<X> where X::Sampler: ::core::cmp::PartialEq {
#[inline]
fn eq(&self, other: &Uniform<X>) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl<X: ::core::cmp::Eq + SampleUniform> ::core::cmp::Eq for Uniform<X> where
X::Sampler: ::core::cmp::Eq {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<X::Sampler>;
}
}Eq)]
216#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
217#[cfg_attr(feature = "serde", serde(bound(serialize = "X::Sampler: Serialize")))]
218#[cfg_attr(
219 feature = "serde",
220 serde(bound(deserialize = "X::Sampler: Deserialize<'de>"))
221)]
222pub struct Uniform<X: SampleUniform>(X::Sampler);
223
224impl<X: SampleUniform> Uniform<X> {
225 pub fn new<B1, B2>(low: B1, high: B2) -> Result<Uniform<X>, Error>
236 where
237 B1: SampleBorrow<X> + Sized,
238 B2: SampleBorrow<X> + Sized,
239 {
240 X::Sampler::new(low, high).map(Uniform)
241 }
242
243 pub fn new_inclusive<B1, B2>(low: B1, high: B2) -> Result<Uniform<X>, Error>
249 where
250 B1: SampleBorrow<X> + Sized,
251 B2: SampleBorrow<X> + Sized,
252 {
253 X::Sampler::new_inclusive(low, high).map(Uniform)
254 }
255}
256
257impl<X: SampleUniform> Distribution<X> for Uniform<X> {
258 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> X {
259 self.0.sample(rng)
260 }
261}
262
263pub trait SampleUniform: Sized {
271 type Sampler: UniformSampler<X = Self>;
273}
274
275pub trait UniformSampler: Sized {
286 type X;
288
289 fn new<B1, B2>(low: B1, high: B2) -> Result<Self, Error>
299 where
300 B1: SampleBorrow<Self::X> + Sized,
301 B2: SampleBorrow<Self::X> + Sized;
302
303 fn new_inclusive<B1, B2>(low: B1, high: B2) -> Result<Self, Error>
308 where
309 B1: SampleBorrow<Self::X> + Sized,
310 B2: SampleBorrow<Self::X> + Sized;
311
312 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X;
314
315 fn sample_single<R: Rng + ?Sized, B1, B2>(
340 low: B1,
341 high: B2,
342 rng: &mut R,
343 ) -> Result<Self::X, Error>
344 where
345 B1: SampleBorrow<Self::X> + Sized,
346 B2: SampleBorrow<Self::X> + Sized,
347 {
348 let uniform: Self = UniformSampler::new(low, high)?;
349 Ok(uniform.sample(rng))
350 }
351
352 fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(
361 low: B1,
362 high: B2,
363 rng: &mut R,
364 ) -> Result<Self::X, Error>
365 where
366 B1: SampleBorrow<Self::X> + Sized,
367 B2: SampleBorrow<Self::X> + Sized,
368 {
369 let uniform: Self = UniformSampler::new_inclusive(low, high)?;
370 Ok(uniform.sample(rng))
371 }
372}
373
374impl<X: SampleUniform> TryFrom<Range<X>> for Uniform<X> {
375 type Error = Error;
376
377 fn try_from(r: Range<X>) -> Result<Uniform<X>, Error> {
378 Uniform::new(r.start, r.end)
379 }
380}
381
382impl<X: SampleUniform> TryFrom<RangeInclusive<X>> for Uniform<X> {
383 type Error = Error;
384
385 fn try_from(r: ::core::ops::RangeInclusive<X>) -> Result<Uniform<X>, Error> {
386 Uniform::new_inclusive(r.start(), r.end())
387 }
388}
389
390pub trait SampleBorrow<Borrowed> {
396 fn borrow(&self) -> &Borrowed;
400}
401impl<Borrowed> SampleBorrow<Borrowed> for Borrowed
402where
403 Borrowed: SampleUniform,
404{
405 #[inline(always)]
406 fn borrow(&self) -> &Borrowed {
407 self
408 }
409}
410impl<Borrowed> SampleBorrow<Borrowed> for &Borrowed
411where
412 Borrowed: SampleUniform,
413{
414 #[inline(always)]
415 fn borrow(&self) -> &Borrowed {
416 self
417 }
418}
419
420pub trait SampleRange<T> {
440 fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<T, Error>;
442
443 fn is_empty(&self) -> bool;
445}
446
447impl<T: SampleUniform + PartialOrd> SampleRange<T> for Range<T> {
448 #[inline]
449 fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<T, Error> {
450 T::Sampler::sample_single(self.start, self.end, rng)
451 }
452
453 #[inline]
454 fn is_empty(&self) -> bool {
455 !(self.start < self.end)
456 }
457}
458
459impl<T: SampleUniform + PartialOrd> SampleRange<T> for RangeInclusive<T> {
460 #[inline]
461 fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<T, Error> {
462 T::Sampler::sample_single_inclusive(self.start(), self.end(), rng)
463 }
464
465 #[inline]
466 fn is_empty(&self) -> bool {
467 !(self.start() <= self.end())
468 }
469}
470
471macro_rules! impl_sample_range_u {
472 ($t:ty) => {
473 impl SampleRange<$t> for RangeTo<$t> {
474 #[inline]
475 fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<$t, Error> {
476 <$t as SampleUniform>::Sampler::sample_single(0, self.end, rng)
477 }
478
479 #[inline]
480 fn is_empty(&self) -> bool {
481 0 == self.end
482 }
483 }
484
485 impl SampleRange<$t> for RangeToInclusive<$t> {
486 #[inline]
487 fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<$t, Error> {
488 <$t as SampleUniform>::Sampler::sample_single_inclusive(0, self.end, rng)
489 }
490
491 #[inline]
492 fn is_empty(&self) -> bool {
493 false
494 }
495 }
496 };
497}
498
499impl SampleRange<u8> for RangeTo<u8> {
#[inline]
fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
-> Result<u8, Error> {
<u8 as SampleUniform>::Sampler::sample_single(0, self.end, rng)
}
#[inline]
fn is_empty(&self) -> bool { 0 == self.end }
}
impl SampleRange<u8> for RangeToInclusive<u8> {
#[inline]
fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
-> Result<u8, Error> {
<u8 as
SampleUniform>::Sampler::sample_single_inclusive(0, self.end,
rng)
}
#[inline]
fn is_empty(&self) -> bool { false }
}impl_sample_range_u!(u8);
500impl SampleRange<u16> for RangeTo<u16> {
#[inline]
fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
-> Result<u16, Error> {
<u16 as SampleUniform>::Sampler::sample_single(0, self.end, rng)
}
#[inline]
fn is_empty(&self) -> bool { 0 == self.end }
}
impl SampleRange<u16> for RangeToInclusive<u16> {
#[inline]
fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
-> Result<u16, Error> {
<u16 as
SampleUniform>::Sampler::sample_single_inclusive(0, self.end,
rng)
}
#[inline]
fn is_empty(&self) -> bool { false }
}impl_sample_range_u!(u16);
501impl SampleRange<u32> for RangeTo<u32> {
#[inline]
fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
-> Result<u32, Error> {
<u32 as SampleUniform>::Sampler::sample_single(0, self.end, rng)
}
#[inline]
fn is_empty(&self) -> bool { 0 == self.end }
}
impl SampleRange<u32> for RangeToInclusive<u32> {
#[inline]
fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
-> Result<u32, Error> {
<u32 as
SampleUniform>::Sampler::sample_single_inclusive(0, self.end,
rng)
}
#[inline]
fn is_empty(&self) -> bool { false }
}impl_sample_range_u!(u32);
502impl SampleRange<u64> for RangeTo<u64> {
#[inline]
fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
-> Result<u64, Error> {
<u64 as SampleUniform>::Sampler::sample_single(0, self.end, rng)
}
#[inline]
fn is_empty(&self) -> bool { 0 == self.end }
}
impl SampleRange<u64> for RangeToInclusive<u64> {
#[inline]
fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
-> Result<u64, Error> {
<u64 as
SampleUniform>::Sampler::sample_single_inclusive(0, self.end,
rng)
}
#[inline]
fn is_empty(&self) -> bool { false }
}impl_sample_range_u!(u64);
503impl SampleRange<u128> for RangeTo<u128> {
#[inline]
fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
-> Result<u128, Error> {
<u128 as SampleUniform>::Sampler::sample_single(0, self.end, rng)
}
#[inline]
fn is_empty(&self) -> bool { 0 == self.end }
}
impl SampleRange<u128> for RangeToInclusive<u128> {
#[inline]
fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
-> Result<u128, Error> {
<u128 as
SampleUniform>::Sampler::sample_single_inclusive(0, self.end,
rng)
}
#[inline]
fn is_empty(&self) -> bool { false }
}impl_sample_range_u!(u128);
504impl SampleRange<usize> for RangeTo<usize> {
#[inline]
fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
-> Result<usize, Error> {
<usize as SampleUniform>::Sampler::sample_single(0, self.end, rng)
}
#[inline]
fn is_empty(&self) -> bool { 0 == self.end }
}
impl SampleRange<usize> for RangeToInclusive<usize> {
#[inline]
fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
-> Result<usize, Error> {
<usize as
SampleUniform>::Sampler::sample_single_inclusive(0, self.end,
rng)
}
#[inline]
fn is_empty(&self) -> bool { false }
}impl_sample_range_u!(usize);
505
506#[cfg(test)]
507mod tests {
508 use super::*;
509 use crate::RngExt;
510 use core::time::Duration;
511
512 #[test]
513 #[cfg(feature = "serde")]
514 fn test_uniform_serialization() {
515 let unit_box: Uniform<i32> = Uniform::new(-1, 1).unwrap();
516 let de_unit_box: Uniform<i32> =
517 postcard::from_bytes(&postcard::to_allocvec(&unit_box).unwrap()).unwrap();
518 assert_eq!(unit_box.0, de_unit_box.0);
519
520 let unit_box: Uniform<f32> = Uniform::new(-1., 1.).unwrap();
521 let de_unit_box: Uniform<f32> =
522 postcard::from_bytes(&postcard::to_allocvec(&unit_box).unwrap()).unwrap();
523 assert_eq!(unit_box.0, de_unit_box.0);
524 }
525
526 #[test]
527 fn test_custom_uniform() {
528 use crate::distr::uniform::{SampleBorrow, SampleUniform, UniformFloat, UniformSampler};
529 #[derive(Clone, Copy, PartialEq, PartialOrd)]
530 struct MyF32 {
531 x: f32,
532 }
533 #[derive(Clone, Copy, Debug)]
534 struct UniformMyF32(UniformFloat<f32>);
535 impl UniformSampler for UniformMyF32 {
536 type X = MyF32;
537
538 fn new<B1, B2>(low: B1, high: B2) -> Result<Self, Error>
539 where
540 B1: SampleBorrow<Self::X> + Sized,
541 B2: SampleBorrow<Self::X> + Sized,
542 {
543 UniformFloat::<f32>::new(low.borrow().x, high.borrow().x).map(UniformMyF32)
544 }
545
546 fn new_inclusive<B1, B2>(low: B1, high: B2) -> Result<Self, Error>
547 where
548 B1: SampleBorrow<Self::X> + Sized,
549 B2: SampleBorrow<Self::X> + Sized,
550 {
551 UniformSampler::new(low, high)
552 }
553
554 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
555 MyF32 {
556 x: self.0.sample(rng),
557 }
558 }
559 }
560 impl SampleUniform for MyF32 {
561 type Sampler = UniformMyF32;
562 }
563
564 let (low, high) = (MyF32 { x: 17.0f32 }, MyF32 { x: 22.0f32 });
565 let uniform = Uniform::new(low, high).unwrap();
566 let mut rng = crate::test::rng(804);
567 for _ in 0..100 {
568 let x: MyF32 = rng.sample(uniform);
569 assert!(low <= x && x < high);
570 }
571 }
572
573 #[test]
574 fn value_stability() {
575 fn test_samples<T: SampleUniform + Copy + fmt::Debug + PartialEq>(
576 lb: T,
577 ub: T,
578 expected_single: &[T],
579 expected_multiple: &[T],
580 ) where
581 Uniform<T>: Distribution<T>,
582 {
583 let mut rng = crate::test::rng(897);
584 let mut buf = [lb; 3];
585
586 for x in &mut buf {
587 *x = T::Sampler::sample_single(lb, ub, &mut rng).unwrap();
588 }
589 assert_eq!(&buf, expected_single);
590
591 let distr = Uniform::new(lb, ub).unwrap();
592 for x in &mut buf {
593 *x = rng.sample(&distr);
594 }
595 assert_eq!(&buf, expected_multiple);
596 }
597
598 test_samples(
599 0f32,
600 1e-2f32,
601 &[0.0003070104, 0.0026630748, 0.00979833],
602 &[0.008194133, 0.00398172, 0.007428536],
603 );
604 test_samples(
605 -1e10f64,
606 1e10f64,
607 &[-4673848682.871551, 6388267422.932352, 4857075081.198343],
608 &[1173375212.1808167, 1917642852.109581, 2365076174.3153973],
609 );
610
611 test_samples(
612 Duration::new(2, 0),
613 Duration::new(4, 0),
614 &[
615 Duration::new(2, 532615131),
616 Duration::new(3, 638826742),
617 Duration::new(3, 485707508),
618 ],
619 &[
620 Duration::new(3, 117337521),
621 Duration::new(3, 191764285),
622 Duration::new(3, 236507617),
623 ],
624 );
625 }
626
627 #[test]
628 fn uniform_distributions_can_be_compared() {
629 assert_eq!(
630 Uniform::new(1.0, 2.0).unwrap(),
631 Uniform::new(1.0, 2.0).unwrap()
632 );
633
634 assert_eq!(
636 Uniform::new(1_u32, 2_u32).unwrap(),
637 Uniform::new(1_u32, 2_u32).unwrap()
638 );
639 }
640}