30 #ifndef MATHLIB_STANDALONE 31 #include <R_ext/Memory.h> 34 #define min0(x, y) (((x) <= (y)) ? (x) : (y)) 35 #define max0(x, y) (((x) <= (y)) ? (y) : (x)) 38 static void K_bessel(Float *x, Float *alpha,
int *nb,
39 int *ize, Float *bk,
int *ncalc);
42 Float bessel_k(Float x, Float alpha,
double expo)
46 #ifndef MATHLIB_STANDALONE 52 if (ISNAN(x) || ISNAN(alpha))
return x + alpha;
55 ML_ERROR(ME_RANGE,
"bessel_k");
61 nb = 1+ (int)floor(alpha);
62 alpha -= (double)(nb-1);
63 #ifdef MATHLIB_STANDALONE 64 bk = (Float *) calloc(nb,
sizeof(Float));
65 if (!bk) MATHLIB_ERROR(
"%s", _(
"bessel_k allocation error"));
68 bk = (Float *) R_alloc((
size_t) nb,
sizeof(Float));
70 K_bessel(&x, &alpha, &nb, &ize, bk, &ncalc);
73 MATHLIB_WARNING4(_(
"bessel_k(%g): ncalc (=%d) != nb (=%d); alpha=%g. Arg. out of range?\n"),
76 MATHLIB_WARNING2(_(
"bessel_k(%g,nu=%g): precision lost in result\n"),
77 x, alpha+(
double)nb-1);
80 #ifdef MATHLIB_STANDALONE 91 Float bessel_k_ex(Float x, Float alpha,
double expo, Float *bk)
97 if (ISNAN(x) || ISNAN(alpha))
return x + alpha;
100 ML_ERROR(ME_RANGE,
"bessel_k");
106 nb = 1+ (int)floor(alpha);
107 alpha -= (double)(nb-1);
108 K_bessel(&x, &alpha, &nb, &ize, bk, &ncalc);
111 MATHLIB_WARNING4(_(
"bessel_k(%g): ncalc (=%d) != nb (=%d); alpha=%g. Arg. out of range?\n"),
112 x, ncalc, nb, alpha);
114 MATHLIB_WARNING2(_(
"bessel_k(%g,nu=%g): precision lost in result\n"),
115 x, alpha+(
double)nb-1);
121 template<
class Float>
122 static void K_bessel(Float *x, Float *alpha,
int *nb,
123 int *ize, Float *bk,
int *ncalc)
218 const static double a = .11593151565841244881;
224 const static double p[8] = { .805629875690432845,20.4045500205365151,
225 157.705605106676174,536.671116469207504,900.382759291288778,
226 730.923886650660393,229.299301509425145,.822467033424113231 };
227 const static double q[7] = { 29.4601986247850434,277.577868510221208,
228 1206.70325591027438,2762.91444159791519,3443.74050506564618,
229 2210.63190113378647,572.267338359892221 };
231 const static double r[5] = { -.48672575865218401848,13.079485869097804016,
232 -101.96490580880537526,347.65409106507813131,
233 3.495898124521934782e-4 };
234 const static double s[4] = { -25.579105509976461286,212.57260432226544008,
235 -610.69018684944109624,422.69668805777760407 };
237 const static double t[6] = { 1.6125990452916363814e-10,
238 2.5051878502858255354e-8,2.7557319615147964774e-6,
239 1.9841269840928373686e-4,.0083333333333334751799,
240 .16666666666666666446 };
242 const static double estm[6] = { 52.0583,5.7607,2.7782,14.4303,185.3004, 9.3715 };
243 const static double estf[7] = { 41.8341,7.1075,6.4306,42.511,1.35633,84.5096,20.};
246 int iend, i, j, k, m, ii, mplus1;
247 Float x2by4, twox, c, blpha, ratio, wminf;
248 Float d1, d2, d3, f0, f1, f2, p0, q0, t1, t2, twonu;
249 Float dm, ex, bk1, bk2, nu;
255 *ncalc = min0(*nb,0) - 2;
256 if (*nb > 0 && (0. <= nu && nu < 1.) && (1 <= *ize && *ize <= 2)) {
257 if(ex <= 0 || (*ize == 1 && ex > xmax_BESS_K)) {
259 if(ex < 0) ML_ERROR(ME_RANGE,
"K_bessel");
260 for(i=0; i < *nb; i++)
263 for(i=0; i < *nb; i++)
269 if (nu < sqxmin_BESS_K) {
272 }
else if (nu > .5) {
287 for (i = 2; i <= 7; i += 2) {
288 d1 = c * d1 + p[i - 1];
290 t1 = c * t1 + q[i - 1];
296 f0 = a + nu * (p[7] - nu * (d1 + d2) / (t1 + t2)) - f1;
297 q0 = exp(-nu * (a - nu * (p[7] + nu * (d1-d2) / (t1-t2)) - f1));
305 for (i = 0; i < 4; ++i) {
311 if (fabs(f1) <= .5) {
314 for (i = 0; i < 6; ++i) {
317 d2 = f0 + f0 * f1 * d2;
321 f0 = d2 - nu * d1 / (t1 * p0);
327 bk[0] = f0 + ex * f0;
339 if (bk[0] >= c / ratio) {
342 bk[0] = ratio * bk[0] / ex;
355 for (i = 1; i < *nb; ++i) {
370 x2by4 = ex * ex / 4.;
384 f0 = (d2 * f0 + p0 + q0) / d3;
388 t2 = c * (p0 - d2 * f0);
391 }
while (fabs(t1 / (f1 + bk1)) > DBL_EPSILON ||
392 fabs(t2 / (f2 + bk2)) > DBL_EPSILON);
394 bk2 = 2. * (f2 + bk2) / ex;
400 wminf = estf[0] * ex + estf[1];
402 }
else if (DBL_EPSILON * ex > 1.) {
407 bk1 = 1. / (M_SQRT_2dPI * sqrt(ex));
408 for (i = 0; i < *nb; ++i)
423 d2 = trunc(estm[0] / ex + estm[1]);
428 for (i = 2; i <= m; ++i) {
431 ratio = (d3 + d2) / (twox + d1 - ratio);
437 d2 = trunc(estm[2] * ex + estm[3]);
445 f0 = (2. * (c + d2) / ex + .5 * ex / (c + d2 + 1.)) * DBL_MIN;
446 for (i = 3; i <= m; ++i) {
448 f2 = (d3 + d2 + d2) * f0;
449 blpha = (1. + d1 / d2) * (f2 + blpha);
454 f1 = (d3 + 2.) * f0 / ex + f1;
457 for (i = 1; i <= 7; ++i) {
458 d1 = c * d1 + p[i - 1];
459 t1 = c * t1 + q[i - 1];
461 p0 = exp(c * (a + c * (p[7] - c * d1 / t1) - log(ex))) / ex;
462 f2 = (c + .5 - ratio) * f1 / ex;
463 bk1 = p0 + (d3 * f0 - f2 + f0 + blpha) / (f2 + f1 + f0) * p0;
467 wminf = estf[2] * ex + estf[3];
473 dm = trunc(estm[4] / ex + estm[5]);
478 for (i = 2; i <= m; ++i) {
482 ratio = (d3 + d2) / (twox + d1 - ratio);
483 blpha = (ratio + ratio * blpha) / dm;
485 bk1 = 1. / ((M_SQRT_2dPI + M_SQRT_2dPI * blpha) * sqrt(ex));
488 wminf = estf[4] * (ex - fabs(ex - estf[6])) + estf[5];
494 bk2 = bk1 + bk1 * (nu + .5 - ratio) / ex;
512 m = min0((
int) trunc(wminf - nu),iend);
513 for (i = 2; i <= m; ++i) {
518 if (bk1 >= DBL_MAX / twonu * ex)
521 if (bk1 / ex >= DBL_MAX / twonu)
524 bk2 = twonu / ex * bk1 + t1;
539 for (i = mplus1; i <= iend; ++i) {
541 ratio = twonu / ex + 1./ratio;
546 if (bk2 >= DBL_MAX / ratio)
552 *ncalc = max0(1, mplus1 - k);
559 for (i = *ncalc; i < *nb; ++i) {
561 if (bk[i-1] >= DBL_MAX / bk[i])