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_receiver_is_total_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_receiver_is_total_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> {
425 fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<T, Error>;
427
428 fn is_empty(&self) -> bool;
430}
431
432impl<T: SampleUniform + PartialOrd> SampleRange<T> for Range<T> {
433 #[inline]
434 fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<T, Error> {
435 T::Sampler::sample_single(self.start, self.end, rng)
436 }
437
438 #[inline]
439 fn is_empty(&self) -> bool {
440 !(self.start < self.end)
441 }
442}
443
444impl<T: SampleUniform + PartialOrd> SampleRange<T> for RangeInclusive<T> {
445 #[inline]
446 fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<T, Error> {
447 T::Sampler::sample_single_inclusive(self.start(), self.end(), rng)
448 }
449
450 #[inline]
451 fn is_empty(&self) -> bool {
452 !(self.start() <= self.end())
453 }
454}
455
456macro_rules! impl_sample_range_u {
457 ($t:ty) => {
458 impl SampleRange<$t> for RangeTo<$t> {
459 #[inline]
460 fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<$t, Error> {
461 <$t as SampleUniform>::Sampler::sample_single(0, self.end, rng)
462 }
463
464 #[inline]
465 fn is_empty(&self) -> bool {
466 0 == self.end
467 }
468 }
469
470 impl SampleRange<$t> for RangeToInclusive<$t> {
471 #[inline]
472 fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<$t, Error> {
473 <$t as SampleUniform>::Sampler::sample_single_inclusive(0, self.end, rng)
474 }
475
476 #[inline]
477 fn is_empty(&self) -> bool {
478 false
479 }
480 }
481 };
482}
483
484impl 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);
485impl 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);
486impl 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);
487impl 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);
488impl 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);
489impl 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);
490
491#[cfg(test)]
492mod tests {
493 use super::*;
494 use crate::RngExt;
495 use core::time::Duration;
496
497 #[test]
498 #[cfg(feature = "serde")]
499 fn test_uniform_serialization() {
500 let unit_box: Uniform<i32> = Uniform::new(-1, 1).unwrap();
501 let de_unit_box: Uniform<i32> =
502 postcard::from_bytes(&postcard::to_allocvec(&unit_box).unwrap()).unwrap();
503 assert_eq!(unit_box.0, de_unit_box.0);
504
505 let unit_box: Uniform<f32> = Uniform::new(-1., 1.).unwrap();
506 let de_unit_box: Uniform<f32> =
507 postcard::from_bytes(&postcard::to_allocvec(&unit_box).unwrap()).unwrap();
508 assert_eq!(unit_box.0, de_unit_box.0);
509 }
510
511 #[test]
512 fn test_custom_uniform() {
513 use crate::distr::uniform::{SampleBorrow, SampleUniform, UniformFloat, UniformSampler};
514 #[derive(Clone, Copy, PartialEq, PartialOrd)]
515 struct MyF32 {
516 x: f32,
517 }
518 #[derive(Clone, Copy, Debug)]
519 struct UniformMyF32(UniformFloat<f32>);
520 impl UniformSampler for UniformMyF32 {
521 type X = MyF32;
522
523 fn new<B1, B2>(low: B1, high: B2) -> Result<Self, Error>
524 where
525 B1: SampleBorrow<Self::X> + Sized,
526 B2: SampleBorrow<Self::X> + Sized,
527 {
528 UniformFloat::<f32>::new(low.borrow().x, high.borrow().x).map(UniformMyF32)
529 }
530
531 fn new_inclusive<B1, B2>(low: B1, high: B2) -> Result<Self, Error>
532 where
533 B1: SampleBorrow<Self::X> + Sized,
534 B2: SampleBorrow<Self::X> + Sized,
535 {
536 UniformSampler::new(low, high)
537 }
538
539 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
540 MyF32 {
541 x: self.0.sample(rng),
542 }
543 }
544 }
545 impl SampleUniform for MyF32 {
546 type Sampler = UniformMyF32;
547 }
548
549 let (low, high) = (MyF32 { x: 17.0f32 }, MyF32 { x: 22.0f32 });
550 let uniform = Uniform::new(low, high).unwrap();
551 let mut rng = crate::test::rng(804);
552 for _ in 0..100 {
553 let x: MyF32 = rng.sample(uniform);
554 assert!(low <= x && x < high);
555 }
556 }
557
558 #[test]
559 fn value_stability() {
560 fn test_samples<T: SampleUniform + Copy + fmt::Debug + PartialEq>(
561 lb: T,
562 ub: T,
563 expected_single: &[T],
564 expected_multiple: &[T],
565 ) where
566 Uniform<T>: Distribution<T>,
567 {
568 let mut rng = crate::test::rng(897);
569 let mut buf = [lb; 3];
570
571 for x in &mut buf {
572 *x = T::Sampler::sample_single(lb, ub, &mut rng).unwrap();
573 }
574 assert_eq!(&buf, expected_single);
575
576 let distr = Uniform::new(lb, ub).unwrap();
577 for x in &mut buf {
578 *x = rng.sample(&distr);
579 }
580 assert_eq!(&buf, expected_multiple);
581 }
582
583 test_samples(
584 0f32,
585 1e-2f32,
586 &[0.0003070104, 0.0026630748, 0.00979833],
587 &[0.008194133, 0.00398172, 0.007428536],
588 );
589 test_samples(
590 -1e10f64,
591 1e10f64,
592 &[-4673848682.871551, 6388267422.932352, 4857075081.198343],
593 &[1173375212.1808167, 1917642852.109581, 2365076174.3153973],
594 );
595
596 test_samples(
597 Duration::new(2, 0),
598 Duration::new(4, 0),
599 &[
600 Duration::new(2, 532615131),
601 Duration::new(3, 638826742),
602 Duration::new(3, 485707508),
603 ],
604 &[
605 Duration::new(3, 117337521),
606 Duration::new(3, 191764285),
607 Duration::new(3, 236507617),
608 ],
609 );
610 }
611
612 #[test]
613 fn uniform_distributions_can_be_compared() {
614 assert_eq!(
615 Uniform::new(1.0, 2.0).unwrap(),
616 Uniform::new(1.0, 2.0).unwrap()
617 );
618
619 assert_eq!(
621 Uniform::new(1_u32, 2_u32).unwrap(),
622 Uniform::new(1_u32, 2_u32).unwrap()
623 );
624 }
625}