25 fError(0), fRelError(0),
45 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++) {
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 MATH_ERROR_MSG(
"AdaptiveIntegratorMultiDim::DoIntegral()",
"Logic error: idvax0 < 1!");
370 wth[idvax0-1] = 0.5*wth[idvax0-1];
371 ctr[idvax0-1] -= wth[idvax0-1];
409 MATH_ERROR_MSG(
"AdaptiveIntegratorMultiDim::SetOptions",
"Invalid options");
#define MATH_ERROR_MSG(loc, str)
#define MATH_WARN_MSGVAL(loc, txt, x)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
void SetOptions(const ROOT::Math::IntegratorMultiDimOptions &opt)
set the options
void SetAbsTolerance(double absTol)
set absolute tolerance
const IMultiGenFunction * fFun
double DoIntegral(const double *xmin, const double *xmax, bool absVal=false)
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 SetSize(unsigned int size)
set workspace size
void SetMaxPts(unsigned int n)
set max points
void SetFunction(const IMultiGenFunction &f)
set the integration function (must implement multi-dim function interface: IBaseFunctionMultiDim)
ROOT::Math::IntegratorMultiDimOptions Options() const
get the option used for the integration
void SetRelTolerance(double relTol)
set relative tolerance
double Integral(const double *xmin, const double *xmax)
evaluate the integral with the previously given function between xmin[] and xmax[]
void SetAbsTolerance(double tol)
non-static methods for setting options
double RelTolerance() const
absolute tolerance
void SetRelTolerance(double tol)
set the relative tolerance
unsigned int WKSize() const
size of the workspace
double AbsTolerance() const
non-static methods for retrieving options
void SetWKSize(unsigned int size)
set workspace size
Documentation for the abstract class IBaseFunctionMultiDim.
Numerical multi dimensional integration options.
static unsigned int DefaultWKSize()
void SetIntegrator(const char *name)
set multi-dim integrator name
static unsigned int DefaultNCalls()
void SetNCalls(unsigned int calls)
set maximum number of function calls
unsigned int NCalls() const
maximum number of function calls
static double DefaultRelTolerance()
static double DefaultAbsTolerance()
IntegrationMultiDim::Type IntegratorType() const
type of the integrator (return the enumeration type)
@ kADAPTIVE
adaptive multi-dimensional integration
Namespace for new Math classes and functions.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...