statrs/function/
logistic.rs

1//! Provides the [logistic](http://en.wikipedia.org/wiki/Logistic_function) and
2//! related functions
3
4use crate::error::StatsError;
5use crate::Result;
6
7/// Computes the logistic function
8pub fn logistic(p: f64) -> f64 {
9    1.0 / ((-p).exp() + 1.0)
10}
11
12/// Computes the logit function
13///
14/// # Panics
15///
16/// If `p < 0.0` or `p > 1.0`
17pub fn logit(p: f64) -> f64 {
18    checked_logit(p).unwrap()
19}
20
21/// Computes the logit function
22///
23/// # Errors
24///
25/// If `p < 0.0` or `p > 1.0`
26pub fn checked_logit(p: f64) -> Result<f64> {
27    if !(0.0..=1.0).contains(&p) {
28        Err(StatsError::ArgIntervalIncl("p", 0.0, 1.0))
29    } else {
30        Ok((p / (1.0 - p)).ln())
31    }
32}
33
34#[rustfmt::skip]
35#[cfg(test)]
36mod tests {
37    use std::f64;
38
39    #[test]
40    fn test_logistic() {
41        assert_eq!(super::logistic(f64::NEG_INFINITY), 0.0);
42        assert_eq!(super::logistic(-11.512915464920228103874353849992239636376994324587), 0.00001);
43        assert_almost_eq!(super::logistic(-6.9067547786485535272274487616830597875179908939086), 0.001, 1e-18);
44        assert_almost_eq!(super::logistic(-2.1972245773362193134015514347727700402304323440139), 0.1, 1e-16);
45        assert_eq!(super::logistic(0.0), 0.5);
46        assert_almost_eq!(super::logistic(2.1972245773362195801634726294284168954491240598975), 0.9, 1e-15);
47        assert_almost_eq!(super::logistic(6.9067547786485526081487245019905638981131702804661), 0.999, 1e-15);
48        assert_eq!(super::logistic(11.512915464924779098232747799811946290419057060965), 0.99999);
49        assert_eq!(super::logistic(f64::INFINITY), 1.0);
50    }
51
52    #[test]
53    fn test_logit() {
54        assert_eq!(super::logit(0.0), f64::NEG_INFINITY);
55        assert_eq!(super::logit(0.00001), -11.512915464920228103874353849992239636376994324587);
56        assert_eq!(super::logit(0.001), -6.9067547786485535272274487616830597875179908939086);
57        assert_eq!(super::logit(0.1), -2.1972245773362193134015514347727700402304323440139);
58        assert_eq!(super::logit(0.5), 0.0);
59        assert_eq!(super::logit(0.9), 2.1972245773362195801634726294284168954491240598975);
60        assert_eq!(super::logit(0.999), 6.9067547786485526081487245019905638981131702804661);
61        assert_eq!(super::logit(0.99999), 11.512915464924779098232747799811946290419057060965);
62        assert_eq!(super::logit(1.0), f64::INFINITY);
63    }
64
65    #[test]
66    #[should_panic]
67    fn test_logit_p_lt_0() {
68        super::logit(-1.0);
69    }
70
71    #[test]
72    #[should_panic]
73    fn test_logit_p_gt_1() {
74        super::logit(2.0);
75    }
76
77    #[test]
78    fn test_checked_logit_p_lt_0() {
79        assert!(super::checked_logit(-1.0).is_err());
80    }
81
82    #[test]
83    fn test_checked_logit_p_gt_1() {
84        assert!(super::checked_logit(2.0).is_err());
85    }
86}