13e12c5d1SDavid du Colombier #include <math.h>
23e12c5d1SDavid du Colombier #include <errno.h>
33e12c5d1SDavid du Colombier /*
43e12c5d1SDavid du Colombier floating point Bessel's function
53e12c5d1SDavid du Colombier of the first and second kinds
63e12c5d1SDavid du Colombier of order one
73e12c5d1SDavid du Colombier
83e12c5d1SDavid du Colombier j1(x) returns the value of J1(x)
93e12c5d1SDavid du Colombier for all real values of x.
103e12c5d1SDavid du Colombier
113e12c5d1SDavid du Colombier There are no error returns.
123e12c5d1SDavid du Colombier Calls sin, cos, sqrt.
133e12c5d1SDavid du Colombier
143e12c5d1SDavid du Colombier There is a niggling bug in J1 which
153e12c5d1SDavid du Colombier causes errors up to 2e-16 for x in the
163e12c5d1SDavid du Colombier interval [-8,8].
173e12c5d1SDavid du Colombier The bug is caused by an inappropriate order
183e12c5d1SDavid du Colombier of summation of the series. rhm will fix it
193e12c5d1SDavid du Colombier someday.
203e12c5d1SDavid du Colombier
213e12c5d1SDavid du Colombier Coefficients are from Hart & Cheney.
223e12c5d1SDavid du Colombier #6050 (20.98D)
233e12c5d1SDavid du Colombier #6750 (19.19D)
243e12c5d1SDavid du Colombier #7150 (19.35D)
253e12c5d1SDavid du Colombier
263e12c5d1SDavid du Colombier y1(x) returns the value of Y1(x)
273e12c5d1SDavid du Colombier for positive real values of x.
283e12c5d1SDavid du Colombier For x<=0, error number EDOM is set and a
293e12c5d1SDavid du Colombier large negative value is returned.
303e12c5d1SDavid du Colombier
313e12c5d1SDavid du Colombier Calls sin, cos, sqrt, log, j1.
323e12c5d1SDavid du Colombier
333e12c5d1SDavid du Colombier The values of Y1 have not been checked
343e12c5d1SDavid du Colombier to more than ten places.
353e12c5d1SDavid du Colombier
363e12c5d1SDavid du Colombier Coefficients are from Hart & Cheney.
373e12c5d1SDavid du Colombier #6447 (22.18D)
383e12c5d1SDavid du Colombier #6750 (19.19D)
393e12c5d1SDavid du Colombier #7150 (19.35D)
403e12c5d1SDavid du Colombier */
413e12c5d1SDavid du Colombier
423e12c5d1SDavid du Colombier static double pzero, qzero;
433e12c5d1SDavid du Colombier static double tpi = .6366197723675813430755350535e0;
443e12c5d1SDavid du Colombier static double pio4 = .7853981633974483096156608458e0;
453e12c5d1SDavid du Colombier static double p1[] = {
463e12c5d1SDavid du Colombier 0.581199354001606143928050809e21,
473e12c5d1SDavid du Colombier -.6672106568924916298020941484e20,
483e12c5d1SDavid du Colombier 0.2316433580634002297931815435e19,
493e12c5d1SDavid du Colombier -.3588817569910106050743641413e17,
503e12c5d1SDavid du Colombier 0.2908795263834775409737601689e15,
513e12c5d1SDavid du Colombier -.1322983480332126453125473247e13,
523e12c5d1SDavid du Colombier 0.3413234182301700539091292655e10,
533e12c5d1SDavid du Colombier -.4695753530642995859767162166e7,
543e12c5d1SDavid du Colombier 0.2701122710892323414856790990e4,
553e12c5d1SDavid du Colombier };
563e12c5d1SDavid du Colombier static double q1[] = {
573e12c5d1SDavid du Colombier 0.1162398708003212287858529400e22,
583e12c5d1SDavid du Colombier 0.1185770712190320999837113348e20,
593e12c5d1SDavid du Colombier 0.6092061398917521746105196863e17,
603e12c5d1SDavid du Colombier 0.2081661221307607351240184229e15,
613e12c5d1SDavid du Colombier 0.5243710262167649715406728642e12,
623e12c5d1SDavid du Colombier 0.1013863514358673989967045588e10,
633e12c5d1SDavid du Colombier 0.1501793594998585505921097578e7,
643e12c5d1SDavid du Colombier 0.1606931573481487801970916749e4,
653e12c5d1SDavid du Colombier 1.0,
663e12c5d1SDavid du Colombier };
673e12c5d1SDavid du Colombier static double p2[] = {
683e12c5d1SDavid du Colombier -.4435757816794127857114720794e7,
693e12c5d1SDavid du Colombier -.9942246505077641195658377899e7,
703e12c5d1SDavid du Colombier -.6603373248364939109255245434e7,
713e12c5d1SDavid du Colombier -.1523529351181137383255105722e7,
723e12c5d1SDavid du Colombier -.1098240554345934672737413139e6,
733e12c5d1SDavid du Colombier -.1611616644324610116477412898e4,
743e12c5d1SDavid du Colombier 0.0,
753e12c5d1SDavid du Colombier };
763e12c5d1SDavid du Colombier static double q2[] = {
773e12c5d1SDavid du Colombier -.4435757816794127856828016962e7,
783e12c5d1SDavid du Colombier -.9934124389934585658967556309e7,
793e12c5d1SDavid du Colombier -.6585339479723087072826915069e7,
803e12c5d1SDavid du Colombier -.1511809506634160881644546358e7,
813e12c5d1SDavid du Colombier -.1072638599110382011903063867e6,
823e12c5d1SDavid du Colombier -.1455009440190496182453565068e4,
833e12c5d1SDavid du Colombier 1.0,
843e12c5d1SDavid du Colombier };
853e12c5d1SDavid du Colombier static double p3[] = {
863e12c5d1SDavid du Colombier 0.3322091340985722351859704442e5,
873e12c5d1SDavid du Colombier 0.8514516067533570196555001171e5,
883e12c5d1SDavid du Colombier 0.6617883658127083517939992166e5,
893e12c5d1SDavid du Colombier 0.1849426287322386679652009819e5,
903e12c5d1SDavid du Colombier 0.1706375429020768002061283546e4,
913e12c5d1SDavid du Colombier 0.3526513384663603218592175580e2,
923e12c5d1SDavid du Colombier 0.0,
933e12c5d1SDavid du Colombier };
943e12c5d1SDavid du Colombier static double q3[] = {
953e12c5d1SDavid du Colombier 0.7087128194102874357377502472e6,
963e12c5d1SDavid du Colombier 0.1819458042243997298924553839e7,
973e12c5d1SDavid du Colombier 0.1419460669603720892855755253e7,
983e12c5d1SDavid du Colombier 0.4002944358226697511708610813e6,
993e12c5d1SDavid du Colombier 0.3789022974577220264142952256e5,
1003e12c5d1SDavid du Colombier 0.8638367769604990967475517183e3,
1013e12c5d1SDavid du Colombier 1.0,
1023e12c5d1SDavid du Colombier };
1033e12c5d1SDavid du Colombier static double p4[] = {
1043e12c5d1SDavid du Colombier -.9963753424306922225996744354e23,
1053e12c5d1SDavid du Colombier 0.2655473831434854326894248968e23,
1063e12c5d1SDavid du Colombier -.1212297555414509577913561535e22,
1073e12c5d1SDavid du Colombier 0.2193107339917797592111427556e20,
1083e12c5d1SDavid du Colombier -.1965887462722140658820322248e18,
1093e12c5d1SDavid du Colombier 0.9569930239921683481121552788e15,
1103e12c5d1SDavid du Colombier -.2580681702194450950541426399e13,
1113e12c5d1SDavid du Colombier 0.3639488548124002058278999428e10,
1123e12c5d1SDavid du Colombier -.2108847540133123652824139923e7,
1133e12c5d1SDavid du Colombier 0.0,
1143e12c5d1SDavid du Colombier };
1153e12c5d1SDavid du Colombier static double q4[] = {
1163e12c5d1SDavid du Colombier 0.5082067366941243245314424152e24,
1173e12c5d1SDavid du Colombier 0.5435310377188854170800653097e22,
1183e12c5d1SDavid du Colombier 0.2954987935897148674290758119e20,
1193e12c5d1SDavid du Colombier 0.1082258259408819552553850180e18,
1203e12c5d1SDavid du Colombier 0.2976632125647276729292742282e15,
1213e12c5d1SDavid du Colombier 0.6465340881265275571961681500e12,
1223e12c5d1SDavid du Colombier 0.1128686837169442121732366891e10,
1233e12c5d1SDavid du Colombier 0.1563282754899580604737366452e7,
1243e12c5d1SDavid du Colombier 0.1612361029677000859332072312e4,
1253e12c5d1SDavid du Colombier 1.0,
1263e12c5d1SDavid du Colombier };
1273e12c5d1SDavid du Colombier
128*afa28516SDavid du Colombier static void
asympt(double arg)1293e12c5d1SDavid du Colombier asympt(double arg)
1303e12c5d1SDavid du Colombier {
1313e12c5d1SDavid du Colombier double zsq, n, d;
1323e12c5d1SDavid du Colombier int i;
1333e12c5d1SDavid du Colombier
1343e12c5d1SDavid du Colombier zsq = 64/(arg*arg);
1353e12c5d1SDavid du Colombier for(n=0,d=0,i=6;i>=0;i--) {
1363e12c5d1SDavid du Colombier n = n*zsq + p2[i];
1373e12c5d1SDavid du Colombier d = d*zsq + q2[i];
1383e12c5d1SDavid du Colombier }
1393e12c5d1SDavid du Colombier pzero = n/d;
1403e12c5d1SDavid du Colombier for(n=0,d=0,i=6;i>=0;i--) {
1413e12c5d1SDavid du Colombier n = n*zsq + p3[i];
1423e12c5d1SDavid du Colombier d = d*zsq + q3[i];
1433e12c5d1SDavid du Colombier }
1443e12c5d1SDavid du Colombier qzero = (8/arg)*(n/d);
1453e12c5d1SDavid du Colombier }
1463e12c5d1SDavid du Colombier
1473e12c5d1SDavid du Colombier double
j1(double arg)1483e12c5d1SDavid du Colombier j1(double arg)
1493e12c5d1SDavid du Colombier {
1503e12c5d1SDavid du Colombier double xsq, n, d, x;
1513e12c5d1SDavid du Colombier int i;
1523e12c5d1SDavid du Colombier
1533e12c5d1SDavid du Colombier x = arg;
1543e12c5d1SDavid du Colombier if(x < 0)
1553e12c5d1SDavid du Colombier x = -x;
1563e12c5d1SDavid du Colombier if(x > 8) {
1573e12c5d1SDavid du Colombier asympt(x);
1583e12c5d1SDavid du Colombier n = x - 3*pio4;
1593e12c5d1SDavid du Colombier n = sqrt(tpi/x)*(pzero*cos(n) - qzero*sin(n));
1603e12c5d1SDavid du Colombier if(arg < 0)
1613e12c5d1SDavid du Colombier n = -n;
1623e12c5d1SDavid du Colombier return n;
1633e12c5d1SDavid du Colombier }
1643e12c5d1SDavid du Colombier xsq = x*x;
1653e12c5d1SDavid du Colombier for(n=0,d=0,i=8;i>=0;i--) {
1663e12c5d1SDavid du Colombier n = n*xsq + p1[i];
1673e12c5d1SDavid du Colombier d = d*xsq + q1[i];
1683e12c5d1SDavid du Colombier }
1693e12c5d1SDavid du Colombier return arg*n/d;
1703e12c5d1SDavid du Colombier }
1713e12c5d1SDavid du Colombier
1723e12c5d1SDavid du Colombier double
y1(double arg)1733e12c5d1SDavid du Colombier y1(double arg)
1743e12c5d1SDavid du Colombier {
1753e12c5d1SDavid du Colombier double xsq, n, d, x;
1763e12c5d1SDavid du Colombier int i;
1773e12c5d1SDavid du Colombier
1783e12c5d1SDavid du Colombier errno = 0;
1793e12c5d1SDavid du Colombier x = arg;
1803e12c5d1SDavid du Colombier if(x <= 0) {
1813e12c5d1SDavid du Colombier errno = EDOM;
1823e12c5d1SDavid du Colombier return -HUGE_VAL;
1833e12c5d1SDavid du Colombier }
1843e12c5d1SDavid du Colombier if(x > 8) {
1853e12c5d1SDavid du Colombier asympt(x);
1863e12c5d1SDavid du Colombier n = x - 3*pio4;
1873e12c5d1SDavid du Colombier return sqrt(tpi/x)*(pzero*sin(n) + qzero*cos(n));
1883e12c5d1SDavid du Colombier }
1893e12c5d1SDavid du Colombier xsq = x*x;
1903e12c5d1SDavid du Colombier for(n=0,d=0,i=9;i>=0;i--) {
1913e12c5d1SDavid du Colombier n = n*xsq + p4[i];
1923e12c5d1SDavid du Colombier d = d*xsq + q4[i];
1933e12c5d1SDavid du Colombier }
1943e12c5d1SDavid du Colombier return x*n/d + tpi*(j1(x)*log(x)-1/x);
1953e12c5d1SDavid du Colombier }
196