50constexpr int nPoints = 5;
59double addMidpoints(std::function<
double(
double)>
const &func,
double savedResult,
int n,
double xmin,
double xmax)
65 return range * func(xmid);
69 for (
int j = 1; j <
n - 1; j++) {
73 double del = range / (3. * tnm);
77 for (
int j = 1; j <= it; j++) {
83 return (savedResult + range *
sum / tnm) / 3.;
92double addTrapezoids(std::function<
double(
double)>
const &func,
double savedResult,
int n,
double xmin,
double xmax)
98 return 0.5 * range * (func(
xmin) + func(
xmax));
103 const int nInt = 1 << (
n - 2);
104 const double del = range / nInt;
108 for (
int j = 0; j < nInt; ++j) {
113 return 0.5 * (savedResult + range *
sum / nInt);
119std::pair<double, double> extrapolate(
int n,
double const *
h,
double const *s,
double *
c,
double *
d)
121 double const *xa = &
h[
n - nPoints];
122 double const *ya = &s[
n - nPoints];
125 double dif = std::abs(xa[1]);
126 for (
int i = 1; i <= nPoints; i++) {
127 double dift = std::abs(xa[i]);
135 double extrapError = 0.0;
136 double extrapValue = ya[ns--];
137 for (
int m = 1;
m < nPoints;
m++) {
138 for (
int i = 1; i <= nPoints -
m; i++) {
140 double hp = xa[i +
m];
141 double w =
c[i + 1] -
d[i];
142 double den = ho - hp;
144 throw std::runtime_error(
"RooRombergIntegrator::extrapolate: internal error");
150 extrapError = 2 * ns < (nPoints -
m) ?
c[ns + 1] :
d[ns--];
151 extrapValue += extrapError;
153 return {extrapValue, extrapError};
161std::pair<double, int>
integrate1d(std::function<
double(
double)> func,
bool doTrapezoid,
int maxSteps,
int minStepsZero,
162 int fixSteps,
double epsAbs,
double epsRel,
bool doExtrap,
double xmin,
double xmax,
163 std::span<double> hArr, std::span<double> sArr)
165 assert(
int(hArr.size()) == maxSteps + 2);
166 assert(
int(sArr.size()) == maxSteps + 2);
171 std::array<double, nPoints + 1> cArr = {};
172 std::array<double, nPoints + 1> dArr = {};
175 double zeroThresh = epsAbs / range;
176 for (
int j = 1; j <= maxSteps; ++j) {
179 doTrapezoid ? addTrapezoids(func, sArr[j - 1], j,
xmin,
xmax) : addMidpoints(func, sArr[j - 1], j,
xmin,
xmax);
181 if (j >= minStepsZero) {
183 for (
int jj = 0; jj <= j; jj++) {
184 if (sArr[j] >= zeroThresh) {
203 }
else if (j >= nPoints) {
205 double extrapValue = 0.0;
206 double extrapError = 0.0;
210 std::tie(extrapValue, extrapError) = extrapolate(j, hArr.data(), sArr.data(), cArr.data(), dArr.data());
212 extrapValue = sArr[j];
213 extrapError = sArr[j] - sArr[j - 1];
216 if (std::abs(extrapError) <= epsRel * std::abs(extrapValue)) {
217 return {extrapValue, j};
219 if (std::abs(extrapError) <= epsAbs) {
220 return {extrapValue, j};
224 hArr[j + 1] = doTrapezoid ? hArr[j] / 4. : hArr[j] / 9.;
227 return {sArr[maxSteps], maxSteps};
246 RooCategory extrap(
"extrapolation",
"Extrapolation procedure");
250 RooRealVar maxSteps(
"maxSteps",
"Maximum number of steps", 20);
251 RooRealVar minSteps(
"minSteps",
"Minimum number of steps", 999);
252 RooRealVar fixSteps(
"fixSteps",
"Fixed number of steps", 0);
253 RooRealVar numSeg(
"numSeg",
"Number of segments", 3);
255 std::string
name =
"RooIntegrator1D";
258 return std::make_unique<RooRombergIntegrator>(function, config, 1,
false);
270 return std::make_unique<RooRombergIntegrator>(function, config, 2,
false);
272 std::string name2d =
"RooIntegrator2D";
282 return std::make_unique<RooRombergIntegrator>(function, config, 1,
true);
285 fact.
registerPlugin(
"RooSegmentedIntegrator1D", creatorSeg, {numSeg},
293 return std::make_unique<RooRombergIntegrator>(function, config, 2,
true);
301 "RooSegmentedIntegrator1D");
310 :
RooAbsIntegrator(function), _rule(rule), _maxSteps(maxSteps), _epsAbs(eps), _epsRel(eps)
323 int maxSteps,
double eps)
324 :
RooAbsIntegrator(function), _rule(rule), _maxSteps(maxSteps), _epsAbs(eps), _epsRel(eps)
341 _epsAbs(config.epsAbs()),
342 _epsRel(config.epsRel())
351 if (doSegmentation) {
358 oocoutE(
nullptr, Integration) <<
"RooRombergIntegrator::ctor() ERROR: fixSteps>maxSteps, fixSteps set to maxSteps"
375 _epsAbs(config.epsAbs()),
376 _epsRel(config.epsRel())
409 oocoutE(
nullptr, Integration) <<
"RooRombergIntegrator::initialize: cannot integrate invalid function"
431 oocoutE(
nullptr, Integration) <<
"RooRombergIntegrator::setLimits: cannot override integrand's limits"
437 for (
int iDim = 0; iDim <
_nDim; ++iDim) {
452 const_cast<std::vector<double> &
>(
_xmin).resize(
_nDim);
453 const_cast<std::vector<double> &
>(
_xmax).resize(
_nDim);
454 for (
int iDim = 0; iDim <
_nDim; ++iDim) {
459 for (
int iDim = 0; iDim <
_nDim; ++iDim) {
464 oocoutE(
nullptr, Integration) <<
"RooRombergIntegrator::checkLimits: bad range with min > max (_xmin[" << iDim
465 <<
"] = " <<
xmin <<
" _xmax[" << iDim <<
"] = " <<
xmax <<
")" << std::endl;
503 const double segSize = (
xmax -
xmin) / nSeg;
505 for (
int iSeg = 0; iSeg < nSeg; iSeg++) {
507 _xmax[iDim] =
xmin + (iSeg + 1) * segSize;
508 double part =
integral(iDim, 1, wksp);
521 double *hArr = wksp.data();
522 double *sArr = wksp.data() + nWorkingArr;
527 std::span<double> nextWksp{wksp.data() + 2 *
_maxSteps + 4, wksp.data() + wksp.size()};
529 auto func = [&](
double x) {
542 <<
" over range (" <<
xmin <<
"," <<
xmax <<
") did not converge after "
545 ooccoutW(
nullptr, Integration) <<
" [" << j <<
"] h = " << hArr[j] <<
" , s = " << sArr[j] << std::endl;
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t del
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
double getRealValue(const char *name, double defVal=0.0, bool verbose=false) const
Get value of a RooAbsReal stored in set with given name.
Int_t getCatIndex(const char *name, Int_t defVal=0, bool verbose=false) const
Get index value of a RooAbsCategory stored in set with given name.
Abstract interface for evaluating a real-valued function of one real variable and performing numerica...
virtual double getMaxLimit(UInt_t dimension) const =0
virtual double getMinLimit(UInt_t dimension) const =0
UInt_t getDimension() const
virtual const char * getName() const
Name of function binding.
Abstract interface for integrators of real-valued functions that implement the RooAbsFunc interface.
bool isValid() const
Is integrator in valid state.
const RooAbsFunc * _function
Pointer to function binding of integrand.
const RooAbsFunc * integrand() const
Return integrand function binding.
bool _valid
Is integrator in valid state?
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Object to represent discrete states.
bool defineType(const std::string &label)
Define a state with given name.
bool setLabel(const char *label, bool printError=true) override
Set value by specifying the name of the desired state.
RooNumIntConfig holds the configuration parameters of the various numeric integrators used by RooReal...
const RooArgSet & getConfigSection(const char *name) const
Retrieve configuration information specific to integrator with given name.
static RooNumIntConfig & defaultConfig()
Return reference to instance of default numeric integrator configuration object.
RooNumIntFactory is a factory to instantiate numeric integrators from a given function binding and a ...
bool registerPlugin(std::string const &name, Creator const &creator, const RooArgSet &defConfig, bool canIntegrate1D, bool canIntegrate2D, bool canIntegrateND, bool canIntegrateOpenEnded, const char *depName="")
Method accepting registration of a prototype numeric integrator along with a RooArgSet of its default...
static constexpr int isInfinite(double x)
Return true if x is infinite by RooNumber internal specification.
RooRealVar represents a variable that can be changed from the outside.
RooRombergIntegrator implements an adaptive numerical integration algorithm.
std::vector< double > _xmin
! Lower integration bounds
std::vector< double > _wksp
! Integrator workspace
RooRombergIntegrator(const RooAbsFunc &function, SummationRule rule=Trapezoid, int maxSteps=0, double eps=0)
Construct integrator on given function binding, using specified summation rule, maximum number of ste...
bool _useIntegrandLimits
If true limits of function binding are used.
static void registerIntegrator(RooNumIntFactory &fact)
Register integrator plugins, their parameters and capabilities with RooNumIntFactory.
double _epsRel
Relative convergence tolerance.
bool checkLimits() const override
Check that our integration range is finite and otherwise return false.
bool initialize()
Initialize the integrator.
double integral(const double *yvec=nullptr) override
bool _doExtrap
Apply conversion step?
int _nSeg
Number of segments.
std::vector< double > _xmax
! Upper integration bounds
bool setLimits(double *xmin, double *xmax) override
Change our integration limits.
int _fixSteps
Fixed number of steps.
double _epsAbs
Absolute convergence tolerance.
int _maxSteps
Maximum number of steps.
int _minStepsZero
Minimum number of steps to declare convergence to zero.
std::pair< double, int > integrate1d(std::function< double(double)> func, bool doTrapezoid, int maxSteps, int minStepsZero, int fixSteps, double epsAbs, double epsRel, bool doExtrap, double xmin, double xmax, std::span< double > hArr, std::span< double > sArr)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
static uint64_t sum(uint64_t i)