OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
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 namespace openfpm
9 {
10  namespace math
11  {
23  static inline size_t factorial(size_t f)
24  {
25  size_t fc = 1;
26 
27  for (size_t s = 2 ; s <= f ; s++)
28  {
29  fc *= s;
30  }
31 
32  return fc;
33  }
34 
48  static inline size_t C(size_t n, size_t k)
49  {
50  return factorial(n)/(factorial(k)*factorial(n-k));
51  }
52 
63  static inline size_t round_big_2(size_t n)
64  {
65  n--;
66  n |= n >> 1; // Divide by 2^k for consecutive doublings of k up to 32,
67  n |= n >> 2; // and then or the results.
68  n |= n >> 4;
69  n |= n >> 8;
70  n |= n >> 16;
71  n++;
72 
73  return n;
74  }
75 
76 
89  template<class T>
90  inline constexpr size_t pow(const T base, unsigned const exponent)
91  {
92  // (parentheses not required in next line)
93  return (exponent == 0) ? 1 : (base * pow(base, exponent-1));
94  }
95 
96  /* \brief Return the positive modulo of a number
97  *
98  * # Example
99  * \snippet mathutil_unit_test.hpp positive modulo
100  *
101  * \param i number
102  * \param n modulo
103  *
104  */
105  static inline long int positive_modulo(long int i, long int n)
106  {
107  return (i % n + n) % n;
108  }
109 
125  template<typename T> static inline T periodic(const T & pos, const T & p2, const T & p1)
126  {
127  T pos_tmp;
128 
129  pos_tmp = pos - (p2 - p1) * (long int)( (pos -p1) / (p2 - p1));
130  pos_tmp += (pos < p1)?(p2 - p1):0;
131 
132  return pos_tmp;
133  }
134 
152  template<typename T> static inline T periodic_l(const T & pos, const T & p2, const T & p1)
153  {
154  T pos_tmp = pos;
155 
156  if (pos >= p2)
157  {
158  pos_tmp = p1 + (pos - p2);
159  }
160  else if (pos < p1)
161  {
162  pos_tmp = p2 - (p1 - pos);
163 
164  // This is a round off error fix
165  // if the shift bring exactly on p2 p2 we back the particle to p1
166  if (pos_tmp == p2)
167  pos_tmp = p1;
168  }
169 
170  return pos_tmp;
171  }
172 
177  inline long int size_t_floor(double x)
178  {
179  size_t i = (long int)x; /* truncate */
180  return i - ( i > x ); /* convert trunc to floor */
181  }
182 
187  inline long int size_t_floor(float x)
188  {
189  size_t i = (long int)x; /* truncate */
190  return i - ( i > x ); /* convert trunc to floor */
191  }
192 
193  const int tab64[64] = {
194  63, 0, 58, 1, 59, 47, 53, 2,
195  60, 39, 48, 27, 54, 33, 42, 3,
196  61, 51, 37, 40, 49, 18, 28, 20,
197  55, 30, 34, 11, 43, 14, 22, 4,
198  62, 57, 46, 52, 38, 26, 32, 41,
199  50, 36, 17, 19, 29, 10, 13, 21,
200  56, 45, 25, 31, 35, 16, 9, 12,
201  44, 24, 15, 8, 23, 7, 6, 5};
202 
208  inline int log2_64 (uint64_t value)
209  {
210  value |= value >> 1;
211  value |= value >> 2;
212  value |= value >> 4;
213  value |= value >> 8;
214  value |= value >> 16;
215  value |= value >> 32;
216  return tab64[((uint64_t)((value - (value >> 1))*0x07EDD5E59A4E28C2)) >> 58];
217  }
218 
219 #ifdef HAVE_LIBQUADMATH
220 
225  inline long int size_t_floor(boost::multiprecision::float128 x)
226  {
227  size_t i = (long int)x; /* truncate */
228  return i - ( i > x ); /* convert trunc to floor */
229  }
230 
231 #endif
232  }
233 }
234 
235 #endif