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
00027 #include "RooFit.h"
00028
00029 #include "RooImproperIntegrator1D.h"
00030 #include "RooImproperIntegrator1D.h"
00031 #include "RooIntegrator1D.h"
00032 #include "RooInvTransform.h"
00033 #include "RooNumber.h"
00034 #include "RooNumIntFactory.h"
00035 #include "RooArgSet.h"
00036 #include "RooMsgService.h"
00037
00038 #include "Riostream.h"
00039 #include <math.h>
00040 #include "TClass.h"
00041
00042
00043
00044 ClassImp(RooImproperIntegrator1D)
00045 ;
00046
00047
00048
00049
00050 void RooImproperIntegrator1D::registerIntegrator(RooNumIntFactory& fact)
00051 {
00052
00053
00054 RooImproperIntegrator1D* proto = new RooImproperIntegrator1D() ;
00055 fact.storeProtoIntegrator(proto,RooArgSet(),RooIntegrator1D::Class()->GetName()) ;
00056 }
00057
00058
00059
00060
00061 RooImproperIntegrator1D::RooImproperIntegrator1D() :
00062 _case(ClosedBothEnds), _xmin(-10), _xmax(10), _useIntegrandLimits(kTRUE),
00063 _origFunc(0), _function(0), _integrator1(0), _integrator2(0), _integrator3(0)
00064 {
00065
00066 }
00067
00068
00069
00070 RooImproperIntegrator1D::RooImproperIntegrator1D(const RooAbsFunc& function) :
00071 RooAbsIntegrator(function),
00072 _useIntegrandLimits(kTRUE),
00073 _origFunc((RooAbsFunc*)&function),
00074 _function(0),
00075 _integrator1(0),
00076 _integrator2(0),
00077 _integrator3(0)
00078 {
00079
00080
00081 initialize(&function) ;
00082 }
00083
00084
00085
00086
00087 RooImproperIntegrator1D::RooImproperIntegrator1D(const RooAbsFunc& function, const RooNumIntConfig& config) :
00088 RooAbsIntegrator(function),
00089 _useIntegrandLimits(kTRUE),
00090 _origFunc((RooAbsFunc*)&function),
00091 _function(0),
00092 _config(config),
00093 _integrator1(0),
00094 _integrator2(0),
00095 _integrator3(0)
00096 {
00097
00098
00099 initialize(&function) ;
00100 }
00101
00102
00103
00104
00105 RooImproperIntegrator1D::RooImproperIntegrator1D(const RooAbsFunc& function, Double_t xmin, Double_t xmax, const RooNumIntConfig& config) :
00106 RooAbsIntegrator(function),
00107 _xmin(xmin),
00108 _xmax(xmax),
00109 _useIntegrandLimits(kFALSE),
00110 _origFunc((RooAbsFunc*)&function),
00111 _function(0),
00112 _config(config),
00113 _integrator1(0),
00114 _integrator2(0),
00115 _integrator3(0)
00116 {
00117
00118 initialize(&function) ;
00119 }
00120
00121
00122
00123
00124 RooAbsIntegrator* RooImproperIntegrator1D::clone(const RooAbsFunc& function, const RooNumIntConfig& config) const
00125 {
00126
00127 return new RooImproperIntegrator1D(function,config) ;
00128 }
00129
00130
00131
00132
00133 void RooImproperIntegrator1D::initialize(const RooAbsFunc* function)
00134 {
00135
00136
00137 if(!isValid()) {
00138 oocoutE((TObject*)0,Integration) << "RooImproperIntegrator: cannot integrate invalid function" << endl;
00139 return;
00140 }
00141
00142 if (function) {
00143 _function= new RooInvTransform(*function);
00144 } else {
00145 function = _origFunc ;
00146 if (_integrator1) {
00147 delete _integrator1 ;
00148 _integrator1 = 0 ;
00149 }
00150 if (_integrator2) {
00151 delete _integrator2 ;
00152 _integrator2 = 0 ;
00153 }
00154 if (_integrator3) {
00155 delete _integrator3 ;
00156 _integrator3 = 0 ;
00157 }
00158 }
00159
00160
00161
00162 switch(_case= limitsCase()) {
00163 case ClosedBothEnds:
00164
00165 _integrator1= new RooIntegrator1D(*function,_xmin,_xmax,_config);
00166 break;
00167 case OpenBothEnds:
00168
00169
00170 _integrator1= new RooIntegrator1D(*function,-1,+1,RooIntegrator1D::Trapezoid);
00171
00172 _integrator2= new RooIntegrator1D(*_function,-1,0,RooIntegrator1D::Midpoint);
00173 _integrator3= new RooIntegrator1D(*_function,0,+1,RooIntegrator1D::Midpoint);
00174 break;
00175 case OpenBelowSpansZero:
00176
00177 _integrator1= new RooIntegrator1D(*_function,-1,0,RooIntegrator1D::Midpoint);
00178 _integrator2= new RooIntegrator1D(*function,-1,_xmax,RooIntegrator1D::Trapezoid);
00179 break;
00180 case OpenBelow:
00181
00182 _integrator1= new RooIntegrator1D(*_function,1/_xmax,0,RooIntegrator1D::Midpoint);
00183 break;
00184 case OpenAboveSpansZero:
00185
00186 _integrator1= new RooIntegrator1D(*_function,0,+1,RooIntegrator1D::Midpoint);
00187 _integrator2= new RooIntegrator1D(*function,_xmin,+1,RooIntegrator1D::Trapezoid);
00188 break;
00189 case OpenAbove:
00190
00191 _integrator1= new RooIntegrator1D(*_function,0,1/_xmin,RooIntegrator1D::Midpoint);
00192 break;
00193 case Invalid:
00194 default:
00195 _valid= kFALSE;
00196 }
00197 }
00198
00199
00200
00201 RooImproperIntegrator1D::~RooImproperIntegrator1D()
00202 {
00203
00204
00205 if(0 != _integrator1) delete _integrator1;
00206 if(0 != _integrator2) delete _integrator2;
00207 if(0 != _integrator3) delete _integrator3;
00208 if(0 != _function) delete _function;
00209 }
00210
00211
00212
00213 Bool_t RooImproperIntegrator1D::setLimits(Double_t *xmin, Double_t *xmax)
00214 {
00215
00216
00217
00218
00219 if(_useIntegrandLimits) {
00220 oocoutE((TObject*)0,Integration) << "RooIntegrator1D::setLimits: cannot override integrand's limits" << endl;
00221 return kFALSE;
00222 }
00223
00224 _xmin= *xmin;
00225 _xmax= *xmax;
00226 return checkLimits();
00227 }
00228
00229
00230
00231 Bool_t RooImproperIntegrator1D::checkLimits() const
00232 {
00233
00234
00235
00236
00237
00238
00239 if (_useIntegrandLimits) {
00240 if(_xmin == integrand()->getMinLimit(0) &&
00241 _xmax == integrand()->getMaxLimit(0)) return kTRUE;
00242 }
00243
00244
00245 if(limitsCase() != _case) {
00246
00247 const_cast<RooImproperIntegrator1D*>(this)->initialize() ;
00248 return kTRUE ;
00249 }
00250
00251
00252 switch(_case) {
00253 case ClosedBothEnds:
00254 _integrator1->setLimits(_xmin,_xmax);
00255 break;
00256 case OpenBothEnds:
00257
00258 break;
00259 case OpenBelowSpansZero:
00260 _integrator2->setLimits(-1,_xmax);
00261 break;
00262 case OpenBelow:
00263 _integrator1->setLimits(1/_xmax,0);
00264 break;
00265 case OpenAboveSpansZero:
00266 _integrator2->setLimits(_xmin,+1);
00267 break;
00268 case OpenAbove:
00269 _integrator1->setLimits(0,1/_xmin);
00270 break;
00271 case Invalid:
00272 default:
00273 return kFALSE;
00274 }
00275 return kTRUE;
00276 }
00277
00278
00279
00280 RooImproperIntegrator1D::LimitsCase RooImproperIntegrator1D::limitsCase() const
00281 {
00282
00283
00284
00285 if(0 == integrand() || !integrand()->isValid()) return Invalid;
00286
00287 if (_useIntegrandLimits) {
00288 _xmin= integrand()->getMinLimit(0);
00289 _xmax= integrand()->getMaxLimit(0);
00290 }
00291
00292 Bool_t inf1= RooNumber::isInfinite(_xmin);
00293 Bool_t inf2= RooNumber::isInfinite(_xmax);
00294 if(!inf1 && !inf2) {
00295
00296 return ClosedBothEnds;
00297 }
00298 else if(inf1 && inf2) {
00299
00300 return OpenBothEnds;
00301 }
00302 else if(inf1) {
00303 if(_xmax >= 0) {
00304 return OpenBelowSpansZero;
00305 }
00306 else {
00307 return OpenBelow;
00308 }
00309 }
00310 else {
00311 if(_xmin <= 0) {
00312 return OpenAboveSpansZero;
00313 }
00314 else {
00315 return OpenAbove;
00316 }
00317 }
00318
00319 }
00320
00321
00322
00323 Double_t RooImproperIntegrator1D::integral(const Double_t* yvec)
00324 {
00325
00326
00327 Double_t result(0);
00328 if(0 != _integrator1) result+= _integrator1->integral(yvec);
00329 if(0 != _integrator2) result+= _integrator2->integral(yvec);
00330 if(0 != _integrator3) result+= _integrator3->integral(yvec);
00331 return result;
00332 }