1 
   2 /*
   3  * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.  Oracle designates this
   9  * particular file as subject to the "Classpath" exception as provided
  10  * by Oracle in the LICENSE file that accompanied this code.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  23  * or visit www.oracle.com if you need additional information or have any
  24  * questions.
  25  */
  26 
  27 /*
  28  * __ieee754_jn(n, x), __ieee754_yn(n, x)
  29  * floating point Bessel's function of the 1st and 2nd kind
  30  * of order n
  31  *
  32  * Special cases:
  33  *      y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
  34  *      y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
  35  * Note 2. About jn(n,x), yn(n,x)
  36  *      For n=0, j0(x) is called,
  37  *      for n=1, j1(x) is called,
  38  *      for n<x, forward recursion us used starting
  39  *      from values of j0(x) and j1(x).
  40  *      for n>x, a continued fraction approximation to
  41  *      j(n,x)/j(n-1,x) is evaluated and then backward
  42  *      recursion is used starting from a supposed value
  43  *      for j(n,x). The resulting value of j(0,x) is
  44  *      compared with the actual value to correct the
  45  *      supposed value of j(n,x).
  46  *
  47  *      yn(n,x) is similar in all respects, except
  48  *      that forward recursion is used for all
  49  *      values of n>1.
  50  *
  51  */
  52 
  53 #include "fdlibm.h"
  54 
  55 #ifdef __STDC__
  56 static const double
  57 #else
  58 static double
  59 #endif
  60 invsqrtpi=  5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
  61 two   =  2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
  62 one   =  1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */
  63 
  64 static double zero  =  0.00000000000000000000e+00;
  65 
  66 #ifdef __STDC__
  67         double __ieee754_jn(int n, double x)
  68 #else
  69         double __ieee754_jn(n,x)
  70         int n; double x;
  71 #endif
  72 {
  73         int i,hx,ix,lx, sgn;
  74         double a, b, temp = 0, di;
  75         double z, w;
  76 
  77     /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
  78      * Thus, J(-n,x) = J(n,-x)
  79      */
  80         hx = __HI(x);
  81         ix = 0x7fffffff&hx;
  82         lx = __LO(x);
  83     /* if J(n,NaN) is NaN */
  84         if((ix|((unsigned)(lx|-lx))>>31)>0x7ff00000) return x+x;
  85         if(n<0){
  86                 n = -n;
  87                 x = -x;
  88                 hx ^= 0x80000000;
  89         }
  90         if(n==0) return(__ieee754_j0(x));
  91         if(n==1) return(__ieee754_j1(x));
  92         sgn = (n&1)&(hx>>31);   /* even n -- 0, odd n -- sign(x) */
  93         x = fabs(x);
  94         if((ix|lx)==0||ix>=0x7ff00000)  /* if x is 0 or inf */
  95             b = zero;
  96         else if((double)n<=x) {
  97                 /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
  98             if(ix>=0x52D00000) { /* x > 2**302 */
  99     /* (x >> n**2)
 100      *      Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
 101      *      Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
 102      *      Let s=sin(x), c=cos(x),
 103      *          xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
 104      *
 105      *             n    sin(xn)*sqt2    cos(xn)*sqt2
 106      *          ----------------------------------
 107      *             0     s-c             c+s
 108      *             1    -s-c            -c+s
 109      *             2    -s+c            -c-s
 110      *             3     s+c             c-s
 111      */
 112                 switch(n&3) {
 113                     case 0: temp =  cos(x)+sin(x); break;
 114                     case 1: temp = -cos(x)+sin(x); break;
 115                     case 2: temp = -cos(x)-sin(x); break;
 116                     case 3: temp =  cos(x)-sin(x); break;
 117                 }
 118                 b = invsqrtpi*temp/sqrt(x);
 119             } else {
 120                 a = __ieee754_j0(x);
 121                 b = __ieee754_j1(x);
 122                 for(i=1;i<n;i++){
 123                     temp = b;
 124                     b = b*((double)(i+i)/x) - a; /* avoid underflow */
 125                     a = temp;
 126                 }
 127             }
 128         } else {
 129             if(ix<0x3e100000) { /* x < 2**-29 */
 130     /* x is tiny, return the first Taylor expansion of J(n,x)
 131      * J(n,x) = 1/n!*(x/2)^n  - ...
 132      */
 133                 if(n>33)        /* underflow */
 134                     b = zero;
 135                 else {
 136                     temp = x*0.5; b = temp;
 137                     for (a=one,i=2;i<=n;i++) {
 138                         a *= (double)i;         /* a = n! */
 139                         b *= temp;              /* b = (x/2)^n */
 140                     }
 141                     b = b/a;
 142                 }
 143             } else {
 144                 /* use backward recurrence */
 145                 /*                      x      x^2      x^2
 146                  *  J(n,x)/J(n-1,x) =  ----   ------   ------   .....
 147                  *                      2n  - 2(n+1) - 2(n+2)
 148                  *
 149                  *                      1      1        1
 150                  *  (for large x)   =  ----  ------   ------   .....
 151                  *                      2n   2(n+1)   2(n+2)
 152                  *                      -- - ------ - ------ -
 153                  *                       x     x         x
 154                  *
 155                  * Let w = 2n/x and h=2/x, then the above quotient
 156                  * is equal to the continued fraction:
 157                  *                  1
 158                  *      = -----------------------
 159                  *                     1
 160                  *         w - -----------------
 161                  *                        1
 162                  *              w+h - ---------
 163                  *                     w+2h - ...
 164                  *
 165                  * To determine how many terms needed, let
 166                  * Q(0) = w, Q(1) = w(w+h) - 1,
 167                  * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
 168                  * When Q(k) > 1e4      good for single
 169                  * When Q(k) > 1e9      good for double
 170                  * When Q(k) > 1e17     good for quadruple
 171                  */
 172             /* determine k */
 173                 double t,v;
 174                 double q0,q1,h,tmp; int k,m;
 175                 w  = (n+n)/(double)x; h = 2.0/(double)x;
 176                 q0 = w;  z = w+h; q1 = w*z - 1.0; k=1;
 177                 while(q1<1.0e9) {
 178                         k += 1; z += h;
 179                         tmp = z*q1 - q0;
 180                         q0 = q1;
 181                         q1 = tmp;
 182                 }
 183                 m = n+n;
 184                 for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t);
 185                 a = t;
 186                 b = one;
 187                 /*  estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
 188                  *  Hence, if n*(log(2n/x)) > ...
 189                  *  single 8.8722839355e+01
 190                  *  double 7.09782712893383973096e+02
 191                  *  long double 1.1356523406294143949491931077970765006170e+04
 192                  *  then recurrent value may overflow and the result is
 193                  *  likely underflow to zero
 194                  */
 195                 tmp = n;
 196                 v = two/x;
 197                 tmp = tmp*__ieee754_log(fabs(v*tmp));
 198                 if(tmp<7.09782712893383973096e+02) {
 199                     for(i=n-1,di=(double)(i+i);i>0;i--){
 200                         temp = b;
 201                         b *= di;
 202                         b  = b/x - a;
 203                         a = temp;
 204                         di -= two;
 205                     }
 206                 } else {
 207                     for(i=n-1,di=(double)(i+i);i>0;i--){
 208                         temp = b;
 209                         b *= di;
 210                         b  = b/x - a;
 211                         a = temp;
 212                         di -= two;
 213                     /* scale b to avoid spurious overflow */
 214                         if(b>1e100) {
 215                             a /= b;
 216                             t /= b;
 217                             b  = one;
 218                         }
 219                     }
 220                 }
 221                 b = (t*__ieee754_j0(x)/b);
 222             }
 223         }
 224         if(sgn==1) return -b; else return b;
 225 }
 226 
 227 #ifdef __STDC__
 228         double __ieee754_yn(int n, double x)
 229 #else
 230         double __ieee754_yn(n,x)
 231         int n; double x;
 232 #endif
 233 {
 234         int i,hx,ix,lx;
 235         int sign;
 236         double a, b, temp = 0;
 237 
 238         hx = __HI(x);
 239         ix = 0x7fffffff&hx;
 240         lx = __LO(x);
 241     /* if Y(n,NaN) is NaN */
 242         if((ix|((unsigned)(lx|-lx))>>31)>0x7ff00000) return x+x;
 243         if((ix|lx)==0) return -one/zero;
 244         if(hx<0) return zero/zero;
 245         sign = 1;
 246         if(n<0){
 247                 n = -n;
 248                 sign = 1 - ((n&1)<<1);
 249         }
 250         if(n==0) return(__ieee754_y0(x));
 251         if(n==1) return(sign*__ieee754_y1(x));
 252         if(ix==0x7ff00000) return zero;
 253         if(ix>=0x52D00000) { /* x > 2**302 */
 254     /* (x >> n**2)
 255      *      Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
 256      *      Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
 257      *      Let s=sin(x), c=cos(x),
 258      *          xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
 259      *
 260      *             n    sin(xn)*sqt2    cos(xn)*sqt2
 261      *          ----------------------------------
 262      *             0     s-c             c+s
 263      *             1    -s-c            -c+s
 264      *             2    -s+c            -c-s
 265      *             3     s+c             c-s
 266      */
 267                 switch(n&3) {
 268                     case 0: temp =  sin(x)-cos(x); break;
 269                     case 1: temp = -sin(x)-cos(x); break;
 270                     case 2: temp = -sin(x)+cos(x); break;
 271                     case 3: temp =  sin(x)+cos(x); break;
 272                 }
 273                 b = invsqrtpi*temp/sqrt(x);
 274         } else {
 275             a = __ieee754_y0(x);
 276             b = __ieee754_y1(x);
 277         /* quit if b is -inf */
 278             for(i=1;i<n&&(__HI(b) != 0xfff00000);i++){
 279                 temp = b;
 280                 b = ((double)(i+i)/x)*b - a;
 281                 a = temp;
 282             }
 283         }
 284         if(sign>0) return b; else return -b;
 285 }