00001 #include "FastSimulation/Utilities/interface/BaseNumericalRandomGenerator.h"
00002 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00003
00004 #include <cmath>
00005
00006
00007 BaseNumericalRandomGenerator::BaseNumericalRandomGenerator(
00008 const RandomEngine* engine,
00009 double xmin, double xmax, int n, int iter ) :
00010 random(engine),
00011 xmin(xmin), xmax(xmax), n(n), iter(iter)
00012 {
00013 f.resize(n);
00014 sampling.resize(n);
00015 }
00016
00017 void
00018 BaseNumericalRandomGenerator::initialize() {
00019
00020 m = n-1;
00021 rmin = 0.;
00022 deltar = (double)m-rmin;
00023
00024 std::vector<double> a,y,z,xnew;
00025 a.resize(n);
00026 y.resize(n);
00027 z.resize(n);
00028 xnew.resize(n);
00029
00030 double sig1 = 0.;
00031
00032
00033 double du = (xmax-xmin)/(float)m;
00034 sampling[0] = xmin;
00035 for (int i=1; i<n; ++i)
00036 sampling[i] = sampling[i-1] + du;
00037
00038
00039 for (int it=0; it<iter; ++it) {
00040
00041
00042 for (int i=0; i<n; ++i )
00043 f[i] = function(sampling[i]);
00044
00045
00046 for (int i=0; i<m; ++i )
00047 a[i] = (sampling[i+1]-sampling[i]) * (f[i+1]+f[i]) / 2.;
00048
00049
00050 y[0]=0.;
00051 for (int i=1; i<n; ++i )
00052 y[i] = y[i-1] + a[i-1];
00053
00054
00055 double dz = y[n-1]/(float)m;
00056 z[0]=0;
00057 for (int i=1; i<n; ++i )
00058 z[i] = z[i-1] + dz;
00059
00060
00061
00062 xnew[0] = sampling[0];
00063 xnew[n-1] = sampling[n-1];
00064 int k=0;
00065 for ( int i=1; i<m; ++i ) {
00066 while ( y[k+1] < z[i] ) ++k;
00067 double r = (z[i]-y[k]) / (y[k+1]-y[k]);
00068 xnew[i] = sampling[k] + (sampling[k+1]-sampling[k])*r;
00069 }
00070
00071 for ( int i=0; i<n; ++i )
00072 sampling[i] = xnew[i];
00073
00074 sig1 = sig1 + y[m];
00075
00076
00077
00078
00079 }
00080
00081 }
00082
00083 double
00084 BaseNumericalRandomGenerator::generate() const {
00085
00086 double r=rmin+deltar*random->flatShoot();
00087 int i=(int)r;
00088 double s=r-(double)i;
00089
00090 return sampling[i]+s*(sampling[i+1]-sampling[i]);
00091
00092 }
00093
00094 double
00095 BaseNumericalRandomGenerator::generateExp() const {
00096
00097 double r=rmin+deltar*random->flatShoot();
00098 int i=(int)r;
00099
00100
00101 double b = -std::log(f[i+1]/f[i]) / (sampling[i+1]-sampling[i]);
00102 double a = f[i] * std::exp(b*sampling[i]);
00103
00104 double umin = -a/b*std::exp(-b*sampling[i]);
00105 double umax = -a/b*std::exp(-b*sampling[i+1]);
00106 double u= (umax-umin) * random->flatShoot() + umin;
00107
00108 return -std::log(-b/a*u) / b;
00109
00110 }
00111
00112 double
00113 BaseNumericalRandomGenerator::generateLin() const {
00114
00115 double r=rmin+deltar*random->flatShoot();
00116 int i=(int)r;
00117
00118
00119 double a = (f[i+1]-f[i]) / (sampling[i+1]-sampling[i]);
00120 double b = f[i] - a*sampling[i];
00121
00122 double umin = a*sampling[i]*sampling[i]/2. + b*sampling[i];
00123 double umax = a*sampling[i+1]*sampling[i+1]/2. + b*sampling[i+1];
00124 double u= (umax-umin) * random->flatShoot() + umin;
00125
00126 return (-b+std::sqrt(b*b+2.*a*u))/a;
00127
00128 }
00129
00130
00131 bool BaseNumericalRandomGenerator::setSubInterval(double x1,double x2){
00132 if(x1<xmin||x2>xmax) return false;
00133 if(x1>x2)
00134 {
00135 double tmp=x1;
00136 x1=x2;
00137 x2=tmp;
00138 }
00139
00140 unsigned ibin=1;
00141 for(;ibin<(unsigned)n&&x1>sampling[ibin];++ibin);
00142 unsigned ibin1=ibin;
00143 for(;ibin<(unsigned)n&&x2>sampling[ibin];++ibin);
00144 unsigned ibin2=ibin;
00145
00146
00147
00148
00149 rmin = ibin1+(x1-sampling[ibin1])/(sampling[ibin1]-sampling[ibin1-1]);
00150 deltar= ibin2+(x2-sampling[ibin2])/(sampling[ibin2]-sampling[ibin2-1]) - rmin;
00151
00152 return true;
00153 }