46 ClassImp(RooIntegrator1D);
54 void RooIntegrator1D::registerIntegrator(RooNumIntFactory& fact)
56 RooCategory sumRule(
"sumRule",
"Summation Rule") ;
57 sumRule.defineType(
"Trapezoid",RooIntegrator1D::Trapezoid) ;
58 sumRule.defineType(
"Midpoint",RooIntegrator1D::Midpoint) ;
59 sumRule.setLabel(
"Trapezoid") ;
60 RooCategory extrap(
"extrapolation",
"Extrapolation procedure") ;
61 extrap.defineType(
"None",0) ;
62 extrap.defineType(
"Wynn-Epsilon",1) ;
63 extrap.setLabel(
"Wynn-Epsilon") ;
64 RooRealVar maxSteps(
"maxSteps",
"Maximum number of steps",20) ;
65 RooRealVar minSteps(
"minSteps",
"Minimum number of steps",999) ;
66 RooRealVar fixSteps(
"fixSteps",
"Fixed number of steps",0) ;
68 RooIntegrator1D* proto =
new RooIntegrator1D() ;
69 fact.storeProtoIntegrator(proto,RooArgSet(sumRule,extrap,maxSteps,minSteps,fixSteps)) ;
70 RooNumIntConfig::defaultConfig().method1D().setLabel(proto->IsA()->GetName()) ;
79 RooIntegrator1D::RooIntegrator1D() :
80 _h(0), _s(0), _c(0), _d(0), _x(0)
90 RooIntegrator1D::RooIntegrator1D(
const RooAbsFunc&
function, SummationRule rule,
91 Int_t maxSteps, Double_t eps) :
92 RooAbsIntegrator(function), _rule(rule), _maxSteps(maxSteps), _minStepsZero(999), _fixSteps(0), _epsAbs(eps), _epsRel(eps), _doExtrap(kTRUE)
94 _useIntegrandLimits= kTRUE;
105 RooIntegrator1D::RooIntegrator1D(
const RooAbsFunc&
function, Double_t xmin, Double_t xmax,
106 SummationRule rule, Int_t maxSteps, Double_t eps) :
107 RooAbsIntegrator(function),
116 _useIntegrandLimits= kFALSE;
119 _valid= initialize();
128 RooIntegrator1D::RooIntegrator1D(
const RooAbsFunc&
function,
const RooNumIntConfig& config) :
129 RooAbsIntegrator(function,config.printEvalCounter()),
130 _epsAbs(config.epsAbs()),
131 _epsRel(config.epsRel())
134 const RooArgSet& configSet = config.getConfigSection(IsA()->GetName()) ;
135 _rule = (SummationRule) configSet.getCatIndex(
"sumRule",Trapezoid) ;
136 _maxSteps = (Int_t) configSet.getRealValue(
"maxSteps",20) ;
137 _minStepsZero = (Int_t) configSet.getRealValue(
"minSteps",999) ;
138 _fixSteps = (Int_t) configSet.getRealValue(
"fixSteps",0) ;
139 _doExtrap = (Bool_t) configSet.getCatIndex(
"extrapolation",1) ;
141 if (_fixSteps>_maxSteps) {
142 oocoutE((TObject*)0,Integration) <<
"RooIntegrator1D::ctor() ERROR: fixSteps>maxSteps, fixSteps set to maxSteps" << endl ;
143 _fixSteps = _maxSteps ;
146 _useIntegrandLimits= kTRUE;
147 _valid= initialize();
156 RooIntegrator1D::RooIntegrator1D(
const RooAbsFunc&
function, Double_t xmin, Double_t xmax,
157 const RooNumIntConfig& config) :
158 RooAbsIntegrator(function,config.printEvalCounter()),
159 _epsAbs(config.epsAbs()),
160 _epsRel(config.epsRel())
163 const RooArgSet& configSet = config.getConfigSection(IsA()->GetName()) ;
164 _rule = (SummationRule) configSet.getCatIndex(
"sumRule",Trapezoid) ;
165 _maxSteps = (Int_t) configSet.getRealValue(
"maxSteps",20) ;
166 _minStepsZero = (Int_t) configSet.getRealValue(
"minSteps",999) ;
167 _fixSteps = (Int_t) configSet.getRealValue(
"fixSteps",0) ;
168 _doExtrap = (Bool_t) configSet.getCatIndex(
"extrapolation",1) ;
170 _useIntegrandLimits= kFALSE;
173 _valid= initialize();
181 RooAbsIntegrator* RooIntegrator1D::clone(
const RooAbsFunc&
function,
const RooNumIntConfig& config)
const
183 return new RooIntegrator1D(
function,config) ;
191 Bool_t RooIntegrator1D::initialize()
195 _maxSteps= (_rule == Trapezoid) ? 20 : 14;
198 if(_epsRel <= 0) _epsRel= 1e-6;
199 if(_epsAbs <= 0) _epsAbs= 1e-6;
203 oocoutE((TObject*)0,Integration) <<
"RooIntegrator1D::initialize: cannot integrate invalid function" << endl;
208 _x =
new Double_t[_function->getDimension()] ;
212 _h=
new Double_t[_maxSteps + 2];
213 _s=
new Double_t[_maxSteps + 2];
214 _c=
new Double_t[_nPoints + 1];
215 _d=
new Double_t[_nPoints + 1];
217 return checkLimits();
224 RooIntegrator1D::~RooIntegrator1D()
240 Bool_t RooIntegrator1D::setLimits(Double_t *xmin, Double_t *xmax)
242 if(_useIntegrandLimits) {
243 oocoutE((TObject*)0,Integration) <<
"RooIntegrator1D::setLimits: cannot override integrand's limits" << endl;
248 return checkLimits();
256 Bool_t RooIntegrator1D::checkLimits()
const
258 if(_useIntegrandLimits) {
259 assert(0 != integrand() && integrand()->isValid());
260 const_cast<double&
>(_xmin) = integrand()->getMinLimit(0);
261 const_cast<double&
>(_xmax) = integrand()->getMaxLimit(0);
263 const_cast<double&
>(_range) = _xmax - _xmin;
265 oocoutE((TObject*)0,Integration) <<
"RooIntegrator1D::checkLimits: bad range with min > max (_xmin = " << _xmin <<
" _xmax = " << _xmax <<
")" << endl;
268 return (RooNumber::isInfinite(_xmin) || RooNumber::isInfinite(_xmax)) ? kFALSE : kTRUE;
275 Double_t RooIntegrator1D::integral(
const Double_t *yvec)
284 for (UInt_t i = 0 ; i<_function->getDimension()-1 ; i++) {
291 Double_t zeroThresh = _epsAbs/_range ;
292 for(Int_t j = 1; j <= _maxSteps; ++j) {
294 _s[j]= (_rule == Trapezoid) ? addTrapezoids(j) : addMidpoints(j);
296 if (j >= _minStepsZero) {
297 Bool_t allZero(kTRUE) ;
298 for (
int jj=0 ; jj<=j ; jj++) {
299 if (_s[j]>=zeroThresh) {
317 }
else if(j >= _nPoints) {
323 _extrapValue = _s[j] ;
324 _extrapError = _s[j]-_s[j-1] ;
327 if(fabs(_extrapError) <= _epsRel*fabs(_extrapValue)) {
330 if(fabs(_extrapError) <= _epsAbs) {
331 return _extrapValue ;
336 _h[j+1]= (_rule == Trapezoid) ? _h[j]/4. : _h[j]/9.;
339 oocoutW((TObject*)0,Integration) <<
"RooIntegrator1D::integral: integral of " << _function->getName() <<
" over range (" << _xmin <<
"," << _xmax <<
") did not converge after "
340 << _maxSteps <<
" steps" << endl;
341 for(Int_t j = 1; j <= _maxSteps; ++j) {
342 ooccoutW((TObject*)0,Integration) <<
" [" << j <<
"] h = " << _h[j] <<
" , s = " << _s[j] << endl;
345 return _s[_maxSteps] ;
356 Double_t RooIntegrator1D::addMidpoints(Int_t n)
358 Double_t x,tnm,sum,del,ddel;
362 Double_t xmid= 0.5*(_xmin + _xmax);
363 return (_savedResult= _range*integrand(xvec(xmid)));
366 for(it=1, j=1; j < n-1; j++) it*= 3;
368 del= _range/(3.*tnm);
371 for(sum= 0, j= 1; j <= it; j++) {
372 sum+= integrand(xvec(x));
374 sum+= integrand(xvec(x));
377 return (_savedResult= (_savedResult + _range*sum/tnm)/3.);
388 Double_t RooIntegrator1D::addTrapezoids(Int_t n)
392 return (_savedResult= 0.5*_range*(integrand(xvec(_xmin)) + integrand(xvec(_xmax))));
397 const int nInt = std::pow(2, n-2);
398 const double del = _range/nInt;
399 const double xmin = _xmin;
403 for (
int j=0; j<nInt; ++j) {
404 double x = xmin + (0.5+j)*del;
405 sum += integrand(xvec(x));
408 return (_savedResult= 0.5*(_savedResult + _range*sum/nInt));
417 void RooIntegrator1D::extrapolate(Int_t n)
419 Double_t *xa= &_h[n-_nPoints];
420 Double_t *ya= &_s[n-_nPoints];
422 Double_t den,dif,dift,ho,hp,w;
425 for (i= 1; i <= _nPoints; i++) {
426 if ((dift=fabs(xa[i])) < dif) {
433 _extrapValue= ya[ns--];
434 for(m= 1; m < _nPoints; m++) {
435 for(i= 1; i <= _nPoints-m; i++) {
439 if((den=ho-hp) == 0.0) {
440 oocoutE((TObject*)0,Integration) <<
"RooIntegrator1D::extrapolate: internal error" << endl;
446 _extrapValue += (_extrapError=(2*ns < (_nPoints-m) ? _c[ns+1] : _d[ns--]));