source: sasmodels/sasmodels/models/lib/sas_J1.c @ 3f8584a2

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

clean separation between float/double bessel functions

  • Property mode set to 100644
File size: 4.5 KB
Line 
1/*                                                      j1.c
2 *
3 *      Bessel function of order one
4 *
5 *
6 *
7 * SYNOPSIS:
8 *
9 * double x, y, j1();
10 *
11 * y = j1( x );
12 *
13 *
14 *
15 * DESCRIPTION:
16 *
17 * Returns Bessel function of order one of the argument.
18 *
19 * The domain is divided into the intervals [0, 8] and
20 * (8, infinity). In the first interval a 24 term Chebyshev
21 * expansion is used. In the second, the asymptotic
22 * trigonometric representation is employed using two
23 * rational functions of degree 5/5.
24 *
25 *
26 *
27 * ACCURACY:
28 *
29 *                      Absolute error:
30 * arithmetic   domain      # trials      peak         rms
31 *    DEC       0, 30       10000       4.0e-17     1.1e-17
32 *    IEEE      0, 30       30000       2.6e-16     1.1e-16
33 *
34 *
35 */
36
37/*
38Cephes Math Library Release 2.8:  June, 2000
39Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier
40*/
41
42#if FLOAT_SIZE>4
43
44//Cephes double pression function
45constant double RPJ1[8] = {
46    -8.99971225705559398224E8,
47    4.52228297998194034323E11,
48    -7.27494245221818276015E13,
49    3.68295732863852883286E15,
50    0.0,
51    0.0,
52    0.0,
53    0.0 };
54
55constant double RQJ1[8] = {
56    6.20836478118054335476E2,
57    2.56987256757748830383E5,
58    8.35146791431949253037E7,
59    2.21511595479792499675E10,
60    4.74914122079991414898E12,
61    7.84369607876235854894E14,
62    8.95222336184627338078E16,
63    5.32278620332680085395E18
64    };
65
66constant double PPJ1[8] = {
67    7.62125616208173112003E-4,
68    7.31397056940917570436E-2,
69    1.12719608129684925192E0,
70    5.11207951146807644818E0,
71    8.42404590141772420927E0,
72    5.21451598682361504063E0,
73    1.00000000000000000254E0,
74    0.0} ;
75
76
77constant double PQJ1[8] = {
78    5.71323128072548699714E-4,
79    6.88455908754495404082E-2,
80    1.10514232634061696926E0,
81    5.07386386128601488557E0,
82    8.39985554327604159757E0,
83    5.20982848682361821619E0,
84    9.99999999999999997461E-1,
85    0.0 };
86
87constant double QPJ1[8] = {
88    5.10862594750176621635E-2,
89    4.98213872951233449420E0,
90    7.58238284132545283818E1,
91    3.66779609360150777800E2,
92    7.10856304998926107277E2,
93    5.97489612400613639965E2,
94    2.11688757100572135698E2,
95    2.52070205858023719784E1 };
96
97constant double QQJ1[8] = {
98    7.42373277035675149943E1,
99    1.05644886038262816351E3,
100    4.98641058337653607651E3,
101    9.56231892404756170795E3,
102    7.99704160447350683650E3,
103    2.82619278517639096600E3,
104    3.36093607810698293419E2,
105    0.0 };
106
107double j1(double x);
108double j1(double x)
109{
110
111    double w, z, p, q, xn;
112
113    const double Z1 = 1.46819706421238932572E1;
114    const double Z2 = 4.92184563216946036703E1;
115    const double THPIO4 =  2.35619449019234492885;
116    const double SQ2OPI = 0.79788456080286535588;
117
118    w = x;
119    if( x < 0 )
120        w = -x;
121
122    if( w <= 5.0 ) {
123        z = x * x;
124        w = polevl( z, RPJ1, 3 ) / p1evl( z, RQJ1, 8 );
125        w = w * x * (z - Z1) * (z - Z2);
126        return( w );
127    }
128
129    w = 5.0/x;
130    z = w * w;
131
132    p = polevl( z, PPJ1, 6)/polevl( z, PQJ1, 6 );
133    q = polevl( z, QPJ1, 7)/p1evl( z, QQJ1, 7 );
134
135    xn = x - THPIO4;
136
137    double sn, cn;
138    SINCOS(xn, sn, cn);
139    p = p * cn - w * q * sn;
140
141    return( p * SQ2OPI / sqrt(x) );
142}
143
144#else
145//Single precission version of cephes
146constant float JPJ1[8] = {
147    -4.878788132172128E-009,
148    6.009061827883699E-007,
149    -4.541343896997497E-005,
150    1.937383947804541E-003,
151    -3.405537384615824E-002,
152    0.0,
153    0.0,
154    0.0
155    };
156
157constant float MO1J1[8] = {
158    6.913942741265801E-002,
159    -2.284801500053359E-001,
160    3.138238455499697E-001,
161    -2.102302420403875E-001,
162    5.435364690523026E-003,
163    1.493389585089498E-001,
164    4.976029650847191E-006,
165    7.978845453073848E-001
166    };
167
168constant float PH1J1[8] = {
169    -4.497014141919556E+001,
170    5.073465654089319E+001,
171    -2.485774108720340E+001,
172    7.222973196770240E+000,
173    -1.544842782180211E+000,
174    3.503787691653334E-001,
175    -1.637986776941202E-001,
176    3.749989509080821E-001
177    };
178
179float j1f(float x);
180float j1f(float x)
181{
182
183    float xx, w, z, p, q, xn;
184
185    const float Z1 = 1.46819706421238932572E1;
186    const float THPIO4F =  2.35619449019234492885;    /* 3*pi/4 */
187
188
189    xx = x;
190    if( xx < 0 )
191        xx = -x;
192
193    if( xx <= 2.0 ) {
194        z = xx * xx;
195        p = (z-Z1) * xx * polevl( z, JPJ1, 4 );
196        return( p );
197    }
198
199    q = 1.0/x;
200    w = sqrt(q);
201
202    p = w * polevl( q, MO1J1, 7);
203    w = q*q;
204    xn = q * polevl( w, PH1J1, 7) - THPIO4F;
205    p = p * cos(xn + xx);
206
207    return(p);
208}
209#endif
210
211#if FLOAT_SIZE>4
212#define sas_J1 j1
213#else
214#define sas_J1 j1f
215#endif
216
217//Finally J1c function that equals 2*J1(x)/x
218double sas_J1c(double x);
219double sas_J1c(double x)
220{
221    return (x != 0.0 ) ? 2.0*sas_J1(x)/x : 1.0;
222}
Note: See TracBrowser for help on using the repository browser.