statrs/function/
harmonic.rs1use crate::consts;
6use crate::function::gamma;
7
8pub fn harmonic(t: u64) -> f64 {
14 match t {
15 0 => 1.0,
16 _ => consts::EULER_MASCHERONI + gamma::digamma(t as f64 + 1.0),
17 }
18}
19
20pub fn gen_harmonic(n: u64, m: f64) -> f64 {
27 match n {
28 0 => 1.0,
29 _ => (0..n).fold(0.0, |acc, x| acc + (x as f64 + 1.0).powf(-m)),
30 }
31}
32
33#[rustfmt::skip]
34#[cfg(test)]
35mod tests {
36 use std::f64;
37
38 #[test]
39 fn test_harmonic() {
40 assert_eq!(super::harmonic(0), 1.0);
41 assert_almost_eq!(super::harmonic(1), 1.0, 1e-14);
42 assert_almost_eq!(super::harmonic(2), 1.5, 1e-14);
43 assert_almost_eq!(super::harmonic(4), 2.083333333333333333333, 1e-14);
44 assert_almost_eq!(super::harmonic(8), 2.717857142857142857143, 1e-14);
45 assert_almost_eq!(super::harmonic(16), 3.380728993228993228993, 1e-14);
46 }
47
48 #[test]
49 fn test_gen_harmonic() {
50 assert_eq!(super::gen_harmonic(0, 0.0), 1.0);
51 assert_eq!(super::gen_harmonic(0, f64::INFINITY), 1.0);
52 assert_eq!(super::gen_harmonic(0, f64::NEG_INFINITY), 1.0);
53 assert_eq!(super::gen_harmonic(1, 0.0), 1.0);
54 assert_eq!(super::gen_harmonic(1, f64::INFINITY), 1.0);
55 assert_eq!(super::gen_harmonic(1, f64::NEG_INFINITY), 1.0);
56 assert_eq!(super::gen_harmonic(2, 1.0), 1.5);
57 assert_eq!(super::gen_harmonic(2, 3.0), 1.125);
58 assert_eq!(super::gen_harmonic(2, f64::INFINITY), 1.0);
59 assert_eq!(super::gen_harmonic(2, f64::NEG_INFINITY), f64::INFINITY);
60 assert_almost_eq!(super::gen_harmonic(4, 1.0), 2.083333333333333333333, 1e-14);
61 assert_eq!(super::gen_harmonic(4, 3.0), 1.177662037037037037037);
62 assert_eq!(super::gen_harmonic(4, f64::INFINITY), 1.0);
63 assert_eq!(super::gen_harmonic(4, f64::NEG_INFINITY), f64::INFINITY);
64 }
65}