10 virtual int operator() (
unsigned yn, Real *y, Real *e, Real_t x) = 0;
12 FtnBase(
unsigned yn) : n(yn) { }
15 class Function :
public FtnBase {
17 typedef std::function<int(
unsigned yn, Real *y, Real *e, Real_t x,
void *fdata)> f1Type;
18 virtual int operator() (
unsigned yn, Real *y, Real *e, Real_t x)
override {
return function_(yn, y, e, x, fdata_); }
19 Function(
unsigned yn,
const f1Type & function,
void *fdata)
20 : FtnBase(yn), function_(function), fdata_(fdata) { }
22 void * fdata() {
return fdata_; }
28 class GK :
public GaussKronrod {
30 typedef void (*PrintHookerType) (Real*, Real*,
size_t *,
void *);
31 GK(
size_t n,
size_t m) : GaussKronrod(m), limit(n) { }
32 int QAG(FtnBase &f, Real_t
a, Real_t b, Real_t epsabs, Real_t epsrel, Real *result, Real *abserr, PrintHookerType PrintHooker);
35 Real rescale_error(Real err, Real_t result_abs, Real_t result_asc);
36 int qag(FtnBase &f, Real_t
a, Real_t b, Real *result, Real *abserr);
39 Real GK::rescale_error(Real err, Real_t result_abs, Real_t result_asc) {
41 if (result_asc != Real(0) && err != Real(0)) {
43 Real exponent = Real(3)/Real(2);
44 Real scale = pow((200 * err / result_asc), exponent);
45 if (scale < Real(1)) err = result_asc * scale;
46 else err = result_asc;
48 if (result_abs > mpfr::minval() / (50 * mpfr::machine_epsilon())) {
49 Real min_err = 50 * mpfr::machine_epsilon() * result_abs;
50 if (min_err > err) err = min_err;
55 int GK::qag(FtnBase &f, Real_t
a, Real_t b, Real *result, Real *abserr) {
56 const Real center = (
a + b) / 2;
57 const Real half_length = (b -
a) / 2;
58 const Real abs_half_length = abs(half_length);
61 std::vector<Real> f_center(yn), ef_center(yn);
62 if (f(yn, f_center.data(), ef_center.data(), center))
return FAILURE;
64 std::vector<Real> result_gauss(yn), result_kronrod(yn), result_abs(yn), result_asc(yn), mean(yn), err(yn);
65 for (
int j = 0; j < yn; j++) {
66 result_gauss[j] = Real(0);
67 result_kronrod[j] = f_center[j] * wgk_[n_ - 1];
68 result_abs[j] = abs(result_kronrod[j]);
69 result_asc[j] = mean[j] = err[j] = Real(0);
70 if (n_ % 2 == 0) result_gauss[j] = f_center[j] * wg_[n_ / 2 - 1];
73 std::vector<Real> fv1(yn * n_), e_fv1(yn * n_), fv2(yn * n_), e_fv2(yn * n_);
75 std::vector<int> RC1(n_), RC2(n_);
76 std::fill(RC1.begin(), RC1.end(), 0);
77 std::fill(RC2.begin(), RC2.end(), 0);
78 auto prec = mpfr::mpreal::get_default_prec();
79 auto rnd = mpfr::mpreal::get_default_rnd();
80 #pragma omp parallel for
81 for (
int jj = 0; jj < 2*n_; jj++) {
82 int j = jj / 2, j2 = jj % 2;
83 if (mpfr::mpreal::get_default_prec() != prec)
84 mpfr::mpreal::set_default_prec(prec);
85 mpfr::mpreal::set_default_rnd(rnd);
86 Real abscissa = half_length * xgk_[j];
88 RC1[j] = f(yn, fv1.data() + yn * j, e_fv1.data() + yn * j, center - abscissa);
90 RC2[j] = f(yn, fv2.data() + yn * j, e_fv2.data() + yn * j, center + abscissa);
93 for (
int j = 0; j < n_; j++)
94 if (RC1[j] != 0 || RC2[j] != 0)
return FAILURE;
96 for (
int jj = 0; jj < yn; jj++) {
97 for (
int j = 0; j < (n_ - 1) / 2; j++) {
99 Real fval1 = fv1[yn * jtw + jj];
100 Real fval2 = fv2[yn * jtw + jj];
101 Real fsum = fval1 + fval2;
102 result_gauss[jj] += wg_[j] * fsum;
103 result_kronrod[jj] += wgk_[jtw] * fsum;
104 result_abs[jj] += wgk_[jtw] * (abs(fval1) + abs(fval2));
106 for (
int j = 0; j < n_ / 2; j++) {
108 Real fval1 = fv1[yn * jtwm1 + jj];
109 Real fval2 = fv2[yn * jtwm1 + jj];
110 result_kronrod[jj] += wgk_[jtwm1] * (fval1 + fval2);
111 result_abs[jj] += wgk_[jtwm1] * (abs(fval1) + abs(fval2));
115 Real fsum, fval1, fval2;
116 for (
int j = 0; j < (n_ - 1) / 2; j++) {
118 Real abscissa = half_length * xgk_[jtw];
119 f(yn, fv1.data() + yn * jtw, e_fv1.data() + yn * jtw, center - abscissa);
120 f(yn, fv2.data() + yn * jtw, e_fv2.data() + yn * jtw, center + abscissa);
121 for (
int jj = 0; jj < yn; jj++) {
122 Real_t fval1 = fv1[yn * jtw + jj];
123 Real_t fval2 = fv2[yn * jtw + jj];
124 fsum = fval1 + fval2;
125 result_gauss[jj] += wg_[j] * fsum;
126 result_kronrod[jj] += wgk_[jtw] * fsum;
127 result_abs[jj] += wgk_[jtw] * (abs(fval1) + abs(fval2));
130 for (
int j = 0; j < n_ / 2; j++) {
132 Real abscissa = half_length * xgk_[jtwm1];
133 f(yn, fv1.data() + yn * jtwm1, e_fv1.data() + yn * jtwm1, center - abscissa);
134 f(yn, fv2.data() + yn * jtwm1, e_fv2.data() + yn * jtwm1, center + abscissa);
135 for (
int jj = 0; jj < yn; jj++) {
136 Real_t fval1 = fv1[yn * jtwm1 + jj];
137 Real_t fval2 = fv2[yn * jtwm1 + jj];
138 result_kronrod[jj] += wgk_[jtwm1] * (fval1 + fval2);
139 result_abs[jj] += wgk_[jtwm1] * (abs(fval1) + abs(fval2));
144 for (
int jj = 0; jj < yn; jj++) {
145 mean[jj] = result_kronrod[jj] / 2;
146 result_asc[jj] = wgk_[n_ - 1] * abs(f_center[jj] - mean[jj]);
147 for (
int j = 0; j < n_ - 1; j++) {
148 result_asc[jj] += wgk_[j] * (abs(fv1[yn * j + jj] - mean[jj]) + abs(fv2[yn * j + jj] - mean[jj]));
151 err[jj] = (result_kronrod[jj] - result_gauss[jj]) * half_length;
152 result_kronrod[jj] *= half_length;
153 result_abs[jj] *= abs_half_length;
154 result_asc[jj] *= abs_half_length;
155 result[jj] = result_kronrod[jj];
156 abserr[jj] = rescale_error(err[jj], result_abs[jj], result_asc[jj]);
162 inline Real max(
unsigned yn, Real *x) {
163 Real max_value = x[0];
164 for (
int j = 1; j < yn; j++)
if (max_value < x[j]) max_value = x[j];
168 int GK::QAG(FtnBase &f, Real_t
a, Real_t b, Real_t epsabs, Real_t epsrel, Real *result, Real *abserr, PrintHookerType PrintHooker) {
172 size_t maximum_level = 0;
177 std::vector<Real> alist(n), blist(n);
178 std::vector<std::vector<Real>> rlist(n, std::vector<Real>(yn));
179 std::vector<std::vector<Real>> elist(n, std::vector<Real>(yn));
180 std::vector<size_t> order(n), level(n);
182 std::vector<Real> area(yn), errsum(yn), result0(yn), abserr0(yn), tolerance(yn);
183 size_t iteration = 0;
191 for (
int j = 0; j < yn; j++) rlist[0][j] = elist[0][j] = Real(0);
197 for (
int j = 0; j < yn; j++) result[j] = abserr[j] = Real(0);
199 if (this->qag(f,
a, b, result0.data(), abserr0.data()))
return FAILURE;
203 for (
int j = 0; j < yn; j++) {
204 rlist[0][j] = result0[j];
205 elist[0][j] = abserr0[j];
210 for (
int j = 0; j < yn; j++) tolerance[j] = max(epsabs, epsrel * abs(result0[j]));
213 for (
int j = 0; j < yn; j++) {
214 if (abserr0[j] > tolerance[j]) { ok =
false;
break; }
218 for (
int j = 0; j < yn; j++) {
219 result[j] = result0[j];
220 abserr[j] = abserr0[j];
223 auto fdata = ((Function&)f).fdata();
224 if (PrintHooker) PrintHooker(result, abserr, &kk, fdata);
228 for (
int j = 0; j < yn; j++) {
229 area[j] = result0[j];
230 errsum[j] = abserr0[j];
236 Real a_i, b_i, r_i[yn], e_i[yn];
237 std::vector<Real> area1(yn), area2(yn), area12(yn);
238 std::vector<Real> error1(yn), error2(yn), error12(yn);
240 for (
int j = 0; j < yn; j++) {
241 area1[j] = area2[j] = area12[j] = error1[j] = error2[j] = error12[j] = Real(0);
248 for (
int j = 0; j < yn; j++) {
249 r_i[j] = rlist[i_work][j];
250 e_i[j] = elist[i_work][j];
255 b1 = (a_i + b_i) / Real(2);
259 if (this->qag(f, a1, b1, area1.data(), error1.data()))
return FAILURE;
260 if (this->qag(f, a2, b2, area2.data(), error2.data()))
return FAILURE;
262 for (
int j = 0; j < yn; j++) {
263 area12[j] = area1[j] + area2[j];
264 error12[j] = error1[j] + error2[j];
265 errsum[j] += (error12[j] - e_i[j]);
266 area[j] += area12[j] - r_i[j];
267 tolerance[j] = max(epsabs, epsrel * abs(area[j]));
271 const size_t i_max = i_work;
272 const size_t i_new = size;
273 const size_t new_level = level[i_max] + 1;
276 if (max(yn, error2.data()) > max(yn, error1.data())) {
278 for (
int j = 0; j < yn; j++) {
279 rlist[i_max][j] = area2[j];
280 elist[i_max][j] = error2[j];
282 level[i_max] = new_level;
286 for (
int j = 0; j < yn; j++) {
287 rlist[i_new][j] = area1[j];
288 elist[i_new][j] = error1[j];
290 level[i_new] = new_level;
293 for (
int j = 0; j < yn; j++) {
294 rlist[i_max][j] = area1[j];
295 elist[i_max][j] = error1[j];
297 level[i_max] = new_level;
301 for (
int j = 0; j < yn; j++) {
302 rlist[i_new][j] = area2[j];
303 elist[i_new][j] = error2[j];
305 level[i_new] = new_level;
309 if (new_level > maximum_level) maximum_level = new_level;
312 const size_t last = size - 1;
315 size_t i_nrmax = nrmax;
316 size_t i_maxerr = order[i_nrmax];
324 errmax = max(yn, elist[i_maxerr].data());
325 while (i_nrmax > 0 && errmax > max(yn, elist[order[i_nrmax - 1]].data())) {
326 order[i_nrmax] = order[i_nrmax - 1];
329 if (last < (limit / 2 + 2)) top = last;
330 else top = limit - last + 1;
332 while (i < top && errmax < max(yn, elist[order[i]].data())) {
333 order[i - 1] = order[i];
336 order[i - 1] = i_maxerr;
337 errmin = max(yn, elist[last].data());
339 while (k > i - 2 && errmin >= max(yn, elist[order[k]].data())) {
340 order[k + 1] = order[k];
346 i_maxerr = order[i_nrmax];
356 for (
int j = 0; j < yn; j++) {
357 r_i[j] = rlist[i_work][j];
358 e_i[j] = elist[i_work][j];
363 size_t kk = iteration;
364 auto fdata = ((Function&)f).fdata();
365 PrintHooker(area.data(), errsum.data(), &kk, fdata);
366 if (kk != iteration) {
367 for (
int j = 0; j < yn; j++) {
369 abserr[j] = errsum[j];
376 for (
int j = 0; j < yn; j++) {
377 if (errsum[j] > tolerance[j]) { ok =
false;
break; }
380 }
while (iteration < limit && !ok);
382 for (
int j = 0; j < yn; j++) {
384 for (
size_t k = 0; k < size; k++) result[j] += rlist[k][j];
385 abserr[j] = errsum[j];