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