Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
native_dilog_math.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "native_math.hpp"
5
6namespace uni20::detail::native_math
7{
8// Defining series on [0,1/2]. The tail after n terms is bounded by
9// t^(n+1)/((n+1)^2*(1-t)); digits+4 terms suffice even at t=1/2.
10template <NativeReal R> R dilog_series(R t)
11{
12 R power = t, sum = t, low = 0;
13 for (int k = 2; k <= numeric_limits<R>::digits() + 4; ++k)
14 {
15 power *= t;
16 R term = power / R(k * k);
17 R next = sum + term;
18 low += (sum - next) + term;
19 sum = next;
20 if (term <= numeric_limits<R>::epsilon() * sum / 8) break;
21 }
22 return sum + low;
23}
24
25template <NativeReal R> R dilog_real(R x)
26{
27 using L = numeric_limits<R>;
28 if (std::isnan(x)) return x;
29 if (std::isinf(x)) return -L::infinity();
30 if (x == R(0)) return x;
31 constexpr R sixth = pi<R> * pi<R> / 6;
32 if (x == R(1)) return sixth;
33 if (x < R(-1))
34 {
35 R inverse = R(1) / x, logarithm = std::log(-x), small = std::log1p(-inverse);
36 R reduced = native_math::dilog_series(inverse / (inverse - R(1)));
37 return std::fma(-logarithm / 2, logarithm, std::fma(small / 2, small, reduced) - sixth);
38 }
39 if (x < R(0))
40 {
41 R logarithm = std::log1p(-x);
42 return -std::fma(logarithm / 2, logarithm, native_math::dilog_series(x / (x - R(1))));
43 }
44 if (x <= R(0.5)) return native_math::dilog_series(x);
45 R logarithm = std::log(x);
46 if (x < R(1)) return std::fma(-logarithm, std::log1p(-x), sixth - native_math::dilog_series(R(1) - x));
47 if (x < R(2))
48 return std::fma(logarithm, logarithm / 2 - std::log(x - R(1)), sixth + native_math::dilog_series((x - R(1)) / x));
49 return std::fma(-logarithm / 2, logarithm, 2 * sixth - native_math::dilog_series(R(1) / x));
50}
51} // namespace uni20::detail::native_math
constexpr detail::scalar_math::dilog_real_fn dilog_real
Real part of the dilogarithm.
Definition math.hpp:609
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