source: sasmodels/sasmodels/models/lib/j0d.c @ 38daeec

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 38daeec was 07142f3, checked in by wojciech, 8 years ago

ifdef corrected in bessel functions

  • Property mode set to 100644
File size: 6.8 KB
Line 
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/*
87Cephes Math Library Release 2.8:  June, 2000
88Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier
89*/
90
91/* Note: all coefficients satisfy the relative error criterion
92 * except YP, YQ which are designed for absolute error. */
93
94double j0( double );
95
96double j0(double x) {
97
98//Cephes single precission
99#if FLOAT_SIZE>4
100    double w, z, p, q, xn;
101
102    const double TWOOPI = 6.36619772367581343075535E-1;
103    const double SQ2OPI = 7.9788456080286535587989E-1;
104    const double PIO4 = 7.85398163397448309616E-1;
105
106    const double DR1 = 5.78318596294678452118E0;
107    const double DR2 = 3.04712623436620863991E1;
108
109    const double PP[8] = {
110        7.96936729297347051624E-4,
111        8.28352392107440799803E-2,
112        1.23953371646414299388E0,
113        5.44725003058768775090E0,
114        8.74716500199817011941E0,
115        5.30324038235394892183E0,
116        9.99999999999999997821E-1,
117        0.0
118    };
119
120    const double PQ[8] = {
121        9.24408810558863637013E-4,
122        8.56288474354474431428E-2,
123        1.25352743901058953537E0,
124        5.47097740330417105182E0,
125        8.76190883237069594232E0,
126        5.30605288235394617618E0,
127        1.00000000000000000218E0,
128        0.0
129    };
130
131    const double QP[8] = {
132        -1.13663838898469149931E-2,
133        -1.28252718670509318512E0,
134        -1.95539544257735972385E1,
135        -9.32060152123768231369E1,
136        -1.77681167980488050595E2,
137        -1.47077505154951170175E2,
138        -5.14105326766599330220E1,
139        -6.05014350600728481186E0,
140    };
141
142    const double QQ[8] = {
143        /*  1.00000000000000000000E0,*/
144        6.43178256118178023184E1,
145        8.56430025976980587198E2,
146        3.88240183605401609683E3,
147        7.24046774195652478189E3,
148        5.93072701187316984827E3,
149        2.06209331660327847417E3,
150        2.42005740240291393179E2,
151    };
152
153    const double YP[8] = {
154        1.55924367855235737965E4,
155        -1.46639295903971606143E7,
156        5.43526477051876500413E9,
157        -9.82136065717911466409E11,
158        8.75906394395366999549E13,
159        -3.46628303384729719441E15,
160        4.42733268572569800351E16,
161        -1.84950800436986690637E16,
162    };
163
164    const double YQ[7] = {
165        /* 1.00000000000000000000E0,*/
166        1.04128353664259848412E3,
167        6.26107330137134956842E5,
168        2.68919633393814121987E8,
169        8.64002487103935000337E10,
170        2.02979612750105546709E13,
171        3.17157752842975028269E15,
172        2.50596256172653059228E17,
173    };
174
175    const double RP[8] = {
176        -4.79443220978201773821E9,
177        1.95617491946556577543E12,
178        -2.49248344360967716204E14,
179        9.70862251047306323952E15,
180        0.0,
181        0.0,
182        0.0,
183        0.0
184    };
185
186    const double RQ[8] = {
187        /* 1.00000000000000000000E0,*/
188        4.99563147152651017219E2,
189        1.73785401676374683123E5,
190        4.84409658339962045305E7,
191        1.11855537045356834862E10,
192        2.11277520115489217587E12,
193        3.10518229857422583814E14,
194        3.18121955943204943306E16,
195        1.71086294081043136091E18,
196    };
197
198    if( x < 0 )
199            x = -x;
200
201    if( x <= 5.0 ) {
202            z = x * x;
203            if( x < 1.0e-5 )
204                    return( 1.0 - z/4.0 );
205
206            p = (z - DR1) * (z - DR2);
207            p = p * polevl( z, RP, 3)/p1evl( z, RQ, 8 );
208            return( p );
209        }
210
211    w = 5.0/x;
212    q = 25.0/(x*x);
213    p = polevl( q, PP, 6)/polevl( q, PQ, 6 );
214    q = polevl( q, QP, 7)/p1evl( q, QQ, 7 );
215    xn = x - PIO4;
216
217    double sn, cn;
218    SINCOS(xn, sn, cn);
219    p = p * cn - w * q * sn;
220
221    return( p * SQ2OPI / sqrt(x) );
222//Cephes single precission
223#else
224    double xx, w, z, p, q, xn;
225
226    const double YZ1 =  0.43221455686510834878;
227    const double YZ2 = 22.401876406482861405;
228    const double YZ3 = 64.130620282338755553;
229    const double DR1 =  5.78318596294678452118;
230    const double PIO4F = 0.7853981633974483096;
231
232    double MO[8] = {
233        -6.838999669318810E-002,
234        1.864949361379502E-001,
235        -2.145007480346739E-001,
236        1.197549369473540E-001,
237        -3.560281861530129E-003,
238        -4.969382655296620E-002,
239        -3.355424622293709E-006,
240        7.978845717621440E-001
241    };
242
243    double PH[8] = {
244        3.242077816988247E+001,
245        -3.630592630518434E+001,
246        1.756221482109099E+001,
247        -4.974978466280903E+000,
248        1.001973420681837E+000,
249        -1.939906941791308E-001,
250        6.490598792654666E-002,
251        -1.249992184872738E-001
252    };
253
254    double YP[8] = {
255        9.454583683980369E-008,
256        -9.413212653797057E-006,
257        5.344486707214273E-004,
258        -1.584289289821316E-002,
259        1.707584643733568E-001,
260        0.0,
261        0.0,
262        0.0
263    };
264
265    double JP[8] = {
266        -6.068350350393235E-008,
267        6.388945720783375E-006,
268        -3.969646342510940E-004,
269        1.332913422519003E-002,
270        -1.729150680240724E-001,
271        0.0,
272        0.0,
273        0.0
274    };
275
276    if( x < 0 )
277            xx = -x;
278    else
279            xx = x;
280
281    if( x <= 2.0 ) {
282            z = xx * xx;
283            if( x < 1.0e-3 )
284                    return( 1.0 - 0.25*z );
285
286            p = (z-DR1) * polevl( z, JP, 4);
287            return( p );
288        }
289
290    q = 1.0/x;
291    w = sqrtf(q);
292
293    p = w * polevl( q, MO, 7);
294    w = q*q;
295    xn = q * polevl( w, PH, 7) - PIO4F;
296    p = p * cosf(xn + xx);
297    return(p);
298#endif
299
300}
301
Note: See TracBrowser for help on using the repository browser.