OpenFPM  5.2.0
Project that contain the implementation of distributed structures
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 
10 namespace 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 
126  template<class T>
127  __host__ __device__ double intpowlog(const T base, unsigned const exponent)
128  {
129  T out = 1, curpwr = base;
130  for(unsigned _e = exponent ; _e > 0; _e = _e >> 1)
131  {
132  if ((_e & 1) > 0)
133  out *= curpwr;
134 
135  curpwr *= curpwr;
136  }
137 
138  return out;
139  }
140 
141  /* \brief Return the positive modulo of a number
142  *
143  * # Example
144  * \snippet mathutil_unit_test.hpp positive modulo
145  *
146  * \param i number
147  * \param n modulo
148  *
149  */
150  __host__ __device__ static inline
151  long int positive_modulo(long int i, long int n)
152  {
153  return (i % n + n) % n;
154  }
155 
171  template<typename T>
172  __host__ __device__ static inline
173  T periodic(const T & pos, const T & p2, const T & p1)
174  {
175  T pos_tmp;
176 
177  pos_tmp = pos - (p2 - p1) * (long int)( (pos -p1) / (p2 - p1));
178  pos_tmp += (pos < p1)?(p2 - p1):0;
179 
180  return pos_tmp;
181  }
182 
200  template<typename T>
201  __device__ __host__ static inline
202  T periodic_l(const T & pos, const T & p2, const T & p1)
203  {
204  T pos_tmp = pos;
205 
206  if (pos >= p2)
207  {
208  pos_tmp = p1 + (pos - p2);
209  }
210  else if (pos < p1)
211  {
212  pos_tmp = p2 - (p1 - pos);
213 
214  // This is a round off error fix
215  // if the shift bring exactly on p2 p2 we back the particle to p1
216  if (pos_tmp == p2)
217  pos_tmp = p1;
218  }
219 
220  return pos_tmp;
221  }
222 
227  __host__ __device__ inline long int size_t_floor(double x)
228  {
229  size_t i = (long int)x; /* truncate */
230  return i - ( i > x ); /* convert trunc to floor */
231  }
232 
237  __host__ __device__ inline long int size_t_floor(float x)
238  {
239  size_t i = (long int)x; /* truncate */
240  return i - ( i > x ); /* convert trunc to floor */
241  }
242 
247  __device__ __host__ inline int uint_floor(double x)
248  {
249  unsigned int i = (int)x; /* truncate */
250  return i - ( i > x ); /* convert trunc to floor */
251  }
252 
257  __device__ __host__ inline int uint_floor(float x)
258  {
259  unsigned int i = (int)x; /* truncate */
260  return i - ( i > x ); /* convert trunc to floor */
261  }
262 
263  const int tab64[64] = {
264  63, 0, 58, 1, 59, 47, 53, 2,
265  60, 39, 48, 27, 54, 33, 42, 3,
266  61, 51, 37, 40, 49, 18, 28, 20,
267  55, 30, 34, 11, 43, 14, 22, 4,
268  62, 57, 46, 52, 38, 26, 32, 41,
269  50, 36, 17, 19, 29, 10, 13, 21,
270  56, 45, 25, 31, 35, 16, 9, 12,
271  44, 24, 15, 8, 23, 7, 6, 5};
272 
278  __host__ __device__ inline int log2_64 (uint64_t value)
279  {
280  value |= value >> 1;
281  value |= value >> 2;
282  value |= value >> 4;
283  value |= value >> 8;
284  value |= value >> 16;
285  value |= value >> 32;
286  return tab64[((uint64_t)((value - (value >> 1))*0x07EDD5E59A4E28C2)) >> 58];
287  }
288 
289 
290 #ifdef HAVE_LIBQUADMATH
291 
296  __host__ __device__ inline long int size_t_floor(boost::multiprecision::float128 x)
297  {
298  size_t i = (long int)x; /* truncate */
299  return i - ( i > x ); /* convert trunc to floor */
300  }
301 
302 #endif
303  }
304 }
305 
306 #endif
int sgn(T val)
Gets the sign of a variable.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
convert a type into constant type
Definition: aggregate.hpp:302