source: sasmodels/sasmodels/models/lib/sas_J0.c @ 1596de3

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 1596de3 was 1596de3, checked in by Paul Kienzle <pkienzle@…>, 8 years ago

code formatting

  • Property mode set to 100644
File size: 6.0 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
46/*
47Cephes Math Library Release 2.8:  June, 2000
48Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier
49*/
50
51/* Note: all coefficients satisfy the relative error criterion
52 * except YP, YQ which are designed for absolute error. */
53
54#if FLOAT_SIZE>4
55//Cephes double precission
56double j0(double x);
57
58 constant double PPJ0[8] = {
59        7.96936729297347051624E-4,
60        8.28352392107440799803E-2,
61        1.23953371646414299388E0,
62        5.44725003058768775090E0,
63        8.74716500199817011941E0,
64        5.30324038235394892183E0,
65        9.99999999999999997821E-1,
66        0.0
67    };
68
69 constant double PQJ0[8] = {
70        9.24408810558863637013E-4,
71        8.56288474354474431428E-2,
72        1.25352743901058953537E0,
73        5.47097740330417105182E0,
74        8.76190883237069594232E0,
75        5.30605288235394617618E0,
76        1.00000000000000000218E0,
77        0.0
78    };
79
80 constant double QPJ0[8] = {
81        -1.13663838898469149931E-2,
82        -1.28252718670509318512E0,
83        -1.95539544257735972385E1,
84        -9.32060152123768231369E1,
85        -1.77681167980488050595E2,
86        -1.47077505154951170175E2,
87        -5.14105326766599330220E1,
88        -6.05014350600728481186E0,
89    };
90
91 constant double QQJ0[8] = {
92        /*  1.00000000000000000000E0,*/
93        6.43178256118178023184E1,
94        8.56430025976980587198E2,
95        3.88240183605401609683E3,
96        7.24046774195652478189E3,
97        5.93072701187316984827E3,
98        2.06209331660327847417E3,
99        2.42005740240291393179E2,
100    };
101
102 constant double YPJ0[8] = {
103        1.55924367855235737965E4,
104        -1.46639295903971606143E7,
105        5.43526477051876500413E9,
106        -9.82136065717911466409E11,
107        8.75906394395366999549E13,
108        -3.46628303384729719441E15,
109        4.42733268572569800351E16,
110        -1.84950800436986690637E16,
111 };
112
113
114 constant double YQJ0[7] = {
115        /* 1.00000000000000000000E0,*/
116        1.04128353664259848412E3,
117        6.26107330137134956842E5,
118        2.68919633393814121987E8,
119        8.64002487103935000337E10,
120        2.02979612750105546709E13,
121        3.17157752842975028269E15,
122        2.50596256172653059228E17,
123  };
124
125 constant double RPJ0[8] = {
126        -4.79443220978201773821E9,
127        1.95617491946556577543E12,
128        -2.49248344360967716204E14,
129        9.70862251047306323952E15,
130        0.0,
131        0.0,
132        0.0,
133        0.0
134  };
135
136 constant double RQJ0[8] = {
137        /* 1.00000000000000000000E0,*/
138        4.99563147152651017219E2,
139        1.73785401676374683123E5,
140        4.84409658339962045305E7,
141        1.11855537045356834862E10,
142        2.11277520115489217587E12,
143        3.10518229857422583814E14,
144        3.18121955943204943306E16,
145        1.71086294081043136091E18,
146  };
147
148double j0(double x)
149{
150    double w, z, p, q, xn;
151
152    //const double TWOOPI = 6.36619772367581343075535E-1;
153    const double SQ2OPI = 7.9788456080286535587989E-1;
154    const double PIO4 = 7.85398163397448309616E-1;
155
156    const double DR1 = 5.78318596294678452118E0;
157    const double DR2 = 3.04712623436620863991E1;
158
159
160    if( x < 0 )
161        x = -x;
162
163    if( x <= 5.0 ) {
164        z = x * x;
165        if( x < 1.0e-5 )
166            return( 1.0 - z/4.0 );
167
168        p = (z - DR1) * (z - DR2);
169        p = p * polevl( z, RPJ0, 3)/p1evl( z, RQJ0, 8 );
170        return( p );
171    }
172
173    w = 5.0/x;
174    q = 25.0/(x*x);
175    p = polevl( q, PPJ0, 6)/polevl( q, PQJ0, 6 );
176    q = polevl( q, QPJ0, 7)/p1evl( q, QQJ0, 7 );
177    xn = x - PIO4;
178
179    double sn, cn;
180    SINCOS(xn, sn, cn);
181    p = p * cn - w * q * sn;
182
183    return( p * SQ2OPI / sqrt(x) );
184}
185#else
186//Cephes single precission
187float j0f(float x);
188
189 constant float MOJ0[8] = {
190        -6.838999669318810E-002,
191        1.864949361379502E-001,
192        -2.145007480346739E-001,
193        1.197549369473540E-001,
194        -3.560281861530129E-003,
195        -4.969382655296620E-002,
196        -3.355424622293709E-006,
197        7.978845717621440E-001
198  };
199
200 constant float PHJ0[8] = {
201        3.242077816988247E+001,
202        -3.630592630518434E+001,
203        1.756221482109099E+001,
204        -4.974978466280903E+000,
205        1.001973420681837E+000,
206        -1.939906941791308E-001,
207        6.490598792654666E-002,
208        -1.249992184872738E-001
209  };
210
211 constant float JPJ0[8] = {
212        -6.068350350393235E-008,
213        6.388945720783375E-006,
214        -3.969646342510940E-004,
215        1.332913422519003E-002,
216        -1.729150680240724E-001,
217        0.0,
218        0.0,
219        0.0
220 };
221
222float j0f(float x)
223{
224    float 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 float DR1 =  5.78318596294678452118;
230    const float PIO4F = 0.7853981633974483096;
231
232    if( x < 0 )
233        xx = -x;
234    else
235        xx = x;
236
237    if( x <= 2.0 ) {
238        z = xx * xx;
239        if( x < 1.0e-3 )
240            return( 1.0 - 0.25*z );
241
242        p = (z-DR1) * polevl( z, JPJ0, 4);
243        return( p );
244    }
245
246    q = 1.0/x;
247    w = sqrt(q);
248
249    p = w * polevl( q, MOJ0, 7);
250    w = q*q;
251    xn = q * polevl( w, PHJ0, 7) - PIO4F;
252    p = p * cos(xn + xx);
253    return(p);
254}
255#endif
256
257#if FLOAT_SIZE>4
258#define sas_J0 j0
259#else
260#define sas_J0 j0f
261#endif
Note: See TracBrowser for help on using the repository browser.