rand_simple/distributions/bernoulli.rs
1use crate::create_state;
2use crate::standard_distributions::xorshift160_0_to_1;
3
4/// Bernoulli Distribution
5///
6/// # Example Usage
7/// ```
8/// let mut bernoulli = rand_simple::Bernoulli::new(1192u32);
9///
10/// // Default parameters
11/// assert_eq!(format!("{bernoulli}"), "Bernoulli(Probability) = Bernoulli(0.5)");
12/// println!("Does the event occur (1) or not (0) with a probability θ = 0.5? -> {}", bernoulli.sample());
13///
14/// // Updating the probability parameter
15/// let probability: f64 = 0.8f64;
16/// let result: Result<f64, &str> = bernoulli.try_set_params(probability);
17/// assert_eq!(format!("{bernoulli}"), "Bernoulli(Probability) = Bernoulli(0.8)");
18/// println!("Does the event occur (1) or not (0) with a probability θ = {}? -> {}", probability, bernoulli.sample());
19/// ```
20pub struct Bernoulli {
21 xyzuv: [u32; 5], // 状態変数
22 probability: f64, // 発生確率
23}
24
25impl Bernoulli {
26 /// コンストラクタ
27 /// * `_seed` - 乱数の種
28 pub fn new(_seed: u32) -> Self {
29 let xyzuv: [u32; 5] = create_state(_seed);
30 Self {
31 xyzuv,
32 probability: 0.5_f64,
33 }
34 }
35
36 /// ある確率の事象が生じたか(1u64)、否か(0u64)を返す
37 pub fn sample(&mut self) -> u64 {
38 if xorshift160_0_to_1(&mut self.xyzuv) <= self.probability {
39 1_u64
40 } else {
41 0_u64
42 }
43 }
44
45 /// 確率変数のパラメータを変更する
46 /// * `probability` - 尺度母数
47 pub fn try_set_params(&mut self, probability: f64) -> Result<f64, &str> {
48 if !(0_f64..=1_f64).contains(&probability) {
49 Err("発生確率が0より小さいか、1よりも大きいです。確率変数のパラメータは前回の設定を維持します。")
50 } else {
51 self.probability = probability;
52 Ok(probability)
53 }
54 }
55}
56
57impl core::fmt::Display for Bernoulli {
58 /// Formatter for displaying in functions like println! macro
59 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
60 write!(
61 f,
62 "Bernoulli(Probability) = Bernoulli({})",
63 self.probability
64 )?;
65 Ok(())
66 }
67}