gsl_specfunc__bessel_K0.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /* specfunc/bessel_K0.c
  2. *
  3. * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman
  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. /* Author: G. Jungman */
  20. #include "gsl__config.h"
  21. #include "gsl_math.h"
  22. #include "gsl_errno.h"
  23. #include "gsl_sf_exp.h"
  24. #include "gsl_sf_bessel.h"
  25. #include "gsl_specfunc__error.h"
  26. #include "gsl_specfunc__chebyshev.h"
  27. #include "gsl_specfunc__cheb_eval.c"
  28. /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/
  29. /* based on SLATEC bk0(), bk0e() */
  30. /* chebyshev expansions
  31. series for bk0 on the interval 0. to 4.00000d+00
  32. with weighted error 3.57e-19
  33. log weighted error 18.45
  34. significant figures required 17.99
  35. decimal places required 18.97
  36. series for ak0 on the interval 1.25000d-01 to 5.00000d-01
  37. with weighted error 5.34e-17
  38. log weighted error 16.27
  39. significant figures required 14.92
  40. decimal places required 16.89
  41. series for ak02 on the interval 0. to 1.25000d-01
  42. with weighted error 2.34e-17
  43. log weighted error 16.63
  44. significant figures required 14.67
  45. decimal places required 17.20
  46. */
  47. static double bk0_data[11] = {
  48. -0.03532739323390276872,
  49. 0.3442898999246284869,
  50. 0.03597993651536150163,
  51. 0.00126461541144692592,
  52. 0.00002286212103119451,
  53. 0.00000025347910790261,
  54. 0.00000000190451637722,
  55. 0.00000000001034969525,
  56. 0.00000000000004259816,
  57. 0.00000000000000013744,
  58. 0.00000000000000000035
  59. };
  60. static cheb_series bk0_cs = {
  61. bk0_data,
  62. 10,
  63. -1, 1,
  64. 10
  65. };
  66. static double ak0_data[17] = {
  67. -0.07643947903327941,
  68. -0.02235652605699819,
  69. 0.00077341811546938,
  70. -0.00004281006688886,
  71. 0.00000308170017386,
  72. -0.00000026393672220,
  73. 0.00000002563713036,
  74. -0.00000000274270554,
  75. 0.00000000031694296,
  76. -0.00000000003902353,
  77. 0.00000000000506804,
  78. -0.00000000000068895,
  79. 0.00000000000009744,
  80. -0.00000000000001427,
  81. 0.00000000000000215,
  82. -0.00000000000000033,
  83. 0.00000000000000005
  84. };
  85. static cheb_series ak0_cs = {
  86. ak0_data,
  87. 16,
  88. -1, 1,
  89. 10
  90. };
  91. static double ak02_data[14] = {
  92. -0.01201869826307592,
  93. -0.00917485269102569,
  94. 0.00014445509317750,
  95. -0.00000401361417543,
  96. 0.00000015678318108,
  97. -0.00000000777011043,
  98. 0.00000000046111825,
  99. -0.00000000003158592,
  100. 0.00000000000243501,
  101. -0.00000000000020743,
  102. 0.00000000000001925,
  103. -0.00000000000000192,
  104. 0.00000000000000020,
  105. -0.00000000000000002
  106. };
  107. static cheb_series ak02_cs = {
  108. ak02_data,
  109. 13,
  110. -1, 1,
  111. 8
  112. };
  113. /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
  114. int gsl_sf_bessel_K0_scaled_e(const double x, gsl_sf_result * result)
  115. {
  116. /* CHECK_POINTER(result) */
  117. if(x <= 0.0) {
  118. DOMAIN_ERROR(result);
  119. }
  120. else if(x <= 2.0) {
  121. const double lx = log(x);
  122. const double ex = exp(x);
  123. int stat_I0;
  124. gsl_sf_result I0;
  125. gsl_sf_result c;
  126. cheb_eval_e(&bk0_cs, 0.5*x*x-1.0, &c);
  127. stat_I0 = gsl_sf_bessel_I0_e(x, &I0);
  128. result->val = ex * ((-lx+M_LN2)*I0.val - 0.25 + c.val);
  129. result->err = ex * ((M_LN2+fabs(lx))*I0.err + c.err);
  130. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  131. return stat_I0;
  132. }
  133. else if(x <= 8.0) {
  134. const double sx = sqrt(x);
  135. gsl_sf_result c;
  136. cheb_eval_e(&ak0_cs, (16.0/x-5.0)/3.0, &c);
  137. result->val = (1.25 + c.val) / sx;
  138. result->err = c.err / sx;
  139. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  140. return GSL_SUCCESS;
  141. }
  142. else {
  143. const double sx = sqrt(x);
  144. gsl_sf_result c;
  145. cheb_eval_e(&ak02_cs, 16.0/x-1.0, &c);
  146. result->val = (1.25 + c.val) / sx;
  147. result->err = (c.err + GSL_DBL_EPSILON) / sx;
  148. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  149. return GSL_SUCCESS;
  150. }
  151. }
  152. int gsl_sf_bessel_K0_e(const double x, gsl_sf_result * result)
  153. {
  154. /* CHECK_POINTER(result) */
  155. if(x <= 0.0) {
  156. DOMAIN_ERROR(result);
  157. }
  158. else if(x <= 2.0) {
  159. const double lx = log(x);
  160. int stat_I0;
  161. gsl_sf_result I0;
  162. gsl_sf_result c;
  163. cheb_eval_e(&bk0_cs, 0.5*x*x-1.0, &c);
  164. stat_I0 = gsl_sf_bessel_I0_e(x, &I0);
  165. result->val = (-lx+M_LN2)*I0.val - 0.25 + c.val;
  166. result->err = (fabs(lx) + M_LN2) * I0.err + c.err;
  167. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  168. return stat_I0;
  169. }
  170. else {
  171. gsl_sf_result K0_scaled;
  172. int stat_K0 = gsl_sf_bessel_K0_scaled_e(x, &K0_scaled);
  173. int stat_e = gsl_sf_exp_mult_err_e(-x, GSL_DBL_EPSILON*fabs(x),
  174. K0_scaled.val, K0_scaled.err,
  175. result);
  176. return GSL_ERROR_SELECT_2(stat_e, stat_K0);
  177. }
  178. }
  179. /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
  180. #include "gsl_specfunc__eval.h"
  181. double gsl_sf_bessel_K0_scaled(const double x)
  182. {
  183. EVAL_RESULT(gsl_sf_bessel_K0_scaled_e(x, &result));
  184. }
  185. double gsl_sf_bessel_K0(const double x)
  186. {
  187. EVAL_RESULT(gsl_sf_bessel_K0_e(x, &result));
  188. }