ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

jn_yn.c
Go to the documentation of this file.
00001 /* @(#)e_jn.c 5.1 93/09/24 */
00002 /*
00003  * ====================================================
00004  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
00005  *
00006  * Developed at SunPro, a Sun Microsystems, Inc. business.
00007  * Permission to use, copy, modify, and distribute this
00008  * software is freely granted, provided that this notice
00009  * is preserved.
00010  * ====================================================
00011  */
00012 
00013 #if defined(LIBM_SCCS) && !defined(lint)
00014 static char rcsid[] = "$NetBSD: e_jn.c,v 1.9 1995/05/10 20:45:34 jtc Exp $";
00015 #endif
00016 
00017 /*
00018  * __ieee754_jn(n, x), __ieee754_yn(n, x)
00019  * floating point Bessel's function of the 1st and 2nd kind
00020  * of order n
00021  *
00022  * Special cases:
00023  *  y0(0)=y1(0)=yn(n,0) = -inf with overflow signal;
00024  *  y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
00025  * Note 2. About jn(n,x), yn(n,x)
00026  *  For n=0, j0(x) is called,
00027  *  for n=1, j1(x) is called,
00028  *  for n<x, forward recursion us used starting
00029  *  from values of j0(x) and j1(x).
00030  *  for n>x, a continued fraction approximation to
00031  *  j(n,x)/j(n-1,x) is evaluated and then backward
00032  *  recursion is used starting from a supposed value
00033  *  for j(n,x). The resulting value of j(0,x) is
00034  *  compared with the actual value to correct the
00035  *  supposed value of j(n,x).
00036  *
00037  *  yn(n,x) is similar in all respects, except
00038  *  that forward recursion is used for all
00039  *  values of n>1.
00040  *
00041  */
00042 
00043 #include "math.h"
00044 #include "ieee754.h"
00045 
00046 #ifdef __STDC__
00047 static const double
00048 #else
00049 static double
00050 #endif
00051 invsqrtpi=  5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
00052 two   =  2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
00053 one   =  1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */
00054 
00055 #ifdef __STDC__
00056 static const double zero  =  0.00000000000000000000e+00;
00057 #else
00058 static double zero  =  0.00000000000000000000e+00;
00059 #endif
00060 
00061 #ifdef __STDC__
00062     double __ieee754_jn(int n, double x)
00063 #else
00064     double __ieee754_jn(n,x)
00065     int n; double x;
00066 #endif
00067 {
00068     int32_t i,hx,ix,lx, sgn;
00069     double a, b, temp, di;
00070     double z, w;
00071 
00072     /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
00073      * Thus, J(-n,x) = J(n,-x)
00074      */
00075     EXTRACT_WORDS(hx,lx,x);
00076     ix = 0x7fffffff&hx;
00077     /* if J(n,NaN) is NaN */
00078     if((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000) return x+x;
00079     if(n<0){
00080         n = -n;
00081         x = -x;
00082         hx ^= 0x80000000;
00083     }
00084     if(n==0) return(__ieee754_j0(x));
00085     if(n==1) return(__ieee754_j1(x));
00086     sgn = (n&1)&(hx>>31);   /* even n -- 0, odd n -- sign(x) */
00087     x = fabs(x);
00088     if((ix|lx)==0||ix>=0x7ff00000)  /* if x is 0 or inf */
00089         b = zero;
00090     else if((double)n<=x) {
00091         /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
00092         if(ix>=0x52D00000) { /* x > 2**302 */
00093     /* (x >> n**2)
00094      *      Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
00095      *      Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
00096      *      Let s=sin(x), c=cos(x),
00097      *      xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
00098      *
00099      *         n    sin(xn)*sqt2    cos(xn)*sqt2
00100      *      ----------------------------------
00101      *         0     s-c         c+s
00102      *         1    -s-c        -c+s
00103      *         2    -s+c        -c-s
00104      *         3     s+c         c-s
00105      */
00106         double s;
00107         double c;
00108         __sincos (x, &s, &c);
00109         switch(n&3) {
00110             case 0: temp =  c + s; break;
00111             case 1: temp = -c + s; break;
00112             case 2: temp = -c - s; break;
00113             case 3: temp =  c - s; break;
00114         }
00115         b = invsqrtpi*temp/__ieee754_sqrt(x);
00116         } else {
00117             a = __ieee754_j0(x);
00118             b = __ieee754_j1(x);
00119             for(i=1;i<n;i++){
00120             temp = b;
00121             b = b*((double)(i+i)/x) - a; /* avoid underflow */
00122             a = temp;
00123             }
00124         }
00125     } else {
00126         if(ix<0x3e100000) { /* x < 2**-29 */
00127     /* x is tiny, return the first Taylor expansion of J(n,x)
00128      * J(n,x) = 1/n!*(x/2)^n  - ...
00129      */
00130         if(n>33)    /* underflow */
00131             b = zero;
00132         else {
00133             temp = x*0.5; b = temp;
00134             for (a=one,i=2;i<=n;i++) {
00135             a *= (double)i;     /* a = n! */
00136             b *= temp;      /* b = (x/2)^n */
00137             }
00138             b = b/a;
00139         }
00140         } else {
00141         /* use backward recurrence */
00142         /*          x      x^2      x^2
00143          *  J(n,x)/J(n-1,x) =  ----   ------   ------   .....
00144          *          2n  - 2(n+1) - 2(n+2)
00145          *
00146          *          1      1        1
00147          *  (for large x)   =  ----  ------   ------   .....
00148          *          2n   2(n+1)   2(n+2)
00149          *          -- - ------ - ------ -
00150          *           x     x         x
00151          *
00152          * Let w = 2n/x and h=2/x, then the above quotient
00153          * is equal to the continued fraction:
00154          *          1
00155          *  = -----------------------
00156          *             1
00157          *     w - -----------------
00158          *            1
00159          *          w+h - ---------
00160          *             w+2h - ...
00161          *
00162          * To determine how many terms needed, let
00163          * Q(0) = w, Q(1) = w(w+h) - 1,
00164          * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
00165          * When Q(k) > 1e4  good for single
00166          * When Q(k) > 1e9  good for double
00167          * When Q(k) > 1e17 good for quadruple
00168          */
00169         /* determine k */
00170         double t,v;
00171         double q0,q1,h,tmp; int32_t k,m;
00172         w  = (n+n)/(double)x; h = 2.0/(double)x;
00173         q0 = w;  z = w+h; q1 = w*z - 1.0; k=1;
00174         while(q1<1.0e9) {
00175             k += 1; z += h;
00176             tmp = z*q1 - q0;
00177             q0 = q1;
00178             q1 = tmp;
00179         }
00180         m = n+n;
00181         for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t);
00182         a = t;
00183         b = one;
00184         /*  estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
00185          *  Hence, if n*(log(2n/x)) > ...
00186          *  single 8.8722839355e+01
00187          *  double 7.09782712893383973096e+02
00188          *  long double 1.1356523406294143949491931077970765006170e+04
00189          *  then recurrent value may overflow and the result is
00190          *  likely underflow to zero
00191          */
00192         tmp = n;
00193         v = two/x;
00194         tmp = tmp*__ieee754_log(fabs(v*tmp));
00195         if(tmp<7.09782712893383973096e+02) {
00196                 for(i=n-1,di=(double)(i+i);i>0;i--){
00197                 temp = b;
00198             b *= di;
00199             b  = b/x - a;
00200                 a = temp;
00201             di -= two;
00202                 }
00203         } else {
00204                 for(i=n-1,di=(double)(i+i);i>0;i--){
00205                 temp = b;
00206             b *= di;
00207             b  = b/x - a;
00208                 a = temp;
00209             di -= two;
00210             /* scale b to avoid spurious overflow */
00211             if(b>1e100) {
00212                 a /= b;
00213                 t /= b;
00214                 b  = one;
00215             }
00216                 }
00217         }
00218             b = (t*__ieee754_j0(x)/b);
00219         }
00220     }
00221     if(sgn==1) return -b; else return b;
00222 }
00223 
00224 #ifdef __STDC__
00225     double __ieee754_yn(int n, double x)
00226 #else
00227     double __ieee754_yn(n,x)
00228     int n; double x;
00229 #endif
00230 {
00231     int32_t i,hx,ix,lx;
00232     int32_t sign;
00233     double a, b, temp;
00234 
00235     EXTRACT_WORDS(hx,lx,x);
00236     ix = 0x7fffffff&hx;
00237     /* if Y(n,NaN) is NaN */
00238     if((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000) return x+x;
00239     if((ix|lx)==0) return -HUGE_VAL+x; /* -inf and overflow exception.  */;
00240     if(hx<0) return zero/(zero*x);
00241     sign = 1;
00242     if(n<0){
00243         n = -n;
00244         sign = 1 - ((n&1)<<1);
00245     }
00246     if(n==0) return(__ieee754_y0(x));
00247     if(n==1) return(sign*__ieee754_y1(x));
00248     if(ix==0x7ff00000) return zero;
00249     if(ix>=0x52D00000) { /* x > 2**302 */
00250     /* (x >> n**2)
00251      *      Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
00252      *      Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
00253      *      Let s=sin(x), c=cos(x),
00254      *      xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
00255      *
00256      *         n    sin(xn)*sqt2    cos(xn)*sqt2
00257      *      ----------------------------------
00258      *         0     s-c         c+s
00259      *         1    -s-c        -c+s
00260      *         2    -s+c        -c-s
00261      *         3     s+c         c-s
00262      */
00263         double c;
00264         double s;
00265         __sincos (x, &s, &c);
00266         switch(n&3) {
00267             case 0: temp =  s - c; break;
00268             case 1: temp = -s - c; break;
00269             case 2: temp = -s + c; break;
00270             case 3: temp =  s + c; break;
00271         }
00272         b = invsqrtpi*temp/__ieee754_sqrt(x);
00273     } else {
00274         u_int32_t high;
00275         a = __ieee754_y0(x);
00276         b = __ieee754_y1(x);
00277     /* quit if b is -inf */
00278         GET_HIGH_WORD(high,b);
00279         for(i=1;i<n&&high!=0xfff00000;i++){
00280         temp = b;
00281         b = ((double)(i+i)/x)*b - a;
00282         GET_HIGH_WORD(high,b);
00283         a = temp;
00284         }
00285     }
00286     if(sign>0) return b; else return -b;
00287 }

Generated on Fri May 25 2012 04:34:54 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.