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};
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;
323 if (isbrgs+irgnst > iwk)
fStatus = 2;
324 if (ifncls+2*irlcls > maxpts) {
325 if (sum1==0 && sum2==0 && sum3==0 && sum4==0 && sum5==0){
334 if ( ( relerr < epsrel || abserr < epsabs ) && ifncls >= minpts)
fStatus = 0;
337 if (ifncls >= minpts) {
338 if (relerr < epsrel ) {
339 printf(
"relative tol reached for value %20.10g an rel error %20.10g \n",aresult, relerr);
342 if (abserr < epsabs ) {
343 printf(
"Absolute tol reached for value %20.10g and abs error %20.10g \n",aresult, abserr);
352 abserr -= wk[isbrgn-1];
353 result -= wk[isbrgn-2];
354 idvax0 = (
unsigned int)(wk[isbrgn-3]);
356 isbtmp = isbrgn-2*j-4;
358 width[j] = wk[isbtmp-1];
363 MATH_ERROR_MSG(
"AdaptiveIntegratorMultiDim::DoIntegral()",
"Logic error: idvax0 < 1!");
366 width[idvax0-1] = 0.5*width[idvax0-1];
367 ctr[idvax0-1] -= width[idvax0-1];