25 fError(0), fRelError(0),
99 double ctr[15], wth[15], wthl[15],
z[15];
101 static const double xl2 = 0.358568582800318073;
102 static const double xl4 = 0.948683298050513796;
103 static const double xl5 = 0.688247201611685289;
104 static const double w2 = 980./6561;
105 static const double w4 = 200./19683;
106 static const double wp2 = 245./486;
107 static const double wp4 = 25./729;
109 static const double wn1[14] = { -0.193872885230909911, -0.555606360818980835,
110 -0.876695625666819078, -1.15714067977442459, -1.39694152314179743,
111 -1.59609815576893754, -1.75461057765584494, -1.87247878880251983,
112 -1.94970278920896201, -1.98628257887517146, -1.98221815780114818,
113 -1.93750952598689219, -1.85215668343240347, -1.72615963013768225};
115 static const double wn3[14] = { 0.0518213686937966768, 0.0314992633236803330,
116 0.0111771579535639891,-0.00914494741655235473,-0.0294670527866686986,
117 -0.0497891581567850424,-0.0701112635269013768, -0.0904333688970177241,
118 -0.110755474267134071, -0.131077579637250419, -0.151399685007366752,
119 -0.171721790377483099, -0.192043895747599447, -0.212366001117715794};
121 static const double wn5[14] = { 0.871183254585174982e-01, 0.435591627292587508e-01,
122 0.217795813646293754e-01, 0.108897906823146873e-01, 0.544489534115734364e-02,
123 0.272244767057867193e-02, 0.136122383528933596e-02, 0.680611917644667955e-03,
124 0.340305958822333977e-03, 0.170152979411166995e-03, 0.850764897055834977e-04,
125 0.425382448527917472e-04, 0.212691224263958736e-04, 0.106345612131979372e-04};
127 static const double wpn1[14] = { -1.33196159122085045, -2.29218106995884763,
128 -3.11522633744855959, -3.80109739368998611, -4.34979423868312742,
129 -4.76131687242798352, -5.03566529492455417, -5.17283950617283939,
130 -5.17283950617283939, -5.03566529492455417, -4.76131687242798352,
131 -4.34979423868312742, -3.80109739368998611, -3.11522633744855959};
133 static const double wpn3[14] = { 0.0445816186556927292, -0.0240054869684499309,
134 -0.0925925925925925875, -0.161179698216735251, -0.229766803840877915,
135 -0.298353909465020564, -0.366941015089163228, -0.435528120713305891,
136 -0.504115226337448555, -0.572702331961591218, -0.641289437585733882,
137 -0.709876543209876532, -0.778463648834019195, -0.847050754458161859};
145 if (n < 2 || n > 15) {
146 MATH_WARN_MSGVAL(
"AdaptiveIntegratorMultiDim::Integral",
"Wrong function dimension",n);
150 double twondm =
std::pow(2.0,static_cast<int>(n));
153 unsigned int ifncls = 0;
155 unsigned int irgnst = 2*n+3;
156 unsigned int irlcls = (
unsigned int)(twondm) +2*n*(n+1)+1;
157 unsigned int isbrgn = irgnst;
158 unsigned int isbrgs = irgnst;
162 unsigned int maxpts = std::max(
fMaxPts, irlcls) ;
164 if (minpts < 1) minpts = irlcls;
165 if (maxpts < minpts) maxpts = 10*minpts;
171 unsigned int iwk = std::max(
fSize, irgnst*(1 +maxpts/irlcls)/2 );
172 double *wk =
new double[iwk+10];
175 for (j=0; j<n; j++) {
176 ctr[j] = (xmax[j] + xmin[j])*0.5;
177 wth[j] = (xmax[j] - xmin[j])*0.5;
180 double rgnvol, sum1, sum2, sum3, sum4, sum5, difmax, f2, f3, dif, aresult;
181 double rgncmp=0, rgnval, rgnerr;
183 unsigned int j1, k, l,
m, idvaxn=0, idvax0=0, isbtmp, isbtpp;
189 for (j=0; j<n; j++) {
193 sum1 = (*fFun)((
const double*)z);
200 for (j=0; j<n; j++) {
201 z[j] = ctr[j] - xl2*wth[j];
202 if (absValue) f2 = std::abs((*
fFun)(z));
203 else f2 = (*fFun)(
z);
204 z[j] = ctr[j] + xl2*wth[j];
205 if (absValue) f2 += std::abs((*
fFun)(z));
206 else f2 += (*fFun)(
z);
207 wthl[j] = xl4*wth[j];
208 z[j] = ctr[j] - wthl[j];
209 if (absValue) f3 = std::abs((*
fFun)(z));
210 else f3 = (*fFun)(
z);
211 z[j] = ctr[j] + wthl[j];
212 if (absValue) f3 += std::abs((*
fFun)(z));
213 else f3 += (*fFun)(
z);
216 dif = std::abs(7*f2-f3-12*sum1);
230 wthl[j1] = -wthl[j1];
231 z[j1] = ctr[j1] + wthl[j1];
234 z[k] = ctr[k] + wthl[k];
235 if (absValue) sum4 += std::abs((*
fFun)(z));
236 else sum4 += (*fFun)(
z);
247 wthl[j] = -xl5*wth[j];
248 z[j] = ctr[j] + wthl[j];
251 if (absValue) sum5 += std::abs((*
fFun)(z));
252 else sum5 += (*fFun)(
z);
255 z[j] = ctr[j] + wthl[j];
256 if (wthl[j] > 0)
goto L90;
259 rgncmp = rgnvol*(wpn1[n-2]*sum1+wp2*sum2+wpn3[n-2]*sum3+wp4*sum4);
260 rgnval = wn1[n-2]*sum1+w2*sum2+wn3[n-2]*sum3+w4*sum4+wn5[n-2]*sum5;
265 rgnerr = std::abs(rgnval-rgncmp);
270 aresult = std::abs(result);
281 if (isbtmp > isbrgs)
goto L160;
282 if (isbtmp < isbrgs) {
283 isbtpp = isbtmp + irgnst;
284 if (wk[isbtmp-1] < wk[isbtpp-1]) isbtmp = isbtpp;
286 if (rgnerr >= wk[isbtmp-1])
goto L160;
287 for (k=0;k<irgnst;k++) {
288 wk[isbrgn-k-1] = wk[isbtmp-k-1];
294 isbtmp = (isbrgn/(2*irgnst))*irgnst;
295 if (isbtmp >= irgnst && rgnerr > wk[isbtmp-1]) {
296 for (k=0;k<irgnst;k++) {
297 wk[isbrgn-k-1] = wk[isbtmp-k-1];
304 wk[isbrgn-1] = rgnerr;
305 wk[isbrgn-2] = rgnval;
306 wk[isbrgn-3] = double(idvaxn);
308 isbtmp = isbrgn-2*j-4;
310 wk[isbtmp-1] = wth[j];
314 ctr[idvax0-1] += 2*wth[idvax0-1];
321 if (aresult != 0) relerr = abserr/aresult;
324 if (relerr < 1
e-1 && aresult < 1
e-20)
fStatus = 0;
325 if (relerr < 1
e-3 && aresult < 1
e-10)
fStatus = 0;
326 if (relerr < 1
e-5 && aresult < 1
e-5)
fStatus = 0;
327 if (isbrgs+irgnst > iwk)
fStatus = 2;
328 if (ifncls+2*irlcls > maxpts) {
329 if (sum1==0 && sum2==0 && sum3==0 && sum4==0 && sum5==0){
338 if ( ( relerr < epsrel || abserr < epsabs ) && ifncls >= minpts)
fStatus = 0;
341 if (ifncls >= minpts) {
342 if (relerr < epsrel ) {
343 printf(
"relative tol reached for value %20.10g an rel error %20.10g \n",aresult, relerr);
346 if (abserr < epsabs ) {
347 printf(
"Absolute tol reached for value %20.10g and abs error %20.10g \n",aresult, abserr);
356 abserr -= wk[isbrgn-1];
357 result -= wk[isbrgn-2];
358 idvax0 = (
unsigned int)(wk[isbrgn-3]);
360 isbtmp = isbrgn-2*j-4;
362 wth[j] = wk[isbtmp-1];
367 ::Error(
"AdaptiveIntegratorMultiDim::DoIntegral()",
"Logic error: idvax0 < 1!");
369 wth[idvax0-1] = 0.5*wth[idvax0-1];
370 ctr[idvax0-1] -= wth[idvax0-1];
408 MATH_ERROR_MSG(
"AdaptiveIntegratorMultiDim::SetOptions",
"Invalid options");
static double DefaultAbsTolerance()
double DoIntegral(const double *xmin, const double *xmax, bool absVal=false)
const IMultiGenFunction * fFun
unsigned int NCalls() const
maximum number of function calls
void SetFunction(const IMultiGenFunction &f)
set the integration function (must implement multi-dim function interface: IBaseFunctionMultiDim) ...
Namespace for new ROOT classes and functions.
ROOT::Math::IntegratorMultiDimOptions Options() const
get the option used for the integration
void SetWKSize(unsigned int size)
set workspace size
void SetMaxPts(unsigned int n)
set max points
void SetAbsTolerance(double absTol)
set absolute tolerance
void SetNCalls(unsigned int calls)
set maximum number of function calls
double RelTolerance() const
absolute tolerance
IntegrationMultiDim::Type IntegratorType() const
type of the integrator (return the enumeration type)
void SetRelTolerance(double relTol)
set relative tolerance
static unsigned int DefaultWKSize()
double pow(double, double)
#define MATH_ERROR_MSG(loc, str)
double Integral(const double *xmin, const double *xmax)
evaluate the integral with the previously given function between xmin[] and xmax[] ...
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t Int_t m
unsigned int WKSize() const
size of the workspace
Documentation for the abstract class IBaseFunctionMultiDim.
Numerical multi dimensional integration options.
double AbsTolerance() const
non-static methods for retrivieng options
void SetIntegrator(const char *name)
set multi-dim integrator name
double Error() const
return integration error
#define MATH_WARN_MSGVAL(loc, str, x)
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Namespace for new Math classes and functions.
you should not use this method at all Int_t Int_t z
void SetSize(unsigned int size)
set workspace size
static double DefaultRelTolerance()
void SetOptions(const ROOT::Math::IntegratorMultiDimOptions &opt)
set the options
AdaptiveIntegratorMultiDim(double absTol=0.0, double relTol=1E-9, unsigned int maxpts=100000, unsigned int size=0)
Construct given optionally tolerance (absolute and relative), maximum number of function evaluation (...
void SetRelTolerance(double tol)
set the relative tolerance
virtual unsigned int NDim() const =0
Retrieve the dimension of the function.
static unsigned int DefaultNCalls()
void SetAbsTolerance(double tol)
non-static methods for setting options