Hi,

While working with RooAddPdf, I found that computing integrals was surprisingly slow, compared to performing the integrals on its component PDFs.

Basically the goal is to compute the fraction of the RooAddPdf within a subrange of the observable. This can be done by computing a normalized integral of the RooAddPdf for this range. Alternatively, one can perform these integrals on each of the PDFs that go into the sum, and then combining them by hand. I was expecting the latter to be slightly slower (due to the overhead of performing multiple independent computations instead of a single one) but it seems instead to be significantly faster.

I have tried to reproduce the effect in a simple example, which is given below and shows the “by hand” method to be about 50% faster than using RooAddPdf directly.

Would anybody know what is causing this, and if there is a way to work around it ? (the performance problems are a major issue in the real-life situation which prompted this).

Thanks,

• Nicolas
``````{
RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR);

RooRealVar mgg("mgg", "", 105, 160);
RooConstVar mH("mH", "", 125);
RooConstVar sigmaH("sigmaH", "", 1.5);
RooConstVar slope("slope", "", -0.02);
RooGaussian sigPdf("sigPdf", "", mgg, mH, sigmaH);
RooGenericPdf bkgPdf("bkgPdf", "", "exp(slope*mgg)", RooArgList(mgg, slope));
RooConstVar nSig("nSig", "", 100);
RooConstVar nBkg("nBkg", "", 10000);
RooAddPdf totPdf("totPdf", "", RooArgList(sigPdf, bkgPdf), RooArgList(nSig, nBkg));

f = mgg.frame();
totPdf.plotOn(f);
f->Draw();

mgg.setRange("peak", 120, 130);

TStopwatch t;
t.Start();
for (unsigned int i = 0; i < 50000; i++) {
RooAbsReal* integral = totPdf.createIntegral(mgg, mgg, "peak");
double value = integral->getVal();
if (i ==0) cout << value << endl;
delete integral;
}
cout << "elapsed time (RooAddPdf method) = " << t.RealTime() << " s." << endl;

t.Reset();
t.Start();
for (unsigned int i = 0; i < 50000; i++) {
RooAbsReal* sigInt = sigPdf.createIntegral(mgg, mgg, "peak");
RooAbsReal* bkgInt = bkgPdf.createIntegral(mgg, mgg, "peak");
double value = (nSig.getVal()*sigInt->getVal() + nBkg.getVal()*bkgInt->getVal())/(nSig.getVal() + nBkg.getVal());
if (i ==0) cout << value << endl;
delete sigInt;
delete bkgInt;
}
cout << "elapsed time (component method) = " << t.RealTime() << " s." << endl;
}
``````

Hi,
The problem is that when using the RooAddPdf you are computing an integral of an integral that is very slow. The RooAddPdf needs to compute the integral of its components, because each component needs to be normalised and then you are doing afterwards another integral.
If you would not use a RooGenericPdf, but a pdf supporting analytical integration this would not be a problem.

Lorenzo

Hi Lorenzo,

Thanks a lot for the fast reply. Unfortunately a RooGenericPdf needs to be supported in the real-life application on which this is based.

But I am still not sure I get how this is different: for the “by hand” case one also needs to normalize the components (including the RooGenericPdf) so one needs to compute 2 integrals for each component (over the full range, and over the limited range). Naively I don’t see why this would need a more complex treatment in the RooAddPdf case ?

Best,

• Nicolas

Actually when running your code, I get this:

``````0.209191
elapsed time (RooAddPdf method) = 11.7918 s.
0.209191
elapsed time (component method) = 11.847 s.
``````

so no difference in time. .What are you getting and which ROOT version are you using ?

Cheers

Lorenzo

Using 6.22/06 on my (Ubuntu 20.04) laptop, I get

``````0.209191
elapsed time (RooAddPdf method) = 5.16092 s.
0.209191
elapsed time (component method) = 3.41692 s.
``````

On lxplus with 6.22.06-x86_64-centos7-gcc8-opt I get a smaller relative difference,

``````0.209191
elapsed time (RooAddPdf method) = 8.06336 s.
0.209191
elapsed time (component method) = 5.85298 s.
``````

but still 40% or so slower using RooAddPdf.

Your result is the one I was expecting, if by any chance it means this is somehow resolved in the master already, it would be great.

Best,

• Nicolas

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.