/* jnf.c * * Bessel function of integer order * * * * SYNOPSIS: * * int n; * float x, y, jnf(); * * y = jnf( n, x ); * * * * DESCRIPTION: * * Returns Bessel function of order n, where n is a * (possibly negative) integer. * * The ratio of jn(x) to j0(x) is computed by backward * recurrence. First the ratio jn/jn-1 is found by a * continued fraction expansion. Then the recurrence * relating successive orders is applied until j0 or j1 is * reached. * * If n = 0 or 1 the routine for j0 or j1 is called * directly. * * * * ACCURACY: * * Absolute error: * arithmetic range # trials peak rms * IEEE 0, 15 30000 3.6e-7 3.6e-8 * * * Not suitable for large n or x. Use jvf() instead. * */ /* jn.c Cephes Math Library Release 2.2: June, 1992 Copyright 1984, 1987, 1992 by Stephen L. Moshier Direct inquiries to 30 Frost Street, Cambridge, MA 02140 */ #include "mconf.h" extern float MACHEPF; #ifdef ANSIC float j0f(float), j1f(float); float jnf( int n, float xx ) #else float j0f(), j1f(); float jnf( n, xx ) int n; double xx; #endif { float x, pkm2, pkm1, pk, xk, r, ans, xinv, sign; int k; x = xx; sign = 1.0; if( n < 0 ) { n = -n; if( (n & 1) != 0 ) /* -1**n */ sign = -1.0; } if( n == 0 ) return( sign * j0f(x) ); if( n == 1 ) return( sign * j1f(x) ); if( n == 2 ) return( sign * (2.0 * j1f(x) / x - j0f(x)) ); /* if( x < MACHEPF ) return( 0.0 ); */ /* continued fraction */ k = 24; pk = 2 * (n + k); ans = pk; xk = x * x; do { pk -= 2.0; ans = pk - (xk/ans); } while( --k > 0 ); /*ans = x/ans;*/ /* backward recurrence */ pk = 1.0; /*pkm1 = 1.0/ans;*/ xinv = 1.0/x; pkm1 = ans * xinv; k = n-1; r = (float )(2 * k); do { pkm2 = (pkm1 * r - pk * x) * xinv; pk = pkm1; pkm1 = pkm2; r -= 2.0; } while( --k > 0 ); r = pk; if( r < 0 ) r = -r; ans = pkm1; if( ans < 0 ) ans = -ans; if( r > ans ) /* if( fabs(pk) > fabs(pkm1) ) */ ans = sign * j1f(x)/pk; else ans = sign * j0f(x)/pkm1; return( ans ); }