gsl_integration__qk.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /* integration/qk.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 <float.h>
  21. #include <math.h>
  22. #include "gsl_integration.h"
  23. #include "gsl_integration__err.c"
  24. void
  25. gsl_integration_qk (const int n,
  26. const double xgk[], const double wg[], const double wgk[],
  27. double fv1[], double fv2[],
  28. const gsl_function * f, double a, double b,
  29. double *result, double *abserr,
  30. double *resabs, double *resasc)
  31. {
  32. const double center = 0.5 * (a + b);
  33. const double half_length = 0.5 * (b - a);
  34. const double abs_half_length = fabs (half_length);
  35. const double f_center = GSL_FN_EVAL (f, center);
  36. double result_gauss = 0;
  37. double result_kronrod = f_center * wgk[n - 1];
  38. double result_abs = fabs (result_kronrod);
  39. double result_asc = 0;
  40. double mean = 0, err = 0;
  41. int j;
  42. if (n % 2 == 0)
  43. {
  44. result_gauss = f_center * wg[n / 2 - 1];
  45. }
  46. for (j = 0; j < (n - 1) / 2; j++)
  47. {
  48. const int jtw = j * 2 + 1; /* j=1,2,3 jtw=2,4,6 */
  49. const double abscissa = half_length * xgk[jtw];
  50. const double fval1 = GSL_FN_EVAL (f, center - abscissa);
  51. const double fval2 = GSL_FN_EVAL (f, center + abscissa);
  52. const double fsum = fval1 + fval2;
  53. fv1[jtw] = fval1;
  54. fv2[jtw] = fval2;
  55. result_gauss += wg[j] * fsum;
  56. result_kronrod += wgk[jtw] * fsum;
  57. result_abs += wgk[jtw] * (fabs (fval1) + fabs (fval2));
  58. }
  59. for (j = 0; j < n / 2; j++)
  60. {
  61. int jtwm1 = j * 2;
  62. const double abscissa = half_length * xgk[jtwm1];
  63. const double fval1 = GSL_FN_EVAL (f, center - abscissa);
  64. const double fval2 = GSL_FN_EVAL (f, center + abscissa);
  65. fv1[jtwm1] = fval1;
  66. fv2[jtwm1] = fval2;
  67. result_kronrod += wgk[jtwm1] * (fval1 + fval2);
  68. result_abs += wgk[jtwm1] * (fabs (fval1) + fabs (fval2));
  69. };
  70. mean = result_kronrod * 0.5;
  71. result_asc = wgk[n - 1] * fabs (f_center - mean);
  72. for (j = 0; j < n - 1; j++)
  73. {
  74. result_asc += wgk[j] * (fabs (fv1[j] - mean) + fabs (fv2[j] - mean));
  75. }
  76. /* scale by the width of the integration region */
  77. err = (result_kronrod - result_gauss) * half_length;
  78. result_kronrod *= half_length;
  79. result_abs *= abs_half_length;
  80. result_asc *= abs_half_length;
  81. *result = result_kronrod;
  82. *resabs = result_abs;
  83. *resasc = result_asc;
  84. *abserr = rescale_error (err, result_abs, result_asc);
  85. }