use std::{
cmp::Ordering,
ops::{Bound, RangeBounds},
};
use crate::{
rand::{
distributions::{
uniform::{SampleBorrow, SampleUniform, Uniform},
Distribution,
},
thread_rng, Rng,
},
Bounded,
};
#[inline]
pub fn random_fill_exclusively<X: SampleUniform, B1: SampleBorrow<X>, B2: SampleBorrow<X>>(
out: &mut [X],
min: B1,
max_exclusive: B2,
) {
random_fill_exclusively_with_rng(out, min, max_exclusive, &mut thread_rng())
}
#[inline]
pub fn random_fill_exclusively_with_rng<
X: SampleUniform,
B1: SampleBorrow<X>,
B2: SampleBorrow<X>,
T: Rng,
>(
out: &mut [X],
min: B1,
max_exclusive: B2,
rng: &mut T,
) {
let uniform = Uniform::new(min, max_exclusive);
for x in out.iter_mut() {
*x = uniform.sample(rng);
}
}
#[inline]
pub fn random_fill_inclusively<X: SampleUniform, B1: SampleBorrow<X>, B2: SampleBorrow<X>>(
out: &mut [X],
min: B1,
max_inclusive: B2,
) {
random_fill_inclusively_with_rng(out, min, max_inclusive, &mut thread_rng());
}
#[inline]
pub fn random_fill_inclusively_with_rng<
X: SampleUniform,
B1: SampleBorrow<X>,
B2: SampleBorrow<X>,
T: Rng,
>(
out: &mut [X],
min: B1,
max_inclusive: B2,
rng: &mut T,
) {
let uniform = Uniform::new_inclusive(min, max_inclusive);
let mut random_iter = uniform.sample_iter(rng);
for x in out.iter_mut() {
*x = random_iter.next().unwrap();
}
}
#[inline]
pub fn random_fill_inclusively_cmp<X: SampleUniform + Ord + Clone, B: SampleBorrow<X>>(
out: &mut [X],
a: B,
b: B,
) {
random_fill_inclusively_cmp_with_rng(out, a, b, &mut thread_rng());
}
#[inline]
pub fn random_fill_inclusively_cmp_with_rng<
X: SampleUniform + Ord + Clone,
B: SampleBorrow<X>,
T: Rng,
>(
out: &mut [X],
a: B,
b: B,
rng: &mut T,
) {
match a.borrow().cmp(b.borrow()) {
Ordering::Greater => random_fill_inclusively_with_rng(out, b, a, rng),
Ordering::Equal => {
for x in out.iter_mut() {
*x = a.borrow().clone();
}
},
Ordering::Less => random_fill_inclusively_with_rng(out, a, b, rng),
}
}
#[inline]
pub fn random_fill<X: SampleUniform + Bounded>(out: &mut [X]) {
random_fill_with_rng(out, &mut thread_rng())
}
#[inline]
pub fn random_fill_with_rng<X: SampleUniform + Bounded, T: Rng>(out: &mut [X], rng: &mut T) {
random_fill_inclusively_with_rng(out, X::min_value(), X::max_value(), rng);
}
#[inline]
pub fn random_fill_at_least<X: SampleUniform + Bounded, B: SampleBorrow<X>>(out: &mut [X], min: B) {
random_fill_at_least_with_rng(out, min, &mut thread_rng());
}
#[inline]
pub fn random_fill_at_least_with_rng<X: SampleUniform + Bounded, B: SampleBorrow<X>, T: Rng>(
out: &mut [X],
min: B,
rng: &mut T,
) {
random_fill_inclusively_with_rng(out, min, X::max_value(), rng);
}
#[inline]
pub fn random_fill_at_most<X: SampleUniform + Bounded, B: SampleBorrow<X>>(
out: &mut [X],
max_inclusive: B,
) {
random_fill_at_most_with_rng(out, max_inclusive, &mut thread_rng());
}
#[inline]
pub fn random_fill_at_most_with_rng<X: SampleUniform + Bounded, B: SampleBorrow<X>, T: Rng>(
out: &mut [X],
max_inclusive: B,
rng: &mut T,
) {
random_fill_inclusively_with_rng(out, X::min_value(), max_inclusive, rng);
}
#[inline]
pub fn random_fill_at_most_exclusively<X: SampleUniform + Bounded, B: SampleBorrow<X>>(
out: &mut [X],
max_exclusive: B,
) {
random_fill_at_most_exclusively_with_rng(out, max_exclusive, &mut thread_rng());
}
#[inline]
pub fn random_fill_at_most_exclusively_with_rng<
X: SampleUniform + Bounded,
B: SampleBorrow<X>,
T: Rng,
>(
out: &mut [X],
max_exclusive: B,
rng: &mut T,
) {
random_fill_exclusively_with_rng(out, X::min_value(), max_exclusive, rng);
}
#[inline]
pub fn random_fill_ranged<X: SampleUniform + Bounded, R: RangeBounds<X>>(out: &mut [X], range: R) {
random_fill_ranged_with_rng(out, range, &mut thread_rng())
}
#[inline]
pub fn random_fill_ranged_with_rng<X: SampleUniform + Bounded, R: RangeBounds<X>, T: Rng>(
out: &mut [X],
range: R,
rng: &mut T,
) {
let start = range.start_bound();
let end = range.end_bound();
match start {
Bound::Excluded(_) => {
panic!("random_fill_ranged_with_rng called with a start bound which is exclusive")
},
Bound::Included(min) => match end {
Bound::Excluded(max_exclusive) => {
random_fill_exclusively_with_rng(out, min, max_exclusive, rng)
},
Bound::Included(max_inclusive) => {
random_fill_inclusively_with_rng(out, min, max_inclusive, rng)
},
Bound::Unbounded => random_fill_at_least_with_rng(out, min, rng),
},
Bound::Unbounded => match end {
Bound::Excluded(max_exclusive) => {
random_fill_at_most_exclusively_with_rng(out, max_exclusive, rng)
},
Bound::Included(max_inclusive) => random_fill_at_most_with_rng(out, max_inclusive, rng),
Bound::Unbounded => random_fill_with_rng(out, rng),
},
}
}