Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
CLHEP::HepStat Class Reference

#include <Stat.h>

Static Public Member Functions

static double flatToGaussian (double r)
 
static double inverseErf (double t)
 
static double erf (double x)
 
static double erfQ (double x)
 
static double gammln (double x)
 

Detailed Description

Author

Definition at line 50 of file Stat.h.

Member Function Documentation

◆ erf()

double CLHEP::HepStat::erf ( double  x)
static

Definition at line 268 of file flatToGaussian.cc.

268 {
269
270// Math:
271//
272// For any given x we can "quickly" find t0 = erfQ (x) = erf(x) + epsilon.
273//
274// Then we can find x1 = inverseErf (t0) = inverseErf (erf(x)+epsilon)
275//
276// Expanding in the small epsion,
277//
278// x1 = x + epsilon * [deriv(inverseErf(u),u) at u = t0] + O(epsilon**2)
279//
280// so epsilon is (x1-x) / [deriv(inverseErf(u),u) at u = t0] + O(epsilon**2)
281//
282// But the derivative of an inverse function is one over the derivative of the
283// function, so
284// epsilon = (x1-x) * [deriv(erf(v),v) at v = x] + O(epsilon**2)
285//
286// And the definition of the erf integral makes that derivative trivial.
287// Ultimately,
288//
289// erf(x) = erfQ(x) - (inverseErf(erfQ(x))-x) * exp(-x**2) * 2/sqrt(CLHEP::pi)
290//
291
292 double t0 = erfQ(x);
293 double deriv = std::exp(-x*x) * (2.0 / std::sqrt(CLHEP::pi));
294
295 return t0 - (inverseErf (t0) - x) * deriv;
296
297}
static double erfQ(double x)
Definition: erfQ.cc:23
static double inverseErf(double t)

Referenced by G4QMDMeanField::Cal2BodyQuantities(), and G4FPYSamplingOps::ShiftParameters().

◆ erfQ()

double CLHEP::HepStat::erfQ ( double  x)
static

Definition at line 23 of file erfQ.cc.

23 {
24//
25// erfQ is accurate to 7 places.
26// See Numerical Recipes P 221
27//
28
29 double t, z, erfc;
30
31 z = std::abs(x);
32 t = 1.0/(1.0+.5*z);
33
34 erfc= t*std::exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+
35 t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+
36 t*(-0.82215223+t*0.17087277 ))) ))) )));
37
38 // (The derivation of this formula should be obvious.)
39
40 if ( x < 0 ) erfc = 2.0 - erfc;
41
42 return 1 - erfc;
43
44}

Referenced by erf().

◆ flatToGaussian()

double CLHEP::HepStat::flatToGaussian ( double  r)
static

Definition at line 88 of file flatToGaussian.cc.

