All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
inte_singular_gsl.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2006-2014, Jerry Gagelman
5  and Andrew W. Steiner
6 
7  This file is part of O2scl.
8 
9  O2scl is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 3 of the License, or
12  (at your option) any later version.
13 
14  O2scl is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with O2scl. If not, see <http://www.gnu.org/licenses/>.
21 
22  -------------------------------------------------------------------
23 */
24 #ifndef O2SCL_GSL_INTE_SINGULAR_H
25 #define O2SCL_GSL_INTE_SINGULAR_H
26 
27 /** \file inte_singular_gsl.h
28  \brief File defining \ref o2scl::inte_singular_gsl
29 */
30 
31 #include <cmath>
32 
33 #include <gsl/gsl_integration.h>
34 
35 #include <o2scl/string_conv.h>
36 #include <o2scl/inte.h>
37 #include <o2scl/inte_kronrod_gsl.h>
38 
39 #ifndef DOXYGEN_NO_O2NS
40 namespace o2scl {
41 #endif
42 
43  /** \brief Base class for integrating a function with a
44  singularity (GSL)
45 
46  This class contains the extrapolation table mechanics and the
47  base integration function for singular integrals from GSL. The
48  casual end-user should use the classes explained in the
49  \ref inte_section section of the User's guide.
50 
51  \future Some of the functions inside this class could
52  be moved out of header files?
53  */
54  template<class func_t> class inte_singular_gsl :
55  public inte_kronrod_gsl<func_t> {
56 
57  public:
58 
59  /** \brief A structure for extrapolation for \ref inte_qags_gsl
60 
61  \future Move this to a new class, with qelg() as a method
62  */
63  typedef struct extrapolation_table {
64  /// Index of new element in the first column
65  size_t n;
66  /// Lower diagonals of the triangular epsilon table
67  double rlist2[52];
68  /// Number of calls
69  size_t nres;
70  /// Three most recent results
71  double res3la[3];
72  } extrap_table;
73 
74  protected:
75 
76  /// Initialize the table
78  table->n = 0;
79  table->nres = 0;
80  return;
81  }
82 
83  /// Append a result to the table
84  void append_table(struct extrapolation_table *table, double y) {
85  size_t n;
86  n = table->n;
87  table->rlist2[n] = y;
88  table->n++;
89  return;
90  }
91 
92  /** \brief Test if the integrand satisfies \f$ f = |f| \f$
93  */
94  inline int test_positivity(double result, double resabs) {
95  double dbl_eps=std::numeric_limits<double>::epsilon();
96  int status=(fabs(result) >= (1-50*dbl_eps)*resabs);
97  return status;
98  }
99 
100  /** \brief Determines the limit of a given sequence
101  of approximations
102 
103  For certain convergent series \f$ \sum_k a_k \f$ whose error
104  term \f$ E_n = \sum_{k=n}^\infty a_k \f$ is well behaved, it
105  is possible to find a transformation of the sequence that
106  yields a faster converging series to the same limit. This
107  method of extrapolation applies to some sequences of
108  adaptive-approximation and error-estimation for numerical
109  integration. This function implements the \f$
110  \varepsilon\f$-algorithm (\ref Wynn56, \ref Piessens83) for an
111  extrapolation table stored in \c table.
112 
113  Quadpack documentation
114  \verbatim
115  c
116  c list of major variables
117  c -----------------------
118  c e0 - the 4 elements on which the computation of a new
119  c e1 element in the epsilon table is based
120  c e2
121  c e3 e0
122  c e3 e1 new
123  c e2
124  c newelm - number of elements to be computed in the new
125  c diagonal
126  c error - error = abs(e1-e0)+abs(e2-e1)+abs(new-e2)
127  c result - the element in the new diagonal with least value
128  c of error
129  c
130  c machine dependent constants
131  c ---------------------------
132  c
133  c epmach is the largest relative spacing.
134  c oflow is the largest positive magnitude.
135  c limexp is the maximum number of elements the epsilon
136  c table can contain. if this number is reached, the upper
137  c diagonal of the epsilon table is deleted.
138  c
139  \endverbatim
140  */
141  void qelg(struct extrapolation_table *table, double *result,
142  double *abserr) {
143 
144  double *epstab = table->rlist2;
145  double *res3la = table->res3la;
146  const size_t n = table->n - 1;
147 
148  const double current = epstab[n];
149 
150  double absolute = GSL_DBL_MAX;
151  double relative = 5 * GSL_DBL_EPSILON * fabs (current);
152 
153  const size_t newelm = n / 2;
154  const size_t n_orig = n;
155  size_t n_final = n;
156  size_t i;
157 
158  const size_t nres_orig = table->nres;
159 
160  *result = current;
161  *abserr = GSL_DBL_MAX;
162 
163  if (n < 2) {
164  *result = current;
165  *abserr = GSL_MAX_DBL (absolute, relative);
166  return;
167  }
168 
169  epstab[n + 2] = epstab[n];
170  epstab[n] = GSL_DBL_MAX;
171 
172  for (i = 0; i < newelm; i++) {
173  double res = epstab[n - 2 * i + 2];
174  double e0 = epstab[n - 2 * i - 2];
175  double e1 = epstab[n - 2 * i - 1];
176  double e2 = res;
177 
178  double e1abs = fabs (e1);
179  double delta2 = e2 - e1;
180  double err2 = fabs (delta2);
181  double tol2 = GSL_MAX_DBL (fabs (e2), e1abs) * GSL_DBL_EPSILON;
182  double delta3 = e1 - e0;
183  double err3 = fabs (delta3);
184  double tol3 = GSL_MAX_DBL (e1abs, fabs (e0)) * GSL_DBL_EPSILON;
185 
186  double e3, delta1, err1, tol1, ss;
187 
188  if (err2 <= tol2 && err3 <= tol3) {
189  /* If e0, e1 and e2 are equal to within machine accuracy,
190  convergence is assumed. */
191 
192  *result = res;
193  absolute = err2 + err3;
194  relative = 5 * GSL_DBL_EPSILON * fabs (res);
195  *abserr = GSL_MAX_DBL (absolute, relative);
196  return;
197  }
198 
199  e3 = epstab[n - 2 * i];
200  epstab[n - 2 * i] = e1;
201  delta1 = e1 - e3;
202  err1 = fabs (delta1);
203  tol1 = GSL_MAX_DBL (e1abs, fabs (e3)) * GSL_DBL_EPSILON;
204 
205  /* If two elements are very close to each other, omit a part of
206  the table by adjusting the value of n */
207 
208  if (err1 <= tol1 || err2 <= tol2 || err3 <= tol3) {
209  n_final = 2 * i;
210  break;
211  }
212 
213  ss = (1 / delta1 + 1 / delta2) - 1 / delta3;
214 
215  /* Test to detect irregular behaviour in the table, and
216  eventually omit a part of the table by adjusting the value of
217  n. */
218  if (fabs (ss * e1) <= 0.0001) {
219  n_final = 2 * i;
220  break;
221  }
222  /* Compute a new element and eventually adjust the value of
223  result. */
224 
225  res = e1 + 1 / ss;
226  epstab[n - 2 * i] = res;
227 
228  {
229  const double error = err2 + fabs (res - e2) + err3;
230 
231  if (error <= *abserr) {
232  *abserr = error;
233  *result = res;
234  }
235  }
236  }
237 
238  /* Shift the table */
239 
240  {
241  const size_t limexp = 50 - 1;
242 
243  if (n_final == limexp) {
244  n_final = 2 * (limexp / 2);
245  }
246  }
247 
248  if (n_orig % 2 == 1) {
249  for (i = 0; i <= newelm; i++) {
250  epstab[1 + i * 2] = epstab[i * 2 + 3];
251  }
252  } else {
253  for (i = 0; i <= newelm; i++) {
254  epstab[i * 2] = epstab[i * 2 + 2];
255  }
256  }
257  if (n_orig != n_final) {
258  for (i = 0; i <= n_final; i++) {
259  epstab[i] = epstab[n_orig - n_final + i];
260  }
261  }
262 
263  table->n = n_final + 1;
264 
265  if (nres_orig < 3) {
266 
267  res3la[nres_orig] = *result;
268  *abserr = GSL_DBL_MAX;
269 
270  } else {
271  /* Compute error estimate */
272  *abserr = (fabs (*result - res3la[2]) + fabs (*result - res3la[1])
273  + fabs (*result - res3la[0]));
274 
275  res3la[0] = res3la[1];
276  res3la[1] = res3la[2];
277  res3la[2] = *result;
278  }
279 
280  /* In QUADPACK the variable table->nres is incremented at the top of
281  qelg, so it increases on every call. This leads to the array
282  res3la being accessed when its elements are still undefined, so I
283  have moved the update to this point so that its value more
284  useful. */
285 
286  table->nres = nres_orig + 1;
287 
288  *abserr = GSL_MAX_DBL (*abserr, 5 * GSL_DBL_EPSILON * fabs (*result));
289 
290  return;
291  }
292 
293  /// Determine if an interval is large
294  int large_interval (inte_workspace_gsl * workspace) {
295  size_t i = workspace->i ;
296  const size_t * level = workspace->level;
297 
298  if (level[i] < workspace->maximum_level) {
299  return 1;
300  } else {
301  return 0;
302  }
303  }
304 
305  /// Reset workspace to work on the interval with the largest error
306  inline void reset_nrmax (inte_workspace_gsl * workspace) {
307  workspace->nrmax = 0;
308  workspace->i = workspace->order[0] ;
309  }
310 
311  /// Increase workspace
312  int increase_nrmax (inte_workspace_gsl * workspace) {
313  int k;
314  int id = workspace->nrmax;
315  int jupbnd;
316 
317  const size_t * level = workspace->level;
318  const size_t * order = workspace->order;
319 
320  size_t limit = workspace->limit ;
321  size_t last = workspace->size - 1 ;
322 
323  if (last > (1 + limit / 2)) {
324  jupbnd = limit + 1 - last;
325  } else {
326  jupbnd = last;
327  }
328 
329  for (k = id; k <= jupbnd; k++) {
330  size_t i_max = order[workspace->nrmax];
331 
332  workspace->i = i_max ;
333 
334  if (level[i_max] < workspace->maximum_level) {
335  return 1;
336  }
337 
338  workspace->nrmax++;
339 
340  }
341  return 0;
342  }
343 
344  /** \brief Integration function
345 
346  \future Remove goto statements. Before this is done, it might
347  be best to add some tests which fail in the various ways.
348  */
349  int qags(func_t &func, const double a, const double b,
350  const double l_epsabs, const double l_epsrel,
351  double *result, double *abserr) {
352 
353  double area, errsum;
354  double res_ext, err_ext;
355  double result0, abserr0, resabs0, resasc0;
356  double tolerance;
357 
358  double ertest = 0;
359  double error_over_large_intervals = 0;
360  double reseps = 0, abseps = 0, correc = 0;
361  size_t ktmin = 0;
362  int roundoff_type1 = 0, roundoff_type2 = 0, roundoff_type3 = 0;
363  int error_type = 0, error_type2 = 0;
364 
365  size_t iteration = 0;
366 
367  int positive_integrand = 0;
368  int extrapolate = 0;
369  int disallow_extrapolation = 0;
370 
371  struct extrapolation_table table;
372 
373  /* Initialize results */
374 
375  this->w->initialise(a,b);
376 
377  *result = 0;
378  *abserr = 0;
379 
380  size_t limit=this->w->limit;
381 
382  /* Test on accuracy */
383 
384  if (this->tol_abs <= 0 && (this->tol_rel < 50 * GSL_DBL_EPSILON ||
385  this->tol_rel < 0.5e-28)) {
386  this->last_iter=0;
387 
388  std::string estr="Tolerance cannot be achieved with given ";
389  estr+="value of tol_abs, "+dtos(l_epsabs)+", and tol_rel, "+
390  dtos(l_epsrel)+", in inte_singular_gsl::qags().";
391  O2SCL_ERR(estr.c_str(),exc_ebadtol);
392  }
393 
394  /* Perform the first integration */
395 
396  this->gauss_kronrod(func,a,b,&result0,&abserr0,&resabs0,&resasc0);
397 
398  this->w->set_initial_result (result0, abserr0);
399 
400  tolerance = GSL_MAX_DBL (this->tol_abs, this->tol_rel * fabs (result0));
401 
402  if (abserr0 <= 100 * GSL_DBL_EPSILON * resabs0 &&
403  abserr0 > tolerance) {
404 
405  *result = result0;
406  *abserr = abserr0;
407 
408  this->last_iter=1;
409 
410  std::string estr="Cannot reach tolerance because of roundoff error ";
411  estr+="on first attempt in inte_singular_gsl::qags().";
412  O2SCL_CONV_RET(estr.c_str(),exc_eround,this->err_nonconv);
413 
414  } else if ((abserr0 <= tolerance &&
415  abserr0 != resasc0) || abserr0 == 0.0) {
416 
417  *result = result0;
418  *abserr = abserr0;
419  this->last_iter=1;
420  return success;
421 
422  } else if (limit == 1) {
423 
424  *result = result0;
425  *abserr = abserr0;
426 
427  this->last_iter=1;
428  O2SCL_CONV2_RET("A maximum of 1 iteration was insufficient ",
429  "in inte_singular_gsl::qags().",
430  exc_emaxiter,this->err_nonconv);
431  }
432 
433  /* Initialization */
434 
435  initialise_table (&table);
436  append_table (&table, result0);
437 
438  area = result0;
439  errsum = abserr0;
440 
441  res_ext = result0;
442  err_ext = GSL_DBL_MAX;
443 
444  positive_integrand = this->test_positivity (result0, resabs0);
445 
446  iteration = 1;
447 
448  do {
449 
450  // Output iteration information
451  if (this->verbose>0) {
452  std::cout << this->type();
453  std::cout << " Iter: " << iteration;
454  std::cout.setf(std::ios::showpos);
455  std::cout << " Res: " << area;
456  std::cout.unsetf(std::ios::showpos);
457  std::cout << " Err: " << errsum
458  << " Tol: " << tolerance << std::endl;
459  if (this->verbose>1) {
460  char ch;
461  std::cout << "Press a key and type enter to continue. " ;
462  std::cin >> ch;
463  }
464  }
465 
466  size_t current_level;
467  double a1, b1, a2, b2;
468  double a_i, b_i, r_i, e_i;
469  double area1 = 0, area2 = 0, area12 = 0;
470  double error1 = 0, error2 = 0, error12 = 0;
471  double resasc1, resasc2;
472  double resabs1, resabs2;
473  double last_e_i;
474 
475  /* Bisect the subinterval with the largest error estimate */
476 
477  this->w->retrieve (&a_i, &b_i, &r_i, &e_i);
478 
479  current_level = this->w->level[this->w->i] + 1;
480 
481  a1 = a_i;
482  b1 = 0.5 * (a_i + b_i);
483  a2 = b1;
484  b2 = b_i;
485 
486  iteration++;
487 
488  this->gauss_kronrod(func,a1,b1,&area1,&error1,&resabs1,&resasc1);
489  this->gauss_kronrod(func,a2,b2,&area2,&error2,&resabs2,&resasc2);
490 
491  area12 = area1 + area2;
492  error12 = error1 + error2;
493  last_e_i = e_i;
494 
495  /* Improve previous approximations to the integral and test for
496  accuracy.
497 
498  We write these expressions in the same way as the original
499  QUADPACK code so that the rounding errors are the same, which
500  makes testing easier.
501  */
502 
503  errsum = errsum + error12 - e_i;
504  area = area + area12 - r_i;
505 
506  tolerance = GSL_MAX_DBL (this->tol_abs, this->tol_rel * fabs (area));
507  if (resasc1 != error1 && resasc2 != error2) {
508  double delta = r_i - area12;
509 
510  if (fabs (delta) <= 1.0e-5 * fabs (area12) &&
511  error12 >= 0.99 * e_i) {
512  if (!extrapolate) {
513  roundoff_type1++;
514  } else {
515  roundoff_type2++;
516  }
517  }
518  if (iteration > 10 && error12 > e_i) {
519  roundoff_type3++;
520  }
521  }
522 
523  // Test for roundoff and eventually set error flag
524 
525  if (roundoff_type1 + roundoff_type2 >= 10 ||
526  roundoff_type3 >= 20) {
527  /* round off error */
528  error_type = 2;
529  }
530 
531  if (roundoff_type2 >= 5) {
532  error_type2 = 1;
533  }
534 
535  // Set error flag in the case of bad integrand behaviour at
536  // a point of the integration range
537 
538  if (this->w->subinterval_too_small (a1, a2, b2)) {
539  error_type = 4;
540  }
541 
542  /* append the newly-created intervals to the list */
543 
544  this->w->update(a1,b1,area1,error1,a2,b2,area2,error2);
545 
546  if (errsum <= tolerance) {
547 
548  // Output final iteration information
549  if (this->verbose>0) {
550  std::cout << this->type();
551  std::cout << " Iter: " << iteration;
552  std::cout.setf(std::ios::showpos);
553  std::cout << " Res: " << area;
554  std::cout.unsetf(std::ios::showpos);
555  std::cout << " Err: " << errsum
556  << " Tol: " << tolerance << std::endl;
557  if (this->verbose>1) {
558  char ch;
559  std::cout << "Press a key and type enter to continue. " ;
560  std::cin >> ch;
561  }
562  }
563 
564  goto compute_result;
565  }
566 
567  if (error_type) {
568  break;
569  }
570 
571  if (iteration >= limit - 1) {
572  error_type = 1;
573  break;
574  }
575 
576  if (iteration == 2) {
577  error_over_large_intervals = errsum;
578  ertest = tolerance;
579  append_table (&table,area);
580  continue;
581  }
582 
583  if (disallow_extrapolation) {
584  continue;
585  }
586 
587  error_over_large_intervals += -last_e_i;
588 
589  if (current_level < this->w->maximum_level) {
590  error_over_large_intervals += error12;
591  }
592 
593  if (!extrapolate) {
594 
595  /* test whether the interval to be bisected next is the
596  smallest interval. */
597 
598  if (large_interval (this->w)) {
599  continue;
600  }
601 
602  extrapolate = 1;
603  this->w->nrmax = 1;
604  }
605 
606  if (!error_type2 && error_over_large_intervals > ertest) {
607  if (increase_nrmax (this->w)) {
608  continue;
609  }
610  }
611 
612  // Perform extrapolation
613 
614  append_table(&table,area);
615 
616  qelg(&table,&reseps,&abseps);
617 
618  ktmin++;
619 
620  if (ktmin > 5 && err_ext < 0.001 * errsum) {
621  error_type = 5;
622  }
623 
624  if (abseps < err_ext) {
625  ktmin = 0;
626  err_ext = abseps;
627  res_ext = reseps;
628  correc = error_over_large_intervals;
629  ertest = GSL_MAX_DBL (this->tol_abs,
630  this->tol_rel * fabs (reseps));
631  if (err_ext <= ertest) {
632  break;
633  }
634  }
635 
636  /* Prepare bisection of the smallest interval. */
637 
638  if (table.n == 1) {
639  disallow_extrapolation = 1;
640  }
641 
642  if (error_type == 5) {
643  break;
644  }
645 
646  /* work on interval with largest error */
647 
648  reset_nrmax (this->w);
649  extrapolate = 0;
650  error_over_large_intervals = errsum;
651 
652  } while (iteration < limit);
653 
654  *result = res_ext;
655  *abserr = err_ext;
656 
657  if (err_ext == GSL_DBL_MAX)
658  goto compute_result;
659 
660  if (error_type || error_type2) {
661  if (error_type2) {
662  err_ext += correc;
663  }
664 
665  if (error_type == 0)
666  error_type = 3;
667 
668  if (res_ext != 0.0 && area != 0.0) {
669  if (err_ext / fabs (res_ext) > errsum / fabs (area))
670  goto compute_result;
671  } else if (err_ext > errsum) {
672  goto compute_result;
673  } else if (area == 0.0) {
674  goto return_error;
675  }
676  }
677 
678  /* Test on divergence. */
679 
680  {
681  double max_area = GSL_MAX_DBL (fabs (res_ext),fabs (area));
682 
683  if (!positive_integrand && max_area < 0.01 * resabs0)
684  goto return_error;
685  }
686 
687  {
688  double ratio = res_ext / area;
689 
690  if (ratio < 0.01 || ratio > 100.0 || errsum > fabs (area))
691  error_type = 6;
692  }
693 
694  goto return_error;
695 
696  compute_result:
697 
698  *result = this->w->sum_results();
699  *abserr = errsum;
700 
701  return_error:
702 
703  if (error_type > 2) {
704  error_type--;
705  }
706 
707  this->last_iter=iteration;
708 
709  if (error_type == 0) {
710  return success;
711  } else if (error_type == 1) {
712  std::string estr="Maximum number of subdivisions ("+itos(iteration);
713  estr+=") reached in inte_singular_gsl::qags().";
714  O2SCL_CONV_RET(estr.c_str(),exc_emaxiter,this->err_nonconv);
715  } else if (error_type == 2) {
716  std::string estr="Roundoff error prevents tolerance ";
717  estr+="from being achieved in inte_singular_gsl::qags().";
718  O2SCL_CONV_RET(estr.c_str(),exc_eround,this->err_nonconv);
719  } else if (error_type == 3) {
720  std::string estr="Bad integrand behavior ";
721  estr+="in inte_singular_gsl::qags().";
722  O2SCL_CONV_RET(estr.c_str(),exc_esing,this->err_nonconv);
723  } else if (error_type == 4) {
724  std::string estr="Roundoff error detected in extrapolation table ";
725  estr+="in inte_singular_gsl::qags().";
726  O2SCL_CONV_RET(estr.c_str(),exc_eround,this->err_nonconv);
727  } else if (error_type == 5) {
728  std::string estr="Integral is divergent or slowly convergent ";
729  estr+="in inte_singular_gsl::qags().";
730  O2SCL_CONV_RET(estr.c_str(),exc_ediverge,this->err_nonconv);
731  }
732 
733  std::string estr="Could not integrate function in inte_kronrod_gsl";
734  estr+="::qags() (it may have returned a non-finite result).";
735  O2SCL_ERR(estr.c_str(),exc_efailed);
736 
737  return exc_efailed;
738  }
739 
740  };
741 
742  /** \brief Integrate a function with a singularity (GSL)
743  [abstract base]
744 
745  This class contains the GSL-based integration function for
746  applying transformations to the user-defined integrand. The
747  casual end-user should use the classes explained in the
748  \ref inte_section section of the User's guide.
749  */
750  template<class func_t=funct11> class inte_transform_gsl :
751  public inte_singular_gsl<func_t> {
752 
753  public:
754 
755  /// The transformation to apply to the user-supplied function
756  virtual double transform(double t, func_t &func)=0;
757 
758  /** \brief Integration wrapper for internal transformed function
759  type
760  */
761  virtual void gauss_kronrod
762  (func_t &func, double a, double b,
763  double *result, double *abserr, double *resabs, double *resasc) {
764 
765  funct11 fmp=std::bind(std::mem_fn<double(double,func_t &)>
767  this,std::placeholders::_1,func);
768 
769  return this->gauss_kronrod_base
770  (fmp,a,b,result,abserr,resabs,resasc);
771  }
772 
773  };
774 
775 #ifndef DOXYGEN_NO_O2NS
776 }
777 #endif
778 
779 #endif
virtual double transform(double t, func_t &func)=0
The transformation to apply to the user-supplied function.
Integration workspace for the GSL integrators.
void initialise_table(struct extrapolation_table *table)
Initialize the table.
#define O2SCL_CONV_RET(d, n, b)
Set a "convergence" error and return the error value.
Definition: err_hnd.h:292
int qags(func_t &func, const double a, const double b, const double l_epsabs, const double l_epsrel, double *result, double *abserr)
Integration function.
std::function< double(double)> funct11
One-dimensional function typedef.
Definition: funct.h:44
Data table table class.
Definition: table.h:47
size_t * level
Numbers of subdivisions made.
void append_table(struct extrapolation_table *table, double y)
Append a result to the table.
struct o2scl::inte_singular_gsl::extrapolation_table extrap_table
A structure for extrapolation for inte_qags_gsl.
apparent singularity detected
Definition: err_hnd.h:93
exceeded max number of iterations
Definition: err_hnd.h:73
Base class for integrating a function with a singularity (GSL)
int large_interval(inte_workspace_gsl *workspace)
Determine if an interval is large.
#define O2SCL_CONV2_RET(d, d2, n, b)
Set an error and return the error value, two-string version.
Definition: err_hnd.h:298
size_t * order
Linear ordering vector for sort routine.
double rlist2[52]
Lower diagonals of the triangular epsilon table.
size_t last_iter
The most recent number of iterations taken.
Definition: inte.h:63
bool err_nonconv
If true, call the error handler if the routine does not converge or reach the desired tolerance (defa...
Definition: inte.h:81
int update(double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
Determine which new subinterval to add to the workspace stack and perform update. ...
size_t i
Index of current subinterval.
virtual void gauss_kronrod(func_t &func, double a, double b, double *result, double *abserr, double *resabs, double *resasc)
Integration wrapper for user-specified function type.
generic failure
Definition: err_hnd.h:61
int subinterval_too_small(double a1, double a2, double b2)
Test whether the proposed subdivision falls before floating-point precision.
double tol_abs
The maximum absolute uncertainty in the value of the integral (default )
Definition: inte.h:73
virtual void gauss_kronrod(func_t &func, double a, double b, double *result, double *abserr, double *resabs, double *resasc)
Integration wrapper for internal transformed function type.
int test_positivity(double result, double resabs)
Test if the integrand satisfies .
int initialise(double a, double b)
Initialize the workspace for an integration with limits a and b.
double res3la[3]
Three most recent results.
int set_initial_result(double result, double error)
Update the workspace with the result and error from the first integration.
std::string dtos(double x, int prec=6, bool auto_prec=false)
Convert a double to a string.
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
Definition: err_hnd.h:273
size_t size
Current number of subintervals being used.
int retrieve(double *a, double *b, double *r, double *e) const
Retrieve the ith result from the workspace stack.
Integrate a function with a singularity (GSL) [abstract base].
Basic Gauss-Kronrod integration class (GSL)
size_t nrmax
Counter for extrapolation routine.
void qelg(struct extrapolation_table *table, double *result, double *abserr)
Determines the limit of a given sequence of approximations.
inte_workspace_gsl * w
The integration workspace.
void gauss_kronrod_base(func2_t &func, double a, double b, double *result, double *abserr, double *resabs, double *resasc)
The base Gauss-Kronrod integration function template.
double sum_results()
Add up all of the contributions to construct the final result.
double tol_rel
The maximum relative uncertainty in the value of the integral (default )
Definition: inte.h:68
void reset_nrmax(inte_workspace_gsl *workspace)
Reset workspace to work on the interval with the largest error.
int increase_nrmax(inte_workspace_gsl *workspace)
Increase workspace.
A structure for extrapolation for inte_qags_gsl.
size_t n
Index of new element in the first column.
size_t limit
Maximum number of subintervals allocated.
size_t maximum_level
Depth of subdivisions reached.
std::string itos(int x)
Convert an integer to a string.
user specified an invalid tolerance
Definition: err_hnd.h:77
Success.
Definition: err_hnd.h:47
int verbose
Verbosity.
Definition: inte.h:60
failed because of roundoff error
Definition: err_hnd.h:87
integral or series is divergent
Definition: err_hnd.h:95
virtual const char * type()
Return string denoting type ("inte")
Definition: inte.h:106

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).
Hosted at Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads..