mathru/statistics/distrib/
raisedcosine.rs

1use crate::{algebra::abstr::Real, statistics::distrib::Continuous};
2#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4use std::clone::Clone;
5
6/// Raised Cosine distribution
7///
8/// Fore more information:
9/// <https://en.wikipedia.org/wiki/Raised_cosine_distribution>
10///
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12#[derive(Clone, Copy, Debug)]
13pub struct RaisedCosine<T> {
14    mu: T,
15    s: T,
16}
17
18impl<T> RaisedCosine<T>
19where
20    T: Real,
21{
22    /// Creates a probability distribution
23    ///
24    /// # Arguments
25    ///
26    /// * `mu`
27    /// * `s` > 0.0
28    ///
29    /// # Panics
30    ///
31    /// if s < 0.0
32    ///
33    /// # Example
34    ///
35    /// ```
36    /// use mathru::statistics::distrib::RaisedCosine;
37    /// use std::f64::consts::PI;
38    ///
39    /// let mu: f64 = PI;
40    /// let s: f64 = 0.5 * PI;
41    /// let distrib: RaisedCosine<f64> = RaisedCosine::new(mu, s);
42    /// ```
43    pub fn new(mu: T, s: T) -> RaisedCosine<T> {
44        if s < T::zero() {
45            panic!();
46        }
47        RaisedCosine { mu, s }
48    }
49}
50
51impl<T> Continuous<T> for RaisedCosine<T>
52where
53    T: Real,
54{
55    /// Probability density function
56    ///
57    /// # Arguments
58    ///
59    /// * `x` Random variable x
60    ///
61    /// # Panics
62    ///
63    ///
64    ///
65    /// # Example
66    ///
67    /// ```
68    /// use mathru::statistics::distrib::{Continuous, RaisedCosine};
69    ///
70    /// let distrib: RaisedCosine<f64> = RaisedCosine::new(-1.2, 1.5);
71    /// let x: f64 = 5.0;
72    /// let p: f64 = distrib.pdf(x);
73    /// ```
74    fn pdf(&self, x: T) -> T {
75        if (self.mu - self.s) <= x && x < (self.mu + self.s) {
76            return (T::one() + (T::pi() * (x - self.mu) / self.s).cos())
77                / (T::from_f64(2.0) * self.s);
78        }
79
80        T::zero()
81    }
82
83    /// Cumulative distribution function
84    ///
85    /// # Arguments
86    ///
87    ///
88    /// # Example
89    ///
90    /// ```
91    /// use mathru::statistics::distrib::{Continuous, RaisedCosine};
92    /// use std::f64::consts::PI;
93    ///
94    /// let distrib: RaisedCosine<f64> = RaisedCosine::new(1.0, PI);
95    /// let x: f64 = PI / 2.0;
96    /// let p: f64 = distrib.cdf(x);
97    /// ```
98    fn cdf(&self, x: T) -> T {
99        if (self.mu - self.s) <= x && x <= (self.mu + self.s) {
100            let k: T = (x - self.mu) / self.s;
101            (T::one() + k + T::one() / T::pi() * (k * T::pi()).sin()) / T::from_f64(2.0)
102        } else if x < (self.mu - self.s) {
103            T::zero()
104        } else {
105            T::one()
106        }
107    }
108
109    /// Quantile function of inverse cdf
110    fn quantile(&self, _p: T) -> T {
111        unimplemented!();
112    }
113
114    /// Expected value
115    ///
116    /// # Example
117    ///
118    /// ```
119    /// use mathru::statistics::distrib::{Continuous, RaisedCosine};
120    ///
121    /// let distrib: RaisedCosine<f64> = RaisedCosine::new(-2.0, 0.5);
122    /// let mean: f64 = distrib.mean();
123    /// ```
124    fn mean(&self) -> T {
125        self.mu
126    }
127
128    /// Variance
129    ///
130    /// # Example
131    ///
132    /// ```
133    /// use mathru::statistics::distrib::{Continuous, RaisedCosine};
134    /// use std::f64::consts::PI;
135    ///
136    /// let distrib: RaisedCosine<f64> = RaisedCosine::new(2.0, PI);
137    /// let var: f64 = distrib.variance();
138    /// ```
139    fn variance(&self) -> T {
140        self.s * self.s * (T::from_f64(1.0 / 3.0) - T::from_f64(2.0) / (T::pi() * T::pi()))
141    }
142
143    fn skewness(&self) -> T {
144        T::zero()
145    }
146
147    /// Median is the value separating the higher half from the lower half of a
148    /// probability distribution.
149    fn median(&self) -> T {
150        self.mu
151    }
152
153    fn entropy(&self) -> T {
154        unimplemented!();
155    }
156}