1*627f7eb2Smrg /*
2*627f7eb2Smrg * ====================================================
3*627f7eb2Smrg * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
4*627f7eb2Smrg *
5*627f7eb2Smrg * Developed at SunPro, a Sun Microsystems, Inc. business.
6*627f7eb2Smrg * Permission to use, copy, modify, and distribute this
7*627f7eb2Smrg * software is freely granted, provided that this notice
8*627f7eb2Smrg * is preserved.
9*627f7eb2Smrg * ====================================================
10*627f7eb2Smrg */
11*627f7eb2Smrg
12*627f7eb2Smrg /* Modifications for 128-bit long double are
13*627f7eb2Smrg Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
14*627f7eb2Smrg and are incorporated herein by permission of the author. The author
15*627f7eb2Smrg reserves the right to distribute this material elsewhere under different
16*627f7eb2Smrg copying permissions. These modifications are distributed here under
17*627f7eb2Smrg the following terms:
18*627f7eb2Smrg
19*627f7eb2Smrg This library is free software; you can redistribute it and/or
20*627f7eb2Smrg modify it under the terms of the GNU Lesser General Public
21*627f7eb2Smrg License as published by the Free Software Foundation; either
22*627f7eb2Smrg version 2.1 of the License, or (at your option) any later version.
23*627f7eb2Smrg
24*627f7eb2Smrg This library is distributed in the hope that it will be useful,
25*627f7eb2Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
26*627f7eb2Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27*627f7eb2Smrg Lesser General Public License for more details.
28*627f7eb2Smrg
29*627f7eb2Smrg You should have received a copy of the GNU Lesser General Public
30*627f7eb2Smrg License along with this library; if not, see
31*627f7eb2Smrg <http://www.gnu.org/licenses/>. */
32*627f7eb2Smrg
33*627f7eb2Smrg /*
34*627f7eb2Smrg * __ieee754_jn(n, x), __ieee754_yn(n, x)
35*627f7eb2Smrg * floating point Bessel's function of the 1st and 2nd kind
36*627f7eb2Smrg * of order n
37*627f7eb2Smrg *
38*627f7eb2Smrg * Special cases:
39*627f7eb2Smrg * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
40*627f7eb2Smrg * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
41*627f7eb2Smrg * Note 2. About jn(n,x), yn(n,x)
42*627f7eb2Smrg * For n=0, j0(x) is called,
43*627f7eb2Smrg * for n=1, j1(x) is called,
44*627f7eb2Smrg * for n<x, forward recursion us used starting
45*627f7eb2Smrg * from values of j0(x) and j1(x).
46*627f7eb2Smrg * for n>x, a continued fraction approximation to
47*627f7eb2Smrg * j(n,x)/j(n-1,x) is evaluated and then backward
48*627f7eb2Smrg * recursion is used starting from a supposed value
49*627f7eb2Smrg * for j(n,x). The resulting value of j(0,x) is
50*627f7eb2Smrg * compared with the actual value to correct the
51*627f7eb2Smrg * supposed value of j(n,x).
52*627f7eb2Smrg *
53*627f7eb2Smrg * yn(n,x) is similar in all respects, except
54*627f7eb2Smrg * that forward recursion is used for all
55*627f7eb2Smrg * values of n>1.
56*627f7eb2Smrg *
57*627f7eb2Smrg */
58*627f7eb2Smrg
59*627f7eb2Smrg #include "quadmath-imp.h"
60*627f7eb2Smrg
61*627f7eb2Smrg static const __float128
62*627f7eb2Smrg invsqrtpi = 5.6418958354775628694807945156077258584405E-1Q,
63*627f7eb2Smrg two = 2,
64*627f7eb2Smrg one = 1,
65*627f7eb2Smrg zero = 0;
66*627f7eb2Smrg
67*627f7eb2Smrg
68*627f7eb2Smrg __float128
jnq(int n,__float128 x)69*627f7eb2Smrg jnq (int n, __float128 x)
70*627f7eb2Smrg {
71*627f7eb2Smrg uint32_t se;
72*627f7eb2Smrg int32_t i, ix, sgn;
73*627f7eb2Smrg __float128 a, b, temp, di, ret;
74*627f7eb2Smrg __float128 z, w;
75*627f7eb2Smrg ieee854_float128 u;
76*627f7eb2Smrg
77*627f7eb2Smrg
78*627f7eb2Smrg /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
79*627f7eb2Smrg * Thus, J(-n,x) = J(n,-x)
80*627f7eb2Smrg */
81*627f7eb2Smrg
82*627f7eb2Smrg u.value = x;
83*627f7eb2Smrg se = u.words32.w0;
84*627f7eb2Smrg ix = se & 0x7fffffff;
85*627f7eb2Smrg
86*627f7eb2Smrg /* if J(n,NaN) is NaN */
87*627f7eb2Smrg if (ix >= 0x7fff0000)
88*627f7eb2Smrg {
89*627f7eb2Smrg if ((u.words32.w0 & 0xffff) | u.words32.w1 | u.words32.w2 | u.words32.w3)
90*627f7eb2Smrg return x + x;
91*627f7eb2Smrg }
92*627f7eb2Smrg
93*627f7eb2Smrg if (n < 0)
94*627f7eb2Smrg {
95*627f7eb2Smrg n = -n;
96*627f7eb2Smrg x = -x;
97*627f7eb2Smrg se ^= 0x80000000;
98*627f7eb2Smrg }
99*627f7eb2Smrg if (n == 0)
100*627f7eb2Smrg return (j0q (x));
101*627f7eb2Smrg if (n == 1)
102*627f7eb2Smrg return (j1q (x));
103*627f7eb2Smrg sgn = (n & 1) & (se >> 31); /* even n -- 0, odd n -- sign(x) */
104*627f7eb2Smrg x = fabsq (x);
105*627f7eb2Smrg
106*627f7eb2Smrg {
107*627f7eb2Smrg SET_RESTORE_ROUNDF128 (FE_TONEAREST);
108*627f7eb2Smrg if (x == 0 || ix >= 0x7fff0000) /* if x is 0 or inf */
109*627f7eb2Smrg return sgn == 1 ? -zero : zero;
110*627f7eb2Smrg else if ((__float128) n <= x)
111*627f7eb2Smrg {
112*627f7eb2Smrg /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
113*627f7eb2Smrg if (ix >= 0x412D0000)
114*627f7eb2Smrg { /* x > 2**302 */
115*627f7eb2Smrg
116*627f7eb2Smrg /* ??? Could use an expansion for large x here. */
117*627f7eb2Smrg
118*627f7eb2Smrg /* (x >> n**2)
119*627f7eb2Smrg * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
120*627f7eb2Smrg * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
121*627f7eb2Smrg * Let s=sin(x), c=cos(x),
122*627f7eb2Smrg * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
123*627f7eb2Smrg *
124*627f7eb2Smrg * n sin(xn)*sqt2 cos(xn)*sqt2
125*627f7eb2Smrg * ----------------------------------
126*627f7eb2Smrg * 0 s-c c+s
127*627f7eb2Smrg * 1 -s-c -c+s
128*627f7eb2Smrg * 2 -s+c -c-s
129*627f7eb2Smrg * 3 s+c c-s
130*627f7eb2Smrg */
131*627f7eb2Smrg __float128 s;
132*627f7eb2Smrg __float128 c;
133*627f7eb2Smrg sincosq (x, &s, &c);
134*627f7eb2Smrg switch (n & 3)
135*627f7eb2Smrg {
136*627f7eb2Smrg case 0:
137*627f7eb2Smrg temp = c + s;
138*627f7eb2Smrg break;
139*627f7eb2Smrg case 1:
140*627f7eb2Smrg temp = -c + s;
141*627f7eb2Smrg break;
142*627f7eb2Smrg case 2:
143*627f7eb2Smrg temp = -c - s;
144*627f7eb2Smrg break;
145*627f7eb2Smrg case 3:
146*627f7eb2Smrg temp = c - s;
147*627f7eb2Smrg break;
148*627f7eb2Smrg }
149*627f7eb2Smrg b = invsqrtpi * temp / sqrtq (x);
150*627f7eb2Smrg }
151*627f7eb2Smrg else
152*627f7eb2Smrg {
153*627f7eb2Smrg a = j0q (x);
154*627f7eb2Smrg b = j1q (x);
155*627f7eb2Smrg for (i = 1; i < n; i++)
156*627f7eb2Smrg {
157*627f7eb2Smrg temp = b;
158*627f7eb2Smrg b = b * ((__float128) (i + i) / x) - a; /* avoid underflow */
159*627f7eb2Smrg a = temp;
160*627f7eb2Smrg }
161*627f7eb2Smrg }
162*627f7eb2Smrg }
163*627f7eb2Smrg else
164*627f7eb2Smrg {
165*627f7eb2Smrg if (ix < 0x3fc60000)
166*627f7eb2Smrg { /* x < 2**-57 */
167*627f7eb2Smrg /* x is tiny, return the first Taylor expansion of J(n,x)
168*627f7eb2Smrg * J(n,x) = 1/n!*(x/2)^n - ...
169*627f7eb2Smrg */
170*627f7eb2Smrg if (n >= 400) /* underflow, result < 10^-4952 */
171*627f7eb2Smrg b = zero;
172*627f7eb2Smrg else
173*627f7eb2Smrg {
174*627f7eb2Smrg temp = x * 0.5;
175*627f7eb2Smrg b = temp;
176*627f7eb2Smrg for (a = one, i = 2; i <= n; i++)
177*627f7eb2Smrg {
178*627f7eb2Smrg a *= (__float128) i; /* a = n! */
179*627f7eb2Smrg b *= temp; /* b = (x/2)^n */
180*627f7eb2Smrg }
181*627f7eb2Smrg b = b / a;
182*627f7eb2Smrg }
183*627f7eb2Smrg }
184*627f7eb2Smrg else
185*627f7eb2Smrg {
186*627f7eb2Smrg /* use backward recurrence */
187*627f7eb2Smrg /* x x^2 x^2
188*627f7eb2Smrg * J(n,x)/J(n-1,x) = ---- ------ ------ .....
189*627f7eb2Smrg * 2n - 2(n+1) - 2(n+2)
190*627f7eb2Smrg *
191*627f7eb2Smrg * 1 1 1
192*627f7eb2Smrg * (for large x) = ---- ------ ------ .....
193*627f7eb2Smrg * 2n 2(n+1) 2(n+2)
194*627f7eb2Smrg * -- - ------ - ------ -
195*627f7eb2Smrg * x x x
196*627f7eb2Smrg *
197*627f7eb2Smrg * Let w = 2n/x and h=2/x, then the above quotient
198*627f7eb2Smrg * is equal to the continued fraction:
199*627f7eb2Smrg * 1
200*627f7eb2Smrg * = -----------------------
201*627f7eb2Smrg * 1
202*627f7eb2Smrg * w - -----------------
203*627f7eb2Smrg * 1
204*627f7eb2Smrg * w+h - ---------
205*627f7eb2Smrg * w+2h - ...
206*627f7eb2Smrg *
207*627f7eb2Smrg * To determine how many terms needed, let
208*627f7eb2Smrg * Q(0) = w, Q(1) = w(w+h) - 1,
209*627f7eb2Smrg * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
210*627f7eb2Smrg * When Q(k) > 1e4 good for single
211*627f7eb2Smrg * When Q(k) > 1e9 good for double
212*627f7eb2Smrg * When Q(k) > 1e17 good for quadruple
213*627f7eb2Smrg */
214*627f7eb2Smrg /* determine k */
215*627f7eb2Smrg __float128 t, v;
216*627f7eb2Smrg __float128 q0, q1, h, tmp;
217*627f7eb2Smrg int32_t k, m;
218*627f7eb2Smrg w = (n + n) / (__float128) x;
219*627f7eb2Smrg h = 2 / (__float128) x;
220*627f7eb2Smrg q0 = w;
221*627f7eb2Smrg z = w + h;
222*627f7eb2Smrg q1 = w * z - 1;
223*627f7eb2Smrg k = 1;
224*627f7eb2Smrg while (q1 < 1.0e17Q)
225*627f7eb2Smrg {
226*627f7eb2Smrg k += 1;
227*627f7eb2Smrg z += h;
228*627f7eb2Smrg tmp = z * q1 - q0;
229*627f7eb2Smrg q0 = q1;
230*627f7eb2Smrg q1 = tmp;
231*627f7eb2Smrg }
232*627f7eb2Smrg m = n + n;
233*627f7eb2Smrg for (t = zero, i = 2 * (n + k); i >= m; i -= 2)
234*627f7eb2Smrg t = one / (i / x - t);
235*627f7eb2Smrg a = t;
236*627f7eb2Smrg b = one;
237*627f7eb2Smrg /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
238*627f7eb2Smrg * Hence, if n*(log(2n/x)) > ...
239*627f7eb2Smrg * single 8.8722839355e+01
240*627f7eb2Smrg * double 7.09782712893383973096e+02
241*627f7eb2Smrg * long double 1.1356523406294143949491931077970765006170e+04
242*627f7eb2Smrg * then recurrent value may overflow and the result is
243*627f7eb2Smrg * likely underflow to zero
244*627f7eb2Smrg */
245*627f7eb2Smrg tmp = n;
246*627f7eb2Smrg v = two / x;
247*627f7eb2Smrg tmp = tmp * logq (fabsq (v * tmp));
248*627f7eb2Smrg
249*627f7eb2Smrg if (tmp < 1.1356523406294143949491931077970765006170e+04Q)
250*627f7eb2Smrg {
251*627f7eb2Smrg for (i = n - 1, di = (__float128) (i + i); i > 0; i--)
252*627f7eb2Smrg {
253*627f7eb2Smrg temp = b;
254*627f7eb2Smrg b *= di;
255*627f7eb2Smrg b = b / x - a;
256*627f7eb2Smrg a = temp;
257*627f7eb2Smrg di -= two;
258*627f7eb2Smrg }
259*627f7eb2Smrg }
260*627f7eb2Smrg else
261*627f7eb2Smrg {
262*627f7eb2Smrg for (i = n - 1, di = (__float128) (i + i); i > 0; i--)
263*627f7eb2Smrg {
264*627f7eb2Smrg temp = b;
265*627f7eb2Smrg b *= di;
266*627f7eb2Smrg b = b / x - a;
267*627f7eb2Smrg a = temp;
268*627f7eb2Smrg di -= two;
269*627f7eb2Smrg /* scale b to avoid spurious overflow */
270*627f7eb2Smrg if (b > 1e100Q)
271*627f7eb2Smrg {
272*627f7eb2Smrg a /= b;
273*627f7eb2Smrg t /= b;
274*627f7eb2Smrg b = one;
275*627f7eb2Smrg }
276*627f7eb2Smrg }
277*627f7eb2Smrg }
278*627f7eb2Smrg /* j0() and j1() suffer enormous loss of precision at and
279*627f7eb2Smrg * near zero; however, we know that their zero points never
280*627f7eb2Smrg * coincide, so just choose the one further away from zero.
281*627f7eb2Smrg */
282*627f7eb2Smrg z = j0q (x);
283*627f7eb2Smrg w = j1q (x);
284*627f7eb2Smrg if (fabsq (z) >= fabsq (w))
285*627f7eb2Smrg b = (t * z / b);
286*627f7eb2Smrg else
287*627f7eb2Smrg b = (t * w / a);
288*627f7eb2Smrg }
289*627f7eb2Smrg }
290*627f7eb2Smrg if (sgn == 1)
291*627f7eb2Smrg ret = -b;
292*627f7eb2Smrg else
293*627f7eb2Smrg ret = b;
294*627f7eb2Smrg }
295*627f7eb2Smrg if (ret == 0)
296*627f7eb2Smrg {
297*627f7eb2Smrg ret = copysignq (FLT128_MIN, ret) * FLT128_MIN;
298*627f7eb2Smrg errno = ERANGE;
299*627f7eb2Smrg }
300*627f7eb2Smrg else
301*627f7eb2Smrg math_check_force_underflow (ret);
302*627f7eb2Smrg return ret;
303*627f7eb2Smrg }
304*627f7eb2Smrg
305*627f7eb2Smrg
306*627f7eb2Smrg __float128
ynq(int n,__float128 x)307*627f7eb2Smrg ynq (int n, __float128 x)
308*627f7eb2Smrg {
309*627f7eb2Smrg uint32_t se;
310*627f7eb2Smrg int32_t i, ix;
311*627f7eb2Smrg int32_t sign;
312*627f7eb2Smrg __float128 a, b, temp, ret;
313*627f7eb2Smrg ieee854_float128 u;
314*627f7eb2Smrg
315*627f7eb2Smrg u.value = x;
316*627f7eb2Smrg se = u.words32.w0;
317*627f7eb2Smrg ix = se & 0x7fffffff;
318*627f7eb2Smrg
319*627f7eb2Smrg /* if Y(n,NaN) is NaN */
320*627f7eb2Smrg if (ix >= 0x7fff0000)
321*627f7eb2Smrg {
322*627f7eb2Smrg if ((u.words32.w0 & 0xffff) | u.words32.w1 | u.words32.w2 | u.words32.w3)
323*627f7eb2Smrg return x + x;
324*627f7eb2Smrg }
325*627f7eb2Smrg if (x <= 0)
326*627f7eb2Smrg {
327*627f7eb2Smrg if (x == 0)
328*627f7eb2Smrg return ((n < 0 && (n & 1) != 0) ? 1 : -1) / 0.0Q;
329*627f7eb2Smrg if (se & 0x80000000)
330*627f7eb2Smrg return zero / (zero * x);
331*627f7eb2Smrg }
332*627f7eb2Smrg sign = 1;
333*627f7eb2Smrg if (n < 0)
334*627f7eb2Smrg {
335*627f7eb2Smrg n = -n;
336*627f7eb2Smrg sign = 1 - ((n & 1) << 1);
337*627f7eb2Smrg }
338*627f7eb2Smrg if (n == 0)
339*627f7eb2Smrg return (y0q (x));
340*627f7eb2Smrg {
341*627f7eb2Smrg SET_RESTORE_ROUNDF128 (FE_TONEAREST);
342*627f7eb2Smrg if (n == 1)
343*627f7eb2Smrg {
344*627f7eb2Smrg ret = sign * y1q (x);
345*627f7eb2Smrg goto out;
346*627f7eb2Smrg }
347*627f7eb2Smrg if (ix >= 0x7fff0000)
348*627f7eb2Smrg return zero;
349*627f7eb2Smrg if (ix >= 0x412D0000)
350*627f7eb2Smrg { /* x > 2**302 */
351*627f7eb2Smrg
352*627f7eb2Smrg /* ??? See comment above on the possible futility of this. */
353*627f7eb2Smrg
354*627f7eb2Smrg /* (x >> n**2)
355*627f7eb2Smrg * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
356*627f7eb2Smrg * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
357*627f7eb2Smrg * Let s=sin(x), c=cos(x),
358*627f7eb2Smrg * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
359*627f7eb2Smrg *
360*627f7eb2Smrg * n sin(xn)*sqt2 cos(xn)*sqt2
361*627f7eb2Smrg * ----------------------------------
362*627f7eb2Smrg * 0 s-c c+s
363*627f7eb2Smrg * 1 -s-c -c+s
364*627f7eb2Smrg * 2 -s+c -c-s
365*627f7eb2Smrg * 3 s+c c-s
366*627f7eb2Smrg */
367*627f7eb2Smrg __float128 s;
368*627f7eb2Smrg __float128 c;
369*627f7eb2Smrg sincosq (x, &s, &c);
370*627f7eb2Smrg switch (n & 3)
371*627f7eb2Smrg {
372*627f7eb2Smrg case 0:
373*627f7eb2Smrg temp = s - c;
374*627f7eb2Smrg break;
375*627f7eb2Smrg case 1:
376*627f7eb2Smrg temp = -s - c;
377*627f7eb2Smrg break;
378*627f7eb2Smrg case 2:
379*627f7eb2Smrg temp = -s + c;
380*627f7eb2Smrg break;
381*627f7eb2Smrg case 3:
382*627f7eb2Smrg temp = s + c;
383*627f7eb2Smrg break;
384*627f7eb2Smrg }
385*627f7eb2Smrg b = invsqrtpi * temp / sqrtq (x);
386*627f7eb2Smrg }
387*627f7eb2Smrg else
388*627f7eb2Smrg {
389*627f7eb2Smrg a = y0q (x);
390*627f7eb2Smrg b = y1q (x);
391*627f7eb2Smrg /* quit if b is -inf */
392*627f7eb2Smrg u.value = b;
393*627f7eb2Smrg se = u.words32.w0 & 0xffff0000;
394*627f7eb2Smrg for (i = 1; i < n && se != 0xffff0000; i++)
395*627f7eb2Smrg {
396*627f7eb2Smrg temp = b;
397*627f7eb2Smrg b = ((__float128) (i + i) / x) * b - a;
398*627f7eb2Smrg u.value = b;
399*627f7eb2Smrg se = u.words32.w0 & 0xffff0000;
400*627f7eb2Smrg a = temp;
401*627f7eb2Smrg }
402*627f7eb2Smrg }
403*627f7eb2Smrg /* If B is +-Inf, set up errno accordingly. */
404*627f7eb2Smrg if (! finiteq (b))
405*627f7eb2Smrg errno = ERANGE;
406*627f7eb2Smrg if (sign > 0)
407*627f7eb2Smrg ret = b;
408*627f7eb2Smrg else
409*627f7eb2Smrg ret = -b;
410*627f7eb2Smrg }
411*627f7eb2Smrg out:
412*627f7eb2Smrg if (isinfq (ret))
413*627f7eb2Smrg ret = copysignq (FLT128_MAX, ret) * FLT128_MAX;
414*627f7eb2Smrg return ret;
415*627f7eb2Smrg }
416