File indexing completed on 2026-06-02 08:48:22
0001 #ifndef GAUSS_KRONROD_ADAPTIVE_H
0002 #define GAUSS_KRONROD_ADAPTIVE_H
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <cmath>
0012 #include <iostream>
0013 #include <limits>
0014 #include <vector>
0015 #include <stddef.h>
0016 #include <stdlib.h>
0017
0018 #include "../../../functor/one_dimension/FunctionType1D.h"
0019
0020
0021 #include "../Integrator1D.h"
0022
0023 #define GSL_DBL_EPSILON 2.2204460492503131e-16
0024 #define GSL_DBL_MIN 2.2250738585072014e-308
0025 #define GSL_DBL_MAX 1.7976931348623157e+308
0026
0027 #define GSL_ERROR(reason, gsl_errno) \
0028 do { \
0029 gsl_error (reason, __FILE__, __LINE__, gsl_errno) ; \
0030 return gsl_errno ; \
0031 } while (0)
0032
0033 #define GSL_ERROR_VAL(reason, gsl_errno, value) \
0034 do { \
0035 gsl_error (reason, __FILE__, __LINE__, gsl_errno) ; \
0036 return value ; \
0037 } while (0)
0038
0039 namespace NumA {
0040
0041
0042
0043
0044
0045
0046
0047 class GaussKronrodAdaptive: public Integrator1D {
0048 public:
0049 void gsl_error(const char * reason, const char * file, int line,
0050 int gsl_errno) {
0051 std::cerr << "GSL_ERROR = " << gsl_errno << std::endl;
0052 }
0053
0054 enum {
0055 GSL_SUCCESS = 0, GSL_FAILURE = -1, GSL_CONTINUE = -2,
0056 GSL_EDOM = 1,
0057 GSL_ERANGE = 2,
0058 GSL_EFAULT = 3,
0059 GSL_EINVAL = 4,
0060 GSL_EFAILED = 5,
0061 GSL_EFACTOR = 6,
0062 GSL_ESANITY = 7,
0063 GSL_ENOMEM = 8,
0064 GSL_EBADFUNC = 9,
0065 GSL_ERUNAWAY = 10,
0066 GSL_EMAXITER = 11,
0067 GSL_EZERODIV = 12,
0068 GSL_EBADTOL = 13,
0069 GSL_ETOL = 14,
0070 GSL_EUNDRFLW = 15,
0071 GSL_EOVRFLW = 16,
0072 GSL_ELOSS = 17,
0073 GSL_EROUND = 18,
0074 GSL_EBADLEN = 19,
0075 GSL_ENOTSQR = 20,
0076 GSL_ESING = 21,
0077 GSL_EDIVERGE = 22,
0078 GSL_EUNSUP = 23,
0079 GSL_EUNIMPL = 24,
0080 GSL_ECACHE = 25,
0081 GSL_ETABLE = 26,
0082 GSL_ENOPROG = 27,
0083 GSL_ENOPROGJ = 28,
0084 GSL_ETOLF = 29,
0085 GSL_ETOLX = 30,
0086 GSL_ETOLG = 31,
0087 GSL_EOF = 32
0088 };
0089
0090 GaussKronrodAdaptive() :
0091 Integrator1D() {
0092
0093 }
0094
0095 virtual ~GaussKronrodAdaptive() {
0096
0097 }
0098
0099 virtual void configure() {
0100
0101 }
0102
0103 typedef struct {
0104 size_t limit;
0105 size_t size;
0106 size_t nrmax;
0107 size_t i;
0108 size_t maximum_level;
0109 double *alist;
0110 double *blist;
0111 double *rlist;
0112 double *elist;
0113 size_t *order;
0114 size_t *level;
0115 } gsl_integration_workspace;
0116
0117 struct extrapolation_table {
0118 size_t n;
0119 double rlist2[52];
0120 size_t nres;
0121 double res3la[3];
0122 };
0123
0124 inline double integrate(FunctionType1D* pFunction, double a, double b,
0125 std::vector<double> ¶meters) {
0126 double result = 0.;
0127 const size_t limit = 1000;
0128
0129 gsl_integration_workspace * workspace = gsl_integration_workspace_alloc(
0130 limit);
0131
0132 compute(pFunction, a, b, parameters, result, workspace, limit);
0133
0134 gsl_integration_workspace_free(workspace);
0135
0136 return result;
0137 }
0138
0139 inline int compute(FunctionType1D* pFunction, const double a,
0140 const double b, std::vector<double> ¶meters, double &result,
0141 gsl_integration_workspace * workspace, const double limit) {
0142
0143 double epsabs = m_tolerances.getAbsoluteTolerance();
0144 double epsrel = m_tolerances.getRelativeTolerance();
0145
0146
0147
0148
0149
0150
0151 if (epsabs <= 0.) {
0152
0153 epsabs = 1e-06;
0154 }
0155 if (epsrel <= 0.) {
0156
0157 epsrel = 1e-09;
0158 }
0159
0160
0161 double area, errsum;
0162 double res_ext, err_ext;
0163 double result0, abserr0, resabs0, resasc0;
0164 double tolerance;
0165
0166 double ertest = 0;
0167 double error_over_large_intervals = 0;
0168 double reseps = 0, abseps = 0, correc = 0;
0169 size_t ktmin = 0;
0170 int roundoff_type1 = 0, roundoff_type2 = 0, roundoff_type3 = 0;
0171 int error_type = 0, error_type2 = 0;
0172
0173 size_t iteration = 0;
0174
0175 int positive_integrand = 0;
0176 int extrapolate = 0;
0177 int disallow_extrapolation = 0;
0178
0179 struct extrapolation_table table;
0180
0181
0182
0183 initialise(workspace, a, b);
0184
0185 result = 0;
0186 double abserr = 0;
0187
0188 if (limit > workspace->limit) {
0189 GSL_ERROR ("iteration limit exceeds available workspace", GSL_EINVAL)
0190 ;
0191 }
0192
0193
0194
0195 if (epsabs <= 0
0196 && (epsrel < 50 * GSL_DBL_EPSILON || epsrel < 0.5e-28)) {
0197 GSL_ERROR(
0198 "tolerance cannot be acheived with given epsabs and epsrel",
0199 GSL_EBADTOL);
0200 }
0201
0202
0203
0204 gsl_integration_21qk(pFunction, a, b, result0, abserr0, resabs0,
0205 resasc0, parameters);
0206
0207 set_initial_result(workspace, result0, abserr0);
0208
0209 tolerance = GSL_MAX_DBL(epsabs, epsrel * fabs(result0));
0210
0211 if (abserr0 <= 100 * GSL_DBL_EPSILON * resabs0 && abserr0 > tolerance) {
0212 result = result0;
0213 abserr = abserr0;
0214 m_errors.setAbsolute(abserr);
0215
0216 GSL_ERROR("cannot reach tolerance because of roundoff error"
0217 "on first attempt", GSL_EROUND);
0218 } else if ((abserr0 <= tolerance && abserr0 != resasc0)
0219 || abserr0 == 0.0) {
0220 result = result0;
0221 abserr = abserr0;
0222 m_errors.setAbsolute(abserr);
0223
0224 return GSL_SUCCESS;
0225 } else if (limit == 1) {
0226 result = result0;
0227 abserr = abserr0;
0228 m_errors.setAbsolute(abserr);
0229
0230 GSL_ERROR("a maximum of one iteration was insufficient",
0231 GSL_EMAXITER);
0232 }
0233
0234
0235
0236 initialise_table(&table);
0237 append_table(&table, result0);
0238
0239 area = result0;
0240 errsum = abserr0;
0241
0242 res_ext = result0;
0243 err_ext = GSL_DBL_MAX;
0244
0245 positive_integrand = test_positivity(result0, resabs0);
0246
0247 iteration = 1;
0248
0249 do {
0250 size_t current_level;
0251 double a1, b1, a2, b2;
0252 double a_i, b_i, r_i, e_i;
0253 double area1 = 0, area2 = 0, area12 = 0;
0254 double error1 = 0, error2 = 0, error12 = 0;
0255 double resasc1, resasc2;
0256 double resabs1, resabs2;
0257 double last_e_i;
0258
0259
0260
0261 retrieve(workspace, &a_i, &b_i, &r_i, &e_i);
0262
0263 current_level = workspace->level[workspace->i] + 1;
0264
0265 a1 = a_i;
0266 b1 = 0.5 * (a_i + b_i);
0267 a2 = b1;
0268 b2 = b_i;
0269
0270 iteration++;
0271
0272 gsl_integration_21qk(pFunction, a1, b1, area1, error1, resabs1,
0273 resasc1, parameters);
0274 gsl_integration_21qk(pFunction, a2, b2, area2, error2, resabs2,
0275 resasc2, parameters);
0276
0277 area12 = area1 + area2;
0278 error12 = error1 + error2;
0279 last_e_i = e_i;
0280
0281
0282
0283
0284
0285
0286
0287
0288 errsum = errsum + error12 - e_i;
0289 area = area + area12 - r_i;
0290
0291 tolerance = GSL_MAX_DBL(epsabs, epsrel * fabs(area));
0292
0293 if (resasc1 != error1 && resasc2 != error2) {
0294 double delta = r_i - area12;
0295
0296 if (fabs(delta) <= 1.0e-5 * fabs(area12)
0297 && error12 >= 0.99 * e_i) {
0298 if (!extrapolate) {
0299 roundoff_type1++;
0300 } else {
0301 roundoff_type2++;
0302 }
0303 }
0304 if (iteration > 10 && error12 > e_i) {
0305 roundoff_type3++;
0306 }
0307 }
0308
0309
0310
0311 if (roundoff_type1 + roundoff_type2 >= 10 || roundoff_type3 >= 20) {
0312 error_type = 2;
0313 }
0314
0315 if (roundoff_type2 >= 5) {
0316 error_type2 = 1;
0317 }
0318
0319
0320
0321
0322 if (subinterval_too_small(a1, a2, b2)) {
0323 error_type = 4;
0324 }
0325
0326
0327
0328 update(workspace, a1, b1, area1, error1, a2, b2, area2, error2);
0329
0330 if (errsum <= tolerance) {
0331 goto compute_result;
0332 }
0333
0334 if (error_type) {
0335 break;
0336 }
0337
0338 if (iteration >= limit - 1) {
0339 error_type = 1;
0340 break;
0341 }
0342
0343 if (iteration == 2)
0344 {
0345 error_over_large_intervals = errsum;
0346 ertest = tolerance;
0347 append_table(&table, area);
0348 continue;
0349 }
0350
0351 if (disallow_extrapolation) {
0352 continue;
0353 }
0354
0355 error_over_large_intervals += -last_e_i;
0356
0357 if (current_level < workspace->maximum_level) {
0358 error_over_large_intervals += error12;
0359 }
0360
0361 if (!extrapolate) {
0362
0363
0364
0365 if (large_interval(workspace))
0366 continue;
0367
0368 extrapolate = 1;
0369 workspace->nrmax = 1;
0370 }
0371
0372 if (!error_type2 && error_over_large_intervals > ertest) {
0373 if (increase_nrmax(workspace))
0374 continue;
0375 }
0376
0377
0378
0379 append_table(&table, area);
0380
0381 qelg(&table, reseps, abseps);
0382
0383 ktmin++;
0384
0385 if (ktmin > 5 && err_ext < 0.001 * errsum) {
0386 error_type = 5;
0387 }
0388
0389 if (abseps < err_ext) {
0390 ktmin = 0;
0391 err_ext = abseps;
0392 res_ext = reseps;
0393 correc = error_over_large_intervals;
0394 ertest = GSL_MAX_DBL(epsabs, epsrel * fabs(reseps));
0395 if (err_ext <= ertest)
0396 break;
0397 }
0398
0399
0400
0401 if (table.n == 1) {
0402 disallow_extrapolation = 1;
0403 }
0404
0405 if (error_type == 5) {
0406 break;
0407 }
0408
0409
0410
0411 reset_nrmax(workspace);
0412 extrapolate = 0;
0413 error_over_large_intervals = errsum;
0414
0415 } while (iteration < limit);
0416
0417 result = res_ext;
0418 abserr = err_ext;
0419 m_errors.setAbsolute(abserr);
0420
0421 if (err_ext == GSL_DBL_MAX)
0422 goto compute_result;
0423
0424 if (error_type || error_type2) {
0425 if (error_type2) {
0426 err_ext += correc;
0427 }
0428
0429 if (error_type == 0)
0430 error_type = 3;
0431
0432 if (res_ext != 0.0 && area != 0.0) {
0433 if (err_ext / fabs(res_ext) > errsum / fabs(area))
0434 goto compute_result;
0435 } else if (err_ext > errsum) {
0436 goto compute_result;
0437 } else if (area == 0.0) {
0438 goto return_error;
0439 }
0440 }
0441
0442
0443
0444 {
0445 double max_area = GSL_MAX_DBL(fabs(res_ext), fabs(area));
0446
0447 if (!positive_integrand && max_area < 0.01 * resabs0)
0448 goto return_error;
0449 }
0450
0451 {
0452 double ratio = res_ext / area;
0453
0454 if (ratio < 0.01 || ratio > 100.0 || errsum > fabs(area))
0455 error_type = 6;
0456 }
0457
0458 goto return_error;
0459
0460 compute_result:
0461
0462 result = sum_results(workspace);
0463 abserr = errsum;
0464 m_errors.setAbsolute(abserr);
0465
0466 return_error:
0467
0468 if (error_type > 2)
0469 error_type--;
0470
0471 if (error_type == 0) {
0472 return GSL_SUCCESS;
0473 } else if (error_type == 1) {
0474 GSL_ERROR("number of iterations was insufficient", GSL_EMAXITER);
0475 } else if (error_type == 2) {
0476 GSL_ERROR("cannot reach tolerance because of roundoff error",
0477 GSL_EROUND);
0478 } else if (error_type == 3) {
0479 GSL_ERROR(
0480 "bad integrand behavior found in the integration interval",
0481 GSL_ESING);
0482 } else if (error_type == 4) {
0483 GSL_ERROR("roundoff error detected in the extrapolation table",
0484 GSL_EROUND);
0485 } else if (error_type == 5) {
0486 GSL_ERROR("integral is divergent, or slowly convergent",
0487 GSL_EDIVERGE);
0488 } else {
0489 GSL_ERROR("could not integrate function", GSL_EFAILED);
0490 }
0491 }
0492
0493 gsl_integration_workspace *
0494 gsl_integration_workspace_alloc(const size_t n) {
0495 gsl_integration_workspace * w;
0496
0497 if (n == 0) {
0498 GSL_ERROR_VAL("workspace length n must be positive integer",
0499 GSL_EDOM, 0);
0500 }
0501
0502 w = (gsl_integration_workspace *) malloc(
0503 sizeof(gsl_integration_workspace));
0504
0505 if (w == 0) {
0506 GSL_ERROR_VAL("failed to allocate space for workspace struct",
0507 GSL_ENOMEM, 0);
0508 }
0509
0510 w->alist = (double *) malloc(n * sizeof(double));
0511
0512 if (w->alist == 0) {
0513 free(w);
0514
0515 GSL_ERROR_VAL("failed to allocate space for alist ranges",
0516 GSL_ENOMEM, 0);
0517 }
0518
0519 w->blist = (double *) malloc(n * sizeof(double));
0520
0521 if (w->blist == 0) {
0522 free(w->alist);
0523 free(w);
0524
0525 GSL_ERROR_VAL("failed to allocate space for blist ranges",
0526 GSL_ENOMEM, 0);
0527 }
0528
0529 w->rlist = (double *) malloc(n * sizeof(double));
0530
0531 if (w->rlist == 0) {
0532 free(w->blist);
0533 free(w->alist);
0534 free(w);
0535
0536 GSL_ERROR_VAL("failed to allocate space for rlist ranges",
0537 GSL_ENOMEM, 0);
0538 }
0539
0540 w->elist = (double *) malloc(n * sizeof(double));
0541
0542 if (w->elist == 0) {
0543 free(w->rlist);
0544 free(w->blist);
0545 free(w->alist);
0546 free(w);
0547
0548 GSL_ERROR_VAL("failed to allocate space for elist ranges",
0549 GSL_ENOMEM, 0);
0550 }
0551
0552 w->order = (size_t *) malloc(n * sizeof(size_t));
0553
0554 if (w->order == 0) {
0555 free(w->elist);
0556 free(w->rlist);
0557 free(w->blist);
0558 free(w->alist);
0559 free(w);
0560
0561 GSL_ERROR_VAL("failed to allocate space for order ranges",
0562 GSL_ENOMEM, 0);
0563 }
0564
0565 w->level = (size_t *) malloc(n * sizeof(size_t));
0566
0567 if (w->level == 0) {
0568 free(w->order);
0569 free(w->elist);
0570 free(w->rlist);
0571 free(w->blist);
0572 free(w->alist);
0573 free(w);
0574
0575 GSL_ERROR_VAL("failed to allocate space for order ranges",
0576 GSL_ENOMEM, 0);
0577 }
0578
0579 w->size = 0;
0580 w->limit = n;
0581 w->maximum_level = 0;
0582
0583 return w;
0584 }
0585
0586 void gsl_integration_workspace_free(gsl_integration_workspace * w) {
0587 if (w != 0) {
0588 free(w->level);
0589 free(w->order);
0590 free(w->elist);
0591 free(w->rlist);
0592 free(w->blist);
0593 free(w->alist);
0594 free(w);
0595 }
0596 }
0597
0598 inline void initialise(gsl_integration_workspace * workspace, double a,
0599 double b) {
0600 workspace->size = 0;
0601 workspace->nrmax = 0;
0602 workspace->i = 0;
0603 workspace->alist[0] = a;
0604 workspace->blist[0] = b;
0605 workspace->rlist[0] = 0.0;
0606 workspace->elist[0] = 0.0;
0607 workspace->order[0] = 0;
0608 workspace->level[0] = 0;
0609
0610 workspace->maximum_level = 0;
0611 }
0612
0613 inline void retrieve(const gsl_integration_workspace * workspace,
0614 double * a, double * b, double * r, double * e) {
0615 const size_t i = workspace->i;
0616 double * alist = workspace->alist;
0617 double * blist = workspace->blist;
0618 double * rlist = workspace->rlist;
0619 double * elist = workspace->elist;
0620
0621 *a = alist[i];
0622 *b = blist[i];
0623 *r = rlist[i];
0624 *e = elist[i];
0625 }
0626
0627 inline
0628 void update(gsl_integration_workspace * workspace, double a1, double b1,
0629 double area1, double error1, double a2, double b2, double area2,
0630 double error2) {
0631 double * alist = workspace->alist;
0632 double * blist = workspace->blist;
0633 double * rlist = workspace->rlist;
0634 double * elist = workspace->elist;
0635 size_t * level = workspace->level;
0636
0637 const size_t i_max = workspace->i;
0638 const size_t i_new = workspace->size;
0639
0640 const size_t new_level = workspace->level[i_max] + 1;
0641
0642
0643
0644 if (error2 > error1) {
0645 alist[i_max] = a2;
0646 rlist[i_max] = area2;
0647 elist[i_max] = error2;
0648 level[i_max] = new_level;
0649
0650 alist[i_new] = a1;
0651 blist[i_new] = b1;
0652 rlist[i_new] = area1;
0653 elist[i_new] = error1;
0654 level[i_new] = new_level;
0655 } else {
0656 blist[i_max] = b1;
0657 rlist[i_max] = area1;
0658 elist[i_max] = error1;
0659 level[i_max] = new_level;
0660
0661 alist[i_new] = a2;
0662 blist[i_new] = b2;
0663 rlist[i_new] = area2;
0664 elist[i_new] = error2;
0665 level[i_new] = new_level;
0666 }
0667
0668 workspace->size++;
0669
0670 if (new_level > workspace->maximum_level) {
0671 workspace->maximum_level = new_level;
0672 }
0673
0674 qpsrt(workspace);
0675 }
0676
0677 inline
0678 void qpsrt(gsl_integration_workspace * workspace) {
0679 const size_t last = workspace->size - 1;
0680 const size_t limit = workspace->limit;
0681
0682 double * elist = workspace->elist;
0683 size_t * order = workspace->order;
0684
0685 double errmax;
0686 double errmin;
0687 int i, k, top;
0688
0689 size_t i_nrmax = workspace->nrmax;
0690 size_t i_maxerr = order[i_nrmax];
0691
0692
0693
0694 if (last < 2) {
0695 order[0] = 0;
0696 order[1] = 1;
0697 workspace->i = i_maxerr;
0698 return;
0699 }
0700
0701 errmax = elist[i_maxerr];
0702
0703
0704
0705
0706
0707
0708 while (i_nrmax > 0 && errmax > elist[order[i_nrmax - 1]]) {
0709 order[i_nrmax] = order[i_nrmax - 1];
0710 i_nrmax--;
0711 }
0712
0713
0714
0715
0716
0717 if (last < (limit / 2 + 2)) {
0718 top = last;
0719 } else {
0720 top = limit - last + 1;
0721 }
0722
0723
0724
0725
0726 i = i_nrmax + 1;
0727
0728
0729
0730
0731 while (i < top && errmax < elist[order[i]]) {
0732 order[i - 1] = order[i];
0733 i++;
0734 }
0735
0736 order[i - 1] = i_maxerr;
0737
0738
0739
0740 errmin = elist[last];
0741
0742 k = top - 1;
0743
0744 while (k > i - 2 && errmin >= elist[order[k]]) {
0745 order[k + 1] = order[k];
0746 k--;
0747 }
0748
0749 order[k + 1] = last;
0750
0751
0752
0753 i_maxerr = order[i_nrmax];
0754
0755 workspace->i = i_maxerr;
0756 workspace->nrmax = i_nrmax;
0757 }
0758
0759 int increase_nrmax(gsl_integration_workspace * workspace) {
0760 int k;
0761 int id = workspace->nrmax;
0762 int jupbnd;
0763
0764 const size_t * level = workspace->level;
0765 const size_t * order = workspace->order;
0766
0767 size_t limit = workspace->limit;
0768 size_t last = workspace->size - 1;
0769
0770 if (last > (1 + limit / 2)) {
0771 jupbnd = limit + 1 - last;
0772 } else {
0773 jupbnd = last;
0774 }
0775
0776 for (k = id; k <= jupbnd; k++) {
0777 size_t i_max = order[workspace->nrmax];
0778
0779 workspace->i = i_max;
0780
0781 if (level[i_max] < workspace->maximum_level) {
0782 return 1;
0783 }
0784
0785 workspace->nrmax++;
0786
0787 }
0788
0789 return 0;
0790 }
0791
0792 inline void reset_nrmax(gsl_integration_workspace * workspace) {
0793 workspace->nrmax = 0;
0794 workspace->i = workspace->order[0];
0795 }
0796
0797 inline double sum_results(const gsl_integration_workspace * workspace) {
0798 const double * const rlist = workspace->rlist;
0799 const size_t n = workspace->size;
0800
0801 size_t k;
0802 double result_sum = 0;
0803
0804 for (k = 0; k < n; k++) {
0805 result_sum += rlist[k];
0806 }
0807
0808 return result_sum;
0809 }
0810
0811 int large_interval(gsl_integration_workspace * workspace) {
0812 size_t i = workspace->i;
0813 const size_t * level = workspace->level;
0814
0815 if (level[i] < workspace->maximum_level) {
0816 return 1;
0817 } else {
0818 return 0;
0819 }
0820 }
0821
0822 inline void set_initial_result(gsl_integration_workspace * workspace,
0823 double result, double error) {
0824 workspace->size = 1;
0825 workspace->rlist[0] = result;
0826 workspace->elist[0] = error;
0827 }
0828
0829 void initialise_table(struct extrapolation_table *table) {
0830 table->n = 0;
0831 table->nres = 0;
0832 }
0833
0834 void append_table(struct extrapolation_table *table, double y) {
0835 size_t n;
0836 n = table->n;
0837 table->rlist2[n] = y;
0838 table->n++;
0839 }
0840
0841 inline void qelg(struct extrapolation_table *table, double &result,
0842 double &abserr) {
0843 double *epstab = table->rlist2;
0844 double *res3la = table->res3la;
0845 const size_t n = table->n - 1;
0846
0847 const double current = epstab[n];
0848
0849 double absolute = std::numeric_limits<double>::max();
0850 double relative = 5 * std::numeric_limits<double>::epsilon()
0851 * fabs(current);
0852
0853 const size_t newelm = n / 2;
0854 const size_t n_orig = n;
0855 size_t n_final = n;
0856 size_t i;
0857
0858 const size_t nres_orig = table->nres;
0859
0860 result = current;
0861 abserr = std::numeric_limits<double>::max();
0862
0863 if (n < 2) {
0864 result = current;
0865 abserr = GSL_MAX_DBL(absolute, relative);
0866 return;
0867 }
0868
0869 epstab[n + 2] = epstab[n];
0870 epstab[n] = std::numeric_limits<double>::max();
0871
0872 for (i = 0; i < newelm; i++) {
0873 double res = epstab[n - 2 * i + 2];
0874 double e0 = epstab[n - 2 * i - 2];
0875 double e1 = epstab[n - 2 * i - 1];
0876 double e2 = res;
0877
0878 double e1abs = fabs(e1);
0879 double delta2 = e2 - e1;
0880 double err2 = fabs(delta2);
0881 double tol2 = GSL_MAX_DBL(fabs(e2), e1abs)
0882 * std::numeric_limits<double>::epsilon();
0883 double delta3 = e1 - e0;
0884 double err3 = fabs(delta3);
0885 double tol3 = GSL_MAX_DBL(e1abs, fabs(e0))
0886 * std::numeric_limits<double>::epsilon();
0887
0888 double e3, delta1, err1, tol1, ss;
0889
0890 if (err2 <= tol2 && err3 <= tol3) {
0891
0892
0893
0894 result = res;
0895 absolute = err2 + err3;
0896 relative = 5 * std::numeric_limits<double>::epsilon()
0897 * fabs(res);
0898 abserr = GSL_MAX_DBL(absolute, relative);
0899 return;
0900 }
0901
0902 e3 = epstab[n - 2 * i];
0903 epstab[n - 2 * i] = e1;
0904 delta1 = e1 - e3;
0905 err1 = fabs(delta1);
0906 tol1 = GSL_MAX_DBL(e1abs, fabs(e3))
0907 * std::numeric_limits<double>::epsilon();
0908
0909
0910
0911
0912 if (err1 <= tol1 || err2 <= tol2 || err3 <= tol3) {
0913 n_final = 2 * i;
0914 break;
0915 }
0916
0917 ss = (1 / delta1 + 1 / delta2) - 1 / delta3;
0918
0919
0920
0921
0922
0923 if (fabs(ss * e1) <= 0.0001) {
0924 n_final = 2 * i;
0925 break;
0926 }
0927
0928
0929
0930
0931 res = e1 + 1 / ss;
0932 epstab[n - 2 * i] = res;
0933
0934 {
0935 const double error = err2 + fabs(res - e2) + err3;
0936
0937 if (error <= abserr) {
0938 abserr = error;
0939 result = res;
0940 }
0941 }
0942 }
0943
0944
0945
0946 {
0947 const size_t limexp = 50 - 1;
0948
0949 if (n_final == limexp) {
0950 n_final = 2 * (limexp / 2);
0951 }
0952 }
0953
0954 if (n_orig % 2 == 1) {
0955 for (i = 0; i <= newelm; i++) {
0956 epstab[1 + i * 2] = epstab[i * 2 + 3];
0957 }
0958 } else {
0959 for (i = 0; i <= newelm; i++) {
0960 epstab[i * 2] = epstab[i * 2 + 2];
0961 }
0962 }
0963
0964 if (n_orig != n_final) {
0965 for (i = 0; i <= n_final; i++) {
0966 epstab[i] = epstab[n_orig - n_final + i];
0967 }
0968 }
0969
0970 table->n = n_final + 1;
0971
0972 if (nres_orig < 3) {
0973 res3la[nres_orig] = result;
0974 abserr = std::numeric_limits<double>::max();
0975 } else {
0976 abserr = (fabs(result - res3la[2]) + fabs(result - res3la[1])
0977 + fabs(result - res3la[0]));
0978
0979 res3la[0] = res3la[1];
0980 res3la[1] = res3la[2];
0981 res3la[2] = result;
0982 }
0983
0984
0985
0986
0987
0988
0989
0990 table->nres = nres_orig + 1;
0991
0992 abserr = GSL_MAX_DBL(abserr,
0993 5 * std::numeric_limits<double>::epsilon() * fabs(result));
0994
0995 return;
0996 }
0997
0998 inline int test_positivity(double result, double resabs) {
0999 int status = (fabs(result)
1000 >= (1 - 50 * std::numeric_limits<double>::epsilon()) * resabs);
1001
1002 return status;
1003 }
1004
1005 inline int subinterval_too_small(double a1, double a2, double b2) {
1006 const double e = std::numeric_limits<double>::epsilon();
1007 const double u = std::numeric_limits<double>::min();
1008
1009 double tmp = (1 + 100 * e) * (fabs(a2) + 1000 * u);
1010
1011 int status = fabs(a1) <= tmp && fabs(b2) <= tmp;
1012
1013 return status;
1014 }
1015
1016 inline double GSL_MAX_DBL(double a, double b) {
1017 return GSL_MAX(a, b);
1018 }
1019
1020 void gsl_integration_21qk(FunctionType1D* pFunction, double a, double b,
1021 double &result, double &abserr, double &resabs, double &resasc,
1022 std::vector<double> ¶meters) {
1023
1024 double x = 0.;
1025 const int n = 11;
1026 double fv1[11], fv2[11];
1027
1028 const double center = 0.5 * (a + b);
1029 const double half_length = 0.5 * (b - a);
1030 const double abs_half_length = fabs(half_length);
1031
1032 const double f_center = (*pFunction)(center, parameters);
1033
1034 double result_gauss = 0;
1035 double result_kronrod = f_center * wgk[n - 1];
1036
1037 double result_abs = fabs(result_kronrod);
1038 double result_asc = 0;
1039 double mean = 0, err = 0;
1040
1041 int j;
1042
1043 if (n % 2 == 0) {
1044 result_gauss = f_center * wg[n / 2 - 1];
1045 }
1046
1047 for (j = 0; j < (n - 1) / 2; j++) {
1048 const int jtw = j * 2 + 1;
1049 const double abscissa = half_length * xgk[jtw];
1050
1051 x = center - abscissa;
1052 const double fval1 = (*pFunction)(x, parameters);
1053
1054 x = center + abscissa;
1055 const double fval2 = (*pFunction)(x, parameters);
1056
1057 const double fsum = fval1 + fval2;
1058 fv1[jtw] = fval1;
1059 fv2[jtw] = fval2;
1060 result_gauss += wg[j] * fsum;
1061 result_kronrod += wgk[jtw] * fsum;
1062 result_abs += wgk[jtw] * (fabs(fval1) + fabs(fval2));
1063 }
1064
1065 for (j = 0; j < n / 2; j++) {
1066 int jtwm1 = j * 2;
1067 const double abscissa = half_length * xgk[jtwm1];
1068
1069 x = center - abscissa;
1070 const double fval1 = (*pFunction)(x, parameters);
1071
1072 x = center + abscissa;
1073 const double fval2 = (*pFunction)(x, parameters);
1074 fv1[jtwm1] = fval1;
1075 fv2[jtwm1] = fval2;
1076 result_kronrod += wgk[jtwm1] * (fval1 + fval2);
1077 result_abs += wgk[jtwm1] * (fabs(fval1) + fabs(fval2));
1078 };
1079
1080 mean = result_kronrod * 0.5;
1081
1082 result_asc = wgk[n - 1] * fabs(f_center - mean);
1083
1084 for (j = 0; j < n - 1; j++) {
1085 result_asc += wgk[j] * (fabs(fv1[j] - mean) + fabs(fv2[j] - mean));
1086 }
1087
1088
1089
1090 err = (result_kronrod - result_gauss) * half_length;
1091
1092 result_kronrod *= half_length;
1093 result_abs *= abs_half_length;
1094 result_asc *= abs_half_length;
1095
1096 result = result_kronrod;
1097 resabs = result_abs;
1098 resasc = result_asc;
1099 abserr = rescale_error(err, result_abs, result_asc);
1100 }
1101
1102 double rescale_error(double err, const double result_abs,
1103 const double result_asc) {
1104 err = fabs(err);
1105
1106 if (result_asc != 0 && err != 0) {
1107 double scale = pow((200 * err / result_asc), 1.5);
1108
1109 if (scale < 1) {
1110 err = result_asc * scale;
1111 } else {
1112 err = result_asc;
1113 }
1114 }
1115 if (result_abs
1116 > std::numeric_limits<double>::min()
1117 / (50 * std::numeric_limits<double>::epsilon())) {
1118 double min_err = 50 * std::numeric_limits<double>::epsilon()
1119 * result_abs;
1120
1121 if (min_err > err) {
1122 err = min_err;
1123 }
1124 }
1125
1126 return err;
1127 }
1128
1129 double GSL_MAX(double a, double b) {
1130 return (a > b) ? a : b;
1131 }
1132
1133 static const std::vector<double> xgk;
1134 static const std::vector<double> wg;
1135 static const std::vector<double> wgk;
1136
1137 static const std::vector<double> make_xgk_21();
1138 static const std::vector<double> make_wg_21();
1139 static const std::vector<double> make_wgk_21();
1140
1141 virtual GaussKronrodAdaptive* clone() const {
1142 return new GaussKronrodAdaptive(*this);
1143 }
1144
1145 protected:
1146 GaussKronrodAdaptive(const GaussKronrodAdaptive &other) :
1147 Integrator1D(other) {
1148 }
1149 };
1150
1151 }
1152
1153 #endif