CMS 3D CMS Logo

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),
14  fInterpolationType(intType)
15 {
16  PrepareTable(aProbFunc);
17 }
18 
20  : fNBins(theProbSize),
21  fInterpolationType(intType)
22 {}
23 
24 void RandArrayFunction::PrepareTable(const double* aProbFunc) {
25  //Prepares fIntegralPdf.
26  if(fNBins < 1) {
27  edm::LogError("RandArrayFunction") << "RandArrayFunction constructed with no bins - will use flat distribution";
29  return;
30  }
31 
32  fIntegralPdf.resize(fNBins + 1);
33  fIntegralPdf[0] = 0;
34  int ptn;
35  for (ptn = 0; ptn < fNBins; ++ptn ) {
36  double weight = aProbFunc[ptn];
37  if (weight < 0.) {
38  // We can't stomach negative bin contents, they invalidate the
39  // search algorithm when the distribution is fired.
40  edm::LogWarning("RandArrayFunction") << "RandArrayFunction constructed with negative-weight bin "<< ptn << " == " << weight << " -- will substitute 0 weight";
41  weight = 0.;
42  }
43  fIntegralPdf[ptn + 1] = fIntegralPdf[ptn] + weight;
44  }
45 
46  if (fIntegralPdf[fNBins] <= 0.) {
47  edm::LogWarning("RandArrayFunction") << "RandArrayFunction constructed with nothing in bins - will use flat distribution";
49  return;
50  }
51 
52  for (ptn = 0; ptn < fNBins + 1; ++ptn)
53  fIntegralPdf[ptn] /= fIntegralPdf[fNBins];
54 
55  // And another useful variable is ...
56  fOneOverNbins = 1.0 / fNBins;
57  // One last chore:
59  edm::LogInfo("RandArrayFunction") << "RandArrayFunction does not recognize fInterpolationType "<< fInterpolationType << " Will use type 0 (continuous linear interpolation)";
61  }
62 }
63 
65  //Called only by PrepareTable in case of user error.
66  fNBins = 1;
67  fIntegralPdf.resize(2);
68  fIntegralPdf[0] = 0;
69  fIntegralPdf[1] = 1;
70  fOneOverNbins = 1.0;
71 }
72 
73 double RandArrayFunction::MapRandom(double rand) const {
74  // Private method to take the random (however it is created) and map it
75  // according to the distribution.
76 
77  int nBelow = 0; // largest k such that I[k] is known to be <= rand
78  int nAbove = fNBins; // largest k such that I[k] is known to be > rand
79  int middle;
80 
81  while (nAbove > nBelow+1) {
82  middle = (nAbove + nBelow+1)>>1;
83  rand >= fIntegralPdf[middle] ? nBelow = middle : nAbove = middle;
84  }// after this loop, nAbove is always nBelow+1 and they straddle rad:
85 
86  /*assert ( nAbove = nBelow+1 );
87  assert ( fIntegralPdf[nBelow] <= rand );
88  assert ( fIntegralPdf[nAbove] >= rand );*/
89  // If a defective engine produces rand=1, that will
90  // still give sensible results so we relax the > rand assertion
91 
92  if (fInterpolationType == 1) {
93  return nBelow * fOneOverNbins;
94  }
95  else {
96  double binMeasure = fIntegralPdf[nAbove] - fIntegralPdf[nBelow];
97  // binMeasure is always aProbFunc[nBelow],
98  // but we don't have aProbFunc any more so we subtract.
99 
100  if (!binMeasure) {
101  // rand lies right in a bin of measure 0. Simply return the center
102  // of the range of that bin. (Any value between k/N and (k+1)/N is
103  // equally good, in this rare case.)
104  return (nBelow + .5) * fOneOverNbins;
105  }
106 
107  double binFraction = (rand - fIntegralPdf[nBelow]) / binMeasure;
108 
109  return (nBelow + binFraction) * fOneOverNbins;
110  }
111 }
112 
113 void RandArrayFunction::FireArray(int size, double *vect) const {
114  for (int i = 0; i < size; ++i)
115  vect[i] = Fire();
116 }
size
Write out results.
Definition: weight.py:1
std::vector< double > fIntegralPdf
void PrepareTable(const double *aProbFunc)
void FireArray(int size, double *array) const
Signal rand(Signal arg)
Definition: vlib.cc:442
RandArrayFunction(const double *aProbFunc, int theProbSize, int interpolationType=0)
double Fire() const
double MapRandom(double rand) const