gsl_integration__util.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /* integration/util.c
  2. *
  3. * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. static inline
  20. void update (gsl_integration_workspace * workspace,
  21. double a1, double b1, double area1, double error1,
  22. double a2, double b2, double area2, double error2);
  23. static inline void
  24. retrieve (const gsl_integration_workspace * workspace,
  25. double * a, double * b, double * r, double * e);
  26. static inline
  27. void update (gsl_integration_workspace * workspace,
  28. double a1, double b1, double area1, double error1,
  29. double a2, double b2, double area2, double error2)
  30. {
  31. double * alist = workspace->alist ;
  32. double * blist = workspace->blist ;
  33. double * rlist = workspace->rlist ;
  34. double * elist = workspace->elist ;
  35. size_t * level = workspace->level ;
  36. const size_t i_max = workspace->i ;
  37. const size_t i_new = workspace->size ;
  38. const size_t new_level = workspace->level[i_max] + 1;
  39. /* append the newly-created intervals to the list */
  40. if (error2 > error1)
  41. {
  42. alist[i_max] = a2; /* blist[maxerr] is already == b2 */
  43. rlist[i_max] = area2;
  44. elist[i_max] = error2;
  45. level[i_max] = new_level;
  46. alist[i_new] = a1;
  47. blist[i_new] = b1;
  48. rlist[i_new] = area1;
  49. elist[i_new] = error1;
  50. level[i_new] = new_level;
  51. }
  52. else
  53. {
  54. blist[i_max] = b1; /* alist[maxerr] is already == a1 */
  55. rlist[i_max] = area1;
  56. elist[i_max] = error1;
  57. level[i_max] = new_level;
  58. alist[i_new] = a2;
  59. blist[i_new] = b2;
  60. rlist[i_new] = area2;
  61. elist[i_new] = error2;
  62. level[i_new] = new_level;
  63. }
  64. workspace->size++;
  65. if (new_level > workspace->maximum_level)
  66. {
  67. workspace->maximum_level = new_level;
  68. }
  69. qpsrt (workspace) ;
  70. }
  71. static inline void
  72. retrieve (const gsl_integration_workspace * workspace,
  73. double * a, double * b, double * r, double * e)
  74. {
  75. const size_t i = workspace->i;
  76. double * alist = workspace->alist;
  77. double * blist = workspace->blist;
  78. double * rlist = workspace->rlist;
  79. double * elist = workspace->elist;
  80. *a = alist[i] ;
  81. *b = blist[i] ;
  82. *r = rlist[i] ;
  83. *e = elist[i] ;
  84. }
  85. static inline double
  86. sum_results (const gsl_integration_workspace * workspace);
  87. static inline double
  88. sum_results (const gsl_integration_workspace * workspace)
  89. {
  90. const double * const rlist = workspace->rlist ;
  91. const size_t n = workspace->size;
  92. size_t k;
  93. double result_sum = 0;
  94. for (k = 0; k < n; k++)
  95. {
  96. result_sum += rlist[k];
  97. }
  98. return result_sum;
  99. }
  100. static inline int
  101. subinterval_too_small (double a1, double a2, double b2);
  102. static inline int
  103. subinterval_too_small (double a1, double a2, double b2)
  104. {
  105. const double e = GSL_DBL_EPSILON;
  106. const double u = GSL_DBL_MIN;
  107. double tmp = (1 + 100 * e) * (fabs (a2) + 1000 * u);
  108. int status = fabs (a1) <= tmp && fabs (b2) <= tmp;
  109. return status;
  110. }