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