88 {
89
90 double sign = +1.0; // We always compute a negative number of
91 // sigmas. For r > 0 we will multiply by
92 // sign = -1 to return a positive number.
93#ifdef Trace1
94std::cout << "r = " << r << "\n";
95#endif
96
97 if ( r > .5 ) {
98 r = 1-r;
99 sign = -1.0;
100#ifdef Trace1
101std::cout << "r = " << r << "sign negative \n";
102#endif
103 } else if ( r == .5 ) {
104 return 0.0;
105 }
106
107 // Find a pointer to the proper table entries, along with the fraction
108 // of the way in the relevant bin dx and the bin size h.
109
110 // Optimize for the case of table 4 by testing for that first.
111 // By removing that case from the for loop below, we save not only
112 // several table lookups, but also several index calculations that
113 // now become (compile-time) constants.
114 //
115 // Past the case of table 4, we need not be as concerned about speed since
116 // this will happen only .1% of the time.
117
118 const double* tptr = 0;
119 double dx = 0;
120 double h = 0;
121
122 // The following big if block will locate tptr, h, and dx from whichever
123 // table is applicable:
124
125 int index;
126
127 if ( r >= Table4step ) {
128
129 index = int((Table4size<<1) * r); // 1 to Table4size-1
130 if (index <= 0) index = 1; // in case of rounding problem
131 if (index >= Table4size) index = Table4size-1;
132 dx = (Table4size<<1) * r - index; // fraction of way to next bin
133 h = Table4step;
134#ifdef Trace2
135std::cout << "index = " << index << " dx = " << dx << " h = " << h << "\n";
136#endif
137 index = (index<<1) + (Table4offset-2);
138 // at r = table4step+eps, index refers to the start of table 4
139 // and at r = .5 - eps, index refers to the next-to-last entry:
140 // remember, the table has two numbers per actual entry.
141#ifdef Trace2
142std::cout << "offset index = " << index << "\n";
143#endif
144
145 tptr = &gaussTables [index];
146
147 } else if (r < Tsteps[0]) {
148
149 // If r is so small none of the tables apply, use the asymptotic formula.
150 return (sign * transformSmall (r));
151
152 } else {
153
154 for ( int tableN = 3; tableN >= 0; tableN-- ) {
155 if ( r < Tsteps[tableN] ) {continue;} // can't happen when tableN==0
156#ifdef Trace2
157std::cout << "Using table " << tableN << "\n";
158#endif
159 double step = Tsteps[tableN];
160 index = int(r/step); // 1 to TableNsize-1
161 // The following two tests should probably never be true, but
162 // roundoff might cause index to be outside its proper range.
163 // In such a case, the interpolation still makes sense, but we
164 // need to take care that tptr points to valid data in the right table.
165 if (index == 0) index = 1;
166 if (index >= Tsizes[tableN]) index = Tsizes[tableN] - 1;
167 dx = r/step - index; // fraction of way to next bin
168 h = step;
169#ifdef Trace2
170std::cout << "index = " << index << " dx = " << dx << " h = " << h << "\n";
171#endif
172 index = (index<<1) + Toffsets[tableN] - 2;
173 tptr = &gaussTables [index];
174 break;
175 } // end of the for loop which finds tptr, dx and h in one of the tables
176
177 // The code can only get to here by a break statement, having set dx etc.
178 // It not get to here without going through one of the breaks,
179 // because before the for loop we test for the case of r < Tsteps[0].
180
181 } // End of the big if block.
182
183 // At the end of this if block, we have tptr, dx and h -- and if r is less
184 // than the smallest step, we have already returned the proper answer.
185
186 double y0 = *tptr++;
187 double d0 = *tptr++;
188 double y1 = *tptr++;
189 double d1 = *tptr;
190
191#ifdef Trace3
192std::cout << "y0: " << y0 << " y1: " << y1 << " d0: " << d0 << " d1: " << d1 << "\n";
193#endif
194
195 double x2 = dx * dx;
196 double oneMinusX = 1 - dx;
197 double oneMinusX2 = oneMinusX * oneMinusX;
198
199 double f0 = (2. * dx + 1.) * oneMinusX2;
200 double f1 = (3. - 2. * dx) * x2;
201 double g0 = h * dx * oneMinusX2;
202 double g1 = - h * oneMinusX * x2;
203
204#ifdef Trace3
205std::cout << "f0: " << f0 << " f1: " << f1 << " g0: " << g0 << " g1: " << g1 << "\n";
206#endif
207
208 double answer = f0 * y0 + f1 * y1 + g0 * d0 + g1 * d1;
209
210#ifdef Trace1
211std::cout << "variate is: " << sign*answer << "\n";
212#endif
213
214 return sign * answer;
215
216} // flatToGaussian
#define Table4step
#define Table4offset
#define Table4size
double transformSmall(double r)
G4int sign(const T t)

Referenced by inverseErf().

◆ gammln()

double CLHEP::HepStat::gammln ( double  x)
static

Definition at line 18 of file gammln.cc.

18 {
19
20// Returns the value ln(Gamma(xx) for xx > 0. Full accuracy is obtained for
21// xx > 1. For 0 < xx < 1. the reflection formula (6.1.4) can be used first.
22// (Adapted from Numerical Recipes in C. Relative to that routine, this
23// subtracts one from x at the very start, and in exchange does not have to
24// divide ser by x at the end. The results are formally equal, and practically
25// indistinguishable.)
26
27 static const double cof[6] = {76.18009172947146,-86.50532032941677,
28 24.01409824083091, -1.231739572450155,
29 0.1208650973866179e-2, -0.5395239384953e-5};
30 int j;
31 double x = xx - 1.0;
32 double tmp = x + 5.5;
33 tmp -= (x + 0.5) * std::log(tmp);
34 double ser = 1.000000000190015;
35
36 for ( j = 0; j <= 5; j++ ) {
37 x += 1.0;
38 ser += cof[j]/x;
39 }
40 return -tmp + std::log(2.5066282746310005*ser);
41}

◆ inverseErf()

double CLHEP::HepStat::inverseErf ( double  t)
static

Definition at line 260 of file flatToGaussian.cc.

260 {
261
262 // This uses erf(x) = 2*gaussCDF(sqrt(2)*x) - 1
263
264 return std::sqrt(0.5) * flatToGaussian(.5*(t+1));
265
266}
static double flatToGaussian(double r)

Referenced by erf().


The documentation for this class was generated from the following files: