25 fError(0), fRelError(0),
45 fError(0), fRelError(0),
99 double ctr[15],
width[15], widthl[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*
width[j];
202 if (absValue) f2 = std::abs((*
fFun)(z));
203 else f2 = (*fFun)(z);
204 z[j] = ctr[j] + xl2*
width[j];
205 if (absValue) f2 += std::abs((*
fFun)(z));
206 else f2 += (*fFun)(z);
207 widthl[j] = xl4*
width[j];
208 z[j] = ctr[j] - widthl[j];
209 if (absValue) f3 = std::abs((*
fFun)(z));
210 else f3 = (*fFun)(z);
211 z[j] = ctr[j] + widthl[j];
212 if (absValue) f3 += std::abs((*
fFun)(z));
213 else f3 += (*fFun)(z);
216 dif = std::abs(7*f2-f3-12*sum1);
230 widthl[j1] = -widthl[j1];
231 z[j1] = ctr[j1] + widthl[j1];
233 widthl[k] = -widthl[k];
234 z[k] = ctr[k] + widthl[k];
235 if (absValue) sum4 += std::abs((*
fFun)(z));
236 else sum4 += (*fFun)(z);
247 widthl[j] = -xl5*
width[j];
248 z[j] = ctr[j] + widthl[j];
251 if (absValue) sum5 += std::abs((*
fFun)(z));
252 else sum5 += (*fFun)(z);
254 widthl[j] = -widthl[j];
255 z[j] = ctr[j] + widthl[j];
256 if (widthl[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] =
width[j];
314 ctr[idvax0-1] += 2*
width[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];
358 idvax0 = (
unsigned int)(wk[isbrgn-3]);
360 isbtmp = isbrgn-2*j-4;
362 width[j] = wk[isbtmp-1];
367 MATH_ERROR_MSG(
"AdaptiveIntegratorMultiDim::DoIntegral()",
"Logic error: idvax0 < 1!");
371 ctr[idvax0-1] -=
width[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
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
ROOT::Math::IntegratorMultiDimOptions Options() const override
get the option used for the integration
double fError
integration error
unsigned int fMinPts
minimum number of function evaluation requested
const IMultiGenFunction * fFun
double DoIntegral(const double *xmin, const double *xmax, bool absVal=false)
double Integral(const double *xmin, const double *xmax) override
evaluate the integral with the previously given function between xmin[] and xmax[]
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 (...
unsigned int fMaxPts
maximum number of function evaluation requested
void SetSize(unsigned int size)
set workspace size
void SetRelTolerance(double relTol) override
set relative tolerance
void SetFunction(const IMultiGenFunction &f) override
set the integration function (must implement multi-dim function interface: IBaseFunctionMultiDim)
double fResult
last integration result
void SetMaxPts(unsigned int n)
set max points
void SetAbsTolerance(double absTol) override
set absolute tolerance
double fRelError
Relative error.
int fNEval
number of function evaluation
double fAbsTol
absolute tolerance
double fRelTol
relative tolerance
unsigned int fSize
max size of working array (explode with dimension)
void SetOptions(const ROOT::Math::IntegratorMultiDimOptions &opt) override
set the options
int fStatus
status of algorithm (error if not zero)
unsigned int fDim
dimensionality of integrand
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.
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.