18 #include "CLHEP/Random/RandChiSquare.h"
19 #include "CLHEP/Random/DoubConv.h"
27 RandChiSquare::~RandChiSquare() {
31 return genChiSquare( anEngine, a );
35 HepRandomEngine *anEngine = HepRandom::getTheEngine();
36 return genChiSquare( anEngine, a );
39 double RandChiSquare::fire(
double a ) {
40 return genChiSquare( localEngine.get(),
a );
43 void RandChiSquare::shootArray(
const int size,
double* vect,
45 for(
double* v = vect; v != vect+size; ++v )
49 void RandChiSquare::shootArray( HepRandomEngine* anEngine,
50 const int size,
double* vect,
53 for(
double* v = vect; v != vect+size; ++v )
54 *v =
shoot(anEngine,a);
57 void RandChiSquare::fireArray(
const int size,
double* vect) {
58 for(
double* v = vect; v != vect+size; ++v )
62 void RandChiSquare::fireArray(
const int size,
double* vect,
64 for(
double* v = vect; v != vect+size; ++v )
68 double RandChiSquare::genChiSquare( HepRandomEngine *anEngine,
87 static double a_in = -1.0,b,vm,vp,vd;
92 if( a < 1 )
return (-1.0);
99 v = anEngine->flat() * 0.857763884960707;
104 if (z < 0.0) r = r + zz * z / (3.0 *
z);
105 if (u < r * 0.3894003915)
return(z*z);
106 if (zz > (1.036961043 / u + 1.4))
continue;
107 if (2 * std::log(u) < (- zz * 0.5 ))
return(z*z);
114 b = std::sqrt(a - 1.0);
115 vm = - 0.6065306597 * (1.0 - 0.25 / (b * b + 1.0));
116 vm = (-b > vm)? -b : vm;
117 vp = 0.6065306597 * (0.7071067812 + b) / (0.5 + b);
123 u = anEngine->flat();
124 v = anEngine->flat() * vd + vm;
126 if (z < -b)
continue;
129 if (z < 0.0) r = r + zz * z / (3.0 * (z + b));
130 if (u < r * 0.3894003915)
return((z + b)*(z + b));
131 if (zz > (1.036961043 / u + 1.4))
continue;
132 if (2 * std::log(u) < (std::log(1.0 + z / b) * b * b - zz * 0.5 - z * b))
return((z + b)*(z + b));
137 std::ostream & RandChiSquare::put ( std::ostream & os )
const {
138 int pr=os.precision(20);
139 std::vector<unsigned long> t(2);
140 os <<
" " <<
name() <<
"\n";
141 os <<
"Uvec" <<
"\n";
142 t = DoubConv::dto2longs(defaultA);
143 os << defaultA <<
" " << t[0] <<
" " << t[1] <<
"\n";
148 std::istream & RandChiSquare::get ( std::istream & is ) {
151 if (inName !=
name()) {
152 is.clear(std::ios::badbit | is.rdstate());
153 std::cerr <<
"Mismatch when expecting to read state of a "
154 <<
name() <<
" distribution\n"
155 <<
"Name found was " << inName
156 <<
"\nistream is left in the badbit state\n";
159 if (possibleKeywordInput(is,
"Uvec", defaultA)) {
160 std::vector<unsigned long> t(2);
161 is >> defaultA >> t[0] >> t[1]; defaultA = DoubConv::longs2double(t);
ThreeVector shoot(const G4int Ap, const G4int Af)
static int engine(pchar, pchar, double &, pchar &, const dic_type &)