#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Bernoulli {
pub probability: u64
}
impl Bernoulli {
const ALWAYS_TRUE: u64 = u64::MAX;
const SCALE: f64 = 2.0 * (1u64 << 63) as f64;
#[inline(always)]
pub const fn new(probability: f64) -> Option<Self> {
if probability < 0.0 || probability > 1.0 {
None
} else {
if probability == 1.0 {
Some(Self {
probability: Self::ALWAYS_TRUE
})
} else {
Some(Self {
probability: (probability * Self::SCALE) as u64
})
}
}
}
#[inline(always)]
pub const fn is_true(&self, input: u64) -> bool {
if self.probability == Self::ALWAYS_TRUE {
true
} else {
input < self.probability
}
}
#[inline(always)]
pub fn sample(&self, rnd: &crate::Rand) -> bool {
self.is_true(rnd.next_u64())
}
}