/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
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{
22 template <size_t N, typename T> bool isfinite(const autodiff::Real<N, T> &x)
23 {
24 return std::isfinite(autodiff::val(x)) && std::isfinite(autodiff::derivative(x));
25 }
26 using std::isfinite;
27
36 template <int n, typename NumberType>
37 requires requires(NumberType x) {
38 x * x;
39 NumberType(1.) / x;
40 }
41 constexpr KOKKOS_INLINE_FUNCTION NumberType powr(const NumberType x)
42 {
43 if constexpr (n == 0)
44 return NumberType(1.);
45 else if constexpr (n < 0)
46 return NumberType(1.) / powr<-n, NumberType>(x);
47 else if constexpr (n == 1)
48 return x;
49 else if constexpr (n % 2 == 0)
50 return powr<n / 2>(x) * powr<n / 2>(x);
51 else
52 return powr<n / 2>(x) * powr<n / 2>(x) * x;
53 }
54
55 template <typename NumberType>
56 requires std::is_integral_v<NumberType>
57 constexpr KOKKOS_INLINE_FUNCTION NumberType factorial(const NumberType &x)
58 {
59 NumberType res = 1;
60 for (NumberType i = 2; i <= x; ++i)
61 res *= i;
62 return res;
63 }
64
71 template <typename NT> constexpr KOKKOS_INLINE_FUNCTION double V_d(NT d)
72 {
73 using std::pow;
74 using std::tgamma;
75 return pow(M_PI, d / 2.) / tgamma(d / 2. + 1.);
76 }
77
86 template <typename NT1, typename NT2> constexpr KOKKOS_INLINE_FUNCTION double V_d(NT1 d, NT2 extent)
87 {
88 using std::pow;
89 using std::tgamma;
90 return pow(M_PI, d / 2.) / tgamma(d / 2. + 1.) * pow(extent, d);
91 }
92
99 template <typename NT> constexpr KOKKOS_INLINE_FUNCTION double S_d(NT d)
100 {
101 using std::pow;
102 using std::tgamma;
103 return 2. * pow(M_PI, d / 2.) / tgamma(d / 2.);
104 }
105
112 template <typename NT> consteval NT S_d_prec(uint d)
113 {
114 if (d == 1)
115 return 2;
116 else if (d == 2)
117 return static_cast<NT>(2) * static_cast<NT>(M_PI);
118 else if (d == 3)
119 return static_cast<NT>(4) * static_cast<NT>(M_PI);
120 else if (d == 4)
121 return static_cast<NT>(2) * powr<2>(static_cast<NT>(M_PI));
122 else if (d == 5)
123 return static_cast<NT>(8) * powr<2>(static_cast<NT>(M_PI)) / static_cast<NT>(3);
124 else if (d == 6)
125 return powr<3>(static_cast<NT>(M_PI));
126 else if (d == 7)
127 return static_cast<NT>(16) * powr<3>(static_cast<NT>(M_PI)) / static_cast<NT>(15);
128 return std::numeric_limits<NT>::quiet_NaN();
129 }
130
134 template <typename NumberType>
135 requires requires(NumberType x) { x >= 0; }
136 constexpr KOKKOS_INLINE_FUNCTION auto heaviside_theta(const NumberType x)
137 {
138 if constexpr (std::is_same_v<NumberType, autodiff::real>)
139 return x >= 0. ? 1. : 0.;
140 else
141 return x >= static_cast<NumberType>(0) ? static_cast<NumberType>(1) : static_cast<NumberType>(0);
142 }
143
147 template <typename NumberType>
148 requires requires(NumberType x) { x >= 0; }
149 constexpr KOKKOS_INLINE_FUNCTION auto sign(const NumberType x)
150 {
151 if constexpr (std::is_same_v<NumberType, autodiff::real>)
152 return x >= 0. ? 1. : -1.;
153 else
154 return x >= static_cast<NumberType>(0) ? static_cast<NumberType>(1) : static_cast<NumberType>(-1);
155 }
156
164 template <typename T1, typename T2, typename T3>
165 requires(std::is_floating_point<T1>::value || std::is_same_v<T1, autodiff::real> || is_complex<T1>::value) &&
166 (std::is_floating_point<T2>::value || std::is_same_v<T2, autodiff::real> || is_complex<T2>::value) &&
167 std::is_floating_point<T3>::value
168 bool KOKKOS_INLINE_FUNCTION is_close(T1 a, T2 b, T3 eps_)
169 {
171 return is_close(real(a), real(b), eps_) && is_close(imag(a), imag(b), eps_);
172 } else if constexpr (std::is_same_v<T1, autodiff::real> || std::is_same_v<T2, autodiff::real>)
173 return is_close((double)a, (double)b, (double)eps_);
174 else {
175 T1 diff = std::fabs(a - b);
176 if (diff <= eps_) return true;
177 if (diff <= std::fmax(std::fabs(a), std::fabs(b)) * eps_) return true;
178 }
179 return false;
180 }
181
188 template <typename T1, typename T2>
189 requires(std::is_floating_point<T1>::value || std::is_same_v<T1, autodiff::real> || is_complex<T1>::value) &&
190 (std::is_floating_point<T2>::value || std::is_same_v<T2, autodiff::real> || is_complex<T1>::value)
191 bool KOKKOS_INLINE_FUNCTION is_close(T1 a, T2 b)
192 {
194 return is_close(real(a), real(b)) && is_close(imag(a), imag(b));
195 } else if constexpr (std::is_same_v<T1, autodiff::real> || std::is_same_v<T2, autodiff::real>) {
196 constexpr auto eps_ = std::numeric_limits<double>::epsilon() * 10.;
197 return is_close((double)a, (double)b, eps_);
198 } else {
199 constexpr auto eps_ = std::max(std::numeric_limits<T1>::epsilon(), std::numeric_limits<T2>::epsilon());
200 return is_close(a, b, eps_);
201 }
202 return false;
203 }
204
209 template <uint n, typename NT, typename A1, typename A2>
210 requires requires(A1 a1, A2 a2) { a1[0] * a2[0]; }
211 NT dot(const A1 &a1, const A2 &a2)
212 {
213 NT ret = a1[0] * a2[0];
214 for (uint i = 1; i < n; ++i)
215 ret += a1[i] * a2[i];
216 return ret;
217 }
218
219 namespace compute
220 {
221 using ::Kokkos::abs;
222 using ::Kokkos::atan;
223 using ::Kokkos::cos;
224 using ::Kokkos::cosh;
225 using ::Kokkos::exp;
226 using ::Kokkos::imag;
227 using ::Kokkos::log;
228 using ::Kokkos::pow;
229 using ::Kokkos::real;
230 using ::Kokkos::sin;
231 using ::Kokkos::sinh;
232 using ::Kokkos::sqrt;
233 using ::Kokkos::tan;
234 using ::Kokkos::tanh;
235
236 using ::Kokkos::fmax;
237 using ::Kokkos::fmin;
238 using ::Kokkos::max;
239 using ::Kokkos::min;
240
241 using ::Kokkos::abs;
242 using ::Kokkos::fabs;
243
244 using ::Kokkos::atan2;
245 using ::Kokkos::fma;
246
247 template <typename T1, typename T2, typename T3>
248 requires(!std::is_arithmetic_v<T1> || !std::is_arithmetic_v<T2> || !std::is_arithmetic_v<T3>)
249 constexpr KOKKOS_FORCEINLINE_FUNCTION auto fma(const T1 &a, const T2 &b, const T3 &c)
250 {
251 return a * b + c;
252 }
253
254 template <size_t N, typename T>
255 requires std::is_arithmetic_v<T>
256 constexpr KOKKOS_FORCEINLINE_FUNCTION T conj(const autodiff::Real<N, T> x)
257 {
258 return x;
259 }
260
261 template <size_t N, typename T>
262 requires std::is_arithmetic_v<T>
263 constexpr KOKKOS_FORCEINLINE_FUNCTION T conj(const cxReal<N, T> x)
264 {
265 cxReal<N, T> res;
266 autodiff::detail::For<0, N + 1>([&](auto i) constexpr { res[i] = Kokkos::conj(x[i]); });
267 return res;
268 }
269
270 template <typename T>
271 requires std::is_arithmetic_v<T>
272 constexpr KOKKOS_FORCEINLINE_FUNCTION T conj(const T x)
273 {
274 return x;
275 }
276
277 template <typename T>
278 requires is_complex<T>::value
279 constexpr KOKKOS_FORCEINLINE_FUNCTION T conj(const T x)
280 {
281 return Kokkos::conj(x);
282 }
283
284 using DiFfRG::powr;
285
286 template <typename NT> constexpr auto cot(const NT x) { return NT(1) / tan(x); }
287 template <typename NT> constexpr auto coth(const NT x) { return NT(1) / tanh(x); }
288 } // namespace compute
289} // namespace DiFfRG
constexpr auto coth(const NT x)
Definition math.hh:287
constexpr KOKKOS_FORCEINLINE_FUNCTION auto fma(const T1 &a, const T2 &b, const T3 &c)
Definition math.hh:249
constexpr KOKKOS_FORCEINLINE_FUNCTION T conj(const autodiff::Real< N, T > x)
Definition math.hh:256
constexpr auto cot(const NT x)
Definition math.hh:286
Definition complex_math.hh:10
constexpr KOKKOS_INLINE_FUNCTION NumberType factorial(const NumberType &x)
Definition math.hh:57
constexpr KOKKOS_INLINE_FUNCTION double S_d(NT d)
Surface of a d-dimensional sphere.
Definition math.hh:99
constexpr KOKKOS_INLINE_FUNCTION auto heaviside_theta(const NumberType x)
A compile-time evaluatable theta function.
Definition math.hh:136
constexpr KOKKOS_INLINE_FUNCTION auto sign(const NumberType x)
A compile-time evaluatable sign function.
Definition math.hh:149
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:168
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:211
constexpr KOKKOS_INLINE_FUNCTION NumberType powr(const NumberType x)
A compile-time evaluatable power function for whole number exponents.
Definition math.hh:41
consteval NT S_d_prec(uint d)
Surface of a d-dimensional sphere (precompiled)
Definition math.hh:112
constexpr KOKKOS_INLINE_FUNCTION double V_d(NT d)
Volume of a d-dimensional sphere.
Definition math.hh:71
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 isfinite(const autodiff::Real< N, T > &x)
Finite-ness check for autodiff::real.
Definition math.hh:22
Definition complex_math.hh:89