50#include "CLHEP/Random/defs.h"
51#include "CLHEP/Random/RandGeneral.h"
52#include "CLHEP/Random/DoubConv.h"
74 InterpolationType(IntType)
76 prepareTable(aProbFunc);
80 const double* aProbFunc,
86 InterpolationType(IntType)
88 prepareTable(aProbFunc);
92 const double* aProbFunc,
96 localEngine(anEngine),
98 InterpolationType(IntType)
100 prepareTable(aProbFunc);
103void RandGeneral::prepareTable(
const double* aProbFunc) {
109 "RandGeneral constructed with no bins - will use flat distribution\n";
110 useFlatDistribution();
114 theIntegralPdf.resize(nBins+1);
115 theIntegralPdf[0] = 0;
119 for ( ptn = 0; ptn<nBins; ++ptn ) {
120 weight = aProbFunc[ptn];
125 "RandGeneral constructed with negative-weight bin " << ptn <<
126 " = " << weight <<
" \n -- will substitute 0 weight \n";
130 theIntegralPdf[ptn+1] = theIntegralPdf[ptn] + weight;
133 if ( theIntegralPdf[nBins] <= 0 ) {
135 "RandGeneral constructed nothing in bins - will use flat distribution\n";
136 useFlatDistribution();
140 for ( ptn = 0; ptn < nBins+1; ++ptn ) {
141 theIntegralPdf[ptn] /= theIntegralPdf[nBins];
146 oneOverNbins = 1.0 / nBins;
150 if ( (InterpolationType != 0) && (InterpolationType != 1) ) {
152 "RandGeneral does not recognize IntType " << InterpolationType
153 <<
"\n Will use type 0 (continuous linear interpolation \n";
154 InterpolationType = 0;
159void RandGeneral::useFlatDistribution() {
164 theIntegralPdf.resize(2);
165 theIntegralPdf[0] = 0;
166 theIntegralPdf[1] = 1;
184double RandGeneral::mapRandom(
double rand)
const {
194 while (nabove > nbelow+1) {
195 middle = (nabove + nbelow+1)>>1;
196 if (rand >= theIntegralPdf[middle]) {
202 assert ( nabove == nbelow+1 );
203 assert ( theIntegralPdf[nbelow] <= rand );
204 assert ( theIntegralPdf[nabove] >= rand );
208 if ( InterpolationType == 1 ) {
210 return nbelow * oneOverNbins;
214 double binMeasure = theIntegralPdf[nabove] - theIntegralPdf[nbelow];
218 if ( binMeasure == 0 ) {
222 return (nbelow + .5) * oneOverNbins;
225 double binFraction = (rand - theIntegralPdf[nbelow]) / binMeasure;
227 return (nbelow + binFraction) * oneOverNbins;
233 const int size,
double* vect )
237 for (i=0; i<size; ++i) {
238 vect[i] =
shoot(anEngine);
246 for (i=0; i<size; ++i) {
252 long pr=os.precision(20);
253 std::vector<unsigned long> t(2);
254 os <<
" " <<
name() <<
"\n";
255 os <<
"Uvec" <<
"\n";
256 os << nBins <<
" " << oneOverNbins <<
" " << InterpolationType <<
"\n";
258 os << t[0] <<
" " << t[1] <<
"\n";
259 assert (
static_cast<int>(theIntegralPdf.size())==nBins+1);
260 for (
unsigned int i=0; i<theIntegralPdf.size(); ++i) {
262 os << theIntegralPdf[i] <<
" " << t[0] <<
" " << t[1] <<
"\n";
267 long pr=os.precision(20);
268 os <<
" " <<
name() <<
"\n";
269 os << nBins <<
" " << oneOverNbins <<
" " << InterpolationType <<
"\n";
270 assert (
static_cast<int>(theIntegralPdf.size())==nBins+1);
271 for (
unsigned int i=0; i<theIntegralPdf.size(); ++i)
272 os << theIntegralPdf[i] <<
"\n";
281 if (inName !=
name()) {
282 is.clear(std::ios::badbit | is.rdstate());
283 std::cerr <<
"Mismatch when expecting to read state of a "
284 <<
name() <<
" distribution\n"
285 <<
"Name found was " << inName
286 <<
"\nistream is left in the badbit state\n";
290 std::vector<unsigned long> t(2);
291 is >> nBins >> oneOverNbins >> InterpolationType;
293 theIntegralPdf.resize(nBins+1);
294 for (
unsigned int i=0; i<theIntegralPdf.size(); ++i) {
295 is >> theIntegralPdf[i] >> t[0] >> t[1];
301 is >> oneOverNbins >> InterpolationType;
302 theIntegralPdf.resize(nBins+1);
303 for (
unsigned int i=0; i<theIntegralPdf.size(); ++i) is >> theIntegralPdf[i];
static double longs2double(const std::vector< unsigned long > &v)
static std::vector< unsigned long > dto2longs(double d)
RandGeneral(const double *aProbFunc, int theProbSize, int IntType=0)
std::istream & get(std::istream &is)
std::ostream & put(std::ostream &os) const
void fireArray(const int size, double *vect)
HepRandomEngine & engine()
void shootArray(const int size, double *vect)
bool possibleKeywordInput(IS &is, const std::string &key, T &t)