10 virtual int operator() (
unsigned yn, Real *y, Real *e, Real_t x) =0;
12 FtnBase(
unsigned yn) : n(yn) { }
14 class Function :
public FtnBase {
16 typedef std::function<int(
unsigned yn, Real *y, Real *e, Real_t x,
void *fdata)> f1Type;
17 virtual int operator() (
unsigned yn, Real *y, Real *e, Real_t x)
override {
return function_(yn,y,e,x,fdata_); }
18 Function(
unsigned yn,
const f1Type &
function,
void *fdata) : FtnBase(yn), function_(function), fdata_(fdata) { }
20 void * fdata() {
return fdata_; }
26 class GK :
public GaussKronrod {
28 typedef void (*PrintHookerType) (Real*, Real*,
size_t *,
void *);
29 GK(
size_t n,
size_t m) : GaussKronrod(m) , limit(n) { }
30 int QAG(FtnBase &f, Real_t
a, Real_t b, Real_t epsabs, Real_t epsrel, Real *result, Real *abserr, PrintHookerType PrintHooker);
33 Real rescale_error(Real err, Real_t result_abs, Real_t result_asc);
34 int qag(FtnBase &f, Real_t
a, Real_t b, Real *result, Real *abserr);
37 Real GK::rescale_error (Real err, Real_t result_abs, Real_t result_asc) {
39 if (result_asc != Real(0) && err != Real(0)) {
41 Real exponent = Real(3)/Real(2);
42 Real scale = pow((200 * err / result_asc), exponent);
43 if (scale < Real(1)) err = result_asc * scale;
44 else err = result_asc;
46 if (result_abs > mpfr::minval() / (50 * mpfr::machine_epsilon())) {
47 Real min_err = 50 * mpfr::machine_epsilon() * result_abs;
48 if (min_err > err) err = min_err;
53 int GK::qag(FtnBase &f, Real_t
a, Real_t b, Real *result, Real *abserr) {
54 const Real center = (
a + b) / 2;
55 const Real half_length = (b -
a) / 2;
56 const Real abs_half_length = abs(half_length);
58 Real f_center[yn], ef_center[yn];
59 if(f(yn, f_center, ef_center, center))
return FAILURE;
61 Real result_gauss[yn], result_kronrod[yn], result_abs[yn], result_asc[yn], mean[yn], err[yn];
62 for(
int j=0; j<yn; j++) {
63 result_gauss[j] = Real(0);
64 result_kronrod[j] = f_center[j] * wgk_[n_ - 1];
65 result_abs[j] = abs(result_kronrod[j]);
66 result_asc[j] = mean[j] = err[j] = Real(0);
67 if (n_ % 2 == 0) result_gauss[j] = f_center[j] * wg_[n_/2 - 1];
70 Real fv1[yn*n_], e_fv1[yn*n_], fv2[yn*n_], e_fv2[yn*n_];
73 for(
int j=0; j<n_; j++) RC1[j] = RC2[j] = 0;
74 auto prec = mpfr::mpreal::get_default_prec();
75 auto rnd = mpfr::mpreal::get_default_rnd();
76 #pragma omp parallel for
77 for(
int jj = 0; jj < 2*n_; jj++) {
78 int j = jj/2, j2 = jj % 2;
79 mpfr::mpreal::set_default_prec(prec);
80 mpfr::mpreal::set_default_rnd(rnd);
81 Real abscissa = half_length * xgk_[j];
82 if(j2==0) RC1[j] = f(yn, fv1+yn*j, e_fv1+yn*j, center - abscissa);
83 else RC2[j] = f(yn, fv2+yn*j, e_fv2+yn*j, center + abscissa);
86 for(
int j=0; j<n_; j++)
if(RC1[j]!=0 || RC2[j]!=0)
return FAILURE;
88 for(
int jj=0; jj<yn; jj++) {
89 for(
int j = 0; j < (n_ - 1) / 2; j++) {
91 Real fval1 = fv1[yn*jtw+jj];
92 Real fval2 = fv2[yn*jtw+jj];
93 Real fsum = fval1 + fval2;
94 result_gauss[jj] += wg_[j] * fsum;
95 result_kronrod[jj] += wgk_[jtw] * fsum;
96 result_abs[jj] += wgk_[jtw] * (abs(fval1) + abs(fval2));
99 for (
int j = 0; j < n_ / 2; j++) {
101 Real fval1 = fv1[yn*jtwm1+jj];
102 Real fval2 = fv2[yn*jtwm1+jj];
103 result_kronrod[jj] += wgk_[jtwm1] * (fval1 + fval2);
104 result_abs[jj] += wgk_[jtwm1] * (abs(fval1) + abs(fval2));
108 Real fsum, fval1, fval2;
109 for (
int j = 0; j < (n_ - 1) / 2; j++) {
111 Real abscissa = half_length * xgk_[jtw];
112 f(yn, fv1+yn*jtw, e_fv1+yn*jtw, center - abscissa);
113 f(yn, fv2+yn*jtw, e_fv2+yn*jtw, center + abscissa);
114 for(
int jj=0; jj<yn; jj++) {
115 Real_t fval1 = fv1[yn*jtw+jj];
116 Real_t fval2 = fv2[yn*jtw+jj];
117 fsum = fval1 + fval2;
118 result_gauss[jj] += wg_[j] * fsum;
119 result_kronrod[jj] += wgk_[jtw] * fsum;
120 result_abs[jj] += wgk_[jtw] * (abs(fval1) + abs(fval2));
124 for (
int j = 0; j < n_ / 2; j++) {
126 Real abscissa = half_length * xgk_[jtwm1];
127 f(yn, fv1+yn*jtwm1, e_fv1+yn*jtwm1, center - abscissa);
128 f(yn, fv2+yn*jtwm1, e_fv2+yn*jtwm1, center + abscissa);
129 for(
int jj=0; jj<yn; jj++) {
130 Real_t fval1 = fv1[yn*jtwm1+jj];
131 Real_t fval2 = fv2[yn*jtwm1+jj];
132 result_kronrod[jj] += wgk_[jtwm1] * (fval1 + fval2);
133 result_abs[jj] += wgk_[jtwm1] * (abs(fval1) + abs(fval2));
138 for(
int jj=0; jj<yn; jj++) {
139 mean[jj] = result_kronrod[jj] / 2;
140 result_asc[jj] = wgk_[n_ - 1] * abs(f_center[jj] - mean[jj]);
141 for (
int j = 0; j < n_ - 1; j++) {
142 result_asc[jj] += wgk_[j] * (abs(fv1[yn*j+jj] - mean[jj]) + abs(fv2[yn*j+jj] - mean[jj]));
145 err[jj] = (result_kronrod[jj] - result_gauss[jj]) * half_length;
146 result_kronrod[jj] *= half_length;
147 result_abs[jj] *= abs_half_length;
148 result_asc[jj] *= abs_half_length;
149 result[jj] = result_kronrod[jj];
150 abserr[jj] = rescale_error (err[jj], result_abs[jj], result_asc[jj]);
156 inline Real max(
unsigned yn, Real *x) {
158 for(
int j=1; j<yn; j++)
if(max<x[j]) max = x[j];
162 int GK::QAG(FtnBase &f, Real_t
a, Real_t b, Real_t epsabs, Real_t epsrel, Real *result, Real *abserr, PrintHookerType PrintHooker) {
166 size_t maximum_level;
170 Real alist[n], blist[n], rlist[n][yn], elist[n][yn];
171 size_t order[n], level[n];
175 Real area[yn], errsum[yn], result0[yn], abserr0[yn], tolerance[yn];
176 size_t iteration = 0;
184 for(
int j=0; j<yn; j++) rlist[0][j] = elist[0][j] = Real(0);
189 for(
int j=0; j<yn; j++) result[j] = abserr[j] = Real(0);
191 if(this->qag(f,
a, b, result0, abserr0))
return FAILURE;
194 for(
int j=0; j<yn; j++) {
195 rlist[0][j] = result0[j];
196 elist[0][j] = abserr0[j];
201 for(
int j=0; j<yn; j++) tolerance[j] = max (epsabs, epsrel * abs(result0[j]));
203 for(
int j=0; j<yn; j++) {
204 if(abserr0[j]>tolerance[j]) { ok =
false;
break; }
208 for(
int j=0; j<yn; j++) {
209 result[j] = result0[j];
210 abserr[j] = abserr0[j];
213 auto fdata = ((Function&)f).fdata();
214 if(PrintHooker) PrintHooker(result, abserr, &kk, fdata);
218 for(
int j=0; j<yn; j++) {
219 area[j] = result0[j];
220 errsum[j] = abserr0[j];
226 Real a_i, b_i, r_i[yn], e_i[yn];
227 Real area1[yn], area2[yn], area12[yn];
228 Real error1[yn], error2[yn], error12[yn];
230 for(
int j=0; j<yn; j++) {
231 area1[j] = area2[j] = area12[j] = error1[j] = error2[j] = error12[j] = Real(0);
239 for(
int j=0; j<yn; j++) {
240 r_i[j] = rlist[i_work][j];
241 e_i[j] = elist[i_work][j];
246 b1 = (a_i + b_i) / Real(2);
250 if(this->qag(f, a1, b1, area1, error1))
return FAILURE;
251 if(this->qag(f, a2, b2, area2, error2))
return FAILURE;
253 for(
int j=0; j<yn; j++) {
254 area12[j] = area1[j] + area2[j];
255 error12[j] = error1[j] + error2[j];
257 errsum[j] += (error12[j] - e_i[j]);
258 area[j] += area12[j] - r_i[j];
260 tolerance[j] = max (epsabs, epsrel * abs(area[j]));
264 const size_t i_max = i_work;
265 const size_t i_new = size;
267 const size_t new_level = level[i_max] + 1;
271 if (max(yn,error2) > max(yn,error1)) {
273 for(
int j=0; j<yn; j++) {
274 rlist[i_max][j] = area2[j];
275 elist[i_max][j] = error2[j];
277 level[i_max] = new_level;
281 for(
int j=0; j<yn; j++) {
282 rlist[i_new][j] = area1[j];
283 elist[i_new][j] = error1[j];
285 level[i_new] = new_level;
288 for(
int j=0; j<yn; j++) {
289 rlist[i_max][j] = area1[j];
290 elist[i_max][j] = error1[j];
292 level[i_max] = new_level;
296 for(
int j=0; j<yn; j++) {
297 rlist[i_new][j] = area2[j];
298 elist[i_new][j] = error2[j];
300 level[i_new] = new_level;
305 if (new_level > maximum_level) maximum_level = new_level;
308 const size_t last = size - 1;
313 size_t i_nrmax = nrmax;
314 size_t i_maxerr = order[i_nrmax];
322 errmax = max(yn,elist[i_maxerr]);
323 while (i_nrmax > 0 && errmax > max(yn,elist[order[i_nrmax - 1]])) {
324 order[i_nrmax] = order[i_nrmax - 1];
327 if(last < (limit/2 + 2)) top = last;
328 else top = limit - last + 1;
330 while (i < top && errmax < max(yn,elist[order[i]])) {
331 order[i-1] = order[i];
334 order[i-1] = i_maxerr;
335 errmin = max(yn,elist[last]);
337 while (k > i - 2 && errmin >= max(yn,elist[order[k]])) {
338 order[k+1] = order[k];
343 i_maxerr = order[i_nrmax];
353 for(
int j=0; j<yn; j++) {
354 r_i[j] = rlist[i_work][j];
355 e_i[j] = elist[i_work][j];
360 size_t kk = iteration;
361 auto fdata = ((Function&)f).fdata();
362 PrintHooker(area, errsum, &kk, fdata);
364 for(
int j=0; j<yn; j++) {
366 abserr[j] = errsum[j];
372 for(
int j=0; j<yn; j++) {
373 if(errsum[j]>tolerance[j]) { ok =
false;
break; }
376 }
while (iteration < limit && !ok);
378 for(
int j=0; j<yn; j++) {
380 for (
size_t k = 0; k < size; k++) result[j] += rlist[k][j];
381 abserr[j] = errsum[j];