00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "RooFit.h"
00027
00028 #include "RooGrid.h"
00029 #include "RooGrid.h"
00030 #include "RooAbsFunc.h"
00031 #include "RooNumber.h"
00032 #include "RooRandom.h"
00033 #include "TMath.h"
00034 #include "RooMsgService.h"
00035 #include "TClass.h"
00036
00037 #include <math.h>
00038 #include "Riostream.h"
00039 #include <iomanip>
00040
00041 ClassImp(RooGrid)
00042 ;
00043
00044
00045
00046 RooGrid::RooGrid() :
00047 _valid(kFALSE), _dim(0), _bins(0), _boxes(0), _vol(0), _xl(0), _xu(0), _delx(0), _d(0), _xi(0), _xin(0), _weight(0)
00048 {
00049
00050 }
00051
00052
00053
00054 RooGrid::RooGrid(const RooAbsFunc &function)
00055 : _valid(kTRUE), _xl(0),_xu(0),_delx(0),_xi(0)
00056 {
00057
00058
00059
00060 if(!(_valid= function.isValid())) {
00061 oocoutE((TObject*)0,InputArguments) << ClassName() << ": cannot initialize using an invalid function" << endl;
00062 return;
00063 }
00064
00065
00066 _dim= function.getDimension();
00067 _xl= new Double_t[_dim];
00068 _xu= new Double_t[_dim];
00069 _delx= new Double_t[_dim];
00070 _d= new Double_t[_dim*maxBins];
00071 _xi= new Double_t[_dim*(maxBins+1)];
00072 _xin= new Double_t[maxBins+1];
00073 _weight= new Double_t[maxBins];
00074 if(!_xl || !_xu || !_delx || !_d || !_xi || !_xin || !_weight) {
00075 oocoutE((TObject*)0,Integration) << ClassName() << ": memory allocation failed" << endl;
00076 _valid= kFALSE;
00077 return;
00078 }
00079
00080
00081 _valid= initialize(function);
00082 }
00083
00084
00085
00086 RooGrid::~RooGrid()
00087 {
00088
00089 if(_xl) delete[] _xl;
00090 if(_xu) delete[] _xu;
00091 if(_delx) delete[] _delx;
00092 if(_d) delete[] _d;
00093 if(_xi) delete[] _xi;
00094 if(_xin) delete[] _xin;
00095 if(_weight) delete[] _weight;
00096 }
00097
00098
00099
00100 Bool_t RooGrid::initialize(const RooAbsFunc &function)
00101 {
00102
00103
00104
00105
00106 _vol= 1;
00107 _bins= 1;
00108 for(UInt_t index= 0; index < _dim; index++) {
00109 _xl[index]= function.getMinLimit(index);
00110 if(RooNumber::isInfinite(_xl[index])) {
00111 oocoutE((TObject*)0,Integration) << ClassName() << ": lower limit of dimension " << index << " is infinite" << endl;
00112 return kFALSE;
00113 }
00114 _xu[index]= function.getMaxLimit(index);
00115 if(RooNumber::isInfinite(_xl[index])) {
00116 oocoutE((TObject*)0,Integration) << ClassName() << ": upper limit of dimension " << index << " is infinite" << endl;
00117 return kFALSE;
00118 }
00119 Double_t dx= _xu[index] - _xl[index];
00120 if(dx <= 0) {
00121 oocoutE((TObject*)0,Integration) << ClassName() << ": bad range for dimension " << index << ": [" << _xl[index]
00122 << "," << _xu[index] << "]" << endl;
00123 return kFALSE;
00124 }
00125 _delx[index]= dx;
00126 _vol*= dx;
00127 coord(0,index) = 0;
00128 coord(1,index) = 1;
00129 }
00130 return kTRUE;
00131 }
00132
00133
00134
00135 void RooGrid::resize(UInt_t bins)
00136 {
00137
00138
00139
00140
00141
00142
00143 if(bins == _bins) return;
00144
00145
00146 Double_t pts_per_bin = (Double_t) _bins / (Double_t) bins;
00147
00148
00149 for (UInt_t j = 0; j < _dim; j++) {
00150 Double_t xold,xnew(0),dw(0);
00151 Int_t i = 1;
00152
00153
00154 UInt_t k;
00155 for(k = 1; k <= _bins; k++) {
00156 dw += 1.0;
00157 xold = xnew;
00158 xnew = coord(k,j);
00159 while(dw > pts_per_bin) {
00160 dw -= pts_per_bin;
00161 newCoord(i++)= xnew - (xnew - xold) * dw;
00162 }
00163 }
00164
00165 for(k = 1 ; k < bins; k++) {
00166 coord(k, j) = newCoord(k);
00167 }
00168 coord(bins, j) = 1;
00169 }
00170 _bins = bins;
00171 }
00172
00173
00174
00175 void RooGrid::resetValues()
00176 {
00177
00178
00179 for(UInt_t i = 0; i < _bins; i++) {
00180 for (UInt_t j = 0; j < _dim; j++) {
00181 value(i,j)= 0.0;
00182 }
00183 }
00184 }
00185
00186
00187
00188 void RooGrid::generatePoint(const UInt_t box[], Double_t x[], UInt_t bin[], Double_t &vol,
00189 Bool_t useQuasiRandom) const
00190 {
00191
00192
00193
00194
00195
00196
00197 vol= 1;
00198
00199
00200 if(useQuasiRandom) {
00201 RooRandom::quasi(_dim,x);
00202 }
00203 else {
00204 RooRandom::uniform(_dim,x);
00205 }
00206
00207
00208 for(UInt_t j= 0; j < _dim; ++j) {
00209
00210
00211
00212 Double_t z= ((box[j] + x[j])/_boxes)*_bins;
00213
00214
00215
00216
00217 Int_t k= (Int_t)z;
00218 bin[j] = k;
00219 Double_t y, bin_width;
00220 if(k == 0) {
00221 bin_width= coord(1,j);
00222 y= z * bin_width;
00223 }
00224 else {
00225 bin_width= coord(k+1,j) - coord(k,j);
00226 y= coord(k,j) + (z-k)*bin_width;
00227 }
00228
00229 x[j] = _xl[j] + y*_delx[j];
00230
00231
00232 vol *= bin_width;
00233 }
00234 }
00235
00236
00237
00238
00239 void RooGrid::firstBox(UInt_t box[]) const
00240 {
00241
00242
00243
00244 for(UInt_t i= 0; i < _dim; i++) box[i]= 0;
00245 }
00246
00247
00248
00249
00250 Bool_t RooGrid::nextBox(UInt_t box[]) const
00251 {
00252
00253
00254
00255
00256
00257
00258 Int_t j(_dim-1);
00259 while (j >= 0) {
00260 box[j]= (box[j] + 1) % _boxes;
00261 if (0 != box[j]) return kTRUE;
00262 j--;
00263 }
00264
00265 return kFALSE;
00266 }
00267
00268
00269
00270
00271 void RooGrid::printMultiline(ostream& os, Int_t , Bool_t verbose, TString indent) const
00272 {
00273
00274
00275 os << ClassName() << ": volume = " << getVolume() << endl;
00276 os << indent << " Has " << getDimension() << " dimension(s) each subdivided into "
00277 << getNBins() << " bin(s) and sampled with " << _boxes << " box(es)" << endl;
00278 for(UInt_t index= 0; index < getDimension(); index++) {
00279 os << indent << " (" << index << ") ["
00280 << setw(10) << _xl[index] << "," << setw(10) << _xu[index] << "]" << endl;
00281 if(!verbose) continue;
00282 for(UInt_t bin= 0; bin < _bins; bin++) {
00283 os << indent << " bin-" << bin << " : x = " << coord(bin,index) << " , y = "
00284 << value(bin,index) << endl;
00285 }
00286 }
00287 }
00288
00289
00290
00291 void RooGrid::printName(ostream& os) const
00292 {
00293
00294 os << GetName() ;
00295 }
00296
00297
00298
00299 void RooGrid::printTitle(ostream& os) const
00300 {
00301
00302 os << GetTitle() ;
00303 }
00304
00305
00306
00307 void RooGrid::printClassName(ostream& os) const
00308 {
00309
00310 os << IsA()->GetName() ;
00311 }
00312
00313
00314
00315
00316 void RooGrid::accumulate(const UInt_t bin[], Double_t amount)
00317 {
00318
00319
00320
00321 for(UInt_t j = 0; j < _dim; j++) value(bin[j],j) += amount;
00322 }
00323
00324
00325
00326 void RooGrid::refine(Double_t alpha)
00327 {
00328
00329
00330
00331
00332
00333 for (UInt_t j = 0; j < _dim; j++) {
00334
00335
00336
00337 Double_t oldg = value(0,j);
00338 Double_t newg = value(1,j);
00339 value(0,j)= (oldg + newg)/2;
00340 Double_t grid_tot_j = value(0,j);
00341
00342
00343 UInt_t i;
00344 for (i = 1; i < _bins - 1; i++) {
00345 Double_t rc = oldg + newg;
00346 oldg = newg;
00347 newg = value(i+1,j);
00348 value(i,j)= (rc + newg)/3;
00349 grid_tot_j+= value(i,j);
00350 }
00351 value(_bins-1,j)= (newg + oldg)/2;
00352 grid_tot_j+= value(_bins-1,j);
00353
00354
00355
00356 Double_t tot_weight(0);
00357 for (i = 0; i < _bins; i++) {
00358 _weight[i] = 0;
00359 if (value(i,j) > 0) {
00360 oldg = grid_tot_j/value(i,j);
00361
00362 _weight[i] = TMath::Power(((oldg-1.0)/oldg/log(oldg)), alpha);
00363 }
00364 tot_weight += _weight[i];
00365 }
00366
00367 Double_t pts_per_bin = tot_weight / _bins;
00368
00369 Double_t xold;
00370 Double_t xnew = 0;
00371 Double_t dw = 0;
00372
00373 UInt_t k;
00374 i = 1;
00375 for (k = 0; k < _bins; k++) {
00376 dw += _weight[k];
00377 xold = xnew;
00378 xnew = coord(k+1,j);
00379
00380 while(dw > pts_per_bin) {
00381 dw -= pts_per_bin;
00382 newCoord(i++) = xnew - (xnew - xold) * dw / _weight[k];
00383 }
00384 }
00385
00386 for (k = 1 ; k < _bins ; k++) {
00387 coord( k, j) = newCoord(k);
00388 }
00389
00390 coord(_bins, j) = 1;
00391 }
00392 }