5namespace uni20::detail::native_math
7template <NativeReal R> R positive_digamma(R x)
9 constexpr int bits = numeric_limits<R>::digits();
10 constexpr int cutoff = bits <= 24 ? 8 : bits <= 64 ? 16 : 32;
11 constexpr int terms = bits <= 24 ? 4 : bits <= 53 ? 8 : bits <= 64 ? 10 : 16;
14 constexpr R coefficients[] = {R(1LL) / R(12LL),
19 R(-691LL) / R(32760LL),
21 R(-3617LL) / R(8160LL),
22 R(43867LL) / R(14364LL),
23 R(-174611LL) / R(6600LL),
24 R(77683LL) / R(276LL),
25 R(-236364091LL) / R(65520LL),
26 R(657931LL) / R(12LL),
27 R(-3392780147LL) / R(3480LL),
28 R(1723168255201LL) / R(85932LL),
29 R(-7709321041217LL) / R(16320LL)};
30 int shifts = x < R(cutoff) ? static_cast<int>(std::ceil(R(cutoff) - x)) : 0;
31 R y = x + R(shifts), inverse = R(1) / y,
square = inverse * inverse;
32 R polynomial = coefficients[terms - 1];
33 for (
int k = terms - 2; k >= 0; --k)
34 polynomial = std::fma(polynomial,
square, coefficients[k]);
36 R
sum = std::log(y), low = 0;
37 auto add = [&](R term) {
39 low += std::abs(
sum) >= std::abs(term) ? (
sum - next) + term : (term - next) +
sum;
46 for (
int k = 0; k < shifts; ++k)
47 add(-R(1) / (x + R(k)));
51template <NativeReal R> R
digamma(R x)
53 using L = numeric_limits<R>;
54 if (std::isnan(x) || x == -L::infinity())
return L::quiet_NaN();
55 if (x == L::infinity())
return x;
59 if (std::abs(x) <= L::epsilon())
return -R(1) / x - euler_gamma<R>;
60 if (x > 0)
return native_math::positive_digamma(x);
61 if (x == std::trunc(x))
return L::quiet_NaN();
62 return native_math::positive_digamma(R(1) - x) - pi<R> / native_math::tanpi(x);
AsyncTask square(ReadBuffer< int > in, WriteBuffer< int > out)
Definition async_tbb_reduction_example.cpp:39
constexpr detail::scalar_math::digamma_fn digamma
Logarithmic derivative of Gamma.
Definition math.hpp:578
void sum(BackendSelector selector, async::Async< OutputTensor > &output, async::Async< InputTensor > const &input)
Schedule a full sum into an explicit async scalar tensor.
Definition linalg/async/reductions.hpp:309
int add(int a, int b)
Definition dummy.cpp:6