polylog/
li1.rs

1use num::complex::Complex;
2use crate::cln::CLn;
3
4/// Provides the 1st order polylogarithm function `li1()` of a
5/// number of type `T`.
6pub trait Li1<T> {
7    fn li1(&self) -> T;
8}
9
10impl Li1<f64> for f64 {
11    /// Returns the real first order polylogarithm of a real number of
12    /// type `f64`.
13    ///
14    /// # Example:
15    /// ```
16    /// use polylog::Li1;
17    ///
18    /// assert!((2.0_f64.li1()).abs() < std::f64::EPSILON);
19    /// ```
20    fn li1(&self) -> f64 {
21        let x = *self;
22        if x < 1.0 {
23            -(-x).ln_1p()
24        } else if x == 1.0 {
25            std::f64::INFINITY
26        } else { // x > 1.0
27            -(x - 1.0).ln()
28        }
29    }
30}
31
32impl Li1<Complex<f64>> for Complex<f64> {
33    /// Returns the first order polylogarithm of a complex number of
34    /// type `Complex<f64>`.
35    ///
36    /// # Example:
37    /// ```
38    /// use num::complex::Complex;
39    /// use polylog::Li1;
40    ///
41    /// assert!((Complex::new(1.0_f64, 1.0_f64).li1() - Complex::new(0.0_f64, 1.5707963267948966_f64)).norm() < std::f64::EPSILON);
42    /// ```
43    fn li1(&self) -> Complex<f64> {
44        if *self == Complex::new(0.0, 0.0) {
45            *self
46        } else {
47            -(1.0 - self).cln()
48        }
49    }
50}