xref: /plan9/sys/src/ape/lib/ap/math/jn.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
1*3e12c5d1SDavid du Colombier #include <math.h>
2*3e12c5d1SDavid du Colombier #include <errno.h>
3*3e12c5d1SDavid du Colombier 
4*3e12c5d1SDavid du Colombier /*
5*3e12c5d1SDavid du Colombier 	floating point Bessel's function of
6*3e12c5d1SDavid du Colombier 	the first and second kinds and of
7*3e12c5d1SDavid du Colombier 	integer order.
8*3e12c5d1SDavid du Colombier 
9*3e12c5d1SDavid du Colombier 	int n;
10*3e12c5d1SDavid du Colombier 	double x;
11*3e12c5d1SDavid du Colombier 	jn(n,x);
12*3e12c5d1SDavid du Colombier 
13*3e12c5d1SDavid du Colombier 	returns the value of Jn(x) for all
14*3e12c5d1SDavid du Colombier 	integer values of n and all real values
15*3e12c5d1SDavid du Colombier 	of x.
16*3e12c5d1SDavid du Colombier 
17*3e12c5d1SDavid du Colombier 	There are no error returns.
18*3e12c5d1SDavid du Colombier 	Calls j0, j1.
19*3e12c5d1SDavid du Colombier 
20*3e12c5d1SDavid du Colombier 	For n=0, j0(x) is called,
21*3e12c5d1SDavid du Colombier 	for n=1, j1(x) is called,
22*3e12c5d1SDavid du Colombier 	for n<x, forward recursion us used starting
23*3e12c5d1SDavid du Colombier 	from values of j0(x) and j1(x).
24*3e12c5d1SDavid du Colombier 	for n>x, a continued fraction approximation to
25*3e12c5d1SDavid du Colombier 	j(n,x)/j(n-1,x) is evaluated and then backward
26*3e12c5d1SDavid du Colombier 	recursion is used starting from a supposed value
27*3e12c5d1SDavid du Colombier 	for j(n,x). The resulting value of j(0,x) is
28*3e12c5d1SDavid du Colombier 	compared with the actual value to correct the
29*3e12c5d1SDavid du Colombier 	supposed value of j(n,x).
30*3e12c5d1SDavid du Colombier 
31*3e12c5d1SDavid du Colombier 	yn(n,x) is similar in all respects, except
32*3e12c5d1SDavid du Colombier 	that forward recursion is used for all
33*3e12c5d1SDavid du Colombier 	values of n>1.
34*3e12c5d1SDavid du Colombier */
35*3e12c5d1SDavid du Colombier 
36*3e12c5d1SDavid du Colombier double	j0(double);
37*3e12c5d1SDavid du Colombier double	j1(double);
38*3e12c5d1SDavid du Colombier double	y0(double);
39*3e12c5d1SDavid du Colombier double	y1(double);
40*3e12c5d1SDavid du Colombier 
41*3e12c5d1SDavid du Colombier double
jn(int n,double x)42*3e12c5d1SDavid du Colombier jn(int n, double x)
43*3e12c5d1SDavid du Colombier {
44*3e12c5d1SDavid du Colombier 	int i;
45*3e12c5d1SDavid du Colombier 	double a, b, temp;
46*3e12c5d1SDavid du Colombier 	double xsq, t;
47*3e12c5d1SDavid du Colombier 
48*3e12c5d1SDavid du Colombier 	if(n < 0) {
49*3e12c5d1SDavid du Colombier 		n = -n;
50*3e12c5d1SDavid du Colombier 		x = -x;
51*3e12c5d1SDavid du Colombier 	}
52*3e12c5d1SDavid du Colombier 	if(n == 0)
53*3e12c5d1SDavid du Colombier 		return j0(x);
54*3e12c5d1SDavid du Colombier 	if(n == 1)
55*3e12c5d1SDavid du Colombier 		return j1(x);
56*3e12c5d1SDavid du Colombier 	if(x == 0)
57*3e12c5d1SDavid du Colombier 		return 0;
58*3e12c5d1SDavid du Colombier 	if(n > x)
59*3e12c5d1SDavid du Colombier 		goto recurs;
60*3e12c5d1SDavid du Colombier 
61*3e12c5d1SDavid du Colombier 	a = j0(x);
62*3e12c5d1SDavid du Colombier 	b = j1(x);
63*3e12c5d1SDavid du Colombier 	for(i=1; i<n; i++) {
64*3e12c5d1SDavid du Colombier 		temp = b;
65*3e12c5d1SDavid du Colombier 		b = (2*i/x)*b - a;
66*3e12c5d1SDavid du Colombier 		a = temp;
67*3e12c5d1SDavid du Colombier 	}
68*3e12c5d1SDavid du Colombier 	return b;
69*3e12c5d1SDavid du Colombier 
70*3e12c5d1SDavid du Colombier recurs:
71*3e12c5d1SDavid du Colombier 	xsq = x*x;
72*3e12c5d1SDavid du Colombier 	for(t=0,i=n+16; i>n; i--)
73*3e12c5d1SDavid du Colombier 		t = xsq/(2*i - t);
74*3e12c5d1SDavid du Colombier 	t = x/(2*n-t);
75*3e12c5d1SDavid du Colombier 
76*3e12c5d1SDavid du Colombier 	a = t;
77*3e12c5d1SDavid du Colombier 	b = 1;
78*3e12c5d1SDavid du Colombier 	for(i=n-1; i>0; i--) {
79*3e12c5d1SDavid du Colombier 		temp = b;
80*3e12c5d1SDavid du Colombier 		b = (2*i/x)*b - a;
81*3e12c5d1SDavid du Colombier 		a = temp;
82*3e12c5d1SDavid du Colombier 	}
83*3e12c5d1SDavid du Colombier 	return t*j0(x)/b;
84*3e12c5d1SDavid du Colombier }
85*3e12c5d1SDavid du Colombier 
86*3e12c5d1SDavid du Colombier double
yn(int n,double x)87*3e12c5d1SDavid du Colombier yn(int n, double x)
88*3e12c5d1SDavid du Colombier {
89*3e12c5d1SDavid du Colombier 	int i;
90*3e12c5d1SDavid du Colombier 	int sign;
91*3e12c5d1SDavid du Colombier 	double a, b, temp;
92*3e12c5d1SDavid du Colombier 
93*3e12c5d1SDavid du Colombier 	if (x <= 0) {
94*3e12c5d1SDavid du Colombier 		errno = EDOM;
95*3e12c5d1SDavid du Colombier 		return -HUGE_VAL;
96*3e12c5d1SDavid du Colombier 	}
97*3e12c5d1SDavid du Colombier 	sign = 1;
98*3e12c5d1SDavid du Colombier 	if(n < 0) {
99*3e12c5d1SDavid du Colombier 		n = -n;
100*3e12c5d1SDavid du Colombier 		if(n%2 == 1)
101*3e12c5d1SDavid du Colombier 			sign = -1;
102*3e12c5d1SDavid du Colombier 	}
103*3e12c5d1SDavid du Colombier 	if(n == 0)
104*3e12c5d1SDavid du Colombier 		return y0(x);
105*3e12c5d1SDavid du Colombier 	if(n == 1)
106*3e12c5d1SDavid du Colombier 		return sign*y1(x);
107*3e12c5d1SDavid du Colombier 
108*3e12c5d1SDavid du Colombier 	a = y0(x);
109*3e12c5d1SDavid du Colombier 	b = y1(x);
110*3e12c5d1SDavid du Colombier 	for(i=1; i<n; i++) {
111*3e12c5d1SDavid du Colombier 		temp = b;
112*3e12c5d1SDavid du Colombier 		b = (2*i/x)*b - a;
113*3e12c5d1SDavid du Colombier 		a = temp;
114*3e12c5d1SDavid du Colombier 	}
115*3e12c5d1SDavid du Colombier 	return sign*b;
116*3e12c5d1SDavid du Colombier }
117