/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/common/math.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/common/math.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
math.hh
Go to the documentation of this file.
1#pragma once
2
3// DiFfRG
6
7// standard library
8#include <cmath>
9
10// external libraries
11#include <autodiff/forward/real.hpp>
12#include <type_traits>
13
14namespace DiFfRG
15{
21 template <typename T> struct is_autodiff_real : std::false_type {};
22 template <size_t N, typename U> struct is_autodiff_real<autodiff::Real<N, U>> : std::true_type {};
23 template <typename T> inline constexpr bool is_autodiff_real_v = is_autodiff_real<T>::value;
24
31 template <size_t N, typename T> bool isfinite(const autodiff::Real<N, T> &x)
32 {
33 return std::isfinite(autodiff::val(x)) && std::isfinite(autodiff::derivative(x));
34 }
35 using std::isfinite;
36
45 template <int n, typename NumberType>
46 requires requires(NumberType x) {
47 x * x;
48 NumberType(1.) / x;
49 }
50 constexpr KOKKOS_INLINE_FUNCTION NumberType powr(const NumberType x)
51 {
52 if constexpr (n == 0)
53 return NumberType(1.);
54 else if constexpr (n < 0)
55 return NumberType(1.) / powr<-n, NumberType>(x);
56 else if constexpr (n == 1)
57 return x;
58 else if constexpr (n % 2 == 0)
59 return powr<n / 2>(x) * powr<n / 2>(x);
60 else
61 return powr<n / 2>(x) * powr<n / 2>(x) * x;
62 }
63
64 template <typename NumberType>
65 requires std::is_integral_v<NumberType>
66 constexpr KOKKOS_INLINE_FUNCTION NumberType factorial(const NumberType &x)
67 {
68 NumberType res = 1;
69 for (NumberType i = 2; i <= x; ++i)
70 res *= i;
71 return res;
72 }
73
80 template <typename NT> constexpr KOKKOS_INLINE_FUNCTION double V_d(NT d)
81 {
82 using std::pow;
83 using std::tgamma;
84 return pow(M_PI, d / 2.) / tgamma(d / 2. + 1.);
85 }
86
95 template <typename NT1, typename NT2> constexpr KOKKOS_INLINE_FUNCTION double V_d(NT1 d, NT2 extent)
96 {
97 using std::pow;
98 using std::tgamma;
99 return pow(M_PI, d / 2.) / tgamma(d / 2. + 1.) * pow(extent, d);
100 }
101
108 template <typename NT> constexpr KOKKOS_INLINE_FUNCTION double S_d(NT d)
109 {
110 using std::pow;
111 using std::tgamma;
112 return 2. * pow(M_PI, d / 2.) / tgamma(d / 2.);
113 }
114
121 template <typename NT> consteval NT S_d_prec(uint d)
122 {
123 if (d == 1)
124 return 2;
125 else if (d == 2)
126 return static_cast<NT>(2) * static_cast<NT>(M_PI);
127 else if (d == 3)
128 return static_cast<NT>(4) * static_cast<NT>(M_PI);
129 else if (d == 4)
130 return static_cast<NT>(2) * powr<2>(static_cast<NT>(M_PI));
131 else if (d == 5)
132 return static_cast<NT>(8) * powr<2>(static_cast<NT>(M_PI)) / static_cast<NT>(3);
133 else if (d == 6)
134 return powr<3>(static_cast<NT>(M_PI));
135 else if (d == 7)
136 return static_cast<NT>(16) * powr<3>(static_cast<NT>(M_PI)) / static_cast<NT>(15);
137 return std::numeric_limits<NT>::quiet_NaN();
138 }
139
143 template <typename NumberType>
144 requires requires(NumberType x) { x >= 0; }
145 constexpr KOKKOS_INLINE_FUNCTION auto heaviside_theta(const NumberType x)
146 {
147 if constexpr (std::is_same_v<NumberType, autodiff::real>)
148 return x >= 0. ? 1. : 0.;
149 else
150 return x >= static_cast<NumberType>(0) ? static_cast<NumberType>(1) : static_cast<NumberType>(0);
151 }
152
156 template <typename NumberType>
157 requires requires(NumberType x) { x >= 0; }
158 constexpr KOKKOS_INLINE_FUNCTION auto sign(const NumberType x)
159 {
160 if constexpr (std::is_same_v<NumberType, autodiff::real>)
161 return x >= 0. ? 1. : -1.;
162 else
163 return x >= static_cast<NumberType>(0) ? static_cast<NumberType>(1) : static_cast<NumberType>(-1);
164 }
165
173 template <typename T1, typename T2, typename T3>
174 requires(std::is_floating_point<T1>::value || is_autodiff_real_v<T1> || is_complex<T1>::value) &&
175 (std::is_floating_point<T2>::value || is_autodiff_real_v<T2> || is_complex<T2>::value) &&
176 std::is_floating_point<T3>::value
177 bool KOKKOS_INLINE_FUNCTION is_close(T1 a, T2 b, T3 eps_)
178 {
180 return is_close(real(a), real(b), eps_) && is_close(imag(a), imag(b), eps_);
181 } else if constexpr (is_autodiff_real_v<T1> || is_autodiff_real_v<T2>)
182 return is_close((double)a, (double)b, (double)eps_);
183 else {
184 T1 diff = std::fabs(a - b);
185 if (diff <= eps_) return true;
186 if (diff <= std::fmax(std::fabs(a), std::fabs(b)) * eps_) return true;
187 }
188 return false;
189 }
190
197 template <typename T1, typename T2>
198 requires(std::is_floating_point<T1>::value || is_autodiff_real_v<T1> || is_complex<T1>::value) &&
199 (std::is_floating_point<T2>::value || is_autodiff_real_v<T2> || is_complex<T2>::value)
200 bool KOKKOS_INLINE_FUNCTION is_close(T1 a, T2 b)
201 {
203 return is_close(real(a), real(b)) && is_close(imag(a), imag(b));
204 } else if constexpr (is_autodiff_real_v<T1> || is_autodiff_real_v<T2>) {
205 constexpr auto eps_ = std::numeric_limits<double>::epsilon() * 10.;
206 return is_close((double)a, (double)b, eps_);
207 } else {
208 constexpr auto eps_ = std::max(std::numeric_limits<T1>::epsilon(), std::numeric_limits<T2>::epsilon());
209 return is_close(a, b, eps_);
210 }
211 return false;
212 }
213
218 template <uint n, typename NT, typename A1, typename A2>
219 requires requires(A1 a1, A2 a2) { a1[0] * a2[0]; }
220 NT dot(const A1 &a1, const A2 &a2)
221 {
222 NT ret = a1[0] * a2[0];
223 for (uint i = 1; i < n; ++i)
224 ret += a1[i] * a2[i];
225 return ret;
226 }
227
228 namespace compute
229 {
230 using ::Kokkos::abs;
231 using ::Kokkos::atan;
232 using ::Kokkos::cos;
233 using ::Kokkos::cosh;
234 using ::Kokkos::exp;
235 using ::Kokkos::imag;
236 using ::Kokkos::log;
237 using ::Kokkos::pow;
238 using ::Kokkos::real;
239 using ::Kokkos::sin;
240 using ::Kokkos::sinh;
241 using ::Kokkos::sqrt;
242 using ::Kokkos::tan;
243 using ::Kokkos::tanh;
244
245 using ::Kokkos::fmax;
246 using ::Kokkos::fmin;
247 using ::Kokkos::max;
248 using ::Kokkos::min;
249
250 using ::Kokkos::abs;
251 using ::Kokkos::fabs;
252
253 using ::Kokkos::atan2;
254 using ::Kokkos::fma;
255
256 template <typename T1, typename T2, typename T3>
257 requires(!std::is_arithmetic_v<T1> || !std::is_arithmetic_v<T2> || !std::is_arithmetic_v<T3>)
258 constexpr KOKKOS_FORCEINLINE_FUNCTION auto fma(const T1 &a, const T2 &b, const T3 &c)
259 {
260 return a * b + c;
261 }
262
263 template <size_t N, typename T>
264 requires std::is_arithmetic_v<T>
265 constexpr KOKKOS_FORCEINLINE_FUNCTION T conj(const autodiff::Real<N, T> x)
266 {
267 return x;
268 }
269
270 template <size_t N, typename T>
271 requires std::is_arithmetic_v<T>
272 constexpr KOKKOS_FORCEINLINE_FUNCTION T conj(const cxReal<N, T> x)
273 {
274 cxReal<N, T> res;
275 autodiff::detail::For<0, N + 1>([&](auto i) constexpr { res[i] = Kokkos::conj(x[i]); });
276 return res;
277 }
278
279 template <typename T>
280 requires std::is_arithmetic_v<T>
281 constexpr KOKKOS_FORCEINLINE_FUNCTION T conj(const T x)
282 {
283 return x;
284 }
285
286 template <typename T>
287 requires is_complex<T>::value
288 constexpr KOKKOS_FORCEINLINE_FUNCTION T conj(const T x)
289 {
290 return Kokkos::conj(x);
291 }
292
293 using DiFfRG::powr;
294
295 template <typename NT> constexpr auto cot(const NT x) { return NT(1) / tan(x); }
296 template <typename NT> constexpr auto coth(const NT x) { return NT(1) / tanh(x); }
297 } // namespace compute
298} // namespace DiFfRG
constexpr auto coth(const NT x)
Definition math.hh:296
constexpr KOKKOS_FORCEINLINE_FUNCTION auto fma(const T1 &a, const T2 &b, const T3 &c)
Definition math.hh:258
constexpr KOKKOS_FORCEINLINE_FUNCTION T conj(const autodiff::Real< N, T > x)
Definition math.hh:265
constexpr auto cot(const NT x)
Definition math.hh:295
Definition complex_math.hh:10
constexpr KOKKOS_INLINE_FUNCTION NumberType factorial(const NumberType &x)
Definition math.hh:66
constexpr KOKKOS_INLINE_FUNCTION double S_d(NT d)
Surface of a d-dimensional sphere.
Definition math.hh:108
constexpr KOKKOS_INLINE_FUNCTION auto heaviside_theta(const NumberType x)
A compile-time evaluatable theta function.
Definition math.hh:145
constexpr KOKKOS_INLINE_FUNCTION auto sign(const NumberType x)
A compile-time evaluatable sign function.
Definition math.hh:158
constexpr KOKKOS_FORCEINLINE_FUNCTION auto imag(const autodiff::Real< N, T > &)
Definition complex_math.hh:97
NT dot(const A1 &a1, const A2 &a2)
A dot product which takes the dot product between a1 and a2, assuming each has n entries which can be...
Definition math.hh:220
constexpr bool is_autodiff_real_v
Definition math.hh:23
constexpr KOKKOS_INLINE_FUNCTION NumberType powr(const NumberType x)
A compile-time evaluatable power function for whole number exponents.
Definition math.hh:50
consteval NT S_d_prec(uint d)
Surface of a d-dimensional sphere (precompiled)
Definition math.hh:121
constexpr KOKKOS_INLINE_FUNCTION double V_d(NT d)
Volume of a d-dimensional sphere.
Definition math.hh:80
unsigned int uint
Definition utils.hh:24
KOKKOS_FORCEINLINE_FUNCTION auto real(const autodiff::Real< N, T > &a)
Definition complex_math.hh:96
autodiff::Real< N, complex< T > > cxReal
Definition complex_math.hh:86
bool KOKKOS_INLINE_FUNCTION is_close(T1 a, T2 b, T3 eps_)
Function to evaluate whether two floats are equal to numerical precision. Tests for both relative and...
Definition math.hh:177
bool isfinite(const autodiff::Real< N, T > &x)
Finite-ness check for autodiff::real.
Definition math.hh:31
Definition complex_math.hh:19
Type trait: true iff T is any autodiff::Real<N, U> specialization. Allows generic handling of higher-...
Definition math.hh:21
Definition complex_math.hh:89