xref: /csrg-svn/lib/libm/common_source/j0.c (revision 24597)
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