3 * Bessel function of noninteger order
9 * float v, x, y, jvf();
17 * Returns Bessel function of order v of the argument,
18 * where v is real. Negative x is allowed if v is an integer.
20 * Several expansions are included: the ascending power
21 * series, the Hankel expansion, and two transitional
22 * expansions for large v. If v is not too large, it
23 * is reduced by recurrence to a region of best accuracy.
25 * The single precision routine accepts negative v, but with
31 * Results for integer v are indicated by *.
32 * Error criterion is absolute, except relative when |jv()| > 1.
34 * arithmetic domain # trials peak rms
36 * IEEE 0,125 0,125 30000 2.0e-6 2.0e-7
37 * IEEE -17,0 0,125 30000 1.1e-5 4.0e-7
38 * IEEE -100,0 0,125 3000 1.5e-4 7.8e-6
43 Cephes Math Library Release 2.2: June, 1992
44 Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier
45 Direct inquiries to 30 Frost Street, Cambridge, MA 02140
52 extern float MAXNUMF, MACHEPF, MINLOGF, MAXLOGF, PIF;
59 float floorf(float), j0f(float), j1f(float);
60 static float jnxf(float, float);
61 static float jvsf(float, float);
62 static float hankelf(float, float);
63 static float jntf(float, float);
64 static float recurf( float *, float, float * );
65 float sqrtf(float), sinf(float), cosf(float);
66 float lgamf(float), expf(float), logf(float), powf(float, float);
67 float gammaf(float), cbrtf(float), acosf(float);
68 int airyf(float, float *, float *, float *, float *);
69 float polevlf(float, float *, int);
71 float floorf(), j0f(), j1f();
72 float sqrtf(), sinf(), cosf();
73 float lgamf(), expf(), logf(), powf(), gammaf();
74 float cbrtf(), polevlf(), acosf();
76 static float recurf(), jvsf(), hankelf(), jnxf(), jntf(), jvsf();
80 #define fabsf(x) ( (x) < 0 ? -(x) : (x) )
83 float jvf( float nn, float xx )
89 float n, x, k, q, t, y, an, sign;
94 nint = 0; /* Flag for integer n */
95 sign = 1.0; /* Flag for sign inversion */
101 i = an - 16384.0 * floorf( an/16384.0 );
117 return( sign * j1f(x) );
120 if( (x < 0.0) && (y != an) )
122 mtherr( "jvf", DOMAIN );
132 /* Easy cases - x small compared to n */
135 return( sign * jvsf(n,x) );
137 /* x large compared to n */
139 if( (an < k) && (y > 6.0) )
140 return( sign * hankelf(n,x) );
142 if( (n > -100) && (n < 14.0) )
144 /* Note: if x is too large, the continued
145 * fraction will fail; but then the
146 * Hankel expansion can be used.
151 q = recurf( &n, x, &k );
166 /* Recur backwards from a larger value of n
177 q = recurf( &y, x, &k );
184 /* Recur backwards from n to k
191 q = recurf( &n, x, &k );
196 q = recurf( &t, x, &k );
212 /* boundary between convergence of
213 * power series and Hankel expansion
217 t = (0.0083*t + 0.09)*t + 12.9;
221 if( y > t ) /* y = |x| */
226 printf( "y = %.16e, q = %.16e\n", y, q );
236 /* For large positive n, use the uniform expansion
237 * or the transitional expansion.
238 * But if x is of the order of n**2,
239 * these may blow up, whereas the
240 * Hankel expansion will then work.
244 mtherr( "jvf", TLOSS );
256 done: return( sign * y);
259 /* Reduce the order by backward recurrence.
260 * AMS55 #9.1.27 and 9.1.73.
264 static float recurf( float *n, float xx, float *newn )
266 static float recurf( n, xx, newn )
272 float x, pkm2, pkm1, pk, pkp1, qkm2, qkm1;
273 float k, ans, qk, xk, yk, r, t, kf, xinv;
274 static float big = BIG;
278 /* continued fraction for Jn(x)/Jn-1(x) */
287 printf( "n = %.6e, newn = %.6e, cfrac = ", *n, *newn );
301 pk = pkm1 * yk + pkm2 * xk;
302 qk = qkm1 * yk + qkm2 * xk;
313 t = fabsf( (ans - r)/r );
322 if( fabsf(pk) > big )
330 while( t > MACHEPF );
335 printf( "%.6e\n", ans );
338 /* Change n to n-1 if n < 0 and the continued fraction is small
342 if( fabsf(ans) < 0.125 )
353 /* backward recurrence
355 * J (x) = --- J (x) - J (x)
366 pkm2 = (pkm1 * r - pk * x) * xinv;
372 t = fabsf(pkp1) + fabsf(pk);
373 if( (k > (kf + 2.5)) && (fabsf(pkm1) < 0.25*t) )
377 pkm2 = ( (r*(r+2.0)-t)*pk - r*x*pkp1 )/t;
386 while( k > (kf + 0.5) );
389 /* Take the larger of the last two iterates
390 * on the theory that it may have less cancellation error.
392 if( (kf >= 0.0) && (fabsf(pk) > fabsf(pkm1)) )
401 printf( "newn %.6e\n", k );
408 /* Ascending power series for Jv(x).
413 static float jvsf( float nn, float xx )
415 static float jvsf( nn, xx )
419 float n, x, t, u, y, z, k, ay;
434 u *= z / (k * (n+k));
438 if( (ay = fabsf(y)) > 1.0 )
444 y = y * powf( 0.5 * x, n ) / gammaf( n + 1.0 );
448 t = n * logf(0.5*x) - lgamf(n + 1.0);
458 mtherr( "jvf", OVERFLOW );
463 y = sgngamf * expf(t);
467 y = sgngamf * y * expf( t );
470 printf( "y = %.8e\n", y );
475 /* Hankel's asymptotic expansion
480 static float hankelf( float nn, float xx )
482 static float hankelf( nn, xx )
486 float n, x, t, u, z, k, sign, conv;
487 float p, q, j, m, pp, qq;
491 printf( "hankelf: " );
514 u *= (m - k * k)/(j * z);
518 u *= (m - k * k)/(j * z);
528 /* stop if the terms start getting larger */
529 if( (flag != 0) && (t > conv) )
532 printf( "Hankel: convergence to %.4E\n", conv );
539 u = x - (0.5*n + 0.25) * PIF;
540 t = sqrtf( 2.0/(PIF*x) ) * ( pp * cosf(u) - qq * sinf(u) );
545 /* Asymptotic expansion for large n.
549 static float lambda[] = {
551 1.041666666666666666666667E-1,
552 8.355034722222222222222222E-2,
553 1.282265745563271604938272E-1,
554 2.918490264641404642489712E-1,
555 8.816272674437576524187671E-1,
556 3.321408281862767544702647E+0,
557 1.499576298686255465867237E+1,
558 7.892301301158651813848139E+1,
559 4.744515388682643231611949E+2,
560 3.207490090890661934704328E+3
562 static float mu[] = {
564 -1.458333333333333333333333E-1,
565 -9.874131944444444444444444E-2,
566 -1.433120539158950617283951E-1,
567 -3.172272026784135480967078E-1,
568 -9.424291479571202491373028E-1,
569 -3.511203040826354261542798E+0,
570 -1.572726362036804512982712E+1,
571 -8.228143909718594444224656E+1,
572 -4.923553705236705240352022E+2,
573 -3.316218568547972508762102E+3
575 static float P1[] = {
576 -2.083333333333333333333333E-1,
577 1.250000000000000000000000E-1
579 static float P2[] = {
580 3.342013888888888888888889E-1,
581 -4.010416666666666666666667E-1,
582 7.031250000000000000000000E-2
584 static float P3[] = {
585 -1.025812596450617283950617E+0,
586 1.846462673611111111111111E+0,
587 -8.912109375000000000000000E-1,
588 7.324218750000000000000000E-2
590 static float P4[] = {
591 4.669584423426247427983539E+0,
592 -1.120700261622299382716049E+1,
593 8.789123535156250000000000E+0,
594 -2.364086914062500000000000E+0,
595 1.121520996093750000000000E-1
597 static float P5[] = {
598 -2.8212072558200244877E1,
599 8.4636217674600734632E1,
600 -9.1818241543240017361E1,
601 4.2534998745388454861E1,
602 -7.3687943594796316964E0,
603 2.27108001708984375E-1
605 static float P6[] = {
606 2.1257013003921712286E2,
607 -7.6525246814118164230E2,
608 1.0599904525279998779E3,
609 -6.9957962737613254123E2,
610 2.1819051174421159048E2,
611 -2.6491430486951555525E1,
612 5.7250142097473144531E-1
614 static float P7[] = {
615 -1.9194576623184069963E3,
616 8.0617221817373093845E3,
617 -1.3586550006434137439E4,
618 1.1655393336864533248E4,
619 -5.3056469786134031084E3,
620 1.2009029132163524628E3,
621 -1.0809091978839465550E2,
622 1.7277275025844573975E0
627 static float jnxf( float nn, float xx )
629 static float jnxf( nn, xx )
633 float n, x, zeta, sqz, zz, zp, np;
634 float cbn, n23, t, z, sz;
635 float pp, qq, z32i, zzi;
636 float ak, bk, akl, bkl;
637 int sign, doa, dob, nflg, k, s, tk, tkp1, m;
639 static float ai, aip, bi, bip;
643 /* Test for x very close to n.
644 * Use expansion for transition region if so.
648 if( (fabsf(z) <= 0.7) || (n < 0.0) )
658 t = 1.5 * (logf( (1.0+sz)/z ) - sz ); /* zeta ** 3/2 */
659 zeta = cbrtf( t * t );
665 t = 1.5 * (sz - acosf(1.0/z));
666 zeta = -cbrtf( t * t );
673 n23 = cbrtf( n * n );
677 printf("zeta %.5E, Airyf(%.5E)\n", zeta, t );
679 airyf( t, &ai, &aip, &bi, &bip );
681 /* polynomials in expansion */
684 u[1] = polevlf( zzi, P1, 1 )/sz;
685 u[2] = polevlf( zzi, P2, 2 )/zz;
686 u[3] = polevlf( zzi, P3, 3 )/(sz*zz);
688 u[4] = polevlf( zzi, P4, 4 )/pp;
689 u[5] = polevlf( zzi, P5, 5 )/(pp*sz);
691 u[6] = polevlf( zzi, P6, 6 )/pp;
692 u[7] = polevlf( zzi, P7, 7 )/(pp*sz);
695 for( k=0; k<=7; k++ )
696 printf( "u[%d] = %.5E\n", k, u[k] );
702 /* flags to stop when terms get larger */
708 for( k=0; k<=3; k++ )
715 for( s=0; s<=tk; s++ )
723 ak += sign * mu[s] * zp * u[tk-s];
729 if( ((m+1) & 3) > 1 )
733 bk += sign * lambda[s] * zp * u[m];
753 bk += lambda[tkp1] * zp * u[0];
765 printf("a[%d] %.5E, b[%d] %.5E\n", k, ak, k, bk );
772 /* normalizing factor ( 4*zeta/(1 - z**2) )**1/4 */
774 t = sqrtf( sqrtf(t) );
776 t *= ai*pp/cbrtf(n) + aip*qq/(n23*n);
780 /* Asymptotic expansion for transition region,
781 * n large and x close to n.
785 static float PF2[] = {
786 -9.0000000000000000000e-2,
787 8.5714285714285714286e-2
789 static float PF3[] = {
790 1.3671428571428571429e-1,
791 -5.4920634920634920635e-2,
792 -4.4444444444444444444e-3
794 static float PF4[] = {
795 1.3500000000000000000e-3,
796 -1.6036054421768707483e-1,
797 4.2590187590187590188e-2,
798 2.7330447330447330447e-3
800 static float PG1[] = {
801 -2.4285714285714285714e-1,
802 1.4285714285714285714e-2
804 static float PG2[] = {
805 -9.0000000000000000000e-3,
806 1.9396825396825396825e-1,
807 -1.1746031746031746032e-2
809 static float PG3[] = {
810 1.9607142857142857143e-2,
811 -1.5983694083694083694e-1,
812 6.3838383838383838384e-3
817 static float jntf( float nn, float xx )
819 static float jntf( nn, xx )
823 float n, x, z, zz, z3;
824 float cbn, n23, cbtwo;
825 float ai, aip, bi, bip; /* Airy functions */
826 float nk, fk, gk, pp, qq;
834 cbtwo = cbrtf( 2.0 );
838 airyf( zz, &ai, &aip, &bi, &bip );
840 /* polynomials in expansion */
845 F[2] = polevlf( z3, PF2, 1 ) * zz;
846 F[3] = polevlf( z3, PF3, 2 );
847 F[4] = polevlf( z3, PF4, 3 ) * z;
849 G[1] = polevlf( z3, PG1, 1 );
850 G[2] = polevlf( z3, PG2, 2 ) * z;
851 G[3] = polevlf( z3, PG3, 2 ) * zz;
853 for( k=0; k<=4; k++ )
854 printf( "F[%d] = %.5E\n", k, F[k] );
855 for( k=0; k<=3; k++ )
856 printf( "G[%d] = %.5E\n", k, G[k] );
861 n23 = cbrtf( n * n );
863 for( k=0; k<=4; k++ )
873 printf("fk[%d] %.5E, gk[%d] %.5E\n", k, fk, k, gk );
878 fk = cbtwo * ai * pp/cbn + cbrtf(4.0) * aip * qq/n;