4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
26 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
30 #pragma weak __jn = jn
31 #pragma weak __yn = yn
34 * floating point Bessel's function of the 1st and 2nd kind
35 * of order n: jn(n,x),yn(n,x);
38 * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
39 * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
40 * Note 2. About jn(n,x), yn(n,x)
41 * For n=0, j0(x) is called,
42 * for n=1, j1(x) is called,
43 * for n<x, forward recursion us used starting
44 * from values of j0(x) and j1(x).
45 * for n>x, a continued fraction approximation to
46 * j(n,x)/j(n-1,x) is evaluated and then backward
47 * recursion is used starting from a supposed value
48 * for j(n,x). The resulting value of j(0,x) is
49 * compared with the actual value to correct the
50 * supposed value of j(n,x).
52 * yn(n,x) is similar in all respects, except
53 * that forward recursion is used for all
59 #include <float.h> /* DBL_MIN */
60 #include <values.h> /* X_TLOSS */
61 #include "xpg6.h" /* __xpg6 */
63 #define GENERIC double
66 invsqrtpi
= 5.641895835477562869480794515607725858441e-0001,
72 jn(int n
, GENERIC x
) {
74 GENERIC a
, b
, temp
= 0;
78 * J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
79 * Thus, J(-n,x) = J(n,-x)
81 ox
= x
; on
= (GENERIC
)n
;
87 return (x
*x
); /* + -> * for Cheetah */
88 if (!((int) _lib_version
== libm_ieee
||
89 (__xpg6
& _C99SUSv3_math_errexcept
) != 0)) {
90 if (fabs(x
) > X_TLOSS
)
91 return (_SVID_libm_err(on
, ox
, 38));
100 sgn
= signbit(x
); /* old n */
102 if (x
== zero
||!finite(x
)) b
= zero
;
103 else if ((GENERIC
)n
<= x
) {
106 * J(n+1,x)=2n/x *J(n,x)-J(n-1,x)
111 * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
112 * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
113 * Let s=sin(x), c=cos(x),
114 * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
116 * n sin(xn)*sqt2 cos(xn)*sqt2
117 * ----------------------------------
124 case 0: temp
= cos(x
)+sin(x
); break;
125 case 1: temp
= -cos(x
)+sin(x
); break;
126 case 2: temp
= -cos(x
)-sin(x
); break;
127 case 3: temp
= cos(x
)-sin(x
); break;
129 b
= invsqrtpi
*temp
/sqrt(x
);
133 for (i
= 1; i
< n
; i
++) {
135 b
= b
*((GENERIC
)(i
+i
)/x
) - a
; /* avoid underflow */
140 if (x
< 1e-9) { /* use J(n,x) = 1/n!*(x/2)^n */
141 b
= pow(0.5*x
, (GENERIC
) n
);
143 for (a
= one
, i
= 1; i
<= n
; i
++) a
*= (GENERIC
)i
;
148 * use backward recurrence
150 * J(n,x)/J(n-1,x) = ---- ------ ------ .....
151 * 2n - 2(n+1) - 2(n+2)
154 * (for large x) = ---- ------ ------ .....
156 * -- - ------ - ------ -
159 * Let w = 2n/x and h = 2/x, then the above quotient
160 * is equal to the continued fraction:
162 * = -----------------------
164 * w - -----------------
169 * To determine how many terms needed, let
170 * Q(0) = w, Q(1) = w(w+h) - 1,
171 * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
172 * When Q(k) > 1e4 good for single
173 * When Q(k) > 1e9 good for double
174 * When Q(k) > 1e17 good for quaduple
178 double q0
, q1
, h
, tmp
; int k
, m
;
179 w
= (n
+n
)/(double)x
; h
= 2.0/(double)x
;
180 q0
= w
; z
= w
+ h
; q1
= w
*z
- 1.0; k
= 1;
188 for (t
= zero
, i
= 2*(n
+k
); i
>= m
; i
-= 2) t
= one
/(i
/x
-t
);
192 * estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
193 * hence, if n*(log(2n/x)) > ...
194 * single 8.8722839355e+01
195 * double 7.09782712893383973096e+02
196 * long double 1.1356523406294143949491931077970765006170e+04
197 * then recurrent value may overflow and the result is
198 * likely underflow to zero
202 tmp
= tmp
*log(fabs(v
*tmp
));
203 if (tmp
< 7.09782712893383973096e+02) {
204 for (i
= n
-1; i
> 0; i
--) {
210 for (i
= n
-1; i
> 0; i
--) {
231 yn(int n
, GENERIC x
) {
234 GENERIC a
, b
, temp
= 0, ox
, on
;
236 ox
= x
; on
= (GENERIC
)n
;
238 return (x
*x
); /* + -> * for Cheetah */
241 /* return -one/zero; */
242 return (_SVID_libm_err((GENERIC
)n
, x
, 12));
244 /* return zero/zero; */
245 return (_SVID_libm_err((GENERIC
)n
, x
, 13));
248 if (!((int) _lib_version
== libm_ieee
||
249 (__xpg6
& _C99SUSv3_math_errexcept
) != 0)) {
251 return (_SVID_libm_err(on
, ox
, 39));
256 if ((n
&1) == 1) sign
= -1;
268 * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
269 * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
270 * Let s = sin(x), c = cos(x),
271 * xn = x-(2n+1)*pi/4, sqt2 = sqrt(2), then
273 * n sin(xn)*sqt2 cos(xn)*sqt2
274 * ----------------------------------
281 case 0: temp
= sin(x
)-cos(x
); break;
282 case 1: temp
= -sin(x
)-cos(x
); break;
283 case 2: temp
= -sin(x
)+cos(x
); break;
284 case 3: temp
= sin(x
)+cos(x
); break;
286 b
= invsqrtpi
*temp
/sqrt(x
);
291 * fix 1262058 and take care of non-default rounding
293 for (i
= 1; i
< n
; i
++) {
295 b
*= (GENERIC
) (i
+ i
) / x
;