CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
RandArrayFunction.cc
Go to the documentation of this file.
1 /*
2 
3 Nikolai Amelin, Ludmila Malinina, Timur Pocheptsov (C) JINR/Dubna
4 amelin@sunhe.jinr.ru, malinina@sunhe.jinr.ru, pocheptsov@sunhe.jinr.ru
5 November. 2, 2005
6 
7 */
8 //This class is taken from the GEANT4 tool kit and changed!!!!!
9 
11 
12 RandArrayFunction::RandArrayFunction(const double *aProbFunc, int theProbSize, int intType)
13  : fNBins(theProbSize), fInterpolationType(intType) {
14  PrepareTable(aProbFunc);
15 }
16 
17 RandArrayFunction::RandArrayFunction(int theProbSize, int intType) : fNBins(theProbSize), fInterpolationType(intType) {}
18 
19 void RandArrayFunction::PrepareTable(const double *aProbFunc) {
20  //Prepares fIntegralPdf.
21  if (fNBins < 1) {
22  edm::LogError("RandArrayFunction") << "RandArrayFunction constructed with no bins - will use flat distribution";
24  return;
25  }
26 
27  fIntegralPdf.resize(fNBins + 1);
28  fIntegralPdf[0] = 0;
29  int ptn;
30  for (ptn = 0; ptn < fNBins; ++ptn) {
31  double weight = aProbFunc[ptn];
32  if (weight < 0.) {
33  // We can't stomach negative bin contents, they invalidate the
34  // search algorithm when the distribution is fired.
35  edm::LogWarning("RandArrayFunction") << "RandArrayFunction constructed with negative-weight bin " << ptn
36  << " == " << weight << " -- will substitute 0 weight";
37  weight = 0.;
38  }
39  fIntegralPdf[ptn + 1] = fIntegralPdf[ptn] + weight;
40  }
41 
42  if (fIntegralPdf[fNBins] <= 0.) {
43  edm::LogWarning("RandArrayFunction")
44  << "RandArrayFunction constructed with nothing in bins - will use flat distribution";
46  return;
47  }
48 
49  for (ptn = 0; ptn < fNBins + 1; ++ptn)
50  fIntegralPdf[ptn] /= fIntegralPdf[fNBins];
51 
52  // And another useful variable is ...
53  fOneOverNbins = 1.0 / fNBins;
54  // One last chore:
56  edm::LogInfo("RandArrayFunction") << "RandArrayFunction does not recognize fInterpolationType "
57  << fInterpolationType << " Will use type 0 (continuous linear interpolation)";
59  }
60 }
61 
63  //Called only by PrepareTable in case of user error.
64  fNBins = 1;
65  fIntegralPdf.resize(2);
66  fIntegralPdf[0] = 0;
67  fIntegralPdf[1] = 1;
68  fOneOverNbins = 1.0;
69 }
70 
71 double RandArrayFunction::MapRandom(double rand) const {
72  // Private method to take the random (however it is created) and map it
73  // according to the distribution.
74 
75  int nBelow = 0; // largest k such that I[k] is known to be <= rand
76  int nAbove = fNBins; // largest k such that I[k] is known to be > rand
77  int middle;
78 
79  while (nAbove > nBelow + 1) {
80  middle = (nAbove + nBelow + 1) >> 1;
81  rand >= fIntegralPdf[middle] ? nBelow = middle : nAbove = middle;
82  } // after this loop, nAbove is always nBelow+1 and they straddle rad:
83 
84  /*assert ( nAbove = nBelow+1 );
85  assert ( fIntegralPdf[nBelow] <= rand );
86  assert ( fIntegralPdf[nAbove] >= rand );*/
87  // If a defective engine produces rand=1, that will
88  // still give sensible results so we relax the > rand assertion
89 
90  if (fInterpolationType == 1) {
91  return nBelow * fOneOverNbins;
92  } else {
93  double binMeasure = fIntegralPdf[nAbove] - fIntegralPdf[nBelow];
94  // binMeasure is always aProbFunc[nBelow],
95  // but we don't have aProbFunc any more so we subtract.
96 
97  if (!binMeasure) {
98  // rand lies right in a bin of measure 0. Simply return the center
99  // of the range of that bin. (Any value between k/N and (k+1)/N is
100  // equally good, in this rare case.)
101  return (nBelow + .5) * fOneOverNbins;
102  }
103 
104  double binFraction = (rand - fIntegralPdf[nBelow]) / binMeasure;
105 
106  return (nBelow + binFraction) * fOneOverNbins;
107  }
108 }
109 
110 void RandArrayFunction::FireArray(int size, double *vect) const {
111  for (int i = 0; i < size; ++i)
112  vect[i] = Fire();
113 }
std::vector< double > fIntegralPdf
Log< level::Error, false > LogError
void PrepareTable(const double *aProbFunc)
void FireArray(int size, double *array) const
Log< level::Info, false > LogInfo
RandArrayFunction(const double *aProbFunc, int theProbSize, int interpolationType=0)
Log< level::Warning, false > LogWarning
int weight
Definition: histoStyle.py:51
tuple size
Write out results.
double Fire() const
double MapRandom(double rand) const