Garfield++ v2r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
Random.hh
Go to the documentation of this file.
1#ifndef G_RANDOM_H
2#define G_RANDOM_H
3
4#include <cmath>
5#include "RandomEngineRoot.hh"
7
8namespace Garfield {
9
10/// Random number generator
11extern RandomEngineRoot randomEngine;
12
13/// Draw a random number uniformly distributed in the range [0, 1).
14inline double RndmUniform() { return randomEngine.Draw(); }
15
16/// Draw a random number uniformly distributed in the range (0, 1).
17inline double RndmUniformPos() {
18
19 double r = RndmUniform();
20 while (r <= 0.) r = RndmUniform();
21 return r;
22}
23
24/// Draw a Gaussian random variate with mean zero and standard deviation one.
25inline double RndmGaussian() {
26
27 static bool cached = false;
28 static double u = 0.;
29 if (cached) {
30 cached = false;
31 return u;
32 }
33 // Box-Muller algorithm
34 u = 2. * RndmUniform() - 1.;
35 double v = 2. * RndmUniform() - 1.;
36 double r2 = u * u + v * v;
37 while (r2 > 1.) {
38 u = 2. * RndmUniform() - 1.;
39 v = 2. * RndmUniform() - 1.;
40 r2 = u * u + v * v;
41 }
42 const double p = sqrt(-2. * log(r2) / r2);
43 u *= p;
44 cached = true;
45 return v * p;
46}
47
48/// Draw a Gaussian random variate with mean mu and standard deviation sigma.
49inline double RndmGaussian(const double mu, const double sigma) {
50
51 return mu + sigma * RndmGaussian();
52}
53
54/// Draw a Lorentzian random variate with mean mu
55/// and half-width at half maximum gamma.
56inline double RndmLorentzian(const double mu, const double gamma) {
57
58 return mu + gamma * tan(Pi * (RndmUniform() - 0.5));
59}
60
61/// Draw a random number according to a Voigt function with mean mu.
62/// The Voigt function is a convolution of a
63/// Gaussian (standard deviation sigma) and
64/// a Lorentzian (half width gamma).
65inline double RndmVoigt(const double mu, const double sigma,
66 const double gamma) {
67
68 if (sigma <= 0.) return RndmLorentzian(mu, gamma);
69 const double a = gamma / (Sqrt2 * sigma);
70 const double x = RndmLorentzian(0., a) + RndmGaussian(0., 1. / Sqrt2);
71 return mu + x * Sqrt2 * sigma;
72}
73
74/// Draw a Polya distributed random number.
75inline double RndmPolya(const double theta) {
76
77 // Algorithm from Review of Particle Physics
78 // C. Amsler et al, Phys. Lett. B 667 (2008)
79 if (theta <= 0.) return -log(RndmUniformPos());
80 const double c = 3 * (theta + 1.) - 0.75;
81 double u1, u2, v1, v2, v3;
82 double x;
83 while (1) {
84 u1 = RndmUniformPos();
85 v1 = u1 * (1. - u1);
86 if (v1 == 0.) continue;
87 v2 = (u1 - 0.5) * sqrt(c / v1);
88 x = theta + v2;
89 if (x <= 0.) continue;
90 u2 = RndmUniformPos();
91 v3 = 64 * u2 * u2 * pow(v1, 3);
92 if (v3 <= 1. - 2 * v2 * v2 / x ||
93 log(v3) <= 2 * (theta * log(x / theta) - v2)) {
94 return x / (theta + 1.);
95 }
96 }
97}
98
99/// Draw a random number from a Landau distribution.
100double RndmLandau();
101/// Draw a random number from a Vavilov distribution.
102double RndmVavilov(const double rkappa, const double beta2);
103double RndmHeedWF(const double w, const double f);
104
105/// Draw a random (isotropic) direction vector.
106void RndmDirection(double& dx, double& dy, double& dz,
107 const double length = 1.) {
108
109 const double phi = TwoPi * RndmUniform();
110 const double ctheta = 2 * RndmUniform() - 1.;
111 const double stheta = sqrt(1. - ctheta * ctheta);
112 dx = length * cos(phi) * stheta;
113 dy = length * sin(phi) * stheta;
114 dz = length * ctheta;
115}
116
117}
118
119#endif
double Draw()
Draw a random number.
double RndmLorentzian(const double mu, const double gamma)
Definition: Random.hh:56
double RndmHeedWF(const double w, const double f)
Definition: Random.cc:659
double RndmUniform()
Draw a random number uniformly distributed in the range [0, 1).
Definition: Random.hh:14
double RndmVavilov(const double rkappa, const double beta2)
Draw a random number from a Vavilov distribution.
Definition: Random.cc:283
double RndmPolya(const double theta)
Draw a Polya distributed random number.
Definition: Random.hh:75
void RndmDirection(double &dx, double &dy, double &dz, const double length=1.)
Draw a random (isotropic) direction vector.
Definition: Random.hh:106
double RndmVoigt(const double mu, const double sigma, const double gamma)
Definition: Random.hh:65
double RndmUniformPos()
Draw a random number uniformly distributed in the range (0, 1).
Definition: Random.hh:17
double RndmGaussian()
Draw a Gaussian random variate with mean zero and standard deviation one.
Definition: Random.hh:25
double RndmLandau()
Draw a random number from a Landau distribution.
Definition: Random.cc:87
RandomEngineRoot randomEngine
Random number generator.