1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use num::complex::Complex;
use crate::cln::CLn;

/// Provides the 1st order polylogarithm function `li1()` of a
/// number of type `T`.
pub trait Li1<T> {
    fn li1(&self) -> T;
}

impl Li1<f64> for f64 {
    /// Returns the real first order polylogarithm of a real number of
    /// type `f64`.
    ///
    /// # Example:
    /// ```
    /// use polylog::Li1;
    ///
    /// let x = 2.0;
    /// println!("Li1({}) = {}", x, x.li1());
    /// ```
    fn li1(&self) -> f64 {
        let x = *self;
        if x < 1.0 {
            -(-x).ln_1p()
        } else if x == 1.0 {
            std::f64::INFINITY
        } else { // x > 1.0
            -(x - 1.0).ln()
        }
    }
}

impl Li1<Complex<f64>> for Complex<f64> {
    /// Returns the first order polylogarithm of a complex number of
    /// type `Complex<f64>`.
    ///
    /// # Example:
    /// ```
    /// use num::complex::Complex;
    /// use polylog::Li1;
    ///
    /// let z = Complex::new(1.0, 1.0);
    /// println!("Li1({}) = {}", z, z.li1());
    /// ```
    fn li1(&self) -> Complex<f64> {
        -(1.0 - self).cln()
    }
}