gsl_specfunc__bessel.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939
  1. /* specfunc/bessel.c
  2. *
  3. * Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003 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. /* Miscellaneous support functions for Bessel function evaluations.
  21. */
  22. #include "gsl__config.h"
  23. #include "gsl_math.h"
  24. #include "gsl_errno.h"
  25. #include "gsl_sf_airy.h"
  26. #include "gsl_sf_elementary.h"
  27. #include "gsl_sf_exp.h"
  28. #include "gsl_sf_gamma.h"
  29. #include "gsl_sf_trig.h"
  30. #include "gsl_specfunc__error.h"
  31. #include "gsl_specfunc__bessel_amp_phase.h"
  32. #include "gsl_specfunc__bessel_temme.h"
  33. #include "gsl_specfunc__bessel.h"
  34. #define CubeRoot2_ 1.25992104989487316476721060728
  35. /* Debye functions [Abramowitz+Stegun, 9.3.9-10] */
  36. inline static double
  37. debye_u1(const double * tpow)
  38. {
  39. return (3.0*tpow[1] - 5.0*tpow[3])/24.0;
  40. }
  41. inline static double
  42. debye_u2(const double * tpow)
  43. {
  44. return (81.0*tpow[2] - 462.0*tpow[4] + 385.0*tpow[6])/1152.0;
  45. }
  46. inline
  47. static double debye_u3(const double * tpow)
  48. {
  49. return (30375.0*tpow[3] - 369603.0*tpow[5] + 765765.0*tpow[7] - 425425.0*tpow[9])/414720.0;
  50. }
  51. inline
  52. static double debye_u4(const double * tpow)
  53. {
  54. return (4465125.0*tpow[4] - 94121676.0*tpow[6] + 349922430.0*tpow[8] -
  55. 446185740.0*tpow[10] + 185910725.0*tpow[12])/39813120.0;
  56. }
  57. inline
  58. static double debye_u5(const double * tpow)
  59. {
  60. return (1519035525.0*tpow[5] - 49286948607.0*tpow[7] +
  61. 284499769554.0*tpow[9] - 614135872350.0*tpow[11] +
  62. 566098157625.0*tpow[13] - 188699385875.0*tpow[15])/6688604160.0;
  63. }
  64. #if 0
  65. inline
  66. static double debye_u6(const double * tpow)
  67. {
  68. return (2757049477875.0*tpow[6] - 127577298354750.0*tpow[8] +
  69. 1050760774457901.0*tpow[10] - 3369032068261860.0*tpow[12] +
  70. 5104696716244125.0*tpow[14] - 3685299006138750.0*tpow[16] +
  71. 1023694168371875.0*tpow[18])/4815794995200.0;
  72. }
  73. #endif
  74. /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
  75. int
  76. gsl_sf_bessel_IJ_taylor_e(const double nu, const double x,
  77. const int sign,
  78. const int kmax,
  79. const double threshold,
  80. gsl_sf_result * result
  81. )
  82. {
  83. /* CHECK_POINTER(result) */
  84. if(nu < 0.0 || x < 0.0) {
  85. DOMAIN_ERROR(result);
  86. }
  87. else if(x == 0.0) {
  88. if(nu == 0.0) {
  89. result->val = 1.0;
  90. result->err = 0.0;
  91. }
  92. else {
  93. result->val = 0.0;
  94. result->err = 0.0;
  95. }
  96. return GSL_SUCCESS;
  97. }
  98. else {
  99. gsl_sf_result prefactor; /* (x/2)^nu / Gamma(nu+1) */
  100. gsl_sf_result sum;
  101. int stat_pre;
  102. int stat_sum;
  103. int stat_mul;
  104. if(nu == 0.0) {
  105. prefactor.val = 1.0;
  106. prefactor.err = 0.0;
  107. stat_pre = GSL_SUCCESS;
  108. }
  109. else if(nu < INT_MAX-1) {
  110. /* Separate the integer part and use
  111. * y^nu / Gamma(nu+1) = y^N /N! y^f / (N+1)_f,
  112. * to control the error.
  113. */
  114. const int N = (int)floor(nu + 0.5);
  115. const double f = nu - N;
  116. gsl_sf_result poch_factor;
  117. gsl_sf_result tc_factor;
  118. const int stat_poch = gsl_sf_poch_e(N+1.0, f, &poch_factor);
  119. const int stat_tc = gsl_sf_taylorcoeff_e(N, 0.5*x, &tc_factor);
  120. const double p = pow(0.5*x,f);
  121. prefactor.val = tc_factor.val * p / poch_factor.val;
  122. prefactor.err = tc_factor.err * p / poch_factor.val;
  123. prefactor.err += fabs(prefactor.val) / poch_factor.val * poch_factor.err;
  124. prefactor.err += 2.0 * GSL_DBL_EPSILON * fabs(prefactor.val);
  125. stat_pre = GSL_ERROR_SELECT_2(stat_tc, stat_poch);
  126. }
  127. else {
  128. gsl_sf_result lg;
  129. const int stat_lg = gsl_sf_lngamma_e(nu+1.0, &lg);
  130. const double term1 = nu*log(0.5*x);
  131. const double term2 = lg.val;
  132. const double ln_pre = term1 - term2;
  133. const double ln_pre_err = GSL_DBL_EPSILON * (fabs(term1)+fabs(term2)) + lg.err;
  134. const int stat_ex = gsl_sf_exp_err_e(ln_pre, ln_pre_err, &prefactor);
  135. stat_pre = GSL_ERROR_SELECT_2(stat_ex, stat_lg);
  136. }
  137. /* Evaluate the sum.
  138. * [Abramowitz+Stegun, 9.1.10]
  139. * [Abramowitz+Stegun, 9.6.7]
  140. */
  141. {
  142. const double y = sign * 0.25 * x*x;
  143. double sumk = 1.0;
  144. double term = 1.0;
  145. int k;
  146. for(k=1; k<=kmax; k++) {
  147. term *= y/((nu+k)*k);
  148. sumk += term;
  149. if(fabs(term/sumk) < threshold) break;
  150. }
  151. sum.val = sumk;
  152. sum.err = threshold * fabs(sumk);
  153. stat_sum = ( k >= kmax ? GSL_EMAXITER : GSL_SUCCESS );
  154. }
  155. stat_mul = gsl_sf_multiply_err_e(prefactor.val, prefactor.err,
  156. sum.val, sum.err,
  157. result);
  158. return GSL_ERROR_SELECT_3(stat_mul, stat_pre, stat_sum);
  159. }
  160. }
  161. /* x >> nu*nu+1
  162. * error ~ O( ((nu*nu+1)/x)^4 )
  163. *
  164. * empirical error analysis:
  165. * choose GSL_ROOT4_MACH_EPS * x > (nu*nu + 1)
  166. *
  167. * This is not especially useful. When the argument gets
  168. * large enough for this to apply, the cos() and sin()
  169. * start loosing digits. However, this seems inevitable
  170. * for this particular method.
  171. *
  172. * Wed Jun 25 14:39:38 MDT 2003 [GJ]
  173. * This function was inconsistent since the Q term did not
  174. * go to relative order eps^2. That's why the error estimate
  175. * originally given was screwy (it didn't make sense that the
  176. * "empirical" error was coming out O(eps^3)).
  177. * With Q to proper order, the error is O(eps^4).
  178. */
  179. int
  180. gsl_sf_bessel_Jnu_asympx_e(const double nu, const double x, gsl_sf_result * result)
  181. {
  182. double mu = 4.0*nu*nu;
  183. double mum1 = mu-1.0;
  184. double mum9 = mu-9.0;
  185. double mum25 = mu-25.0;
  186. double chi = x - (0.5*nu + 0.25)*M_PI;
  187. double P = 1.0 - mum1*mum9/(128.0*x*x);
  188. double Q = mum1/(8.0*x) * (1.0 - mum9*mum25/(384.0*x*x));
  189. double pre = sqrt(2.0/(M_PI*x));
  190. double c = cos(chi);
  191. double s = sin(chi);
  192. double r = mu/x;
  193. result->val = pre * (c*P - s*Q);
  194. result->err = pre * GSL_DBL_EPSILON * (1.0 + fabs(x)) * (fabs(c*P) + fabs(s*Q));
  195. result->err += pre * fabs(0.1*r*r*r*r);
  196. return GSL_SUCCESS;
  197. }
  198. /* x >> nu*nu+1
  199. */
  200. int
  201. gsl_sf_bessel_Ynu_asympx_e(const double nu, const double x, gsl_sf_result * result)
  202. {
  203. double ampl;
  204. double theta;
  205. double alpha = x;
  206. double beta = -0.5*nu*M_PI;
  207. int stat_a = gsl_sf_bessel_asymp_Mnu_e(nu, x, &ampl);
  208. int stat_t = gsl_sf_bessel_asymp_thetanu_corr_e(nu, x, &theta);
  209. double sin_alpha = sin(alpha);
  210. double cos_alpha = cos(alpha);
  211. double sin_chi = sin(beta + theta);
  212. double cos_chi = cos(beta + theta);
  213. double sin_term = sin_alpha * cos_chi + sin_chi * cos_alpha;
  214. double sin_term_mag = fabs(sin_alpha * cos_chi) + fabs(sin_chi * cos_alpha);
  215. result->val = ampl * sin_term;
  216. result->err = fabs(ampl) * GSL_DBL_EPSILON * sin_term_mag;
  217. result->err += fabs(result->val) * 2.0 * GSL_DBL_EPSILON;
  218. if(fabs(alpha) > 1.0/GSL_DBL_EPSILON) {
  219. result->err *= 0.5 * fabs(alpha);
  220. }
  221. else if(fabs(alpha) > 1.0/GSL_SQRT_DBL_EPSILON) {
  222. result->err *= 256.0 * fabs(alpha) * GSL_SQRT_DBL_EPSILON;
  223. }
  224. return GSL_ERROR_SELECT_2(stat_t, stat_a);
  225. }
  226. /* x >> nu*nu+1
  227. */
  228. int
  229. gsl_sf_bessel_Inu_scaled_asympx_e(const double nu, const double x, gsl_sf_result * result)
  230. {
  231. double mu = 4.0*nu*nu;
  232. double mum1 = mu-1.0;
  233. double mum9 = mu-9.0;
  234. double pre = 1.0/sqrt(2.0*M_PI*x);
  235. double r = mu/x;
  236. result->val = pre * (1.0 - mum1/(8.0*x) + mum1*mum9/(128.0*x*x));
  237. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val) + pre * fabs(0.1*r*r*r);
  238. return GSL_SUCCESS;
  239. }
  240. /* x >> nu*nu+1
  241. */
  242. int
  243. gsl_sf_bessel_Knu_scaled_asympx_e(const double nu, const double x, gsl_sf_result * result)
  244. {
  245. double mu = 4.0*nu*nu;
  246. double mum1 = mu-1.0;
  247. double mum9 = mu-9.0;
  248. double pre = sqrt(M_PI/(2.0*x));
  249. double r = nu/x;
  250. result->val = pre * (1.0 + mum1/(8.0*x) + mum1*mum9/(128.0*x*x));
  251. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val) + pre * fabs(0.1*r*r*r);
  252. return GSL_SUCCESS;
  253. }
  254. /* nu -> Inf; uniform in x > 0 [Abramowitz+Stegun, 9.7.7]
  255. *
  256. * error:
  257. * The error has the form u_N(t)/nu^N where 0 <= t <= 1.
  258. * It is not hard to show that |u_N(t)| is small for such t.
  259. * We have N=6 here, and |u_6(t)| < 0.025, so the error is clearly
  260. * bounded by 0.025/nu^6. This gives the asymptotic bound on nu
  261. * seen below as nu ~ 100. For general MACH_EPS it will be
  262. * nu > 0.5 / MACH_EPS^(1/6)
  263. * When t is small, the bound is even better because |u_N(t)| vanishes
  264. * as t->0. In fact u_N(t) ~ C t^N as t->0, with C ~= 0.1.
  265. * We write
  266. * err_N <= min(0.025, C(1/(1+(x/nu)^2))^3) / nu^6
  267. * therefore
  268. * min(0.29/nu^2, 0.5/(nu^2+x^2)) < MACH_EPS^{1/3}
  269. * and this is the general form.
  270. *
  271. * empirical error analysis, assuming 14 digit requirement:
  272. * choose x > 50.000 nu ==> nu > 3
  273. * choose x > 10.000 nu ==> nu > 15
  274. * choose x > 2.000 nu ==> nu > 50
  275. * choose x > 1.000 nu ==> nu > 75
  276. * choose x > 0.500 nu ==> nu > 80
  277. * choose x > 0.100 nu ==> nu > 83
  278. *
  279. * This makes sense. For x << nu, the error will be of the form u_N(1)/nu^N,
  280. * since the polynomial term will be evaluated near t=1, so the bound
  281. * on nu will become constant for small x. Furthermore, increasing x with
  282. * nu fixed will decrease the error.
  283. */
  284. int
  285. gsl_sf_bessel_Inu_scaled_asymp_unif_e(const double nu, const double x, gsl_sf_result * result)
  286. {
  287. int i;
  288. double z = x/nu;
  289. double root_term = hypot(1.0,z);
  290. double pre = 1.0/sqrt(2.0*M_PI*nu * root_term);
  291. double eta = root_term + log(z/(1.0+root_term));
  292. double ex_arg = ( z < 1.0/GSL_ROOT3_DBL_EPSILON ? nu*(-z + eta) : -0.5*nu/z*(1.0 - 1.0/(12.0*z*z)) );
  293. gsl_sf_result ex_result;
  294. int stat_ex = gsl_sf_exp_e(ex_arg, &ex_result);
  295. if(stat_ex == GSL_SUCCESS) {
  296. double t = 1.0/root_term;
  297. double sum;
  298. double tpow[16];
  299. tpow[0] = 1.0;
  300. for(i=1; i<16; i++) tpow[i] = t * tpow[i-1];
  301. sum = 1.0 + debye_u1(tpow)/nu + debye_u2(tpow)/(nu*nu) + debye_u3(tpow)/(nu*nu*nu)
  302. + debye_u4(tpow)/(nu*nu*nu*nu) + debye_u5(tpow)/(nu*nu*nu*nu*nu);
  303. result->val = pre * ex_result.val * sum;
  304. result->err = pre * ex_result.val / (nu*nu*nu*nu*nu*nu);
  305. result->err += pre * ex_result.err * fabs(sum);
  306. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  307. return GSL_SUCCESS;
  308. }
  309. else {
  310. result->val = 0.0;
  311. result->err = 0.0;
  312. return stat_ex;
  313. }
  314. }
  315. /* nu -> Inf; uniform in x > 0 [Abramowitz+Stegun, 9.7.8]
  316. *
  317. * error:
  318. * identical to that above for Inu_scaled
  319. */
  320. int
  321. gsl_sf_bessel_Knu_scaled_asymp_unif_e(const double nu, const double x, gsl_sf_result * result)
  322. {
  323. int i;
  324. double z = x/nu;
  325. double root_term = hypot(1.0,z);
  326. double pre = sqrt(M_PI/(2.0*nu*root_term));
  327. double eta = root_term + log(z/(1.0+root_term));
  328. double ex_arg = ( z < 1.0/GSL_ROOT3_DBL_EPSILON ? nu*(z - eta) : 0.5*nu/z*(1.0 + 1.0/(12.0*z*z)) );
  329. gsl_sf_result ex_result;
  330. int stat_ex = gsl_sf_exp_e(ex_arg, &ex_result);
  331. if(stat_ex == GSL_SUCCESS) {
  332. double t = 1.0/root_term;
  333. double sum;
  334. double tpow[16];
  335. tpow[0] = 1.0;
  336. for(i=1; i<16; i++) tpow[i] = t * tpow[i-1];
  337. sum = 1.0 - debye_u1(tpow)/nu + debye_u2(tpow)/(nu*nu) - debye_u3(tpow)/(nu*nu*nu)
  338. + debye_u4(tpow)/(nu*nu*nu*nu) - debye_u5(tpow)/(nu*nu*nu*nu*nu);
  339. result->val = pre * ex_result.val * sum;
  340. result->err = pre * ex_result.err * fabs(sum);
  341. result->err += pre * ex_result.val / (nu*nu*nu*nu*nu*nu);
  342. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  343. return GSL_SUCCESS;
  344. }
  345. else {
  346. result->val = 0.0;
  347. result->err = 0.0;
  348. return stat_ex;
  349. }
  350. }
  351. /* Evaluate J_mu(x),J_{mu+1}(x) and Y_mu(x),Y_{mu+1}(x) for |mu| < 1/2
  352. */
  353. int
  354. gsl_sf_bessel_JY_mu_restricted(const double mu, const double x,
  355. gsl_sf_result * Jmu, gsl_sf_result * Jmup1,
  356. gsl_sf_result * Ymu, gsl_sf_result * Ymup1)
  357. {
  358. /* CHECK_POINTER(Jmu) */
  359. /* CHECK_POINTER(Jmup1) */
  360. /* CHECK_POINTER(Ymu) */
  361. /* CHECK_POINTER(Ymup1) */
  362. if(x < 0.0 || fabs(mu) > 0.5) {
  363. Jmu->val = 0.0;
  364. Jmu->err = 0.0;
  365. Jmup1->val = 0.0;
  366. Jmup1->err = 0.0;
  367. Ymu->val = 0.0;
  368. Ymu->err = 0.0;
  369. Ymup1->val = 0.0;
  370. Ymup1->err = 0.0;
  371. GSL_ERROR ("error", GSL_EDOM);
  372. }
  373. else if(x == 0.0) {
  374. if(mu == 0.0) {
  375. Jmu->val = 1.0;
  376. Jmu->err = 0.0;
  377. }
  378. else {
  379. Jmu->val = 0.0;
  380. Jmu->err = 0.0;
  381. }
  382. Jmup1->val = 0.0;
  383. Jmup1->err = 0.0;
  384. Ymu->val = 0.0;
  385. Ymu->err = 0.0;
  386. Ymup1->val = 0.0;
  387. Ymup1->err = 0.0;
  388. GSL_ERROR ("error", GSL_EDOM);
  389. }
  390. else {
  391. int stat_Y;
  392. int stat_J;
  393. if(x < 2.0) {
  394. /* Use Taylor series for J and the Temme series for Y.
  395. * The Taylor series for J requires nu > 0, so we shift
  396. * up one and use the recursion relation to get Jmu, in
  397. * case mu < 0.
  398. */
  399. gsl_sf_result Jmup2;
  400. int stat_J1 = gsl_sf_bessel_IJ_taylor_e(mu+1.0, x, -1, 100, GSL_DBL_EPSILON, Jmup1);
  401. int stat_J2 = gsl_sf_bessel_IJ_taylor_e(mu+2.0, x, -1, 100, GSL_DBL_EPSILON, &Jmup2);
  402. double c = 2.0*(mu+1.0)/x;
  403. Jmu->val = c * Jmup1->val - Jmup2.val;
  404. Jmu->err = c * Jmup1->err + Jmup2.err;
  405. Jmu->err += 2.0 * GSL_DBL_EPSILON * fabs(Jmu->val);
  406. stat_J = GSL_ERROR_SELECT_2(stat_J1, stat_J2);
  407. stat_Y = gsl_sf_bessel_Y_temme(mu, x, Ymu, Ymup1);
  408. return GSL_ERROR_SELECT_2(stat_J, stat_Y);
  409. }
  410. else if(x < 1000.0) {
  411. double P, Q;
  412. double J_ratio;
  413. double J_sgn;
  414. const int stat_CF1 = gsl_sf_bessel_J_CF1(mu, x, &J_ratio, &J_sgn);
  415. const int stat_CF2 = gsl_sf_bessel_JY_steed_CF2(mu, x, &P, &Q);
  416. double Jprime_J_ratio = mu/x - J_ratio;
  417. double gamma = (P - Jprime_J_ratio)/Q;
  418. Jmu->val = J_sgn * sqrt(2.0/(M_PI*x) / (Q + gamma*(P-Jprime_J_ratio)));
  419. Jmu->err = 4.0 * GSL_DBL_EPSILON * fabs(Jmu->val);
  420. Jmup1->val = J_ratio * Jmu->val;
  421. Jmup1->err = fabs(J_ratio) * Jmu->err;
  422. Ymu->val = gamma * Jmu->val;
  423. Ymu->err = fabs(gamma) * Jmu->err;
  424. Ymup1->val = Ymu->val * (mu/x - P - Q/gamma);
  425. Ymup1->err = Ymu->err * fabs(mu/x - P - Q/gamma) + 4.0*GSL_DBL_EPSILON*fabs(Ymup1->val);
  426. return GSL_ERROR_SELECT_2(stat_CF1, stat_CF2);
  427. }
  428. else {
  429. /* Use asymptotics for large argument.
  430. */
  431. const int stat_J0 = gsl_sf_bessel_Jnu_asympx_e(mu, x, Jmu);
  432. const int stat_J1 = gsl_sf_bessel_Jnu_asympx_e(mu+1.0, x, Jmup1);
  433. const int stat_Y0 = gsl_sf_bessel_Ynu_asympx_e(mu, x, Ymu);
  434. const int stat_Y1 = gsl_sf_bessel_Ynu_asympx_e(mu+1.0, x, Ymup1);
  435. stat_J = GSL_ERROR_SELECT_2(stat_J0, stat_J1);
  436. stat_Y = GSL_ERROR_SELECT_2(stat_Y0, stat_Y1);
  437. return GSL_ERROR_SELECT_2(stat_J, stat_Y);
  438. }
  439. }
  440. }
  441. int
  442. gsl_sf_bessel_J_CF1(const double nu, const double x,
  443. double * ratio, double * sgn)
  444. {
  445. const double RECUR_BIG = GSL_SQRT_DBL_MAX;
  446. const int maxiter = 10000;
  447. int n = 1;
  448. double Anm2 = 1.0;
  449. double Bnm2 = 0.0;
  450. double Anm1 = 0.0;
  451. double Bnm1 = 1.0;
  452. double a1 = x/(2.0*(nu+1.0));
  453. double An = Anm1 + a1*Anm2;
  454. double Bn = Bnm1 + a1*Bnm2;
  455. double an;
  456. double fn = An/Bn;
  457. double dn = a1;
  458. double s = 1.0;
  459. while(n < maxiter) {
  460. double old_fn;
  461. double del;
  462. n++;
  463. Anm2 = Anm1;
  464. Bnm2 = Bnm1;
  465. Anm1 = An;
  466. Bnm1 = Bn;
  467. an = -x*x/(4.0*(nu+n-1.0)*(nu+n));
  468. An = Anm1 + an*Anm2;
  469. Bn = Bnm1 + an*Bnm2;
  470. if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) {
  471. An /= RECUR_BIG;
  472. Bn /= RECUR_BIG;
  473. Anm1 /= RECUR_BIG;
  474. Bnm1 /= RECUR_BIG;
  475. Anm2 /= RECUR_BIG;
  476. Bnm2 /= RECUR_BIG;
  477. }
  478. old_fn = fn;
  479. fn = An/Bn;
  480. del = old_fn/fn;
  481. dn = 1.0 / (2.0*(nu+n)/x - dn);
  482. if(dn < 0.0) s = -s;
  483. if(fabs(del - 1.0) < 2.0*GSL_DBL_EPSILON) break;
  484. }
  485. *ratio = fn;
  486. *sgn = s;
  487. if(n >= maxiter)
  488. GSL_ERROR ("error", GSL_EMAXITER);
  489. else
  490. return GSL_SUCCESS;
  491. }
  492. /* Evaluate the continued fraction CF1 for J_{nu+1}/J_nu
  493. * using Gautschi (Euler) equivalent series.
  494. * This exhibits an annoying problem because the
  495. * a_k are not positive definite (in fact they are all negative).
  496. * There are cases when rho_k blows up. Example: nu=1,x=4.
  497. */
  498. #if 0
  499. int
  500. gsl_sf_bessel_J_CF1_ser(const double nu, const double x,
  501. double * ratio, double * sgn)
  502. {
  503. const int maxk = 20000;
  504. double tk = 1.0;
  505. double sum = 1.0;
  506. double rhok = 0.0;
  507. double dk = 0.0;
  508. double s = 1.0;
  509. int k;
  510. for(k=1; k<maxk; k++) {
  511. double ak = -0.25 * (x/(nu+k)) * x/(nu+k+1.0);
  512. rhok = -ak*(1.0 + rhok)/(1.0 + ak*(1.0 + rhok));
  513. tk *= rhok;
  514. sum += tk;
  515. dk = 1.0 / (2.0/x - (nu+k-1.0)/(nu+k) * dk);
  516. if(dk < 0.0) s = -s;
  517. if(fabs(tk/sum) < GSL_DBL_EPSILON) break;
  518. }
  519. *ratio = x/(2.0*(nu+1.0)) * sum;
  520. *sgn = s;
  521. if(k == maxk)
  522. GSL_ERROR ("error", GSL_EMAXITER);
  523. else
  524. return GSL_SUCCESS;
  525. }
  526. #endif
  527. /* Evaluate the continued fraction CF1 for I_{nu+1}/I_nu
  528. * using Gautschi (Euler) equivalent series.
  529. */
  530. int
  531. gsl_sf_bessel_I_CF1_ser(const double nu, const double x, double * ratio)
  532. {
  533. const int maxk = 20000;
  534. double tk = 1.0;
  535. double sum = 1.0;
  536. double rhok = 0.0;
  537. int k;
  538. for(k=1; k<maxk; k++) {
  539. double ak = 0.25 * (x/(nu+k)) * x/(nu+k+1.0);
  540. rhok = -ak*(1.0 + rhok)/(1.0 + ak*(1.0 + rhok));
  541. tk *= rhok;
  542. sum += tk;
  543. if(fabs(tk/sum) < GSL_DBL_EPSILON) break;
  544. }
  545. *ratio = x/(2.0*(nu+1.0)) * sum;
  546. if(k == maxk)
  547. GSL_ERROR ("error", GSL_EMAXITER);
  548. else
  549. return GSL_SUCCESS;
  550. }
  551. int
  552. gsl_sf_bessel_JY_steed_CF2(const double nu, const double x,
  553. double * P, double * Q)
  554. {
  555. const int max_iter = 10000;
  556. const double SMALL = 1.0e-100;
  557. int i = 1;
  558. double x_inv = 1.0/x;
  559. double a = 0.25 - nu*nu;
  560. double p = -0.5*x_inv;
  561. double q = 1.0;
  562. double br = 2.0*x;
  563. double bi = 2.0;
  564. double fact = a*x_inv/(p*p + q*q);
  565. double cr = br + q*fact;
  566. double ci = bi + p*fact;
  567. double den = br*br + bi*bi;
  568. double dr = br/den;
  569. double di = -bi/den;
  570. double dlr = cr*dr - ci*di;
  571. double dli = cr*di + ci*dr;
  572. double temp = p*dlr - q*dli;
  573. q = p*dli + q*dlr;
  574. p = temp;
  575. for (i=2; i<=max_iter; i++) {
  576. a += 2*(i-1);
  577. bi += 2.0;
  578. dr = a*dr + br;
  579. di = a*di + bi;
  580. if(fabs(dr)+fabs(di) < SMALL) dr = SMALL;
  581. fact = a/(cr*cr+ci*ci);
  582. cr = br + cr*fact;
  583. ci = bi - ci*fact;
  584. if(fabs(cr)+fabs(ci) < SMALL) cr = SMALL;
  585. den = dr*dr + di*di;
  586. dr /= den;
  587. di /= -den;
  588. dlr = cr*dr - ci*di;
  589. dli = cr*di + ci*dr;
  590. temp = p*dlr - q*dli;
  591. q = p*dli + q*dlr;
  592. p = temp;
  593. if(fabs(dlr-1.0)+fabs(dli) < GSL_DBL_EPSILON) break;
  594. }
  595. *P = p;
  596. *Q = q;
  597. if(i == max_iter)
  598. GSL_ERROR ("error", GSL_EMAXITER);
  599. else
  600. return GSL_SUCCESS;
  601. }
  602. /* Evaluate continued fraction CF2, using Thompson-Barnett-Temme method,
  603. * to obtain values of exp(x)*K_nu and exp(x)*K_{nu+1}.
  604. *
  605. * This is unstable for small x; x > 2 is a good cutoff.
  606. * Also requires |nu| < 1/2.
  607. */
  608. int
  609. gsl_sf_bessel_K_scaled_steed_temme_CF2(const double nu, const double x,
  610. double * K_nu, double * K_nup1,
  611. double * Kp_nu)
  612. {
  613. const int maxiter = 10000;
  614. int i = 1;
  615. double bi = 2.0*(1.0 + x);
  616. double di = 1.0/bi;
  617. double delhi = di;
  618. double hi = di;
  619. double qi = 0.0;
  620. double qip1 = 1.0;
  621. double ai = -(0.25 - nu*nu);
  622. double a1 = ai;
  623. double ci = -ai;
  624. double Qi = -ai;
  625. double s = 1.0 + Qi*delhi;
  626. for(i=2; i<=maxiter; i++) {
  627. double dels;
  628. double tmp;
  629. ai -= 2.0*(i-1);
  630. ci = -ai*ci/i;
  631. tmp = (qi - bi*qip1)/ai;
  632. qi = qip1;
  633. qip1 = tmp;
  634. Qi += ci*qip1;
  635. bi += 2.0;
  636. di = 1.0/(bi + ai*di);
  637. delhi = (bi*di - 1.0) * delhi;
  638. hi += delhi;
  639. dels = Qi*delhi;
  640. s += dels;
  641. if(fabs(dels/s) < GSL_DBL_EPSILON) break;
  642. }
  643. hi *= -a1;
  644. *K_nu = sqrt(M_PI/(2.0*x)) / s;
  645. *K_nup1 = *K_nu * (nu + x + 0.5 - hi)/x;
  646. *Kp_nu = - *K_nup1 + nu/x * *K_nu;
  647. if(i == maxiter)
  648. GSL_ERROR ("error", GSL_EMAXITER);
  649. else
  650. return GSL_SUCCESS;
  651. }
  652. int gsl_sf_bessel_cos_pi4_e(double y, double eps, gsl_sf_result * result)
  653. {
  654. const double sy = sin(y);
  655. const double cy = cos(y);
  656. const double s = sy + cy;
  657. const double d = sy - cy;
  658. const double abs_sum = fabs(cy) + fabs(sy);
  659. double seps;
  660. double ceps;
  661. if(fabs(eps) < GSL_ROOT5_DBL_EPSILON) {
  662. const double e2 = eps*eps;
  663. seps = eps * (1.0 - e2/6.0 * (1.0 - e2/20.0));
  664. ceps = 1.0 - e2/2.0 * (1.0 - e2/12.0);
  665. }
  666. else {
  667. seps = sin(eps);
  668. ceps = cos(eps);
  669. }
  670. result->val = (ceps * s - seps * d)/ M_SQRT2;
  671. result->err = 2.0 * GSL_DBL_EPSILON * (fabs(ceps) + fabs(seps)) * abs_sum / M_SQRT2;
  672. /* Try to account for error in evaluation of sin(y), cos(y).
  673. * This is a little sticky because we don't really know
  674. * how the library routines are doing their argument reduction.
  675. * However, we will make a reasonable guess.
  676. * FIXME ?
  677. */
  678. if(y > 1.0/GSL_DBL_EPSILON) {
  679. result->err *= 0.5 * y;
  680. }
  681. else if(y > 1.0/GSL_SQRT_DBL_EPSILON) {
  682. result->err *= 256.0 * y * GSL_SQRT_DBL_EPSILON;
  683. }
  684. return GSL_SUCCESS;
  685. }
  686. int gsl_sf_bessel_sin_pi4_e(double y, double eps, gsl_sf_result * result)
  687. {
  688. const double sy = sin(y);
  689. const double cy = cos(y);
  690. const double s = sy + cy;
  691. const double d = sy - cy;
  692. const double abs_sum = fabs(cy) + fabs(sy);
  693. double seps;
  694. double ceps;
  695. if(fabs(eps) < GSL_ROOT5_DBL_EPSILON) {
  696. const double e2 = eps*eps;
  697. seps = eps * (1.0 - e2/6.0 * (1.0 - e2/20.0));
  698. ceps = 1.0 - e2/2.0 * (1.0 - e2/12.0);
  699. }
  700. else {
  701. seps = sin(eps);
  702. ceps = cos(eps);
  703. }
  704. result->val = (ceps * d + seps * s)/ M_SQRT2;
  705. result->err = 2.0 * GSL_DBL_EPSILON * (fabs(ceps) + fabs(seps)) * abs_sum / M_SQRT2;
  706. /* Try to account for error in evaluation of sin(y), cos(y).
  707. * See above.
  708. * FIXME ?
  709. */
  710. if(y > 1.0/GSL_DBL_EPSILON) {
  711. result->err *= 0.5 * y;
  712. }
  713. else if(y > 1.0/GSL_SQRT_DBL_EPSILON) {
  714. result->err *= 256.0 * y * GSL_SQRT_DBL_EPSILON;
  715. }
  716. return GSL_SUCCESS;
  717. }
  718. /************************************************************************
  719. * *
  720. Asymptotic approximations 8.11.5, 8.12.5, and 8.42.7 from
  721. G.N.Watson, A Treatise on the Theory of Bessel Functions,
  722. 2nd Edition (Cambridge University Press, 1944).
  723. Higher terms in expansion for x near l given by
  724. Airey in Phil. Mag. 31, 520 (1916).
  725. This approximation is accurate to near 0.1% at the boundaries
  726. between the asymptotic regions; well away from the boundaries
  727. the accuracy is better than 10^{-5}.
  728. * *
  729. ************************************************************************/
  730. #if 0
  731. double besselJ_meissel(double nu, double x)
  732. {
  733. double beta = pow(nu, 0.325);
  734. double result;
  735. /* Fitted matching points. */
  736. double llimit = 1.1 * beta;
  737. double ulimit = 1.3 * beta;
  738. double nu2 = nu * nu;
  739. if (nu < 5. && x < 1.)
  740. {
  741. /* Small argument and order. Use a Taylor expansion. */
  742. int k;
  743. double xo2 = 0.5 * x;
  744. double gamfactor = pow(nu,nu) * exp(-nu) * sqrt(nu * 2. * M_PI)
  745. * (1. + 1./(12.*nu) + 1./(288.*nu*nu));
  746. double prefactor = pow(xo2, nu) / gamfactor;
  747. double C[5];
  748. C[0] = 1.;
  749. C[1] = -C[0] / (nu+1.);
  750. C[2] = -C[1] / (2.*(nu+2.));
  751. C[3] = -C[2] / (3.*(nu+3.));
  752. C[4] = -C[3] / (4.*(nu+4.));
  753. result = 0.;
  754. for(k=0; k<5; k++)
  755. result += C[k] * pow(xo2, 2.*k);
  756. result *= prefactor;
  757. }
  758. else if(x < nu - llimit)
  759. {
  760. /* Small x region: x << l. */
  761. double z = x / nu;
  762. double z2 = z*z;
  763. double rtomz2 = sqrt(1.-z2);
  764. double omz2_2 = (1.-z2)*(1.-z2);
  765. /* Calculate Meissel exponent. */
  766. double term1 = 1./(24.*nu) * ((2.+3.*z2)/((1.-z2)*rtomz2) -2.);
  767. double term2 = - z2*(4. + z2)/(16.*nu2*(1.-z2)*omz2_2);
  768. double V_nu = term1 + term2;
  769. /* Calculate the harmless prefactor. */
  770. double sterlingsum = 1. + 1./(12.*nu) + 1./(288*nu2);
  771. double harmless = 1. / (sqrt(rtomz2*2.*M_PI*nu) * sterlingsum);
  772. /* Calculate the logarithm of the nu dependent prefactor. */
  773. double ln_nupre = rtomz2 + log(z) - log(1. + rtomz2);
  774. result = harmless * exp(nu*ln_nupre - V_nu);
  775. }
  776. else if(x < nu + ulimit)
  777. {
  778. /* Intermediate region 1: x near nu. */
  779. double eps = 1.-nu/x;
  780. double eps_x = eps * x;
  781. double eps_x_2 = eps_x * eps_x;
  782. double xo6 = x/6.;
  783. double B[6];
  784. static double gam[6] = {2.67894, 1.35412, 1., 0.89298, 0.902745, 1.};
  785. static double sf[6] = {0.866025, 0.866025, 0., -0.866025, -0.866025, 0.};
  786. /* Some terms are identically zero, because sf[] can be zero.
  787. * Some terms do not appear in the result.
  788. */
  789. B[0] = 1.;
  790. B[1] = eps_x;
  791. /* B[2] = 0.5 * eps_x_2 - 1./20.; */
  792. B[3] = eps_x * (eps_x_2/6. - 1./15.);
  793. B[4] = eps_x_2 * (eps_x_2 - 1.)/24. + 1./280.;
  794. /* B[5] = eps_x * (eps_x_2*(0.5*eps_x_2 - 1.)/60. + 43./8400.); */
  795. result = B[0] * gam[0] * sf[0] / pow(xo6, 1./3.);
  796. result += B[1] * gam[1] * sf[1] / pow(xo6, 2./3.);
  797. result += B[3] * gam[3] * sf[3] / pow(xo6, 4./3.);
  798. result += B[4] * gam[4] * sf[4] / pow(xo6, 5./3.);
  799. result /= (3.*M_PI);
  800. }
  801. else
  802. {
  803. /* Region of very large argument. Use expansion
  804. * for x>>l, and we need not be very exacting.
  805. */
  806. double secb = x/nu;
  807. double sec2b= secb*secb;
  808. double cotb = 1./sqrt(sec2b-1.); /* cotb=cot(beta) */
  809. double beta = acos(nu/x);
  810. double trigarg = nu/cotb - nu*beta - 0.25 * M_PI;
  811. double cot3b = cotb * cotb * cotb;
  812. double cot6b = cot3b * cot3b;
  813. double sum1, sum2, expterm, prefactor, trigcos;
  814. sum1 = 2.0 + 3.0 * sec2b;
  815. trigarg -= sum1 * cot3b / (24.0 * nu);
  816. trigcos = cos(trigarg);
  817. sum2 = 4.0 + sec2b;
  818. expterm = sum2 * sec2b * cot6b / (16.0 * nu2);
  819. expterm = exp(-expterm);
  820. prefactor = sqrt(2. * cotb / (nu * M_PI));
  821. result = prefactor * expterm * trigcos;
  822. }
  823. return result;
  824. }
  825. #endif