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;
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];
203 else f2 = (*fFun)(
z);
204 z[j] = ctr[j] + xl2*wth[j];
206 else f2 += (*fFun)(
z);
207 wthl[j] = xl4*wth[j];
208 z[j] = ctr[j] - wthl[j];
210 else f3 = (*fFun)(
z);
211 z[j] = ctr[j] + wthl[j];
213 else f3 += (*fFun)(
z);
230 wthl[j1] = -wthl[j1];
231 z[j1] = ctr[j1] + wthl[j1];
234 z[k] = ctr[k] + wthl[k];
236 else sum4 += (*fFun)(
z);
247 wthl[j] = -xl5*wth[j];
248 z[j] = ctr[j] + wthl[j];
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;
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 < 1e-1 && aresult < 1e-20)
fStatus = 0;
325 if (relerr < 1e-3 && aresult < 1e-10)
fStatus = 0;
326 if (relerr < 1e-5 && aresult < 1e-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
void SetFunction(const IMultiGenFunction &f)
set the integration function (must implement multi-dim function interface: IBaseFunctionMultiDim) ...
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
void SetRelTolerance(double relTol)
set relative tolerance
static unsigned int DefaultWKSize()
double pow(double, double)
static Vc_ALWAYS_INLINE Vector< T > abs(const Vector< T > &x)
#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[] ...
Numerical multi dimensional integration options.
void SetIntegrator(const char *name)
set multi-dim integrator name
virtual unsigned int NDim() const =0
Retrieve the dimension of the function.
unsigned int NCalls() const
maximum number of function calls
double Error() const
return integration error
IntegrationMultiDim::Type IntegratorType() const
type of the integrator (return the enumeration type)
double RelTolerance() const
absolute tolerance
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
#define MATH_WARN_MSGVAL(loc, str, x)
ROOT::Math::IntegratorMultiDimOptions Options() const
get the option used for the integration
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
unsigned int WKSize() const
size of the workspace
double AbsTolerance() const
non-static methods for retrivieng options
Documentation for the abstract class IBaseFunctionMultiDim.
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
static unsigned int DefaultNCalls()
void SetAbsTolerance(double tol)
non-static methods for setting options