gsl_integration__qcheb.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /* integration/qcheb.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 <stdlib.h>
  21. #include "gsl_math.h"
  22. #include "gsl_integration.h"
  23. /* This function computes the 12-th order and 24-th order Chebyshev
  24. approximations to f(x) on [a,b] */
  25. void
  26. gsl_integration_qcheb (gsl_function * f, double a, double b, double *cheb12, double *cheb24)
  27. {
  28. size_t i;
  29. double fval[25], v[12];
  30. /* These are the values of cos(pi*k/24) for k=1..11 needed for the
  31. Chebyshev expansion of f(x) */
  32. const double x[11] = { 0.9914448613738104,
  33. 0.9659258262890683,
  34. 0.9238795325112868,
  35. 0.8660254037844386,
  36. 0.7933533402912352,
  37. 0.7071067811865475,
  38. 0.6087614290087206,
  39. 0.5000000000000000,
  40. 0.3826834323650898,
  41. 0.2588190451025208,
  42. 0.1305261922200516 };
  43. const double center = 0.5 * (b + a);
  44. const double half_length = 0.5 * (b - a);
  45. fval[0] = 0.5 * GSL_FN_EVAL (f, b);
  46. fval[12] = GSL_FN_EVAL (f, center);
  47. fval[24] = 0.5 * GSL_FN_EVAL (f, a);
  48. for (i = 1; i < 12; i++)
  49. {
  50. const size_t j = 24 - i;
  51. const double u = half_length * x[i-1];
  52. fval[i] = GSL_FN_EVAL(f, center + u);
  53. fval[j] = GSL_FN_EVAL(f, center - u);
  54. }
  55. for (i = 0; i < 12; i++)
  56. {
  57. const size_t j = 24 - i;
  58. v[i] = fval[i] - fval[j];
  59. fval[i] = fval[i] + fval[j];
  60. }
  61. {
  62. const double alam1 = v[0] - v[8];
  63. const double alam2 = x[5] * (v[2] - v[6] - v[10]);
  64. cheb12[3] = alam1 + alam2;
  65. cheb12[9] = alam1 - alam2;
  66. }
  67. {
  68. const double alam1 = v[1] - v[7] - v[9];
  69. const double alam2 = v[3] - v[5] - v[11];
  70. {
  71. const double alam = x[2] * alam1 + x[8] * alam2;
  72. cheb24[3] = cheb12[3] + alam;
  73. cheb24[21] = cheb12[3] - alam;
  74. }
  75. {
  76. const double alam = x[8] * alam1 - x[2] * alam2;
  77. cheb24[9] = cheb12[9] + alam;
  78. cheb24[15] = cheb12[9] - alam;
  79. }
  80. }
  81. {
  82. const double part1 = x[3] * v[4];
  83. const double part2 = x[7] * v[8];
  84. const double part3 = x[5] * v[6];
  85. {
  86. const double alam1 = v[0] + part1 + part2;
  87. const double alam2 = x[1] * v[2] + part3 + x[9] * v[10];
  88. cheb12[1] = alam1 + alam2;
  89. cheb12[11] = alam1 - alam2;
  90. }
  91. {
  92. const double alam1 = v[0] - part1 + part2;
  93. const double alam2 = x[9] * v[2] - part3 + x[1] * v[10];
  94. cheb12[5] = alam1 + alam2;
  95. cheb12[7] = alam1 - alam2;
  96. }
  97. }
  98. {
  99. const double alam = (x[0] * v[1] + x[2] * v[3] + x[4] * v[5]
  100. + x[6] * v[7] + x[8] * v[9] + x[10] * v[11]);
  101. cheb24[1] = cheb12[1] + alam;
  102. cheb24[23] = cheb12[1] - alam;
  103. }
  104. {
  105. const double alam = (x[10] * v[1] - x[8] * v[3] + x[6] * v[5]
  106. - x[4] * v[7] + x[2] * v[9] - x[0] * v[11]);
  107. cheb24[11] = cheb12[11] + alam;
  108. cheb24[13] = cheb12[11] - alam;
  109. }
  110. {
  111. const double alam = (x[4] * v[1] - x[8] * v[3] - x[0] * v[5]
  112. - x[10] * v[7] + x[2] * v[9] + x[6] * v[11]);
  113. cheb24[5] = cheb12[5] + alam;
  114. cheb24[19] = cheb12[5] - alam;
  115. }
  116. {
  117. const double alam = (x[6] * v[1] - x[2] * v[3] - x[10] * v[5]
  118. + x[0] * v[7] - x[8] * v[9] - x[4] * v[11]);
  119. cheb24[7] = cheb12[7] + alam;
  120. cheb24[17] = cheb12[7] - alam;
  121. }
  122. for (i = 0; i < 6; i++)
  123. {
  124. const size_t j = 12 - i;
  125. v[i] = fval[i] - fval[j];
  126. fval[i] = fval[i] + fval[j];
  127. }
  128. {
  129. const double alam1 = v[0] + x[7] * v[4];
  130. const double alam2 = x[3] * v[2];
  131. cheb12[2] = alam1 + alam2;
  132. cheb12[10] = alam1 - alam2;
  133. }
  134. cheb12[6] = v[0] - v[4];
  135. {
  136. const double alam = x[1] * v[1] + x[5] * v[3] + x[9] * v[5];
  137. cheb24[2] = cheb12[2] + alam;
  138. cheb24[22] = cheb12[2] - alam;
  139. }
  140. {
  141. const double alam = x[5] * (v[1] - v[3] - v[5]);
  142. cheb24[6] = cheb12[6] + alam;
  143. cheb24[18] = cheb12[6] - alam;
  144. }
  145. {
  146. const double alam = x[9] * v[1] - x[5] * v[3] + x[1] * v[5];
  147. cheb24[10] = cheb12[10] + alam;
  148. cheb24[14] = cheb12[10] - alam;
  149. }
  150. for (i = 0; i < 3; i++)
  151. {
  152. const size_t j = 6 - i;
  153. v[i] = fval[i] - fval[j];
  154. fval[i] = fval[i] + fval[j];
  155. }
  156. cheb12[4] = v[0] + x[7] * v[2];
  157. cheb12[8] = fval[0] - x[7] * fval[2];
  158. {
  159. const double alam = x[3] * v[1];
  160. cheb24[4] = cheb12[4] + alam;
  161. cheb24[20] = cheb12[4] - alam;
  162. }
  163. {
  164. const double alam = x[7] * fval[1] - fval[3];
  165. cheb24[8] = cheb12[8] + alam;
  166. cheb24[16] = cheb12[8] - alam;
  167. }
  168. cheb12[0] = fval[0] + fval[2];
  169. {
  170. const double alam = fval[1] + fval[3];
  171. cheb24[0] = cheb12[0] + alam;
  172. cheb24[24] = cheb12[0] - alam;
  173. }
  174. cheb12[12] = v[0] - v[2];
  175. cheb24[12] = cheb12[12];
  176. for (i = 1; i < 12; i++)
  177. {
  178. cheb12[i] *= 1.0 / 6.0;
  179. }
  180. cheb12[0] *= 1.0 / 12.0;
  181. cheb12[12] *= 1.0 / 12.0;
  182. for (i = 1; i < 24; i++)
  183. {
  184. cheb24[i] *= 1.0 / 12.0;
  185. }
  186. cheb24[0] *= 1.0 / 24.0;
  187. cheb24[24] *= 1.0 / 24.0;
  188. }