Home | History | Annotate | Line # | Download | only in noieee_src
      1  1.8  christos /*	$NetBSD: n_jn.c,v 1.8 2018/03/05 23:00:55 christos Exp $	*/
      2  1.1     ragge /*-
      3  1.1     ragge  * Copyright (c) 1992, 1993
      4  1.1     ragge  *	The Regents of the University of California.  All rights reserved.
      5  1.1     ragge  *
      6  1.1     ragge  * Redistribution and use in source and binary forms, with or without
      7  1.1     ragge  * modification, are permitted provided that the following conditions
      8  1.1     ragge  * are met:
      9  1.1     ragge  * 1. Redistributions of source code must retain the above copyright
     10  1.1     ragge  *    notice, this list of conditions and the following disclaimer.
     11  1.1     ragge  * 2. Redistributions in binary form must reproduce the above copyright
     12  1.1     ragge  *    notice, this list of conditions and the following disclaimer in the
     13  1.1     ragge  *    documentation and/or other materials provided with the distribution.
     14  1.6       agc  * 3. Neither the name of the University nor the names of its contributors
     15  1.1     ragge  *    may be used to endorse or promote products derived from this software
     16  1.1     ragge  *    without specific prior written permission.
     17  1.1     ragge  *
     18  1.1     ragge  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     19  1.1     ragge  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20  1.1     ragge  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21  1.1     ragge  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     22  1.1     ragge  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     23  1.1     ragge  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     24  1.1     ragge  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     25  1.1     ragge  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     26  1.1     ragge  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27  1.1     ragge  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28  1.1     ragge  * SUCH DAMAGE.
     29  1.1     ragge  */
     30  1.1     ragge 
     31  1.1     ragge #ifndef lint
     32  1.2     ragge #if 0
     33  1.1     ragge static char sccsid[] = "@(#)jn.c	8.2 (Berkeley) 11/30/93";
     34  1.2     ragge #endif
     35  1.1     ragge #endif /* not lint */
     36  1.1     ragge 
     37  1.1     ragge /*
     38  1.1     ragge  * 16 December 1992
     39  1.1     ragge  * Minor modifications by Peter McIlroy to adapt non-IEEE architecture.
     40  1.1     ragge  */
     41  1.1     ragge 
     42  1.1     ragge /*
     43  1.1     ragge  * ====================================================
     44  1.1     ragge  * Copyright (C) 1992 by Sun Microsystems, Inc.
     45  1.1     ragge  *
     46  1.1     ragge  * Developed at SunPro, a Sun Microsystems, Inc. business.
     47  1.1     ragge  * Permission to use, copy, modify, and distribute this
     48  1.4    simonb  * software is freely granted, provided that this notice
     49  1.1     ragge  * is preserved.
     50  1.1     ragge  * ====================================================
     51  1.1     ragge  *
     52  1.1     ragge  * ******************* WARNING ********************
     53  1.1     ragge  * This is an alpha version of SunPro's FDLIBM (Freely
     54  1.4    simonb  * Distributable Math Library) for IEEE double precision
     55  1.1     ragge  * arithmetic. FDLIBM is a basic math library written
     56  1.4    simonb  * in C that runs on machines that conform to IEEE
     57  1.4    simonb  * Standard 754/854. This alpha version is distributed
     58  1.4    simonb  * for testing purpose. Those who use this software
     59  1.4    simonb  * should report any bugs to
     60  1.1     ragge  *
     61  1.1     ragge  *		fdlibm-comments (at) sunpro.eng.sun.com
     62  1.1     ragge  *
     63  1.1     ragge  * -- K.C. Ng, Oct 12, 1992
     64  1.1     ragge  * ************************************************
     65  1.1     ragge  */
     66  1.1     ragge 
     67  1.1     ragge /*
     68  1.1     ragge  * jn(int n, double x), yn(int n, double x)
     69  1.1     ragge  * floating point Bessel's function of the 1st and 2nd kind
     70  1.1     ragge  * of order n
     71  1.4    simonb  *
     72  1.1     ragge  * Special cases:
     73  1.1     ragge  *	y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
     74  1.1     ragge  *	y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
     75  1.1     ragge  * Note 2. About jn(n,x), yn(n,x)
     76  1.1     ragge  *	For n=0, j0(x) is called,
     77  1.1     ragge  *	for n=1, j1(x) is called,
     78  1.1     ragge  *	for n<x, forward recursion us used starting
     79  1.1     ragge  *	from values of j0(x) and j1(x).
     80  1.1     ragge  *	for n>x, a continued fraction approximation to
     81  1.1     ragge  *	j(n,x)/j(n-1,x) is evaluated and then backward
     82  1.1     ragge  *	recursion is used starting from a supposed value
     83  1.1     ragge  *	for j(n,x). The resulting value of j(0,x) is
     84  1.1     ragge  *	compared with the actual value to correct the
     85  1.1     ragge  *	supposed value of j(n,x).
     86  1.1     ragge  *
     87  1.1     ragge  *	yn(n,x) is similar in all respects, except
     88  1.1     ragge  *	that forward recursion is used for all
     89  1.1     ragge  *	values of n>1.
     90  1.4    simonb  *
     91  1.1     ragge  */
     92  1.1     ragge 
     93  1.2     ragge #include "mathimpl.h"
     94  1.1     ragge #include <float.h>
     95  1.1     ragge #include <errno.h>
     96  1.1     ragge 
     97  1.3      matt #if defined(__vax__) || defined(tahoe)
     98  1.1     ragge #define _IEEE	0
     99  1.1     ragge #else
    100  1.1     ragge #define _IEEE	1
    101  1.1     ragge #define infnan(x) (0.0)
    102  1.1     ragge #endif
    103  1.1     ragge 
    104  1.5      matt static const double
    105  1.8  christos #if _IEEE
    106  1.1     ragge invsqrtpi= 5.641895835477562869480794515607725858441e-0001,
    107  1.8  christos #endif
    108  1.1     ragge two  = 2.0,
    109  1.1     ragge zero = 0.0,
    110  1.1     ragge one  = 1.0;
    111  1.1     ragge 
    112  1.5      matt double
    113  1.5      matt jn(int n, double x)
    114  1.1     ragge {
    115  1.1     ragge 	int i, sgn;
    116  1.1     ragge 	double a, b, temp;
    117  1.1     ragge 	double z, w;
    118  1.1     ragge 
    119  1.1     ragge     /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
    120  1.1     ragge      * Thus, J(-n,x) = J(n,-x)
    121  1.1     ragge      */
    122  1.1     ragge     /* if J(n,NaN) is NaN */
    123  1.7  christos #if _IEEE
    124  1.7  christos 	if (snan(x)) return x+x;
    125  1.7  christos #endif
    126  1.4    simonb 	if (n<0){
    127  1.1     ragge 		n = -n;
    128  1.1     ragge 		x = -x;
    129  1.1     ragge 	}
    130  1.1     ragge 	if (n==0) return(j0(x));
    131  1.1     ragge 	if (n==1) return(j1(x));
    132  1.1     ragge 	sgn = (n&1)&(x < zero);		/* even n -- 0, odd n -- sign(x) */
    133  1.1     ragge 	x = fabs(x);
    134  1.1     ragge 	if (x == 0 || !finite (x)) 	/* if x is 0 or inf */
    135  1.1     ragge 	    b = zero;
    136  1.1     ragge 	else if ((double) n <= x) {
    137  1.1     ragge 			/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
    138  1.7  christos #if _IEEE
    139  1.7  christos 	    if (x >= 8.148143905337944345e+090) {
    140  1.1     ragge 					/* x >= 2**302 */
    141  1.4    simonb     /* (x >> n**2)
    142  1.1     ragge      *	    Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
    143  1.1     ragge      *	    Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
    144  1.4    simonb      *	    Let s=sin(x), c=cos(x),
    145  1.1     ragge      *		xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
    146  1.1     ragge      *
    147  1.1     ragge      *		   n	sin(xn)*sqt2	cos(xn)*sqt2
    148  1.1     ragge      *		----------------------------------
    149  1.1     ragge      *		   0	 s-c		 c+s
    150  1.1     ragge      *		   1	-s-c 		-c+s
    151  1.1     ragge      *		   2	-s+c		-c-s
    152  1.1     ragge      *		   3	 s+c		 c-s
    153  1.1     ragge      */
    154  1.1     ragge 		switch(n&3) {
    155  1.1     ragge 		    case 0: temp =  cos(x)+sin(x); break;
    156  1.1     ragge 		    case 1: temp = -cos(x)+sin(x); break;
    157  1.1     ragge 		    case 2: temp = -cos(x)-sin(x); break;
    158  1.1     ragge 		    case 3: temp =  cos(x)-sin(x); break;
    159  1.1     ragge 		}
    160  1.1     ragge 		b = invsqrtpi*temp/sqrt(x);
    161  1.7  christos 	    } else
    162  1.7  christos #endif
    163  1.7  christos 	    {
    164  1.1     ragge 	        a = j0(x);
    165  1.1     ragge 	        b = j1(x);
    166  1.1     ragge 	        for(i=1;i<n;i++){
    167  1.1     ragge 		    temp = b;
    168  1.1     ragge 		    b = b*((double)(i+i)/x) - a; /* avoid underflow */
    169  1.1     ragge 		    a = temp;
    170  1.1     ragge 	        }
    171  1.1     ragge 	    }
    172  1.1     ragge 	} else {
    173  1.1     ragge 	    if (x < 1.86264514923095703125e-009) { /* x < 2**-29 */
    174  1.4    simonb     /* x is tiny, return the first Taylor expansion of J(n,x)
    175  1.1     ragge      * J(n,x) = 1/n!*(x/2)^n  - ...
    176  1.1     ragge      */
    177  1.1     ragge 		if (n > 33)	/* underflow */
    178  1.1     ragge 		    b = zero;
    179  1.1     ragge 		else {
    180  1.1     ragge 		    temp = x*0.5; b = temp;
    181  1.1     ragge 		    for (a=one,i=2;i<=n;i++) {
    182  1.1     ragge 			a *= (double)i;		/* a = n! */
    183  1.1     ragge 			b *= temp;		/* b = (x/2)^n */
    184  1.1     ragge 		    }
    185  1.1     ragge 		    b = b/a;
    186  1.1     ragge 		}
    187  1.1     ragge 	    } else {
    188  1.1     ragge 		/* use backward recurrence */
    189  1.4    simonb 		/* 			x      x^2      x^2
    190  1.1     ragge 		 *  J(n,x)/J(n-1,x) =  ----   ------   ------   .....
    191  1.1     ragge 		 *			2n  - 2(n+1) - 2(n+2)
    192  1.1     ragge 		 *
    193  1.4    simonb 		 * 			1      1        1
    194  1.1     ragge 		 *  (for large x)   =  ----  ------   ------   .....
    195  1.1     ragge 		 *			2n   2(n+1)   2(n+2)
    196  1.4    simonb 		 *			-- - ------ - ------ -
    197  1.1     ragge 		 *			 x     x         x
    198  1.1     ragge 		 *
    199  1.1     ragge 		 * Let w = 2n/x and h=2/x, then the above quotient
    200  1.1     ragge 		 * is equal to the continued fraction:
    201  1.1     ragge 		 *		    1
    202  1.1     ragge 		 *	= -----------------------
    203  1.1     ragge 		 *		       1
    204  1.1     ragge 		 *	   w - -----------------
    205  1.1     ragge 		 *			  1
    206  1.1     ragge 		 * 	        w+h - ---------
    207  1.1     ragge 		 *		       w+2h - ...
    208  1.1     ragge 		 *
    209  1.1     ragge 		 * To determine how many terms needed, let
    210  1.1     ragge 		 * Q(0) = w, Q(1) = w(w+h) - 1,
    211  1.1     ragge 		 * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
    212  1.4    simonb 		 * When Q(k) > 1e4	good for single
    213  1.4    simonb 		 * When Q(k) > 1e9	good for double
    214  1.4    simonb 		 * When Q(k) > 1e17	good for quadruple
    215  1.1     ragge 		 */
    216  1.1     ragge 	    /* determine k */
    217  1.1     ragge 		double t,v;
    218  1.1     ragge 		double q0,q1,h,tmp; int k,m;
    219  1.1     ragge 		w  = (n+n)/(double)x; h = 2.0/(double)x;
    220  1.1     ragge 		q0 = w;  z = w+h; q1 = w*z - 1.0; k=1;
    221  1.1     ragge 		while (q1<1.0e9) {
    222  1.1     ragge 			k += 1; z += h;
    223  1.1     ragge 			tmp = z*q1 - q0;
    224  1.1     ragge 			q0 = q1;
    225  1.1     ragge 			q1 = tmp;
    226  1.1     ragge 		}
    227  1.1     ragge 		m = n+n;
    228  1.1     ragge 		for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t);
    229  1.1     ragge 		a = t;
    230  1.1     ragge 		b = one;
    231  1.1     ragge 		/*  estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
    232  1.1     ragge 		 *  Hence, if n*(log(2n/x)) > ...
    233  1.1     ragge 		 *  single 8.8722839355e+01
    234  1.1     ragge 		 *  double 7.09782712893383973096e+02
    235  1.1     ragge 		 *  long double 1.1356523406294143949491931077970765006170e+04
    236  1.1     ragge 		 *  then recurrent value may overflow and the result will
    237  1.1     ragge 		 *  likely underflow to zero
    238  1.1     ragge 		 */
    239  1.1     ragge 		tmp = n;
    240  1.1     ragge 		v = two/x;
    241  1.1     ragge 		tmp = tmp*log(fabs(v*tmp));
    242  1.1     ragge 	    	for (i=n-1;i>0;i--){
    243  1.1     ragge 		        temp = b;
    244  1.1     ragge 		        b = ((i+i)/x)*b - a;
    245  1.1     ragge 		        a = temp;
    246  1.1     ragge 		    /* scale b to avoid spurious overflow */
    247  1.3      matt #			if defined(__vax__) || defined(tahoe)
    248  1.1     ragge #				define BMAX 1e13
    249  1.1     ragge #			else
    250  1.1     ragge #				define BMAX 1e100
    251  1.3      matt #			endif /* defined(__vax__) || defined(tahoe) */
    252  1.1     ragge 			if (b > BMAX) {
    253  1.1     ragge 				a /= b;
    254  1.1     ragge 				t /= b;
    255  1.1     ragge 				b = one;
    256  1.1     ragge 			}
    257  1.1     ragge 		}
    258  1.1     ragge 	    	b = (t*j0(x)/b);
    259  1.1     ragge 	    }
    260  1.1     ragge 	}
    261  1.1     ragge 	return ((sgn == 1) ? -b : b);
    262  1.1     ragge }
    263  1.5      matt 
    264  1.5      matt double
    265  1.5      matt yn(int n, double x)
    266  1.1     ragge {
    267  1.1     ragge 	int i, sign;
    268  1.1     ragge 	double a, b, temp;
    269  1.1     ragge 
    270  1.1     ragge     /* Y(n,NaN), Y(n, x < 0) is NaN */
    271  1.1     ragge 	if (x <= 0 || (_IEEE && x != x))
    272  1.1     ragge 		if (_IEEE && x < 0) return zero/zero;
    273  1.1     ragge 		else if (x < 0)     return (infnan(EDOM));
    274  1.1     ragge 		else if (_IEEE)     return -one/zero;
    275  1.1     ragge 		else		    return(infnan(-ERANGE));
    276  1.1     ragge 	else if (!finite(x)) return(0);
    277  1.1     ragge 	sign = 1;
    278  1.1     ragge 	if (n<0){
    279  1.1     ragge 		n = -n;
    280  1.1     ragge 		sign = 1 - ((n&1)<<2);
    281  1.1     ragge 	}
    282  1.1     ragge 	if (n == 0) return(y0(x));
    283  1.1     ragge 	if (n == 1) return(sign*y1(x));
    284  1.7  christos #if _IEEE
    285  1.7  christos 	if(x >= 8.148143905337944345e+090) { /* x > 2**302 */
    286  1.4    simonb     /* (x >> n**2)
    287  1.1     ragge      *	    Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
    288  1.1     ragge      *	    Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
    289  1.4    simonb      *	    Let s=sin(x), c=cos(x),
    290  1.1     ragge      *		xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
    291  1.1     ragge      *
    292  1.1     ragge      *		   n	sin(xn)*sqt2	cos(xn)*sqt2
    293  1.1     ragge      *		----------------------------------
    294  1.1     ragge      *		   0	 s-c		 c+s
    295  1.1     ragge      *		   1	-s-c 		-c+s
    296  1.1     ragge      *		   2	-s+c		-c-s
    297  1.1     ragge      *		   3	 s+c		 c-s
    298  1.1     ragge      */
    299  1.1     ragge 		switch (n&3) {
    300  1.1     ragge 		    case 0: temp =  sin(x)-cos(x); break;
    301  1.1     ragge 		    case 1: temp = -sin(x)-cos(x); break;
    302  1.1     ragge 		    case 2: temp = -sin(x)+cos(x); break;
    303  1.1     ragge 		    case 3: temp =  sin(x)+cos(x); break;
    304  1.1     ragge 		}
    305  1.1     ragge 		b = invsqrtpi*temp/sqrt(x);
    306  1.7  christos 	} else
    307  1.7  christos #endif
    308  1.7  christos 	{
    309  1.1     ragge 	    a = y0(x);
    310  1.1     ragge 	    b = y1(x);
    311  1.1     ragge 	/* quit if b is -inf */
    312  1.1     ragge 	    for (i = 1; i < n && !finite(b); i++){
    313  1.1     ragge 		temp = b;
    314  1.1     ragge 		b = ((double)(i+i)/x)*b - a;
    315  1.1     ragge 		a = temp;
    316  1.1     ragge 	    }
    317  1.1     ragge 	}
    318  1.1     ragge 	if (!_IEEE && !finite(b))
    319  1.1     ragge 		return (infnan(-sign * ERANGE));
    320  1.1     ragge 	return ((sign > 0) ? b : -b);
    321  1.1     ragge }
    322