18 #include "CLHEP/Random/RandGamma.h"
19 #include "CLHEP/Random/DoubConv.h"
27 RandGamma::~RandGamma() {
32 return genGamma( anEngine, k, lambda );
36 HepRandomEngine *anEngine = HepRandom::getTheEngine();
37 return genGamma( anEngine, k, lambda );
40 double RandGamma::fire(
double k,
double lambda ) {
41 return genGamma( localEngine.get(), k,
lambda );
44 void RandGamma::shootArray(
const int size,
double* vect,
45 double k,
double lambda )
47 for(
double* v = vect; v != vect + size; ++v )
51 void RandGamma::shootArray( HepRandomEngine* anEngine,
52 const int size,
double* vect,
53 double k,
double lambda )
55 for(
double* v = vect; v != vect + size; ++v )
56 *v =
shoot(anEngine,k,lambda);
59 void RandGamma::fireArray(
const int size,
double* vect)
61 for(
double* v = vect; v != vect + size; ++v )
62 *v = fire(defaultK,defaultLambda);
65 void RandGamma::fireArray(
const int size,
double* vect,
66 double k,
double lambda )
68 for(
double* v = vect; v != vect + size; ++v )
72 double RandGamma::genGamma( HepRandomEngine *anEngine,
73 double a,
double lambda ) {
79 static double aa = -1.0, aaa = -1.0, b, c, d, e, r,
s, si, ss, q0,
80 q1 = 0.0416666664, q2 = 0.0208333723, q3 = 0.0079849875,
81 q4 = 0.0015746717, q5 = -0.0003349403, q6 = 0.0003340332,
82 q7 = 0.0006053049, q8 = -0.0004701849, q9 = 0.0001710320,
83 a1 = 0.333333333,
a2 = -0.249999949,
a3 = 0.199999867,
84 a4 =-0.166677482,
a5 = 0.142873973, a6 =-0.124385581,
85 a7 = 0.110368310, a8 = -0.112750886, a9 = 0.104089866,
86 e1 = 1.000000000,
e2 = 0.499999994,
e3 = 0.166666848,
87 e4 = 0.041664508, e5 = 0.008345522, e6 = 0.001353826,
90 double gds,p,q,t,sign_u,u,v,w,x;
95 if( a <= 0.0 )
return (-1.0);
96 if( lambda <= 0.0 )
return (-1.0);
100 b = 1.0 + 0.36788794412 *
a;
103 p = b * anEngine->flat();
106 gds = std::exp(std::log(p) / a);
107 if (std::log(anEngine->flat()) <= -gds)
return(gds/lambda);
111 gds = - std::log ((b - p) / a);
112 if (std::log(anEngine->flat()) <= ((a - 1.0) * std::log(gds)))
return(gds/lambda);
123 d = 5.656854249 - 12.0 *
s;
127 v1 = 2.0 * anEngine->flat() - 1.0;
128 v2 = 2.0 * anEngine->flat() - 1.0;
130 }
while ( v12 > 1.0 );
131 t = v1*std::sqrt(-2.0*std::log(v12)/v12);
134 if (t >= 0.0)
return(gds/lambda);
136 u = anEngine->flat();
137 if (d * u <= t * t * t)
return(gds/lambda);
143 q0 = ((((((((q9 * r + q8) * r + q7) * r + q6) * r + q5) * r + q4) *
144 r + q3) * r + q2) * r + q1) * r;
155 b = 1.654 + 0.0076 * ss;
156 si = 1.68 / s + 0.275;
157 c = 0.062 / s + 0.024;
162 b = 0.463 + s - 0.178 * ss;
164 c = 0.195 / s - 0.079 + 0.016 *
s;
170 if (std::fabs(v) > 0.25)
172 q = q0 - s * t + 0.25 * t * t + (ss + ss) * std::log(1.0 + v);
176 q = q0 + 0.5 * t * t * ((((((((a9 * v + a8) * v + a7) * v + a6) *
177 v +
a5) * v +
a4) * v +
a3) * v +
a2) * v +
a1) * v;
179 if (std::log(1.0 - u) <= q)
return(gds/lambda);
186 e = -std::log(anEngine->flat());
187 u = anEngine->flat();
189 sign_u = (u > 0)? 1.0 : -1.0;
190 t = b + (e * si) * sign_u;
192 while (t <= -0.71874483771719);
194 if (std::fabs(v) > 0.25)
196 q = q0 - s * t + 0.25 * t * t + (ss + ss) * std::log(1.0 + v);
200 q = q0 + 0.5 * t * t * ((((((((a9 * v + a8) * v + a7) * v + a6) *
201 v +
a5) * v +
a4) * v +
a3) * v +
a2) * v +
a1) * v;
203 if (q <= 0.0)
continue;
206 w = std::exp(q) - 1.0;
210 w = ((((((e7 * q + e6) * q + e5) * q +
e4) * q +
e3) * q +
e2) *
213 if ( c * u * sign_u <= w * std::exp(e - 0.5 * t * t))
222 std::ostream & RandGamma::put ( std::ostream & os )
const {
223 int pr=os.precision(20);
224 std::vector<unsigned long> t(2);
225 os <<
" " <<
name() <<
"\n";
226 os <<
"Uvec" <<
"\n";
227 t = DoubConv::dto2longs(defaultK);
228 os << defaultK <<
" " << t[0] <<
" " << t[1] <<
"\n";
229 t = DoubConv::dto2longs(defaultLambda);
230 os << defaultLambda <<
" " << t[0] <<
" " << t[1] <<
"\n";
235 std::istream & RandGamma::get ( std::istream & is ) {
238 if (inName !=
name()) {
239 is.clear(std::ios::badbit | is.rdstate());
240 std::cerr <<
"Mismatch when expecting to read state of a "
241 <<
name() <<
" distribution\n"
242 <<
"Name found was " << inName
243 <<
"\nistream is left in the badbit state\n";
246 if (possibleKeywordInput(is,
"Uvec", defaultK)) {
247 std::vector<unsigned long> t(2);
248 is >> defaultK >> t[0] >> t[1]; defaultK = DoubConv::longs2double(t);
249 is >> defaultLambda>>t[0]>>t[1]; defaultLambda = DoubConv::longs2double(t);
ThreeVector shoot(const G4int Ap, const G4int Af)
static int engine(pchar, pchar, double &, pchar &, const dic_type &)