1*48402Sbostic /*- 2*48402Sbostic * Copyright (c) 1985 The Regents of the University of California. 3*48402Sbostic * All rights reserved. 4*48402Sbostic * 5*48402Sbostic * %sccs.include.proprietary.c% 634118Sbostic */ 734118Sbostic 824598Szliu #ifndef lint 9*48402Sbostic static char sccsid[] = "@(#)j1.c 5.4 (Berkeley) 04/20/91"; 1034118Sbostic #endif /* not lint */ 1124598Szliu 1224598Szliu /* 1324598Szliu floating point Bessel's function 1424598Szliu of the first and second kinds 1524598Szliu of order one 1624598Szliu 1724598Szliu j1(x) returns the value of J1(x) 1824598Szliu for all real values of x. 1924598Szliu 2024598Szliu There are no error returns. 2124598Szliu Calls sin, cos, sqrt. 2224598Szliu 2324598Szliu There is a niggling bug in J1 which 2424598Szliu causes errors up to 2e-16 for x in the 2524598Szliu interval [-8,8]. 2624598Szliu The bug is caused by an inappropriate order 2724598Szliu of summation of the series. rhm will fix it 2824598Szliu someday. 2924598Szliu 3024598Szliu Coefficients are from Hart & Cheney. 3124598Szliu #6050 (20.98D) 3224598Szliu #6750 (19.19D) 3324598Szliu #7150 (19.35D) 3424598Szliu 3524598Szliu y1(x) returns the value of Y1(x) 3624598Szliu for positive real values of x. 3724598Szliu For x<=0, if on the VAX, error number EDOM is set and 3824598Szliu the reserved operand fault is generated; 3924598Szliu otherwise (an IEEE machine) an invalid operation is performed. 4024598Szliu 4124598Szliu Calls sin, cos, sqrt, log, j1. 4224598Szliu 4324598Szliu The values of Y1 have not been checked 4424598Szliu to more than ten places. 4524598Szliu 4624598Szliu Coefficients are from Hart & Cheney. 4724598Szliu #6447 (22.18D) 4824598Szliu #6750 (19.19D) 4924598Szliu #7150 (19.35D) 5024598Szliu */ 5124598Szliu 5235679Sbostic #include "mathimpl.h" 5335679Sbostic 5431853Szliu #if defined(vax)||defined(tahoe) 5524598Szliu #include <errno.h> 5631853Szliu #else /* defined(vax)||defined(tahoe) */ 5735679Sbostic static const double zero = 0.e0; 5831853Szliu #endif /* defined(vax)||defined(tahoe) */ 5935679Sbostic 6024598Szliu static double pzero, qzero; 6135679Sbostic 6235679Sbostic static const double tpi = .6366197723675813430755350535e0; 6335679Sbostic static const double pio4 = .7853981633974483096156608458e0; 6435679Sbostic static const double p1[] = { 6524598Szliu 0.581199354001606143928050809e21, 6624598Szliu -.6672106568924916298020941484e20, 6724598Szliu 0.2316433580634002297931815435e19, 6824598Szliu -.3588817569910106050743641413e17, 6924598Szliu 0.2908795263834775409737601689e15, 7024598Szliu -.1322983480332126453125473247e13, 7124598Szliu 0.3413234182301700539091292655e10, 7224598Szliu -.4695753530642995859767162166e7, 7324598Szliu 0.2701122710892323414856790990e4, 7424598Szliu }; 7535679Sbostic static const double q1[] = { 7624598Szliu 0.1162398708003212287858529400e22, 7724598Szliu 0.1185770712190320999837113348e20, 7824598Szliu 0.6092061398917521746105196863e17, 7924598Szliu 0.2081661221307607351240184229e15, 8024598Szliu 0.5243710262167649715406728642e12, 8124598Szliu 0.1013863514358673989967045588e10, 8224598Szliu 0.1501793594998585505921097578e7, 8324598Szliu 0.1606931573481487801970916749e4, 8424598Szliu 1.0, 8524598Szliu }; 8635679Sbostic static const double p2[] = { 8724598Szliu -.4435757816794127857114720794e7, 8824598Szliu -.9942246505077641195658377899e7, 8924598Szliu -.6603373248364939109255245434e7, 9024598Szliu -.1523529351181137383255105722e7, 9124598Szliu -.1098240554345934672737413139e6, 9224598Szliu -.1611616644324610116477412898e4, 9324598Szliu 0.0, 9424598Szliu }; 9535679Sbostic static const double q2[] = { 9624598Szliu -.4435757816794127856828016962e7, 9724598Szliu -.9934124389934585658967556309e7, 9824598Szliu -.6585339479723087072826915069e7, 9924598Szliu -.1511809506634160881644546358e7, 10024598Szliu -.1072638599110382011903063867e6, 10124598Szliu -.1455009440190496182453565068e4, 10224598Szliu 1.0, 10324598Szliu }; 10435679Sbostic static const double p3[] = { 10524598Szliu 0.3322091340985722351859704442e5, 10624598Szliu 0.8514516067533570196555001171e5, 10724598Szliu 0.6617883658127083517939992166e5, 10824598Szliu 0.1849426287322386679652009819e5, 10924598Szliu 0.1706375429020768002061283546e4, 11024598Szliu 0.3526513384663603218592175580e2, 11124598Szliu 0.0, 11224598Szliu }; 11335679Sbostic static const double q3[] = { 11424598Szliu 0.7087128194102874357377502472e6, 11524598Szliu 0.1819458042243997298924553839e7, 11624598Szliu 0.1419460669603720892855755253e7, 11724598Szliu 0.4002944358226697511708610813e6, 11824598Szliu 0.3789022974577220264142952256e5, 11924598Szliu 0.8638367769604990967475517183e3, 12024598Szliu 1.0, 12124598Szliu }; 12235679Sbostic static const double p4[] = { 12324598Szliu -.9963753424306922225996744354e23, 12424598Szliu 0.2655473831434854326894248968e23, 12524598Szliu -.1212297555414509577913561535e22, 12624598Szliu 0.2193107339917797592111427556e20, 12724598Szliu -.1965887462722140658820322248e18, 12824598Szliu 0.9569930239921683481121552788e15, 12924598Szliu -.2580681702194450950541426399e13, 13024598Szliu 0.3639488548124002058278999428e10, 13124598Szliu -.2108847540133123652824139923e7, 13224598Szliu 0.0, 13324598Szliu }; 13435679Sbostic static const double q4[] = { 13524598Szliu 0.5082067366941243245314424152e24, 13624598Szliu 0.5435310377188854170800653097e22, 13724598Szliu 0.2954987935897148674290758119e20, 13824598Szliu 0.1082258259408819552553850180e18, 13924598Szliu 0.2976632125647276729292742282e15, 14024598Szliu 0.6465340881265275571961681500e12, 14124598Szliu 0.1128686837169442121732366891e10, 14224598Szliu 0.1563282754899580604737366452e7, 14324598Szliu 0.1612361029677000859332072312e4, 14424598Szliu 1.0, 14524598Szliu }; 14624598Szliu 14735679Sbostic static void asympt(); 14835679Sbostic 14924598Szliu double 15024598Szliu j1(arg) double arg;{ 15124598Szliu double xsq, n, d, x; 15224598Szliu int i; 15324598Szliu 15424598Szliu x = arg; 15524598Szliu if(x < 0.) x = -x; 15624598Szliu if(x > 8.){ 15724598Szliu asympt(x); 15824598Szliu n = x - 3.*pio4; 15924598Szliu n = sqrt(tpi/x)*(pzero*cos(n) - qzero*sin(n)); 16024598Szliu if(arg <0.) n = -n; 16124598Szliu return(n); 16224598Szliu } 16324598Szliu xsq = x*x; 16424598Szliu for(n=0,d=0,i=8;i>=0;i--){ 16524598Szliu n = n*xsq + p1[i]; 16624598Szliu d = d*xsq + q1[i]; 16724598Szliu } 16824598Szliu return(arg*n/d); 16924598Szliu } 17024598Szliu 17124598Szliu double 17224598Szliu y1(arg) double arg;{ 17324598Szliu double xsq, n, d, x; 17424598Szliu int i; 17524598Szliu 17624598Szliu x = arg; 17724598Szliu if(x <= 0.){ 17831853Szliu #if defined(vax)||defined(tahoe) 17924598Szliu return(infnan(EDOM)); /* NaN */ 18031853Szliu #else /* defined(vax)||defined(tahoe) */ 18124598Szliu return(zero/zero); /* IEEE machines: invalid operation */ 18231853Szliu #endif /* defined(vax)||defined(tahoe) */ 18324598Szliu } 18424598Szliu if(x > 8.){ 18524598Szliu asympt(x); 18624598Szliu n = x - 3*pio4; 18724598Szliu return(sqrt(tpi/x)*(pzero*sin(n) + qzero*cos(n))); 18824598Szliu } 18924598Szliu xsq = x*x; 19024598Szliu for(n=0,d=0,i=9;i>=0;i--){ 19124598Szliu n = n*xsq + p4[i]; 19224598Szliu d = d*xsq + q4[i]; 19324598Szliu } 19424598Szliu return(x*n/d + tpi*(j1(x)*log(x)-1./x)); 19524598Szliu } 19624598Szliu 19735679Sbostic static void 19824598Szliu asympt(arg) double arg;{ 19924598Szliu double zsq, n, d; 20024598Szliu int i; 20124598Szliu zsq = 64./(arg*arg); 20224598Szliu for(n=0,d=0,i=6;i>=0;i--){ 20324598Szliu n = n*zsq + p2[i]; 20424598Szliu d = d*zsq + q2[i]; 20524598Szliu } 20624598Szliu pzero = n/d; 20724598Szliu for(n=0,d=0,i=6;i>=0;i--){ 20824598Szliu n = n*zsq + p3[i]; 20924598Szliu d = d*zsq + q3[i]; 21024598Szliu } 21124598Szliu qzero = (8./arg)*(n/d); 21224598Szliu } 213