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}