Project
Loading...
Searching...
No Matches
trigonometric.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
16#ifndef MATHUTILS_INCLUDE_MATHUTILS_DETAIL_TRIGONOMETRIC_H_
17#define MATHUTILS_INCLUDE_MATHUTILS_DETAIL_TRIGONOMETRIC_H_
18
19#ifndef GPUCA_GPUCODE_DEVICE
20#include <cmath>
21#include <tuple>
22#endif
23#include "GPUCommonArray.h"
24#include "GPUCommonDef.h"
25#include "GPUCommonMath.h"
28
29namespace o2
30{
31namespace math_utils
32{
33namespace detail
34{
35
36template <typename T>
37GPUhdi() T to02Pi(T phi)
38{
39 T res = phi;
40 // ensure angle in [0:2pi] for the input in [-pi:pi] or [0:pi]
41 if (res < 0.f) {
43 }
44 return res;
45}
46
47template <typename T>
49{
50 phi = to02Pi<T>(phi);
51}
52
53template <typename T>
55{
56 T res = phi;
57 // ensure angle in [0:2pi] for the any input angle
58 while (res < 0.f) {
60 }
63 }
64 return res;
65}
66
67template <typename T>
68inline void bringTo02PiGen(T& phi)
69{
70 phi = to02PiGen<T>(phi);
71}
72
73template <typename T>
75{
76 T res = phi;
77 // ensure angle in [-pi:pi] for the input in [-pi:pi] or [0:pi]
80 } else if (res < -o2::constants::math::PI) {
82 }
83 return res;
84}
85
86template <typename T>
88{
89 phi = toPMPi<T>(phi);
90}
91
92template <typename T>
94{
95 // ensure angle in [-pi:pi] for any input angle
96 T res = phi;
97 while (res < -o2::constants::math::PI) {
99 }
100 while (res > o2::constants::math::PI) {
102 }
103 return res;
104}
105
106template <typename T>
107inline void bringToPMPiGen(T& phi)
108{
109 phi = toPMPiGen<T>(phi);
110}
111
112#ifdef __OPENCL__ // TODO: get rid of that stupid workaround for OpenCL template address spaces
113template <typename T, typename S, typename U>
114GPUhdi() void sincos(T ang, S& s, U& c)
115{
116 return o2::gpu::GPUCommonMath::SinCos(ang, s, c);
117}
118#else
119template <typename T>
120GPUhdi() void sincos(T ang, T& s, T& c)
121{
122 return o2::gpu::GPUCommonMath::SinCos(ang, s, c);
123}
124template <>
125GPUhdi() void sincos(double ang, double& s, double& c)
126{
127 return o2::gpu::GPUCommonMath::SinCosd(ang, s, c);
128}
129#endif
130
131#ifndef GPUCA_GPUCODE_DEVICE
132
133template <typename T>
134GPUhdi() std::tuple<T, T> sincos(T ang)
135{
136 T sin = 0;
137 T cos = 0;
138 sincos<T>(ang, sin, cos);
139 return std::make_tuple(sin, cos);
140}
141
142template <typename T>
143inline std::tuple<T, T> rotateZ(T xL, T yL, T snAlp, T csAlp)
144{
145 // 2D rotation of the point by angle alpha (local to global)
146 return std::make_tuple(xL * csAlp - yL * snAlp, xL * snAlp + yL * csAlp);
147}
148
149template <typename T>
150GPUhdi() std::tuple<T, T> rotateZInv(T xG, T yG, T snAlp, T csAlp)
151{
152 // inverse 2D rotation of the point by angle alpha (global to local)
153 return rotateZ<T>(xG, yG, -snAlp, csAlp);
154}
155
156#endif
157
158template <typename T>
159GPUhdi() void rotateZ(gpu::gpustd::array<T, 3>& xy, T alpha)
160{
161 // transforms vector in tracking frame alpha to global frame
162 T sin, cos;
163 sincos<T>(alpha, sin, cos);
164 const T x = xy[0];
165 xy[0] = x * cos - xy[1] * sin;
166 xy[1] = x * sin + xy[1] * cos;
167}
168
169template <typename T>
171{
172 xG = xL * csAlp - yL * snAlp;
173 yG = xL * snAlp + yL * csAlp;
174 ;
175 // std::tie(xG, yG) = rotateZ<T>(xL, yL, snAlp, csAlp); // must not use std:: - versions on GPU
176}
177
178template <typename T>
180{
181 // inverse 2D rotation of the point by angle alpha (global to local)
182 rotateZ<T>(xG, yG, xL, yL, -snAlp, csAlp);
183}
184
185template <typename T = float>
186GPUhdi() constexpr T sectorDAlpha()
187{
189}
190
191template <typename T>
193{
194 // convert angle to sector ID, phi can be either in 0:2pi or -pi:pi convention
196 if (phi < 0.f) {
198 }
199 return sect % o2::constants::math::NSectors;
200}
201
202template <typename T>
203GPUhdi() T sector2Angle(int sect)
204{
205 // convert sector to its angle center, in -pi:pi convention
206 T ang = o2::constants::math::SectorSpanRad * (0.5f + sect);
207 bringToPMPi<T>(ang);
208 return ang;
209}
210
211template <typename T>
213{
214 // convert angle to its sector alpha
215 return sector2Angle<T>(angle2Sector<T>(phi));
216}
217
218template <typename T>
219GPUhdi() constexpr bool okForPhiMin(T phiMin, T phi)
220{
221 // check if phi is above the phiMin, phi's must be in 0-2pi range
222 const T dphi = phi - phiMin;
223 return ((dphi > 0 && dphi < constants::math::PI) || dphi < -constants::math::PI) ? true : false;
224}
225
226template <typename T>
227GPUhdi() constexpr bool okForPhiMax(T phiMax, T phi)
228{
229 // check if phi is below the phiMax, phi's must be in 0-2pi range
230 const T dphi = phi - phiMax;
231 return ((dphi < 0 && dphi > -constants::math::PI) || dphi > constants::math::PI) ? true : false;
232}
233
234template <typename T>
235GPUhdi() constexpr T meanPhiSmall(T phi0, T phi1)
236{
237 // return mean phi, assume phis in 0:2pi
238 T phi;
239 if (!okForPhiMin(phi0, phi1)) {
240 phi = phi0;
241 phi0 = phi1;
242 phi1 = phi;
243 }
244 if (phi0 > phi1) {
245 phi = 0.5 * (phi1 - (constants::math::TwoPI - phi0)); // wrap
246 } else {
247 phi = 0.5 * (phi0 + phi1);
248 }
250 return phi;
251}
252
253template <typename T>
254GPUhdi() constexpr T deltaPhiSmall(T phi0, T phi1)
255{
256 // return delta phi, assume phi is in 0:2pi
257 T del;
258 if (!okForPhiMin(phi0, phi1)) {
259 del = phi0;
260 phi0 = phi1;
261 phi1 = del;
262 }
263 del = phi1 - phi0;
264 if (del < 0) {
266 }
267 return del;
268}
269
270template <typename T>
271GPUhdi() T fastATan2(T y, T x)
272{
273 // Fast atan2(y,x) for any angle [-Pi,Pi]
274 // Average inaccuracy: 0.00048
275 // Max inaccuracy: 0.00084
276 // Speed: 6.2 times faster than atan2f()
277 constexpr T Pi = 3.1415926535897932384626433832795;
278
279 auto atan = [](T a) -> T {
280 // returns the arctan for the angular range [-Pi/4, Pi/4]
281 // the polynomial coefficients are taken from:
282 // https://stackoverflow.com/questions/42537957/fast-accurate-atan-arctan-approximation-algorithm
283 constexpr T A = 0.0776509570923569;
284 constexpr T B = -0.287434475393028;
285 constexpr T C = (Pi / 4 - A - B);
286 const T a2 = a * a;
287 return ((A * a2 + B) * a2 + C) * a;
288 };
289
290 auto atan2P = [atan](T yy, T xx) -> T {
291 // fast atan2(yy,xx) for the angular range [0,+Pi]
292 constexpr T Pi025 = 1 * Pi / 4;
293 constexpr T Pi075 = 3 * Pi / 4;
294 const T x1 = xx + yy; // point p1 (x1,y1) = (xx,yy) - Pi/4
295 const T y1 = yy - xx;
296 T phi0 = 0;
297 T tan = 0;
298 if (xx < 0) { // p1 is in the range [Pi/4, 3*Pi/4]
299 phi0 = Pi075;
300 tan = -x1 / y1;
301 } else { // p1 is in the range [-Pi/4, Pi/4]
302 phi0 = Pi025;
303 tan = y1 / x1;
304 }
305 return phi0 + atan(tan);
306 };
307
308 // fast atan2(y,x) for any angle [-Pi,Pi]
309 return copysign<T>(atan2P(o2::gpu::GPUCommonMath::Abs(y), x), y);
310}
311
312template <class T>
313GPUdi() T asin(T x)
314{
315 return o2::gpu::GPUCommonMath::ASin(x);
316};
317
318template <class T>
319GPUdi() T acos(T x)
320{
321 return o2::gpu::GPUCommonMath::ACos(x);
322};
323
324template <class T>
325GPUdi() T atan(T x)
326{
327 return o2::gpu::GPUCommonMath::ATan(x);
328};
329
330template <class T>
331GPUdi() T atan2(T y, T x)
332{
333 return o2::gpu::GPUCommonMath::ATan2(y, x);
334};
335
336template <class T>
337GPUdi() T sin(T x)
338{
339 return o2::gpu::GPUCommonMath::Sin(x);
340};
341
342template <class T>
343GPUdi() T cos(T x)
344{
345 return o2::gpu::GPUCommonMath::Cos(x);
346};
347
348template <class T>
349GPUdi() T tan(T x)
350{
351 return o2::gpu::GPUCommonMath::Tan(x);
352};
353
354template <class T>
355GPUdi() T twoPi()
356{
357 return o2::gpu::GPUCommonMath::TwoPi();
358};
359
360template <>
361GPUdi() double twoPi()
362{
364};
365
366template <class T>
367GPUdi() T pi()
368{
369 return o2::gpu::GPUCommonMath::Pi();
370}
371
372template <>
373GPUdi() double pi()
374{
376}
377
378#ifndef GPUCA_GPUCODE_DEVICE
379template <>
380GPUdi() double tan(double x)
381{
382 return std::tan(x);
383};
384template <>
385GPUdi() double sin(double x)
386{
387 return std::sin(x);
388};
389template <>
390GPUdi() double atan2(double y, double x)
391{
392 return std::atan2(y, x);
393};
394template <>
395GPUdi() double atan(double x)
396{
397 return std::atan(x);
398};
399template <>
400GPUdi() double asin(double x)
401{
402 return std::asin(x);
403};
404template <>
405GPUdi() double acos(double x)
406{
407 return std::acos(x);
408};
409template <>
410GPUdi() double cos(double x)
411{
412 return std::cos(x);
413};
414#endif
415
416} // namespace detail
417} // namespace math_utils
418} // namespace o2
419
420#endif /* MATHUTILS_INCLUDE_MATHUTILS_DETAIL_TRIGONOMETRIC_H_ */
useful math constants
uint32_t res
Definition RawData.h:0
Definition A.h:16
Definition B.h:16
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint GLfloat GLfloat GLfloat GLfloat y1
Definition glcorearb.h:5034
GLuint GLfloat GLfloat GLfloat x1
Definition glcorearb.h:5034
GLenum array
Definition glcorearb.h:4274
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
constexpr int NSectors
constexpr float SectorSpanDeg
constexpr float TwoPI
constexpr float SectorSpanRad
constexpr float PI
constexpr float Rad2Deg
void bringTo02PiGen(T &phi)
return((dphi > 0 &&dphi< constants::math::PI)||dphi< -constants::math::PI) ? true GPUhdi() const expr bool okForPhiMax(T phiMax
return((dphi< 0 &&dphi > -constants::math::PI)||dphi > constants::math::PI) ? true T phi1
void bringToPMPiGen(T &phi)
std::tuple< T, T > rotateZ(T xL, T yL, T snAlp, T csAlp)
return copysign< T >(atan2P(o2::gpu::GPUCommonMath::Abs(y), x), y)
GPUdi() int nint(T x)
Definition basicMath.h:66
float angle2Alpha(float phi)
Definition Utils.h:203
int angle2Sector(float phi)
Definition Utils.h:183
float toPMPi(float phi)
Definition Utils.h:90
std::tuple< float, float > rotateZInv(float xG, float yG, float snAlp, float csAlp)
Definition Utils.h:142
float sector2Angle(int sect)
Definition Utils.h:193
void bringToPMPi(float &phi)
Definition Utils.h:100
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.