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