1*24597Szliu #ifndef lint 2*24597Szliu static char sccsid[] = "@(#)j0.c 1.1 (ELEFUNT) 09/06/85"; 3*24597Szliu #endif not lint 4*24597Szliu 5*24597Szliu /* 6*24597Szliu floating point Bessel's function 7*24597Szliu of the first and second kinds 8*24597Szliu of order zero 9*24597Szliu 10*24597Szliu j0(x) returns the value of J0(x) 11*24597Szliu for all real values of x. 12*24597Szliu 13*24597Szliu There are no error returns. 14*24597Szliu Calls sin, cos, sqrt. 15*24597Szliu 16*24597Szliu There is a niggling bug in J0 which 17*24597Szliu causes errors up to 2e-16 for x in the 18*24597Szliu interval [-8,8]. 19*24597Szliu The bug is caused by an inappropriate order 20*24597Szliu of summation of the series. rhm will fix it 21*24597Szliu someday. 22*24597Szliu 23*24597Szliu Coefficients are from Hart & Cheney. 24*24597Szliu #5849 (19.22D) 25*24597Szliu #6549 (19.25D) 26*24597Szliu #6949 (19.41D) 27*24597Szliu 28*24597Szliu y0(x) returns the value of Y0(x) 29*24597Szliu for positive real values of x. 30*24597Szliu For x<=0, if on the VAX, error number EDOM is set and 31*24597Szliu the reserved operand fault is generated; 32*24597Szliu otherwise (an IEEE machine) an invalid operation is performed. 33*24597Szliu 34*24597Szliu Calls sin, cos, sqrt, log, j0. 35*24597Szliu 36*24597Szliu The values of Y0 have not been checked 37*24597Szliu to more than ten places. 38*24597Szliu 39*24597Szliu Coefficients are from Hart & Cheney. 40*24597Szliu #6245 (18.78D) 41*24597Szliu #6549 (19.25D) 42*24597Szliu #6949 (19.41D) 43*24597Szliu */ 44*24597Szliu 45*24597Szliu #include <math.h> 46*24597Szliu #ifdef VAX 47*24597Szliu #include <errno.h> 48*24597Szliu #else /* IEEE double */ 49*24597Szliu static double zero = 0.e0; 50*24597Szliu #endif 51*24597Szliu static double pzero, qzero; 52*24597Szliu static double tpi = .6366197723675813430755350535e0; 53*24597Szliu static double pio4 = .7853981633974483096156608458e0; 54*24597Szliu static double p1[] = { 55*24597Szliu 0.4933787251794133561816813446e21, 56*24597Szliu -.1179157629107610536038440800e21, 57*24597Szliu 0.6382059341072356562289432465e19, 58*24597Szliu -.1367620353088171386865416609e18, 59*24597Szliu 0.1434354939140344111664316553e16, 60*24597Szliu -.8085222034853793871199468171e13, 61*24597Szliu 0.2507158285536881945555156435e11, 62*24597Szliu -.4050412371833132706360663322e8, 63*24597Szliu 0.2685786856980014981415848441e5, 64*24597Szliu }; 65*24597Szliu static double q1[] = { 66*24597Szliu 0.4933787251794133562113278438e21, 67*24597Szliu 0.5428918384092285160200195092e19, 68*24597Szliu 0.3024635616709462698627330784e17, 69*24597Szliu 0.1127756739679798507056031594e15, 70*24597Szliu 0.3123043114941213172572469442e12, 71*24597Szliu 0.6699987672982239671814028660e9, 72*24597Szliu 0.1114636098462985378182402543e7, 73*24597Szliu 0.1363063652328970604442810507e4, 74*24597Szliu 1.0 75*24597Szliu }; 76*24597Szliu static double p2[] = { 77*24597Szliu 0.5393485083869438325262122897e7, 78*24597Szliu 0.1233238476817638145232406055e8, 79*24597Szliu 0.8413041456550439208464315611e7, 80*24597Szliu 0.2016135283049983642487182349e7, 81*24597Szliu 0.1539826532623911470917825993e6, 82*24597Szliu 0.2485271928957404011288128951e4, 83*24597Szliu 0.0, 84*24597Szliu }; 85*24597Szliu static double q2[] = { 86*24597Szliu 0.5393485083869438325560444960e7, 87*24597Szliu 0.1233831022786324960844856182e8, 88*24597Szliu 0.8426449050629797331554404810e7, 89*24597Szliu 0.2025066801570134013891035236e7, 90*24597Szliu 0.1560017276940030940592769933e6, 91*24597Szliu 0.2615700736920839685159081813e4, 92*24597Szliu 1.0, 93*24597Szliu }; 94*24597Szliu static double p3[] = { 95*24597Szliu -.3984617357595222463506790588e4, 96*24597Szliu -.1038141698748464093880530341e5, 97*24597Szliu -.8239066313485606568803548860e4, 98*24597Szliu -.2365956170779108192723612816e4, 99*24597Szliu -.2262630641933704113967255053e3, 100*24597Szliu -.4887199395841261531199129300e1, 101*24597Szliu 0.0, 102*24597Szliu }; 103*24597Szliu static double q3[] = { 104*24597Szliu 0.2550155108860942382983170882e6, 105*24597Szliu 0.6667454239319826986004038103e6, 106*24597Szliu 0.5332913634216897168722255057e6, 107*24597Szliu 0.1560213206679291652539287109e6, 108*24597Szliu 0.1570489191515395519392882766e5, 109*24597Szliu 0.4087714673983499223402830260e3, 110*24597Szliu 1.0, 111*24597Szliu }; 112*24597Szliu static double p4[] = { 113*24597Szliu -.2750286678629109583701933175e20, 114*24597Szliu 0.6587473275719554925999402049e20, 115*24597Szliu -.5247065581112764941297350814e19, 116*24597Szliu 0.1375624316399344078571335453e18, 117*24597Szliu -.1648605817185729473122082537e16, 118*24597Szliu 0.1025520859686394284509167421e14, 119*24597Szliu -.3436371222979040378171030138e11, 120*24597Szliu 0.5915213465686889654273830069e8, 121*24597Szliu -.4137035497933148554125235152e5, 122*24597Szliu }; 123*24597Szliu static double q4[] = { 124*24597Szliu 0.3726458838986165881989980e21, 125*24597Szliu 0.4192417043410839973904769661e19, 126*24597Szliu 0.2392883043499781857439356652e17, 127*24597Szliu 0.9162038034075185262489147968e14, 128*24597Szliu 0.2613065755041081249568482092e12, 129*24597Szliu 0.5795122640700729537480087915e9, 130*24597Szliu 0.1001702641288906265666651753e7, 131*24597Szliu 0.1282452772478993804176329391e4, 132*24597Szliu 1.0, 133*24597Szliu }; 134*24597Szliu 135*24597Szliu double 136*24597Szliu j0(arg) double arg;{ 137*24597Szliu double argsq, n, d; 138*24597Szliu double sin(), cos(), sqrt(); 139*24597Szliu int i; 140*24597Szliu 141*24597Szliu if(arg < 0.) arg = -arg; 142*24597Szliu if(arg > 8.){ 143*24597Szliu asympt(arg); 144*24597Szliu n = arg - pio4; 145*24597Szliu return(sqrt(tpi/arg)*(pzero*cos(n) - qzero*sin(n))); 146*24597Szliu } 147*24597Szliu argsq = arg*arg; 148*24597Szliu for(n=0,d=0,i=8;i>=0;i--){ 149*24597Szliu n = n*argsq + p1[i]; 150*24597Szliu d = d*argsq + q1[i]; 151*24597Szliu } 152*24597Szliu return(n/d); 153*24597Szliu } 154*24597Szliu 155*24597Szliu double 156*24597Szliu y0(arg) double arg;{ 157*24597Szliu double argsq, n, d; 158*24597Szliu double sin(), cos(), sqrt(), log(), j0(); 159*24597Szliu int i; 160*24597Szliu 161*24597Szliu if(arg <= 0.){ 162*24597Szliu #ifdef VAX 163*24597Szliu extern double infnan(); 164*24597Szliu return(infnan(EDOM)); /* NaN */ 165*24597Szliu #else /* IEEE double */ 166*24597Szliu return(zero/zero); /* IEEE machines: invalid operation */ 167*24597Szliu #endif 168*24597Szliu } 169*24597Szliu if(arg > 8.){ 170*24597Szliu asympt(arg); 171*24597Szliu n = arg - pio4; 172*24597Szliu return(sqrt(tpi/arg)*(pzero*sin(n) + qzero*cos(n))); 173*24597Szliu } 174*24597Szliu argsq = arg*arg; 175*24597Szliu for(n=0,d=0,i=8;i>=0;i--){ 176*24597Szliu n = n*argsq + p4[i]; 177*24597Szliu d = d*argsq + q4[i]; 178*24597Szliu } 179*24597Szliu return(n/d + tpi*j0(arg)*log(arg)); 180*24597Szliu } 181*24597Szliu 182*24597Szliu static 183*24597Szliu asympt(arg) double arg;{ 184*24597Szliu double zsq, n, d; 185*24597Szliu int i; 186*24597Szliu zsq = 64./(arg*arg); 187*24597Szliu for(n=0,d=0,i=6;i>=0;i--){ 188*24597Szliu n = n*zsq + p2[i]; 189*24597Szliu d = d*zsq + q2[i]; 190*24597Szliu } 191*24597Szliu pzero = n/d; 192*24597Szliu for(n=0,d=0,i=6;i>=0;i--){ 193*24597Szliu n = n*zsq + p3[i]; 194*24597Szliu d = d*zsq + q3[i]; 195*24597Szliu } 196*24597Szliu qzero = (8./arg)*(n/d); 197*24597Szliu } 198