PandaRoot
PndCAMath.h
Go to the documentation of this file.
1 //-*- Mode: C++ -*-
2 // ************************************************************************
3 // This file is property of and copyright by the ALICE HLT Project *
4 // ALICE Experiment at CERN, All rights reserved. *
5 // See cxx source for full Copyright notice *
6 // *
7 //*************************************************************************
8 
9 #ifndef PNDCAMATH_H
10 #define PNDCAMATH_H
11 
12 #include "PndCADef.h"
13 
14 #include <cstdlib>
15 #include <algorithm>
16 using std::abs;
17 
18 #if defined(HLTCA_STANDALONE)
19 #include <limits>
20 #else
21 #include "TMath.h"
22 #endif
23 
24 #ifdef __SSE__
25 #include <xmmintrin.h>
26 #endif
27 
33 namespace CAMath {
34 template <typename T>
35 static inline T Min(const T &x, const T &y)
36 {
37  return std::min(x, y);
38 }
39 template <typename T>
40 static inline T Max(const T &x, const T &y)
41 {
42  return std::max(x, y);
43 }
44 template <typename T>
45 static inline T Sqrt(const T &x)
46 {
47  return std::sqrt(x);
48 }
49 template <typename T>
50 static inline T RSqrt(const T &x)
51 {
52  const T one = T(1.f);
53  return one / std::sqrt(x);
54 }
55 template <typename T>
56 static inline T Abs(const T &x)
57 {
58  return std::abs(x);
59 }
60 template <typename T>
61 static inline T Log(const T &x)
62 {
63  return std::log(x);
64 }
65 template <typename T>
66 static inline T Log10(const T &x)
67 {
68  return std::log10(x);
69 }
70 template <typename T>
71 static inline T Sin(const T &x)
72 {
73  return std::sin(x);
74 }
75 template <typename T>
76 static inline T Cos(const T &x)
77 {
78  return std::cos(x);
79 }
80 template <typename T>
81 static T Reciprocal(const T &x);
82 template <typename T>
83 static T ApproxSqrt(const T &x);
84 #ifdef USE_TBB
85 template <typename T>
86 static T AtomicMax(T volatile *addr, T val);
87 #endif // USE_TBB
88 
89 template <typename T>
91  typedef bool R;
92 };
93 template <typename T>
94 static typename FiniteReturnTypeHelper<T>::R Finite(const T &x);
95 
96 template <typename T>
97 static T Round(const T &x);
98 
99 template <typename T>
100 static inline T Recip(const T &x)
101 {
102  return T(1) / x;
103 }
104 template <typename T>
105 static T ATan2(const T &y, const T &x);
106 template <typename T>
107 static T ASin(const T &x);
108 
109 float Tan(float x);
110 float Copysign(float x, float y);
111 static inline float TwoPi()
112 {
113  return 6.283185307179586f;
114 }
115 static inline float Pi()
116 {
117  return 3.1415926535897f;
118 }
119 int Nint(float x);
120 
121 #ifdef USE_TBB
122 int AtomicExch(int volatile *addr, int val);
123 int AtomicAdd(int volatile *addr, int val);
124 int AtomicMin(int volatile *addr, int val);
125 #endif // USE_TBB
126 } // namespace CAMath
127 
128 #if defined(HLTCA_STANDALONE)
129 #define choice(c1, c2, c3) c2
130 #else
131 #define choice(c1, c2, c3) c3
132 #endif
133 
134 namespace CAMath {
135 
136 template <>
137 inline float Reciprocal<float>(const float &x)
138 {
139  return 1.f / x;
140 }
141 
142 template <>
143 inline double Reciprocal<double>(const double &x)
144 {
145  return 1. / x;
146 }
147 
148 #ifdef __SSE__
149 template <>
150 inline float RSqrt<float>(const float &x)
151 {
152  float r = x;
153  __m128 tmp;
154  asm("rsqrtss %0,%1\n\t"
155  "movss %1,%0\n\t"
156  : "+m"(r), "=x"(tmp));
157  return r;
158 }
159 #endif // __SSE__
160 
161 template <>
162 inline float ApproxSqrt<float>(const float &x)
163 {
164  float r = x;
165  asm("shr %0\n\t"
166  "add $0x1fc00000,%0\n\t"
167  : "+r"(r));
168  return r;
169 }
170 } // namespace CAMath
171 
172 inline int CAMath::Nint(float x)
173 {
174 #if defined(HLTCA_STANDALONE)
175  int i;
176  if (x >= 0) {
177  i = int(x + 0.5f);
178  if (x + 0.5f == float(i) && i & 1)
179  i--;
180  } else {
181  i = int(x - 0.5f);
182  if (x - 0.5f == float(i) && i & 1)
183  i++;
184  }
185  return i;
186 #else
187  return TMath::Nint(x);
188 #endif
189 }
190 
191 namespace CAMath {
192 template <>
193 inline bool Finite<float>(const float &x)
194 {
195  return choice(1, x < std::numeric_limits<float>::infinity() && -x < std::numeric_limits<float>::infinity(), TMath::Finite(x));
196 }
197 
198 template <>
199 inline float Round<float>(const float &x)
200 {
201  return static_cast<float>(Nint(x));
202 }
203 
204 template <>
205 inline float ATan2<float>(const float &y, const float &x)
206 {
207  return choice(atan2f(y, x), atan2(y, x), TMath::ATan2(y, x));
208 }
209 
210 template <>
211 inline float ASin(const float &x)
212 {
213  return choice(asinf(x), asin(x), TMath::ASin(x));
214 }
215 
216 } // namespace CAMath
217 
218 inline float CAMath::Copysign(float x, float y)
219 {
220  x = CAMath::Abs(x);
221  return (y >= 0) ? x : -x;
222 }
223 
224 inline float CAMath::Tan(float x)
225 {
226  return choice(tanf(x), tan(x), TMath::Tan(x));
227 }
228 
229 #ifdef USE_TBB
230 
231 #include <tbb/atomic.h>
232 
233 inline int CAMath::AtomicExch(int volatile *addr, int val)
234 {
235  tbb::atomic<int> &a = *reinterpret_cast<tbb::atomic<int> *>(const_cast<int *>(addr));
236  return a.fetch_and_store(val);
237 }
238 
239 inline int CAMath::AtomicAdd(int volatile *addr, int val)
240 {
241  tbb::atomic<int> &a = *reinterpret_cast<tbb::atomic<int> *>(const_cast<int *>(addr));
242  return a.fetch_and_add(val);
243 }
244 
245 namespace CAMath {
246 template <>
247 inline int AtomicMax<int>(int volatile *addr, int val)
248 {
249  tbb::atomic<int> &a = *reinterpret_cast<tbb::atomic<int> *>(const_cast<int *>(addr));
250  int old = a;
251  if (old < val) {
252  while (old != a.compare_and_swap(val, old)) {
253  old = a;
254  if (old >= val) {
255  break;
256  }
257  }
258  }
259  return old;
260 }
261 
262 template <>
263 inline unsigned int AtomicMax<unsigned int>(unsigned int volatile *addr, unsigned int val)
264 {
265  tbb::atomic<unsigned int> &a = *reinterpret_cast<tbb::atomic<unsigned int> *>(const_cast<unsigned int *>(addr));
266  unsigned int old = a;
267  if (old < val) {
268  while (old != a.compare_and_swap(val, old)) {
269  old = a;
270  if (old >= val) {
271  break;
272  }
273  }
274  }
275  return old;
276 }
277 } // namespace CAMath
278 
279 inline int CAMath::AtomicMin(int volatile *addr, int val)
280 {
281  tbb::atomic<int> &a = *reinterpret_cast<tbb::atomic<int> *>(const_cast<int *>(addr));
282  int old = a;
283  if (old > val) {
284  while (old != a.compare_and_swap(val, old)) {
285  old = a;
286  if (old <= val) {
287  break;
288  }
289  }
290  }
291  return old;
292 }
293 #endif // USE_TBB
294 
295 #undef choice
296 
297 #endif
static T ASin(const T &x)
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:119
float Round< float >(const float &x)
Definition: PndCAMath.h:199
#define choice(c1, c2, c3)
Definition: PndCAMath.h:131
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:28
static T Sqrt(const T &x)
Definition: PndCAMath.h:45
static T ApproxSqrt(const T &x)
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:118
static T Sin(const T &x)
Definition: PndCAMath.h:71
float ASin(const float &x)
Definition: PndCAMath.h:211
friend F32vec4 log(const F32vec4 &a)
Definition: P4_F32vec4.h:117
float Tan(float x)
Definition: PndCAMath.h:224
static T Round(const T &x)
friend F32vec4 max(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:25
static T Log10(const T &x)
Definition: PndCAMath.h:66
static T Cos(const T &x)
Definition: PndCAMath.h:76
unsigned int i
Definition: P4_F32vec4.h:21
float Copysign(float x, float y)
Definition: PndCAMath.h:218
static T Abs(const T &x)
Definition: PndCAMath.h:56
static T RSqrt(const T &x)
Definition: PndCAMath.h:50
bool Finite< float >(const float &x)
Definition: PndCAMath.h:193
static T Min(const T &x, const T &y)
Definition: PndCAMath.h:35
static T ATan2(const T &y, const T &x)
static T Reciprocal(const T &x)
static float Pi()
Definition: PndCAMath.h:115
friend F32vec4 min(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:24
float ATan2< float >(const float &y, const float &x)
Definition: PndCAMath.h:205
double Reciprocal< double >(const double &x)
Definition: PndCAMath.h:143
friend F32vec4 atan2(const F32vec4 &y, const F32vec4 &x)
Definition: P4_F32vec4.h:124
static T Max(const T &x, const T &y)
Definition: PndCAMath.h:40
static T Log(const T &x)
Definition: PndCAMath.h:61
static float TwoPi()
Definition: PndCAMath.h:111
float f
Definition: P4_F32vec4.h:20
float Reciprocal< float >(const float &x)
Definition: PndCAMath.h:137
static FiniteReturnTypeHelper< T >::R Finite(const T &x)
float ApproxSqrt< float >(const float &x)
Definition: PndCAMath.h:162
static T Recip(const T &x)
Definition: PndCAMath.h:100
int Nint(float x)
Definition: PndCAMath.h:172