OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
mathutil.hpp
1#ifndef MATHUTIL_HPP
2#define MATHUTIL_HPP
3
4#ifdef HAVE_LIBQUADMATH
5#include <boost/multiprecision/float128.hpp>
6#endif
7
8#include "util/cuda_util.hpp"
9
10namespace openfpm
11{
12 namespace math
13 {
21 template <typename T>
22 __host__ __device__ int sgn(T val)
23 {
24 return (T(0) < val) - (val < T(0));
25 }
26
38 __host__ __device__ static inline
39 size_t factorial(size_t f)
40 {
41 size_t fc = 1;
42
43 for (size_t s = 2 ; s <= f ; s++)
44 {
45 fc *= s;
46 }
47
48 return fc;
49 }
50
64 __host__ __device__ static inline
65 size_t C(size_t n, size_t k)
66 {
67 return factorial(n)/(factorial(k)*factorial(n-k));
68 }
69
80 __host__ __device__ static inline
81 size_t round_big_2(size_t n)
82 {
83 n--;
84 n |= n >> 1; // Divide by 2^k for consecutive doublings of k up to 32,
85 n |= n >> 2; // and then or the results.
86 n |= n >> 4;
87 n |= n >> 8;
88 n |= n >> 16;
89 n++;
90
91 return n;
92 }
93
94
107 template<class T>
108 __host__ __device__ inline constexpr
109 size_t pow(const T base, unsigned const exponent)
110 {
111 // (parentheses not required in next line)
112 return (exponent == 0) ? 1 : (base * pow(base, exponent-1));
113 }
114
115 template<class T>
116 __host__ __device__ double intpowlog(const T x, unsigned const e)
117 {
118 if (e == 0) return 1.0;
119 if (e % 2 == 0)
120 {
121 double h = intpowlog(x, e / 2);
122 return h * h;
123 }
124 else
125 {
126 double h = intpowlog(x, e / 2);
127 return h * h * x;
128 }
129 }
130
131
132
133 /* \brief Return the positive modulo of a number
134 *
135 * # Example
136 * \snippet mathutil_unit_test.hpp positive modulo
137 *
138 * \param i number
139 * \param n modulo
140 *
141 */
142 __host__ __device__ static inline
143 long int positive_modulo(long int i, long int n)
144 {
145 return (i % n + n) % n;
146 }
147
163 template<typename T>
164 __host__ __device__ static inline
165 T periodic(const T & pos, const T & p2, const T & p1)
166 {
167 T pos_tmp;
168
169 pos_tmp = pos - (p2 - p1) * (long int)( (pos -p1) / (p2 - p1));
170 pos_tmp += (pos < p1)?(p2 - p1):0;
171
172 return pos_tmp;
173 }
174
192 template<typename T>
193 __device__ __host__ static inline
194 T periodic_l(const T & pos, const T & p2, const T & p1)
195 {
196 T pos_tmp = pos;
197
198 if (pos >= p2)
199 {
200 pos_tmp = p1 + (pos - p2);
201 }
202 else if (pos < p1)
203 {
204 pos_tmp = p2 - (p1 - pos);
205
206 // This is a round off error fix
207 // if the shift bring exactly on p2 p2 we back the particle to p1
208 if (pos_tmp == p2)
209 pos_tmp = p1;
210 }
211
212 return pos_tmp;
213 }
214
219 __host__ __device__ inline long int size_t_floor(double x)
220 {
221 size_t i = (long int)x; /* truncate */
222 return i - ( i > x ); /* convert trunc to floor */
223 }
224
229 __host__ __device__ inline long int size_t_floor(float x)
230 {
231 size_t i = (long int)x; /* truncate */
232 return i - ( i > x ); /* convert trunc to floor */
233 }
234
239 __device__ __host__ inline int uint_floor(double x)
240 {
241 unsigned int i = (int)x; /* truncate */
242 return i - ( i > x ); /* convert trunc to floor */
243 }
244
249 __device__ __host__ inline int uint_floor(float x)
250 {
251 unsigned int i = (int)x; /* truncate */
252 return i - ( i > x ); /* convert trunc to floor */
253 }
254
255 const int tab64[64] = {
256 63, 0, 58, 1, 59, 47, 53, 2,
257 60, 39, 48, 27, 54, 33, 42, 3,
258 61, 51, 37, 40, 49, 18, 28, 20,
259 55, 30, 34, 11, 43, 14, 22, 4,
260 62, 57, 46, 52, 38, 26, 32, 41,
261 50, 36, 17, 19, 29, 10, 13, 21,
262 56, 45, 25, 31, 35, 16, 9, 12,
263 44, 24, 15, 8, 23, 7, 6, 5};
264
270 __host__ __device__ inline int log2_64 (uint64_t value)
271 {
272 value |= value >> 1;
273 value |= value >> 2;
274 value |= value >> 4;
275 value |= value >> 8;
276 value |= value >> 16;
277 value |= value >> 32;
278 return tab64[((uint64_t)((value - (value >> 1))*0x07EDD5E59A4E28C2)) >> 58];
279 }
280
281
282#ifdef HAVE_LIBQUADMATH
283
288 __host__ __device__ inline long int size_t_floor(boost::multiprecision::float128 x)
289 {
290 size_t i = (long int)x; /* truncate */
291 return i - ( i > x ); /* convert trunc to floor */
292 }
293
294#endif
295 }
296}
297
298#endif
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
convert a type into constant type