OpenFPM_pdata  4.1.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  int sgn(T val)
23  {
24  return (T(0) < val) - (val < T(0));
25  }
26 
38  static inline size_t factorial(size_t f)
39  {
40  size_t fc = 1;
41 
42  for (size_t s = 2 ; s <= f ; s++)
43  {
44  fc *= s;
45  }
46 
47  return fc;
48  }
49 
63  static inline size_t C(size_t n, size_t k)
64  {
65  return factorial(n)/(factorial(k)*factorial(n-k));
66  }
67 
78  static inline size_t round_big_2(size_t n)
79  {
80  n--;
81  n |= n >> 1; // Divide by 2^k for consecutive doublings of k up to 32,
82  n |= n >> 2; // and then or the results.
83  n |= n >> 4;
84  n |= n >> 8;
85  n |= n >> 16;
86  n++;
87 
88  return n;
89  }
90 
91 
104  template<class T>
105  inline constexpr size_t pow(const T base, unsigned const exponent)
106  {
107  // (parentheses not required in next line)
108  return (exponent == 0) ? 1 : (base * pow(base, exponent-1));
109  }
110 
111  template<class T>
112  double intpowlog(const T x, unsigned const e)
113  {
114  if (e == 0) return 1.0;
115  if (e % 2 == 0)
116  {
117  double h = intpowlog(x, e / 2);
118  return h * h;
119  }
120  else
121  {
122  double h = intpowlog(x, e / 2);
123  return h * h * x;
124  }
125  }
126 
127 
128 
129  /* \brief Return the positive modulo of a number
130  *
131  * # Example
132  * \snippet mathutil_unit_test.hpp positive modulo
133  *
134  * \param i number
135  * \param n modulo
136  *
137  */
138  static inline long int positive_modulo(long int i, long int n)
139  {
140  return (i % n + n) % n;
141  }
142 
158  template<typename T> static inline T periodic(const T & pos, const T & p2, const T & p1)
159  {
160  T pos_tmp;
161 
162  pos_tmp = pos - (p2 - p1) * (long int)( (pos -p1) / (p2 - p1));
163  pos_tmp += (pos < p1)?(p2 - p1):0;
164 
165  return pos_tmp;
166  }
167 
185  template<typename T> __device__ __host__ static inline T periodic_l(const T & pos, const T & p2, const T & p1)
186  {
187  T pos_tmp = pos;
188 
189  if (pos >= p2)
190  {
191  pos_tmp = p1 + (pos - p2);
192  }
193  else if (pos < p1)
194  {
195  pos_tmp = p2 - (p1 - pos);
196 
197  // This is a round off error fix
198  // if the shift bring exactly on p2 p2 we back the particle to p1
199  if (pos_tmp == p2)
200  pos_tmp = p1;
201  }
202 
203  return pos_tmp;
204  }
205 
210  inline long int size_t_floor(double x)
211  {
212  size_t i = (long int)x; /* truncate */
213  return i - ( i > x ); /* convert trunc to floor */
214  }
215 
220  inline long int size_t_floor(float x)
221  {
222  size_t i = (long int)x; /* truncate */
223  return i - ( i > x ); /* convert trunc to floor */
224  }
225 
230  __device__ __host__ inline int uint_floor(double x)
231  {
232  unsigned int i = (int)x; /* truncate */
233  return i - ( i > x ); /* convert trunc to floor */
234  }
235 
240  __device__ __host__ inline int uint_floor(float x)
241  {
242  unsigned int i = (int)x; /* truncate */
243  return i - ( i > x ); /* convert trunc to floor */
244  }
245 
246  const int tab64[64] = {
247  63, 0, 58, 1, 59, 47, 53, 2,
248  60, 39, 48, 27, 54, 33, 42, 3,
249  61, 51, 37, 40, 49, 18, 28, 20,
250  55, 30, 34, 11, 43, 14, 22, 4,
251  62, 57, 46, 52, 38, 26, 32, 41,
252  50, 36, 17, 19, 29, 10, 13, 21,
253  56, 45, 25, 31, 35, 16, 9, 12,
254  44, 24, 15, 8, 23, 7, 6, 5};
255 
261  inline int log2_64 (uint64_t value)
262  {
263  value |= value >> 1;
264  value |= value >> 2;
265  value |= value >> 4;
266  value |= value >> 8;
267  value |= value >> 16;
268  value |= value >> 32;
269  return tab64[((uint64_t)((value - (value >> 1))*0x07EDD5E59A4E28C2)) >> 58];
270  }
271 
272 
273 #ifdef HAVE_LIBQUADMATH
274 
279  inline long int size_t_floor(boost::multiprecision::float128 x)
280  {
281  size_t i = (long int)x; /* truncate */
282  return i - ( i > x ); /* convert trunc to floor */
283  }
284 
285 #endif
286  }
287 }
288 
289 #endif
convert a type into constant type
Definition: aggregate.hpp:292
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