6namespace uni20::detail::native_math
8template <NativeReal R> R expint_series(R x)
10 using L = numeric_limits<R>;
11 R
sum = euler_gamma<R>, low = 0;
17 add(std::log(std::abs(x)));
19 for (
int k = 1; k <= 8 * L::digits() + 64; ++k)
22 R term = power / R(k);
24 if (R(k) >= 2 * std::abs(x) && std::abs(term) <= L::epsilon() * std::max(R(1), std::abs(
sum)) / 16)
27 return L::quiet_NaN();
33template <NativeReal R> R scaled_e1(R x)
35 using L = numeric_limits<R>;
36 for (
int depth = 16; depth <= 16 * L::digits(); depth *= 2)
38 R lo = R(depth) / (R(1) + R(depth) / x), hi = R(depth);
39 for (
int k = depth - 1; k >= 1; --k)
41 lo = R(k) / (R(1) + R(k) / (x + lo));
42 hi = R(k) / (R(1) + R(k) / (x + hi));
46 if (std::abs(lo - hi) <= 4 * L::epsilon() * lo)
return (lo + hi) / 2;
48 return L::quiet_NaN();
51template <NativeReal R> R scaled_positive_ei(R x)
53 using L = numeric_limits<R>;
54 R
sum = 1, low = 0, term = 1;
55 for (
int k = 1; k <= L::digits(); ++k)
59 low += (
sum - next) + term;
63 if (term <= L::epsilon() *
sum / R(4 * (k + 2)))
return (
sum + low) / x;
65 return L::quiet_NaN();
68template <NativeReal R> R
expint(R x)
70 using L = numeric_limits<R>;
71 if (std::isnan(x))
return x;
72 if (x == 0)
return -L::infinity();
74 if (x > R(2 * L::max_exponent))
return L::infinity();
75 if (x < R(2 * (L::min_exponent - L::digits())))
return -R(0);
76 if (x >= R(-1) && x < R(2 * L::digits()))
return native_math::expint_series(x);
77 R factor = x < 0 ? -native_math::scaled_e1(-x) : native_math::scaled_positive_ei(x);
78 R half = std::exp(x / 2);
79 return half * (half * factor);
locale_t value
Definition data_table.cpp:49
constexpr detail::scalar_math::expint_fn expint
Real principal-value exponential integral Ei.
Definition math.hpp:605
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