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 #include "Riostream.h"
00028
00029 #include "TClass.h"
00030 #include "RooAdaptiveIntegratorND.h"
00031 #include "RooArgSet.h"
00032 #include "RooRealVar.h"
00033 #include "RooNumber.h"
00034 #include "RooMsgService.h"
00035 #include "RooNumIntFactory.h"
00036 #include "RooMultiGenFunction.h"
00037 #include "Math/AdaptiveIntegratorMultiDim.h"
00038
00039 #include <assert.h>
00040 #include <iomanip>
00041
00042
00043
00044 ClassImp(RooAdaptiveIntegratorND)
00045 ;
00046
00047
00048
00049
00050 void RooAdaptiveIntegratorND::registerIntegrator(RooNumIntFactory& fact)
00051 {
00052
00053
00054 RooRealVar maxEval2D("maxEval2D","Max number of function evaluations for 2-dim integrals",100000) ;
00055 RooRealVar maxEval3D("maxEval3D","Max number of function evaluations for 3-dim integrals",1000000) ;
00056 RooRealVar maxEvalND("maxEvalND","Max number of function evaluations for >3-dim integrals",10000000) ;
00057 RooRealVar maxWarn("maxWarn","Max number of warnings on precision not reached that is printed",5) ;
00058
00059 fact.storeProtoIntegrator(new RooAdaptiveIntegratorND(),RooArgSet(maxEval2D,maxEval3D,maxEvalND,maxWarn)) ;
00060 }
00061
00062
00063
00064
00065 RooAdaptiveIntegratorND::RooAdaptiveIntegratorND()
00066 {
00067
00068 _xmin = 0 ;
00069 _xmax = 0 ;
00070 _epsRel = 1e-7 ;
00071 _epsAbs = 1e-7 ;
00072 _nmax = 10000 ;
00073 _func = 0 ;
00074 _integrator = 0 ;
00075 _nError = 0 ;
00076 _nWarn = 0 ;
00077 _useIntegrandLimits = kTRUE ;
00078 _intName = "(none)" ;
00079 }
00080
00081
00082
00083
00084 RooAdaptiveIntegratorND::RooAdaptiveIntegratorND(const RooAbsFunc& function, const RooNumIntConfig& config) :
00085 RooAbsIntegrator(function)
00086 {
00087
00088
00089
00090
00091
00092 _func = new RooMultiGenFunction(function) ;
00093 _nWarn = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxWarn")) ;
00094 switch (_func->NDim()) {
00095 case 1: throw string(Form("RooAdaptiveIntegratorND::ctor ERROR dimension of function must be at least 2")) ;
00096 case 2: _nmax = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxEval2D")) ; break ;
00097 case 3: _nmax = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxEval3D")) ; break ;
00098 default: _nmax = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxEvalND")) ; break ;
00099 }
00100 _integrator = new ROOT::Math::AdaptiveIntegratorMultiDim(config.epsAbs(),config.epsRel(),_nmax) ;
00101 _integrator->SetFunction(*_func) ;
00102 _useIntegrandLimits=kTRUE ;
00103
00104 _xmin = 0 ;
00105 _xmax = 0 ;
00106 _nError = 0 ;
00107 _nWarn = 0 ;
00108 _epsRel = 1e-7 ;
00109 _epsAbs = 1e-7 ;
00110 checkLimits() ;
00111 _intName = function.getName() ;
00112 }
00113
00114
00115
00116
00117 RooAbsIntegrator* RooAdaptiveIntegratorND::clone(const RooAbsFunc& function, const RooNumIntConfig& config) const
00118 {
00119
00120
00121 RooAbsIntegrator* ret = new RooAdaptiveIntegratorND(function,config) ;
00122
00123 return ret ;
00124 }
00125
00126
00127
00128
00129
00130 RooAdaptiveIntegratorND::~RooAdaptiveIntegratorND()
00131 {
00132
00133 delete[] _xmin ;
00134 delete[] _xmax ;
00135 delete _integrator ;
00136 delete _func ;
00137 if (_nError>_nWarn) {
00138 coutW(NumIntegration) << "RooAdaptiveIntegratorND::dtor(" << _intName
00139 << ") WARNING: Number of suppressed warningings about integral evaluations where target precision was not reached is " << _nError-_nWarn << endl ;
00140 }
00141
00142 }
00143
00144
00145
00146
00147 Bool_t RooAdaptiveIntegratorND::checkLimits() const
00148 {
00149
00150
00151
00152 if (!_xmin) {
00153 _xmin = new Double_t[_func->NDim()] ;
00154 _xmax = new Double_t[_func->NDim()] ;
00155 }
00156
00157 if (_useIntegrandLimits) {
00158 for (UInt_t i=0 ; i<_func->NDim() ; i++) {
00159 _xmin[i]= integrand()->getMinLimit(i);
00160 _xmax[i]= integrand()->getMaxLimit(i);
00161 }
00162 }
00163
00164 return kTRUE ;
00165 }
00166
00167
00168
00169 Bool_t RooAdaptiveIntegratorND::setLimits(Double_t *xmin, Double_t *xmax)
00170 {
00171
00172
00173
00174
00175 if(_useIntegrandLimits) {
00176 oocoutE((TObject*)0,Integration) << "RooAdaptiveIntegratorND::setLimits: cannot override integrand's limits" << endl;
00177 return kFALSE;
00178 }
00179 for (UInt_t i=0 ; i<_func->NDim() ; i++) {
00180 _xmin[i]= xmin[i];
00181 _xmax[i]= xmax[i];
00182 }
00183
00184 return checkLimits();
00185 }
00186
00187
00188
00189
00190
00191 Double_t RooAdaptiveIntegratorND::integral(const Double_t* )
00192 {
00193
00194 Double_t ret = _integrator->Integral(_xmin,_xmax) ;
00195 if (_integrator->Status()==1) {
00196 _nError++ ;
00197 if (_nError<=_nWarn) {
00198 coutW(NumIntegration) << "RooAdaptiveIntegratorND::integral(" << integrand()->getName() << ") WARNING: target rel. precision not reached due to nEval limit of "
00199 << _nmax << ", estimated rel. precision is " << Form("%3.1e",_integrator->RelError()) << endl ;
00200 }
00201 if (_nError==_nWarn) {
00202 coutW(NumIntegration) << "RooAdaptiveIntegratorND::integral(" << integrand()->getName()
00203 << ") Further warnings on target precision are suppressed conform specification in integrator specification" << endl ;
00204 }
00205 }
00206 return ret ;
00207 }
00208