flexiblesusy is hosted by Hepforge, IPPP Durham
FlexibleSUSY
harmonic.cpp
Go to the documentation of this file.
1// ====================================================================
2// This file is part of Polylogarithm.
3//
4// Polylogarithm is licenced under the MIT License.
5// ====================================================================
6
7#include "harmonic.hpp"
8#include <cmath>
9#include <limits>
10
11namespace flexiblesusy {
12
13namespace {
14
20double digamma(int64_t n) noexcept
21{
22 // Table[BernoulliB[2n]/(2 n), {n,1,8}]
23 const double c[] = {
24 0.083333333333333333, -0.0083333333333333333, 0.0039682539682539683,
25 -0.0041666666666666667, 0.0075757575757575758, -0.021092796092796093,
26 0.083333333333333333, -0.44325980392156863
27 };
28
29 if (n <= 0) {
30 return std::numeric_limits<double>::quiet_NaN();
31 }
32
33 double res = 0;
34
35 // map potentially small n to n >= 7
36 if (n < 7) { // recurrence formula
37 for (int64_t nu = 1; nu < 7 - n; ++nu) {
38 res -= 1.0/(n + nu);
39 }
40 res -= 1.0/n;
41 n = 7.0;
42 }
43
44 const double t = 1.0/n;
45 const double t2 = t*t;
46
47 return res + std::log(n) - 0.5*t
48 - t2*(c[0] + t2*(c[1] + t2*(c[2] + t2*(c[3] + t2*(c[4] + t2*(c[5] + t2*(c[6] + t2*c[7])))))));
49}
50
51} // anonymous namespace
52
54double harmonic(int64_t n) noexcept
55{
56 if (n <= 0) {
57 return std::numeric_limits<double>::quiet_NaN();
58 } else if (n < 20) {
59 double sum = 1;
60 for (int64_t k = 2; k <= n; ++k) {
61 sum += 1.0/k;
62 }
63 return sum;
64 } else {
65 const double eulergamma = 0.57721566490153286;
66 return eulergamma + digamma(n + 1);
67 }
68}
69
70} // namespace flexiblesusy
Complex< T > log(const Complex< T > &z) noexcept
Definition: complex.hpp:54
double harmonic(int64_t n) noexcept
harmonic number n
Definition: harmonic.cpp:54
auto sum(Idx ini, Idx fin, Function f) -> decltype(EvalEigenXpr< Idx >(ini, f))
Definition: sum.hpp:91