Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
VectorizedTMath.h
Go to the documentation of this file.
1#ifndef ROOT_VectorizedTMath
2#define ROOT_VectorizedTMath
3
4#include "Math/Types.h"
5#include "RConfigure.h" // for R__HAS_STD_EXPERIMENTAL_SIMD
6
7#ifdef R__HAS_STD_EXPERIMENTAL_SIMD
8
9#include <cmath>
10
11namespace TMath {
12
13template <class T, class Abi>
14auto Log2(std::experimental::simd<T, Abi> &x)
15{
16 return log2(x);
17}
18
19/// Calculate a Breit Wigner function with mean and gamma.
20template <class T, class Abi>
21auto BreitWigner(std::experimental::simd<T, Abi> &x, double mean = 0, double gamma = 1)
22{
23 return 0.5 * M_1_PI * (gamma / (0.25 * gamma * gamma + (x - mean) * (x - mean)));
24}
25
26/// Calculate a gaussian function with mean and sigma.
27/// If norm=kTRUE (default is kFALSE) the result is divided
28/// by sqrt(2*Pi)*sigma.
29template <class T, class Abi>
30auto Gaus(std::experimental::simd<T, Abi> &x, double mean = 0, double sigma = 1, Bool_t norm = false)
31{
32 if (sigma == 0)
33 return std::experimental::simd<T, Abi>{1.e30};
34
35 auto inv_sigma = 1.0 / std::experimental::simd<T, Abi>(sigma);
36 auto arg = (x - std::experimental::simd<T, Abi>(mean)) * inv_sigma;
37
38 // For those entries of |arg| > 39 result is zero in double precision
39 std::experimental::simd<T, Abi> out{};
40 where(abs(arg) < 39.0, out) = exp(std::experimental::simd<T, Abi>(-0.5) * arg * arg);
41
42 if (norm)
43 out *= 0.3989422804014327 * inv_sigma; // 1/sqrt(2*Pi)=0.3989422804014327
44 return out;
45}
46
47/// Computes the probability density function of Laplace distribution
48/// at point x, with location parameter alpha and shape parameter beta.
49/// By default, alpha=0, beta=1
50/// This distribution is known under different names, most common is
51/// double exponential distribution, but it also appears as
52/// the two-tailed exponential or the bilateral exponential distribution
53template <class T, class Abi>
54auto LaplaceDist(std::experimental::simd<T, Abi> &x, double alpha = 0, double beta = 1)
55{
56 auto beta_v_inv = std::experimental::simd<T, Abi>(1.0 / beta);
57 auto out = exp(-abs((x - alpha) * beta_v_inv));
58 out *= 0.5 * beta_v_inv;
59 return out;
60}
61
62/// Computes the distribution function of Laplace distribution
63/// at point x, with location parameter alpha and shape parameter beta.
64/// By default, alpha=0, beta=1
65/// This distribution is known under different names, most common is
66/// double exponential distribution, but it also appears as
67/// the two-tailed exponential or the bilateral exponential distribution
68template <class T, class Abi>
69auto LaplaceDistI(std::experimental::simd<T, Abi> &x, double alpha = 0, double beta = 1)
70{
71 auto alpha_v = std::experimental::simd<T, Abi>(alpha);
72 auto beta_v_inv = std::experimental::simd<T, Abi>(1.0) / std::experimental::simd<T, Abi>(beta);
73 auto mask = x <= alpha_v;
74 std::experimental::simd<T, Abi> out{};
75 where(mask, out) = 0.5 * exp(-abs((x - alpha_v) * beta_v_inv));
76 where(!mask, out) = 1 - 0.5 * exp(-abs((x - alpha_v) * beta_v_inv));
77 return out;
78}
79
80/// Computation of the normal frequency function freq(x).
81/// Freq(x) = (1/sqrt(2pi)) Integral(exp(-t^2/2))dt between -infinity and x.
82///
83/// Translated from CERNLIB C300 by Rene Brun.
84template <class T, class Abi>
85auto Freq(std::experimental::simd<T, Abi> &x)
86{
87 double c1 = 0.56418958354775629;
88 double w2 = 1.41421356237309505;
89
90 double p10 = 2.4266795523053175e+2, q10 = 2.1505887586986120e+2, p11 = 2.1979261618294152e+1,
91 q11 = 9.1164905404514901e+1, p12 = 6.9963834886191355e+0, q12 = 1.5082797630407787e+1,
92 p13 = -3.5609843701815385e-2;
93
94 double p20 = 3.00459261020161601e+2, q20 = 3.00459260956983293e+2, p21 = 4.51918953711872942e+2,
95 q21 = 7.90950925327898027e+2, p22 = 3.39320816734343687e+2, q22 = 9.31354094850609621e+2,
96 p23 = 1.52989285046940404e+2, q23 = 6.38980264465631167e+2, p24 = 4.31622272220567353e+1,
97 q24 = 2.77585444743987643e+2, p25 = 7.21175825088309366e+0, q25 = 7.70001529352294730e+1,
98 p26 = 5.64195517478973971e-1, q26 = 1.27827273196294235e+1, p27 = -1.36864857382716707e-7;
99
100 double p30 = -2.99610707703542174e-3, q30 = 1.06209230528467918e-2, p31 = -4.94730910623250734e-2,
101 q31 = 1.91308926107829841e-1, p32 = -2.26956593539686930e-1, q32 = 1.05167510706793207e+0,
102 p33 = -2.78661308609647788e-1, q33 = 1.98733201817135256e+0, p34 = -2.23192459734184686e-2, q34 = 1;
103
104 auto v = abs(x) / w2;
105
106 std::experimental::simd<T, Abi> result{};
107
108 auto mask1 = v < 0.5;
109 auto mask2 = !mask1 && v < 4.0;
110 auto mask3 = !(mask1 || mask2);
111
112 auto v2 = v * v;
113 auto v3 = v2 * v;
114 auto v4 = v3 * v;
115 auto v5 = v4 * v;
116 auto v6 = v5 * v;
117 auto v7 = v6 * v;
118 auto v8 = v7 * v;
119
120 where(mask1, result) = v * (p10 + p11 * v2 + p12 * v4 + p13 * v6) / (q10 + q11 * v2 + q12 * v4 + v6);
121 where(mask2, result) =
122 1.0 - (p20 + p21 * v + p22 * v2 + p23 * v3 + p24 * v4 + p25 * v5 + p26 * v6 + p27 * v7) /
123 (exp(v2) * (q20 + q21 * v + q22 * v2 + q23 * v3 + q24 * v4 + q25 * v5 + q26 * v6 + v7));
124 where(mask3, result) = 1.0 - (c1 + (p30 * v8 + p31 * v6 + p32 * v4 + p33 * v2 + p34) /
125 ((q30 * v8 + q31 * v6 + q32 * v4 + q33 * v2 + q34) * v2)) /
126 (v * exp(v2));
127
128 auto out = 0.5 * (1 - result);
129 where(x > 0, out) = 0.5 + 0.5 * result;
130 return out;
131}
132
133/// Vectorized implementation of Bessel function I_0(x) for a vector x.
134template <class T, class Abi>
135auto BesselI0_Split_More(std::experimental::simd<T, Abi> &ax)
136{
137 auto y = 3.75 / ax;
138 return (exp(ax) / sqrt(ax)) *
139 (0.39894228 +
140 y * (1.328592e-2 +
141 y * (2.25319e-3 +
142 y * (-1.57565e-3 +
143 y * (9.16281e-3 +
144 y * (-2.057706e-2 + y * (2.635537e-2 + y * (-1.647633e-2 + y * 3.92377e-3))))))));
145}
146
147template <class T, class Abi>
148auto BesselI0_Split_Less(std::experimental::simd<T, Abi> &x)
149{
150 auto y = x * x * 0.071111111;
151
152 return 1.0 +
153 y * (3.5156229 + y * (3.0899424 + y * (1.2067492 + y * (0.2659732 + y * (3.60768e-2 + y * 4.5813e-3)))));
154}
155
156template <class T, class Abi>
157auto BesselI0(std::experimental::simd<T, Abi> &x)
158{
159 auto ax = abs(x);
160
161 auto out = BesselI0_Split_More(ax);
162 where(ax <= 3.75, out) = BesselI0_Split_Less(x);
163 return out;
164}
165
166/// Vectorized implementation of modified Bessel function I_1(x) for a vector x.
167template <class T, class Abi>
168auto BesselI1_Split_More(std::experimental::simd<T, Abi> &ax, std::experimental::simd<T, Abi> &x)
169{
170 auto y = 3.75 / ax;
171 auto result = (exp(ax) / sqrt(ax)) *
172 (0.39894228 +
173 y * (-3.988024e-2 +
174 y * (-3.62018e-3 +
175 y * (1.63801e-3 +
176 y * (-1.031555e-2 +
177 y * (2.282967e-2 + y * (-2.895312e-2 + y * (1.787654e-2 + y * -4.20059e-3))))))));
178 where(x < 0, result) = -result;
179 return result;
180}
181
182template <class T, class Abi>
183auto BesselI1_Split_Less(std::experimental::simd<T, Abi> &x)
184{
185 auto y = x * x * 0.071111111;
186
187 return x * (0.5 + y * (0.87890594 +
188 y * (0.51498869 + y * (0.15084934 + y * (2.658733e-2 + y * (3.01532e-3 + y * 3.2411e-4))))));
189}
190
191template <class T, class Abi>
192auto BesselI1(std::experimental::simd<T, Abi> &x)
193{
194 auto ax = abs(x);
195
196 auto out = BesselI1_Split_More(ax, x);
197 where(ax <= 3.75, out) = BesselI1_Split_Less(x);
198 return out;
199}
200
201/// Vectorized implementation of Bessel function J0(x) for a vector x.
202template <class T, class Abi>
203auto BesselJ0_Split1_More(std::experimental::simd<T, Abi> &ax)
204{
205 auto z = 8 / ax;
206 auto y = z * z;
207 auto xx = ax - 0.785398164;
208 auto result1 = 1 + y * (-0.1098628627e-2 + y * (0.2734510407e-4 + y * (-0.2073370639e-5 + y * 0.2093887211e-6)));
209 auto result2 =
210 -0.1562499995e-1 + y * (0.1430488765e-3 + y * (-0.6911147651e-5 + y * (0.7621095161e-6 - y * 0.934935152e-7)));
211 return sqrt(0.636619772 / ax) * (cos(xx) * result1 - z * sin(xx) * result2);
212}
213
214template <class T, class Abi>
215auto BesselJ0_Split1_Less(std::experimental::simd<T, Abi> &x)
216{
217 auto y = x * x;
218 return (57568490574.0 +
219 y * (-13362590354.0 + y * (651619640.7 + y * (-11214424.18 + y * (77392.33017 + y * -184.9052456))))) /
220 (57568490411.0 + y * (1029532985.0 + y * (9494680.718 + y * (59272.64853 + y * (267.8532712 + y)))));
221}
222
223template <class T, class Abi>
224auto BesselJ0(std::experimental::simd<T, Abi> &x)
225{
226 auto ax = abs(x);
227 auto out = BesselJ0_Split1_More(ax);
228 where(ax < 8, out) = BesselJ0_Split1_Less(x);
229 return out;
230}
231
232/// Vectorized implementation of Bessel function J1(x) for a vector x.
233template <class T, class Abi>
234auto BesselJ1_Split1_More(std::experimental::simd<T, Abi> &ax, std::experimental::simd<T, Abi> &x)
235{
236 auto z = 8 / ax;
237 auto y = z * z;
238 auto xx = ax - 2.356194491;
239 auto result1 = 1 + y * (0.183105e-2 + y * (-0.3516396496e-4 + y * (0.2457520174e-5 + y * -0.240337019e-6)));
240 auto result2 =
241 0.04687499995 + y * (-0.2002690873e-3 + y * (0.8449199096e-5 + y * (-0.88228987e-6 - y * 0.105787412e-6)));
242 auto result = sqrt(0.636619772 / ax) * (cos(xx) * result1 - z * sin(xx) * result2);
243 where(x < 0, result) = -result;
244 return result;
245}
246
247template <class T, class Abi>
248auto BesselJ1_Split1_Less(std::experimental::simd<T, Abi> &x)
249{
250 auto y = x * x;
251 return x *
252 (72362614232.0 +
253 y * (-7895059235.0 + y * (242396853.1 + y * (-2972611.439 + y * (15704.48260 + y * -30.16036606))))) /
254 (144725228442.0 + y * (2300535178.0 + y * (18583304.74 + y * (99447.43394 + y * (376.9991397 + y)))));
255}
256
257template <class T, class Abi>
258auto BesselJ1(std::experimental::simd<T, Abi> &x)
259{
260 auto ax = abs(x);
261 auto out = BesselJ1_Split1_More(ax, x);
262 where(ax < 8, out) = BesselJ1_Split1_Less(x);
263 return out;
264}
265
266} // namespace TMath
267
268#endif // R__HAS_STD_EXPERIMENTAL_SIMD
269
270#endif
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t mask
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
RVec< PromoteType< T > > abs(const RVec< T > &v)
Definition RVec.hxx:1829
RVec< PromoteType< T > > log2(const RVec< T > &v)
Definition RVec.hxx:1840
RVec< PromoteType< T > > cos(const RVec< T > &v)
Definition RVec.hxx:1849
RVec< PromoteType< T > > exp(const RVec< T > &v)
Definition RVec.hxx:1834
RVec< PromoteType< T > > sin(const RVec< T > &v)
Definition RVec.hxx:1848
const Double_t sigma
Double_t y[n]
Definition legend1.C:17
return c1
Definition legend1.C:41
Double_t x[n]
Definition legend1.C:17
double gamma(double x)
TMath.
Definition TMathBase.h:35
Double_t Gaus(Double_t x, Double_t mean=0, Double_t sigma=1, Bool_t norm=kFALSE)
Calculates a gaussian function with mean and sigma.
Definition TMath.cxx:471
Double_t Log2(Double_t x)
Returns the binary (base-2) logarithm of x.
Definition TMath.cxx:107
Double_t BesselI1(Double_t x)
Modified Bessel function K_0(x)
Definition TMath.cxx:1494
Double_t LaplaceDistI(Double_t x, Double_t alpha=0, Double_t beta=1)
Computes the cumulative distribution function (lower tail integral) of Laplace distribution at point ...
Definition TMath.cxx:2383
Double_t BreitWigner(Double_t x, Double_t mean=0, Double_t gamma=1)
Calculates a Breit Wigner function with mean and gamma.
Definition TMath.cxx:442
Double_t LaplaceDist(Double_t x, Double_t alpha=0, Double_t beta=1)
Computes the probability density function of Laplace distribution at point x, with location parameter...
Definition TMath.cxx:2367
Double_t BesselJ0(Double_t x)
Modified Bessel function K_1(x)
Definition TMath.cxx:1634
Double_t BesselJ1(Double_t x)
Bessel function J0(x) for any real x.
Definition TMath.cxx:1669
Double_t Freq(Double_t x)
Computation of the normal frequency function freq(x).
Definition TMath.cxx:270
Double_t BesselI0(Double_t x)
Integer order modified Bessel function K_n(x)
Definition TMath.cxx:1426