gsl_integration__qng.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /* integration/qng.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. #include "gsl__config.h"
  20. #include <math.h>
  21. #include <float.h>
  22. #include "gsl_math.h"
  23. #include "gsl_errno.h"
  24. #include "gsl_integration.h"
  25. #include "gsl_integration__err.c"
  26. #include "gsl_integration__qng.h"
  27. int
  28. gsl_integration_qng (const gsl_function *f,
  29. double a, double b,
  30. double epsabs, double epsrel,
  31. double * result, double * abserr, size_t * neval)
  32. {
  33. double fv1[5], fv2[5], fv3[5], fv4[5];
  34. double savfun[21]; /* array of function values which have been computed */
  35. double res10, res21, res43, res87; /* 10, 21, 43 and 87 point results */
  36. double result_kronrod, err ;
  37. double resabs; /* approximation to the integral of abs(f) */
  38. double resasc; /* approximation to the integral of abs(f-i/(b-a)) */
  39. const double half_length = 0.5 * (b - a);
  40. const double abs_half_length = fabs (half_length);
  41. const double center = 0.5 * (b + a);
  42. const double f_center = GSL_FN_EVAL(f, center);
  43. int k ;
  44. if (epsabs <= 0 && (epsrel < 50 * GSL_DBL_EPSILON || epsrel < 0.5e-28))
  45. {
  46. * result = 0;
  47. * abserr = 0;
  48. * neval = 0;
  49. GSL_ERROR ("tolerance cannot be acheived with given epsabs and epsrel",
  50. GSL_EBADTOL);
  51. };
  52. /* Compute the integral using the 10- and 21-point formula. */
  53. res10 = 0;
  54. res21 = w21b[5] * f_center;
  55. resabs = w21b[5] * fabs (f_center);
  56. for (k = 0; k < 5; k++)
  57. {
  58. const double abscissa = half_length * x1[k];
  59. const double fval1 = GSL_FN_EVAL(f, center + abscissa);
  60. const double fval2 = GSL_FN_EVAL(f, center - abscissa);
  61. const double fval = fval1 + fval2;
  62. res10 += w10[k] * fval;
  63. res21 += w21a[k] * fval;
  64. resabs += w21a[k] * (fabs (fval1) + fabs (fval2));
  65. savfun[k] = fval;
  66. fv1[k] = fval1;
  67. fv2[k] = fval2;
  68. }
  69. for (k = 0; k < 5; k++)
  70. {
  71. const double abscissa = half_length * x2[k];
  72. const double fval1 = GSL_FN_EVAL(f, center + abscissa);
  73. const double fval2 = GSL_FN_EVAL(f, center - abscissa);
  74. const double fval = fval1 + fval2;
  75. res21 += w21b[k] * fval;
  76. resabs += w21b[k] * (fabs (fval1) + fabs (fval2));
  77. savfun[k + 5] = fval;
  78. fv3[k] = fval1;
  79. fv4[k] = fval2;
  80. }
  81. resabs *= abs_half_length ;
  82. {
  83. const double mean = 0.5 * res21;
  84. resasc = w21b[5] * fabs (f_center - mean);
  85. for (k = 0; k < 5; k++)
  86. {
  87. resasc +=
  88. (w21a[k] * (fabs (fv1[k] - mean) + fabs (fv2[k] - mean))
  89. + w21b[k] * (fabs (fv3[k] - mean) + fabs (fv4[k] - mean)));
  90. }
  91. resasc *= abs_half_length ;
  92. }
  93. result_kronrod = res21 * half_length;
  94. err = rescale_error ((res21 - res10) * half_length, resabs, resasc) ;
  95. /* test for convergence. */
  96. if (err < epsabs || err < epsrel * fabs (result_kronrod))
  97. {
  98. * result = result_kronrod ;
  99. * abserr = err ;
  100. * neval = 21;
  101. return GSL_SUCCESS;
  102. }
  103. /* compute the integral using the 43-point formula. */
  104. res43 = w43b[11] * f_center;
  105. for (k = 0; k < 10; k++)
  106. {
  107. res43 += savfun[k] * w43a[k];
  108. }
  109. for (k = 0; k < 11; k++)
  110. {
  111. const double abscissa = half_length * x3[k];
  112. const double fval = (GSL_FN_EVAL(f, center + abscissa)
  113. + GSL_FN_EVAL(f, center - abscissa));
  114. res43 += fval * w43b[k];
  115. savfun[k + 10] = fval;
  116. }
  117. /* test for convergence */
  118. result_kronrod = res43 * half_length;
  119. err = rescale_error ((res43 - res21) * half_length, resabs, resasc);
  120. if (err < epsabs || err < epsrel * fabs (result_kronrod))
  121. {
  122. * result = result_kronrod ;
  123. * abserr = err ;
  124. * neval = 43;
  125. return GSL_SUCCESS;
  126. }
  127. /* compute the integral using the 87-point formula. */
  128. res87 = w87b[22] * f_center;
  129. for (k = 0; k < 21; k++)
  130. {
  131. res87 += savfun[k] * w87a[k];
  132. }
  133. for (k = 0; k < 22; k++)
  134. {
  135. const double abscissa = half_length * x4[k];
  136. res87 += w87b[k] * (GSL_FN_EVAL(f, center + abscissa)
  137. + GSL_FN_EVAL(f, center - abscissa));
  138. }
  139. /* test for convergence */
  140. result_kronrod = res87 * half_length ;
  141. err = rescale_error ((res87 - res43) * half_length, resabs, resasc);
  142. if (err < epsabs || err < epsrel * fabs (result_kronrod))
  143. {
  144. * result = result_kronrod ;
  145. * abserr = err ;
  146. * neval = 87;
  147. return GSL_SUCCESS;
  148. }
  149. /* failed to converge */
  150. * result = result_kronrod ;
  151. * abserr = err ;
  152. * neval = 87;
  153. GSL_ERROR("failed to reach tolerance with highest-order rule", GSL_ETOL) ;
  154. }