1 /* j0.c
2 *
3 * Bessel function of order zero
4 *
5 *
6 *
7 * SYNOPSIS:
8 *
9 * double x, y, j0();
10 *
11 * y = j0( x );
12 *
13 *
14 *
15 * DESCRIPTION:
16 *
17 * Returns Bessel function of order zero of the argument.
18 *
19 * The domain is divided into the intervals [0, 5] and
20 * (5, infinity). In the first interval the following rational
21 * approximation is used:
22 *
23 *
24 * 2 2
25 * (w - r ) (w - r ) P (w) / Q (w)
26 * 1 2 3 8
27 *
28 * 2
29 * where w = x and the two r's are zeros of the function.
30 *
31 * In the second interval, the Hankel asymptotic expansion
32 * is employed with two rational functions of degree 6/6
33 * and 7/7.
34 *
35 *
36 *
37 * ACCURACY:
38 *
39 * Absolute error:
40 * arithmetic domain # trials peak rms
41 * DEC 0, 30 10000 4.4e-17 6.3e-18
42 * IEEE 0, 30 60000 4.2e-16 1.1e-16
43 *
44 */
45 /* y0.c
46 *
47 * Bessel function of the second kind, order zero
48 *
49 *
50 *
51 * SYNOPSIS:
52 *
53 * double x, y, y0();
54 *
55 * y = y0( x );
56 *
57 *
58 *
59 * DESCRIPTION:
60 *
61 * Returns Bessel function of the second kind, of order
62 * zero, of the argument.
63 *
64 * The domain is divided into the intervals [0, 5] and
65 * (5, infinity). In the first interval a rational approximation
66 * R(x) is employed to compute
67 * y0(x) = R(x) + 2 * log(x) * j0(x) / PI.
68 * Thus a call to j0() is required.
69 *
70 * In the second interval, the Hankel asymptotic expansion
71 * is employed with two rational functions of degree 6/6
72 * and 7/7.
73 *
74 *
75 *
76 * ACCURACY:
77 *
78 * Absolute error, when y0(x) < 1; else relative error:
79 *
80 * arithmetic domain # trials peak rms
81 * DEC 0, 30 9400 7.0e-17 7.9e-18
82 * IEEE 0, 30 30000 1.3e-15 1.6e-16
83 *
84 */
85
86 /*
87 Cephes Math Library Release 2.1: January, 1989
88 Copyright 1984, 1987, 1989 by Stephen L. Moshier
89 Direct inquiries to 30 Frost Street, Cambridge, MA 02140
90 */
91
92 /* Note: all coefficients satisfy the relative error criterion
93 * except YP, YQ which are designed for absolute error. */
94
95 #include "mconf.h"
96
97 static double PP[7] = {
98 7.96936729297347051624E-4,
99 8.28352392107440799803E-2,
100 1.23953371646414299388E0,
101 5.44725003058768775090E0,
102 8.74716500199817011941E0,
103 5.30324038235394892183E0,
104 9.99999999999999997821E-1,
105 };
106 static double PQ[7] = {
107 9.24408810558863637013E-4,
108 8.56288474354474431428E-2,
109 1.25352743901058953537E0,
110 5.47097740330417105182E0,
111 8.76190883237069594232E0,
112 5.30605288235394617618E0,
113 1.00000000000000000218E0,
114 };
115
116 static double QP[8] = {
117 -1.13663838898469149931E-2,
118 -1.28252718670509318512E0,
119 -1.95539544257735972385E1,
120 -9.32060152123768231369E1,
121 -1.77681167980488050595E2,
122 -1.47077505154951170175E2,
123 -5.14105326766599330220E1,
124 -6.05014350600728481186E0,
125 };
126 static double QQ[7] = {
127 /* 1.00000000000000000000E0,*/
128 6.43178256118178023184E1,
129 8.56430025976980587198E2,
130 3.88240183605401609683E3,
131 7.24046774195652478189E3,
132 5.93072701187316984827E3,
133 2.06209331660327847417E3,
134 2.42005740240291393179E2,
135 };
136
137 static double YP[8] = {
138 1.55924367855235737965E4,
139 -1.46639295903971606143E7,
140 5.43526477051876500413E9,
141 -9.82136065717911466409E11,
142 8.75906394395366999549E13,
143 -3.46628303384729719441E15,
144 4.42733268572569800351E16,
145 -1.84950800436986690637E16,
146 };
147 static double YQ[7] = {
148 /* 1.00000000000000000000E0,*/
149 1.04128353664259848412E3,
150 6.26107330137134956842E5,
151 2.68919633393814121987E8,
152 8.64002487103935000337E10,
153 2.02979612750105546709E13,
154 3.17157752842975028269E15,
155 2.50596256172653059228E17,
156 };
157
158 /* 5.783185962946784521175995758455807035071 */
159 static double DR1 = 5.78318596294678452118E0;
160 /* 30.47126234366208639907816317502275584842 */
161 static double DR2 = 3.04712623436620863991E1;
162
163 static double RP[4] = {
164 -4.79443220978201773821E9,
165 1.95617491946556577543E12,
166 -2.49248344360967716204E14,
167 9.70862251047306323952E15,
168 };
169 static double RQ[8] = {
170 /* 1.00000000000000000000E0,*/
171 4.99563147152651017219E2,
172 1.73785401676374683123E5,
173 4.84409658339962045305E7,
174 1.11855537045356834862E10,
175 2.11277520115489217587E12,
176 3.10518229857422583814E14,
177 3.18121955943204943306E16,
178 1.71086294081043136091E18,
179 };
180
j0(x)181 double j0(x)
182 double x;
183 {
184 double polevl(), p1evl();
185 double w, z, p, q, xn;
186 double sin(), cos(), sqrt();
187 extern double PIO4, SQ2OPI;
188
189
190 if( x < 0 )
191 x = -x;
192
193 if( x <= 5.0 )
194 {
195 z = x * x;
196 if( x < 1.0e-5 )
197 return( 1.0 - z/4.0 );
198
199 p = (z - DR1) * (z - DR2);
200 p = p * polevl( z, RP, 3)/p1evl( z, RQ, 8 );
201 return( p );
202 }
203
204 w = 5.0/x;
205 q = 25.0/(x*x);
206 p = polevl( q, PP, 6)/polevl( q, PQ, 6 );
207 q = polevl( q, QP, 7)/p1evl( q, QQ, 7 );
208 xn = x - PIO4;
209 p = p * cos(xn) - w * q * sin(xn);
210 return( p * SQ2OPI / sqrt(x) );
211 }
212
213 /* y0() 2 */
214 /* Bessel function of second kind, order zero */
215
216 /* Rational approximation coefficients YP[], YQ[] are used here.
217 * The function computed is y0(x) - 2 * log(x) * j0(x) / PI,
218 * whose value at x = 0 is 2 * ( log(0.5) + EUL ) / PI
219 * = 0.073804295108687225.
220 */
221
222 /*
223 #define PIO4 .78539816339744830962
224 #define SQ2OPI .79788456080286535588
225 */
226 extern double MAXNUM;
227
228 #ifdef MY_FIXY0
fixy0(x)229 double fixy0(x)
230 #else
231 double y0(x)
232 #endif
233 double x;
234 {
235 double polevl(), p1evl();
236 double w, z, p, q, xn;
237 double j0(), log(), sin(), cos(), sqrt();
238 extern double TWOOPI, SQ2OPI, PIO4;
239
240
241 if( x <= 5.0 )
242 {
243 if( x <= 0.0 )
244 {
245 mtherr( "y0", DOMAIN );
246 return( -MAXNUM );
247 }
248 z = x * x;
249 w = polevl( z, YP, 7) / p1evl( z, YQ, 7 );
250 w += TWOOPI * log(x) * j0(x);
251 return( w );
252 }
253
254 w = 5.0/x;
255 z = 25.0 / (x * x);
256 p = polevl( z, PP, 6)/polevl( z, PQ, 6 );
257 q = polevl( z, QP, 7)/p1evl( z, QQ, 7 );
258 xn = x - PIO4;
259 p = p * sin(xn) + w * q * cos(xn);
260 return( p * SQ2OPI / sqrt(x) );
261 }
262