50 #include "CLHEP/Random/RandGeneral.h"
51 #include "CLHEP/Random/DoubConv.h"
64 RandGeneral::RandGeneral(
const double* aProbFunc,
68 localEngine(HepRandom::getTheEngine(), do_nothing_deleter()),
70 InterpolationType(IntType)
72 prepareTable(aProbFunc);
75 RandGeneral::RandGeneral(HepRandomEngine& anEngine,
76 const double* aProbFunc,
80 localEngine(&anEngine, do_nothing_deleter()),
82 InterpolationType(IntType)
84 prepareTable(aProbFunc);
87 RandGeneral::RandGeneral(HepRandomEngine* anEngine,
88 const double* aProbFunc,
92 localEngine(anEngine),
94 InterpolationType(IntType)
96 prepareTable(aProbFunc);
99 void RandGeneral::prepareTable(
const double* aProbFunc) {
105 "RandGeneral constructed with no bins - will use flat distribution\n";
106 useFlatDistribution();
110 theIntegralPdf.resize(nBins+1);
111 theIntegralPdf[0] = 0;
115 for ( ptn = 0; ptn<nBins; ++ptn ) {
116 weight = aProbFunc[ptn];
121 "RandGeneral constructed with negative-weight bin " << ptn <<
122 " = " << weight <<
" \n -- will substitute 0 weight \n";
126 theIntegralPdf[ptn+1] = theIntegralPdf[ptn] + weight;
129 if ( theIntegralPdf[nBins] <= 0 ) {
131 "RandGeneral constructed nothing in bins - will use flat distribution\n";
132 useFlatDistribution();
136 for ( ptn = 0; ptn < nBins+1; ++ptn ) {
137 theIntegralPdf[ptn] /= theIntegralPdf[nBins];
142 oneOverNbins = 1.0 / nBins;
146 if ( (InterpolationType != 0) && (InterpolationType != 1) ) {
148 "RandGeneral does not recognize IntType " << InterpolationType
149 <<
"\n Will use type 0 (continuous linear interpolation \n";
150 InterpolationType = 0;
155 void RandGeneral::useFlatDistribution() {
160 theIntegralPdf.resize(2);
161 theIntegralPdf[0] = 0;
162 theIntegralPdf[1] = 1;
172 RandGeneral::~RandGeneral() {
180 double RandGeneral::mapRandom(
double rand)
const {
190 while (nabove > nbelow+1) {
191 middle = (nabove + nbelow+1)>>1;
192 if (rand >= theIntegralPdf[middle]) {
198 assert ( nabove == nbelow+1 );
199 assert ( theIntegralPdf[nbelow] <= rand );
200 assert ( theIntegralPdf[nabove] >= rand );
204 if ( InterpolationType == 1 ) {
206 return nbelow * oneOverNbins;
210 double binMeasure = theIntegralPdf[nabove] - theIntegralPdf[nbelow];
214 if ( binMeasure == 0 ) {
218 return (nbelow + .5) * oneOverNbins;
221 double binFraction = (rand - theIntegralPdf[nbelow]) / binMeasure;
223 return (nbelow + binFraction) * oneOverNbins;
228 void RandGeneral::shootArray( HepRandomEngine* anEngine,
229 const int size,
double* vect )
233 for (i=0; i<size; ++i) {
234 vect[i] =
shoot(anEngine);
238 void RandGeneral::fireArray(
const int size,
double* vect )
242 for (i=0; i<size; ++i) {
247 std::ostream & RandGeneral::put ( std::ostream & os )
const {
248 int pr=os.precision(20);
249 std::vector<unsigned long> t(2);
250 os <<
" " <<
name() <<
"\n";
251 os <<
"Uvec" <<
"\n";
252 os << nBins <<
" " << oneOverNbins <<
" " << InterpolationType <<
"\n";
253 t = DoubConv::dto2longs(oneOverNbins);
254 os << t[0] <<
" " << t[1] <<
"\n";
255 assert (static_cast<int>(theIntegralPdf.size())==nBins+1);
256 for (
unsigned int i=0; i<theIntegralPdf.size(); ++i) {
257 t = DoubConv::dto2longs(theIntegralPdf[i]);
258 os << theIntegralPdf[i] <<
" " << t[0] <<
" " << t[1] <<
"\n";
264 std::istream & RandGeneral::get ( std::istream & is ) {
267 if (inName !=
name()) {
268 is.clear(std::ios::badbit | is.rdstate());
269 std::cerr <<
"Mismatch when expecting to read state of a "
270 <<
name() <<
" distribution\n"
271 <<
"Name found was " << inName
272 <<
"\nistream is left in the badbit state\n";
275 if (possibleKeywordInput(is,
"Uvec", nBins)) {
276 std::vector<unsigned long> t(2);
277 is >> nBins >> oneOverNbins >> InterpolationType;
278 is >> t[0] >> t[1]; oneOverNbins = DoubConv::longs2double(t);
279 theIntegralPdf.resize(nBins+1);
280 for (
unsigned int i=0; i<theIntegralPdf.size(); ++i) {
281 is >> theIntegralPdf[i] >> t[0] >> t[1];
282 theIntegralPdf[i] = DoubConv::longs2double(t);
287 is >> oneOverNbins >> InterpolationType;
288 theIntegralPdf.resize(nBins+1);
289 for (
unsigned int i=0; i<theIntegralPdf.size(); ++i) is >> theIntegralPdf[i];
ThreeVector shoot(const G4int Ap, const G4int Af)
static int engine(pchar, pchar, double &, pchar &, const dic_type &)