use super::*;
use crate::math::tensor::{AsMutTensor, Tensor};
pub struct UniformLsb {
pub n: usize,
}
macro_rules! implement_uniform_some_lsb {
($T:ty) => {
impl RandomGenerable<UniformLsb> for $T {
fn sample(UniformLsb { n }: UniformLsb) -> Self {
random_uniform::<$T>() >> (<$T as Numeric>::BITS - n)
}
}
};
}
implement_uniform_some_lsb!(u8);
implement_uniform_some_lsb!(u16);
implement_uniform_some_lsb!(u32);
implement_uniform_some_lsb!(u64);
implement_uniform_some_lsb!(u128);
pub fn random_uniform_n_lsb<T: RandomGenerable<UniformLsb>>(n: usize) -> T {
T::sample(UniformLsb { n })
}
pub fn fill_with_random_uniform_n_lsb<Scalar, Tensorable>(output: &mut Tensorable, n: usize)
where
Scalar: RandomGenerable<UniformLsb>,
Tensorable: AsMutTensor<Element = Scalar>,
{
output.as_mut_tensor().iter_mut().for_each(|s| {
*s = random_uniform_n_lsb::<Scalar>(n);
});
}
pub fn random_uniform_n_lsb_tensor<T: RandomGenerable<UniformLsb>>(
size: usize,
n: usize,
) -> Tensor<Vec<T>> {
(0..size).map(|_| random_uniform_n_lsb::<T>(n)).collect()
}