gsl_specfunc__bessel_J1.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /* specfunc/bessel_J1.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_trig.h"
  24. #include "gsl_sf_bessel.h"
  25. #include "gsl_specfunc__error.h"
  26. #include "gsl_specfunc__bessel.h"
  27. #include "gsl_specfunc__bessel_amp_phase.h"
  28. #include "gsl_specfunc__cheb_eval.c"
  29. #define ROOT_EIGHT (2.0*M_SQRT2)
  30. /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/
  31. /* based on SLATEC besj1, 1983 version, w. fullerton */
  32. /* chebyshev expansions
  33. series for bj1 on the interval 0. to 1.60000d+01
  34. with weighted error 4.48e-17
  35. log weighted error 16.35
  36. significant figures required 15.77
  37. decimal places required 16.89
  38. */
  39. static double bj1_data[12] = {
  40. -0.11726141513332787,
  41. -0.25361521830790640,
  42. 0.050127080984469569,
  43. -0.004631514809625081,
  44. 0.000247996229415914,
  45. -0.000008678948686278,
  46. 0.000000214293917143,
  47. -0.000000003936093079,
  48. 0.000000000055911823,
  49. -0.000000000000632761,
  50. 0.000000000000005840,
  51. -0.000000000000000044,
  52. };
  53. static cheb_series bj1_cs = {
  54. bj1_data,
  55. 11,
  56. -1, 1,
  57. 8
  58. };
  59. /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
  60. int gsl_sf_bessel_J1_e(const double x, gsl_sf_result * result)
  61. {
  62. double y = fabs(x);
  63. /* CHECK_POINTER(result) */
  64. if(y == 0.0) {
  65. result->val = 0.0;
  66. result->err = 0.0;
  67. return GSL_SUCCESS;
  68. }
  69. else if(y < 2.0*GSL_DBL_MIN) {
  70. UNDERFLOW_ERROR(result);
  71. }
  72. else if(y < ROOT_EIGHT * GSL_SQRT_DBL_EPSILON) {
  73. result->val = 0.5*x;
  74. result->err = 0.0;
  75. return GSL_SUCCESS;
  76. }
  77. else if(y < 4.0) {
  78. gsl_sf_result c;
  79. cheb_eval_e(&bj1_cs, 0.125*y*y-1.0, &c);
  80. result->val = x * (0.25 + c.val);
  81. result->err = fabs(x * c.err);
  82. return GSL_SUCCESS;
  83. }
  84. else {
  85. /* Because the leading term in the phase is y,
  86. * which we assume is exactly known, the error
  87. * in the cos() evaluation is bounded.
  88. */
  89. const double z = 32.0/(y*y) - 1.0;
  90. gsl_sf_result ca;
  91. gsl_sf_result ct;
  92. gsl_sf_result sp;
  93. const int stat_ca = cheb_eval_e(&_gsl_sf_bessel_amp_phase_bm1_cs, z, &ca);
  94. const int stat_ct = cheb_eval_e(&_gsl_sf_bessel_amp_phase_bth1_cs, z, &ct);
  95. const int stat_sp = gsl_sf_bessel_sin_pi4_e(y, ct.val/y, &sp);
  96. const double sqrty = sqrt(y);
  97. const double ampl = (0.75 + ca.val) / sqrty;
  98. result->val = (x < 0.0 ? -ampl : ampl) * sp.val;
  99. result->err = fabs(sp.val) * ca.err/sqrty + fabs(ampl) * sp.err;
  100. result->err += GSL_DBL_EPSILON * fabs(result->val);
  101. return GSL_ERROR_SELECT_3(stat_ca, stat_ct, stat_sp);
  102. }
  103. }
  104. /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
  105. #include "gsl_specfunc__eval.h"
  106. double gsl_sf_bessel_J1(const double x)
  107. {
  108. EVAL_RESULT(gsl_sf_bessel_J1_e(x, &result));
  109. }