mathru/statistics/distrib/bernoulli.rs
1//! Bernoulli Distribution
2use crate::{algebra::abstr::Real, statistics::distrib::Discrete};
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5use std::clone::Clone;
6
7/// Bernoulli distribution
8///
9/// Fore more information:
10///
11/// <https://en.wikipedia.org/wiki/Bernoulli_distribution>
12#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
13#[derive(Clone, Copy, Debug)]
14pub struct Bernoulli<T> {
15 p: T,
16}
17
18impl<T> Bernoulli<T>
19where
20 T: Real,
21{
22 /// Create a probability distribution with p(X=1) = p
23 ///
24 /// # Arguments
25 ///
26 /// * `p` Probability that random varibale X=1, 0.0 <= p <= 1.0
27 ///
28 /// # Panics
29 ///
30 /// if p < 0 || p > 1.0
31 ///
32 /// # Example
33 ///
34 /// ```
35 /// use mathru::statistics::distrib::Bernoulli;
36 ///
37 /// let distrib: Bernoulli<f64> = Bernoulli::new(0.2);
38 /// ```
39 pub fn new(p: T) -> Bernoulli<T> {
40 if p < T::zero() || p > T::one() {
41 panic!()
42 }
43
44 Bernoulli { p }
45 }
46}
47
48impl<T> Discrete<T, u8, T> for Bernoulli<T>
49where
50 T: Real,
51{
52 /// Probability mass function of the Bernoulli distribution
53 ///
54 ///
55 /// # Arguments
56 ///
57 /// * `x` Random variable x ∈ {0, 1}
58 ///
59 /// # Panics
60 ///
61 /// if x ∉ {0, 1}
62 /// # Example
63 ///
64 /// ```
65 /// use mathru::statistics::distrib::{Bernoulli, Discrete};
66 ///
67 /// let distrib: Bernoulli<f64> = Bernoulli::new(0.2);
68 /// let x: u8 = 0;
69 /// let p: f64 = distrib.pmf(x);
70 /// ```
71 fn pmf(&self, x: u8) -> T {
72 if (x == 1) || (x == 0) {
73 if x == 0 {
74 T::one() - self.p
75 } else {
76 self.p
77 }
78 } else {
79 panic!()
80 }
81 }
82
83 /// Cumulative distribution function of the Bernoulli distribution
84 ///
85 /// # Arguments
86 ///
87 /// * `x` Random variable x ∈ {0, 1}
88 ///
89 /// # Example
90 ///
91 /// ```
92 /// use mathru::statistics::distrib::{Bernoulli, Discrete};
93 ///
94 /// let distrib: Bernoulli<f64> = Bernoulli::new(0.2);
95 /// let x: f64 = 0.4;
96 /// let p: f64 = distrib.cdf(x);
97 /// ```
98 fn cdf(&self, x: T) -> T {
99 if x >= T::one() {
100 return T::one();
101 }
102
103 if x <= T::zero() {
104 T::zero()
105 } else {
106 T::one() - self.p
107 }
108 }
109
110 /// Expected value
111 ///
112 /// # Example
113 ///
114 /// ```
115 /// use mathru::statistics::distrib::{Bernoulli, Discrete};
116 ///
117 /// let distrib: Bernoulli<f64> = Bernoulli::new(0.2);
118 /// let mean: f64 = distrib.mean();
119 /// ```
120 fn mean(&self) -> T {
121 self.p
122 }
123
124 /// Variance
125 ///
126 /// # Example
127 ///
128 /// ```
129 /// use mathru::statistics::distrib::{Bernoulli, Discrete};
130 ///
131 /// let distrib: Bernoulli<f64> = Bernoulli::new(0.2);
132 /// let var: f64 = distrib.variance();
133 /// ```
134 fn variance(&self) -> T {
135 self.p * (T::one() - self.p)
136 }
137}