Copyright 2010 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package math
Bessel function of the first and second kinds of order n.
The original C code and the long comment below are from FreeBSD's /usr/src/lib/msun/src/e_jn.c and came with this notice. The go code is a simplified version of the original C. ==================================================== Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. Developed at SunPro, a Sun Microsystems, Inc. business. Permission to use, copy, modify, and distribute this software is freely granted, provided that this notice is preserved. ==================================================== __ieee754_jn(n, x), __ieee754_yn(n, x) floating point Bessel's function of the 1st and 2nd kind of order n Special cases: y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal; y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal. Note 2. About jn(n,x), yn(n,x) For n=0, j0(x) is called, for n=1, j1(x) is called, for n<x, forward recursion is used starting from values of j0(x) and j1(x). for n>x, a continued fraction approximation to j(n,x)/j(n-1,x) is evaluated and then backward recursion is used starting from a supposed value for j(n,x). The resulting value of j(0,x) is compared with the actual value to correct the supposed value of j(n,x). yn(n,x) is similar in all respects, except that forward recursion is used for all values of n>1.
Jn returns the order-n Bessel function of the first kind. Special cases are: Jn(n, ±Inf) = 0 Jn(n, NaN) = NaN
func ( int,  float64) float64 {
	const (
		 = 1.0 / (1 << 29) // 2**-29 0x3e10000000000000
		 = 1 << 302        // 2**302 0x52D0000000000000
special cases
	switch {
	case IsNaN():
		return 
	case IsInf(, 0):
		return 0
J(-n, x) = (-1)**n * J(n, x), J(n, -x) = (-1)**n * J(n, x) Thus, J(-n, x) = J(n, -x)

	if  == 0 {
		return J0()
	}
	if  == 0 {
		return 0
	}
	if  < 0 {
		,  = -, -
	}
	if  == 1 {
		return J1()
	}
	 := false
	if  < 0 {
		 = -
		if &1 == 1 {
			 = true // odd n and negative x
		}
	}
	var  float64
Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x)
		if  >=  { // x > 2**302
(x >> n**2) Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) Let s=sin(x), c=cos(x), xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then n sin(xn)*sqt2 cos(xn)*sqt2 ---------------------------------- 0 s-c c+s 1 -s-c -c+s 2 -s+c -c-s 3 s+c c-s

			var  float64
			switch ,  := Sincos();  & 3 {
			case 0:
				 =  + 
			case 1:
				 = - + 
			case 2:
				 = - - 
			case 3:
				 =  - 
			}
			 = (1 / SqrtPi) *  / Sqrt()
		} else {
			 = J1()
			for ,  := 1, J0();  < ; ++ {
				,  = , *(float64(+)/)- // avoid underflow
			}
		}
	} else {
x is tiny, return the first Taylor expansion of J(n,x) J(n,x) = 1/n!*(x/2)**n - ...

			if  > 33 { // underflow
				 = 0
			} else {
				 :=  * 0.5
				 = 
				 := 1.0
				for  := 2;  <= ; ++ {
					 *= float64() // a = n!
					 *=        // b = (x/2)**n
				}
				 /= 
			}
use backward recurrence x x**2 x**2 J(n,x)/J(n-1,x) = ---- ------ ------ ..... 2n - 2(n+1) - 2(n+2) 1 1 1 (for large x) = ---- ------ ------ ..... 2n 2(n+1) 2(n+2) -- - ------ - ------ - x x x Let w = 2n/x and h=2/x, then the above quotient is equal to the continued fraction: 1 = ----------------------- 1 w - ----------------- 1 w+h - --------- w+2h - ... To determine how many terms needed, let Q(0) = w, Q(1) = w(w+h) - 1, Q(k) = (w+k*h)*Q(k-1) - Q(k-2), When Q(k) > 1e4 good for single When Q(k) > 1e9 good for double When Q(k) > 1e17 good for quadruple
determine k
			 := float64(+) / 
			 := 2 / 
			 := 
			 :=  + 
			 := * - 1
			 := 1
			for  < 1e9 {
				++
				 += 
				,  = , *-
			}
			 :=  + 
			 := 0.0
			for  := 2 * ( + );  >= ;  -= 2 {
				 = 1 / (float64()/ - )
			}
			 := 
estimate log((2/x)**n*n!) = n*log(2/x)+n*ln(n) Hence, if n*(log(2n/x)) > ... single 8.8722839355e+01 double 7.09782712893383973096e+02 long double 1.1356523406294143949491931077970765006170e+04 then recurrent value may overflow and the result is likely underflow to zero

			 := float64()
			 := 2 / 
			 =  * Log(Abs(*))
			if  < 7.09782712893383973096e+02 {
				for  :=  - 1;  > 0; -- {
					 := float64( + )
					,  = , */-
				}
			} else {
				for  :=  - 1;  > 0; -- {
					 := float64( + )
scale b to avoid spurious overflow
					if  > 1e100 {
						 /= 
						 /= 
						 = 1
					}
				}
			}
			 =  * J0() / 
		}
	}
	if  {
		return -
	}
	return 
}
Yn returns the order-n Bessel function of the second kind. Special cases are: Yn(n, +Inf) = 0 Yn(n ≥ 0, 0) = -Inf Yn(n < 0, 0) = +Inf if n is odd, -Inf if n is even Yn(n, x < 0) = NaN Yn(n, NaN) = NaN
func ( int,  float64) float64 {
special cases
	switch {
	case  < 0 || IsNaN():
		return NaN()
	case IsInf(, 1):
		return 0
	}

	if  == 0 {
		return Y0()
	}
	if  == 0 {
		if  < 0 && &1 == 1 {
			return Inf(1)
		}
		return Inf(-1)
	}
	 := false
	if  < 0 {
		 = -
		if &1 == 1 {
			 = true // sign true if n < 0 && |n| odd
		}
	}
	if  == 1 {
		if  {
			return -Y1()
		}
		return Y1()
	}
	var  float64
(x >> n**2) Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) Let s=sin(x), c=cos(x), xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then n sin(xn)*sqt2 cos(xn)*sqt2 ---------------------------------- 0 s-c c+s 1 -s-c -c+s 2 -s+c -c-s 3 s+c c-s

		var  float64
		switch ,  := Sincos();  & 3 {
		case 0:
			 =  - 
		case 1:
			 = - - 
		case 2:
			 = - + 
		case 3:
			 =  + 
		}
		 = (1 / SqrtPi) *  / Sqrt()
	} else {
		 := Y0()
quit if b is -inf
		for  := 1;  <  && !IsInf(, -1); ++ {
			,  = , (float64(+)/)*-
		}
	}
	if  {
		return -
	}
	return