statrs/function/
logistic.rs1use crate::error::StatsError;
5use crate::Result;
6
7pub fn logistic(p: f64) -> f64 {
9 1.0 / ((-p).exp() + 1.0)
10}
11
12pub fn logit(p: f64) -> f64 {
18 checked_logit(p).unwrap()
19}
20
21pub 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}