7namespace uni20::detail::native_math
9template <
class R>
struct standard_special_provider
19#if defined(__cpp_lib_math_special_functions) && __cpp_lib_math_special_functions >= 201603L
21 requires(std::same_as<R, float> || std::same_as<R, double> || std::same_as<R, long double>)
22struct standard_special_provider<R>
24 static R
beta(R x, R y) {
return std::beta(x, y); }
28template <NativeReal R> R
beta(R x, R y)
30 if constexpr (
requires { standard_special_provider<R>::beta(x, y); })
31 return standard_special_provider<R>::beta(x, y);
33 return native_math::portable_beta(x, y);
35template <
class R>
struct lgamma_provider
37template <
class R>
struct bessel_provider
40#define UNI20_NATIVE_LGAMMA_PROVIDER(TYPE, FUNCTION) \
41 template <> struct lgamma_provider<TYPE> \
43 static TYPE call(TYPE x, int* sign) { return FUNCTION(x, sign); } \
45#if UNI20_HAS_LGAMMA_R_FLOAT
48#if UNI20_HAS_LGAMMA_R_DOUBLE
51#if UNI20_HAS_LGAMMA_R_LONG_DOUBLE
54#if UNI20_HAS_FLOAT128 && UNI20_HAS_LGAMMA_R_FLOAT128
57#undef UNI20_NATIVE_LGAMMA_PROVIDER
59#define UNI20_NATIVE_BESSEL_PROVIDER(TYPE, J, Y) \
60 template <> struct bessel_provider<TYPE> \
62 static TYPE first(int n, TYPE x) { return J(n, x); } \
63 static TYPE second(int n, TYPE x) { return Y(n, x); } \
65#if UNI20_HAS_BESSEL_FLOAT
68#if UNI20_HAS_BESSEL_DOUBLE
71#if UNI20_HAS_BESSEL_LONG_DOUBLE
74#if UNI20_HAS_FLOAT128 && UNI20_HAS_BESSEL_FLOAT128
77#undef UNI20_NATIVE_BESSEL_PROVIDER
79template <NativeReal R>
80 requires requires(R x,
int* sign) { lgamma_provider<R>::call(x, sign); }
84 R
value = lgamma_provider<R>::call(x, &sign);
87 if (std::isnan(x) || (x < R(0) && (std::isinf(x) || std::floor(x) == x)))
90 sign = std::signbit(x) ? -1 : 1;
94template <NativeReal R>
95 requires requires(R x) { native_math::lgamma_sign(x); }
98 return native_math::lgamma_sign(x).value;
101template <MathInteger I>
int native_bessel_order(I
value)
103 auto n = math_integer(
value);
106 constexpr auto maximum = numeric_limits<int>::max();
107 if (n < -std::int64_t(maximum) || n > maximum)
108 throw std::out_of_range(
"native Bessel absolute order does not fit int");
109 return static_cast<int>(n);
112template <MathInteger I, NativeReal R>
113 requires requires(R x) { bessel_provider<R>::first(0, x); }
116 int n = native_bessel_order(order);
117 R result = bessel_provider<R>::first(n < 0 ? -n : n, x);
118 return n < 0 && n % 2 != 0 ? -result : result;
121template <MathInteger I, NativeReal R>
122 requires requires(R x) { bessel_provider<R>::second(0, x); }
125 int n = native_bessel_order(order);
126 R result = bessel_provider<R>::second(n < 0 ? -n : n, x);
127 return n < 0 && n % 2 != 0 ? -result : result;
locale_t value
Definition data_table.cpp:49
constexpr detail::scalar_math::lgamma_sign_fn lgamma_sign
Log-absolute-Gamma and its sign as owning values.
Definition math.hpp:572
constexpr detail::scalar_math::bessel_j_fn bessel_j
Integer-order Bessel function of the first kind, with order first.
Definition math.hpp:613
constexpr detail::scalar_math::lgamma_fn lgamma
Logarithm of the absolute Gamma function; native providers are reentrant.
Definition math.hpp:569
constexpr detail::scalar_math::bessel_y_fn bessel_y
Integer-order Bessel function of the second kind, with order first.
Definition math.hpp:617
constexpr detail::scalar_math::beta_fn beta
Real Beta function.
Definition math.hpp:586
#define UNI20_NATIVE_LGAMMA_PROVIDER(TYPE, FUNCTION)
Definition native_special_math.hpp:40
#define UNI20_NATIVE_BESSEL_PROVIDER(TYPE, J, Y)
Definition native_special_math.hpp:59