# Tolerance problem in integration. Can I solve it with Functor?

ROOT Version (6.10/08):
Platform, compiler (Mac OSX,
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin17.5.0):

Hello!
I have a question concerning randomisation.
I have a function:

``````Double_t angle_f(Double_t *x, Double_t *par){

Double_t om=par[0];
Double_t omf=par[1];
Double_t omg=par[2];
Double_t g=par[3];
Double_t lf=par[4];
Double_t lg=par[5];
Double_t N=par[6];

Double_t z1=4*h_h*c/om * 1/(pow(g,-2.)+pow(tt,2.)+pow(omf/om,2.));
Double_t z2=4*h_h*c/om * 1/(pow(g,-2.)+pow(tt,2.)+pow(omg/om,2.));

Double_t f_1=pow(sin(lf/z1),2.);
Double_t f_N=pow(sin(N*(lf/z1+lg/z2)),2.)/pow(sin(lf/z1+lg/z2),2.);

Double_t f=pow(om,2.)*pow(tt,3.)*pow(z1-z2,2.)*f_1*f_N;

return f;

}
``````

And I use it to generate distribution with FillRandom.

``````    TF1 *ang_f=new TF1("ang_f",angle_f,1e-5,4,7);
ang_f->SetParameters(11200,  20.87,  0.73,   39139   ,   62.,    1984.6, 150);
ang_f->SetParNames("omega","omegaf","omegag","gamma",  "lf",   "lg",  "N");
TH1F h_tt=new TH1F("name","name",200,1e-5,4);
h_tt->FillRandom("ang_f",1e6);

``````

This way I have an error

Error in : Error 18 in qags.c at 548 : cannot reach tolerance because of roundoff error
Warning in TF1::IntegralOneDim: Error found in integrating function ang_f in [2.740000,2.760000] using AdaptiveSingular. Result = 5.404230 +/- 0.000000 - status = 18
Info in TF1::IntegralOneDim: Function Parameters = { omega = 11200.000000 , omegaf = 20.870000 , omegag = 0.730000 , gamma = 39139.000000 , lf = 62.000000 , lg = 1984.666667 , N = 150.000000 }

It is clear that it is the problems with huge fluctuations of the function. And I want to avoid errors. Is it possible?
For example using Functor helps to integrate:

``````      Double_t par[] = {11200,  20.87,  0.73,   39139   ,   62.,    1984.6, 150.} ;
ROOT::Math::Functor func ( std::bind2nd ( std::ptr_fun(angle_f) , par ), 7 ) ;
ROOT::Math::Integrator ig (wf_, ROOT::Math::IntegrationOneDim::kADAPTIVESINGULAR, 1e-9, 1e-6, 1000) ;
printf ("\n%e\n",(double)ang_f->Eval(T)/ig.Integral(1e-5,4)) ;

``````

This pice of code above works with no errors. Is it possible to combine those methods?

Cheers
Evgeny

Hi,

Unfortunately inside TH1::FillRandom the default integration tolerance is used (eps=1.E-12), while in your direct call to the Integrator class you use (1.E-9 and 1.E-6).
I think 1.E-12 is probably a tolerance too small in general and I will change the default and make it using the static values from ROOT::Math::IntegratorOneDimOptions

Lorenzo

Hello Lorenzo, thanx for the reply.
Can I do it my self?
Or you mean you want to improve the procedure?

Evgeny

Hi,

I have updated now the code in the master. You can now set a default tolerance before calling TH1::FillRandom, by doing for example:

``````ROOT::Math::IntegratorOneDimOptions::SetDefaultRelTolerance(1.E-6);
``````

Lorenzo

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