Skip to content

Commit 6a06ada

Browse files
committed
add docs and constants
1 parent 6c12c23 commit 6a06ada

File tree

3 files changed

+41
-68
lines changed

3 files changed

+41
-68
lines changed

src/Float128/besselj.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function besselj0(x::BigFloat)
1+
#=function besselj0(x::BigFloat)
22
x = abs(x)
33
T = eltype(x)
44
if iszero(x)
@@ -67,3 +67,4 @@ function besselj0(x::BigFloat)
6767
return z
6868
end
6969
end
70+
=#

src/besselj.jl

Lines changed: 37 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,48 @@
1-
#=
2-
Cephes Math Library Release 2.8: June, 2000
3-
Copyright 1984, 1987, 2000 by Stephen L. Moshier
4-
https://github.com/jeremybarnes/cephes/blob/master/bessel/j0.c
5-
https://github.com/jeremybarnes/cephes/blob/master/bessel/j1.c
6-
=#
7-
function besselj0(x::Float64)
8-
T = Float64
1+
# Bessel functions of the first kind of order zero and one
2+
# besselj0, besselj1
3+
#
4+
# Calculation of besselj0 is done in three branches using polynomial approximations
5+
#
6+
# Branch 1: x <= 5.0
7+
# besselj0 = (x^2 - r1^2)*(x^2 - r2^2)*P3(x^2) / Q8(x^2)
8+
# where r1 and r2 are zeros of J0
9+
# and P3 and Q8 are a 3 and 8 degree polynomial respectively
10+
# Polynomial coefficients are from [1] which is based on [2]
11+
# See [1] for more details and [2] for coefficients of polynomials
12+
#
13+
# Branch 2: 5.0 < x < 80.0
14+
# besselj0 = sqrt(2/(pi*x))*(cos(x - pi/4)*R7(x) - sin(x - pi/4)*R8(x))
15+
# Hankel's asymptotic expansion is used
16+
# where R7 and R8 are rational functions (Pn(x)/Qn(x)) of degree 7 and 8 respectively
17+
# See section 4 of [3] for more details and [1] for coefficients of polynomials
18+
#
19+
# Branch 3: x >= 80.0
20+
# besselj0 = sqrt(2/(pi*x))*beta(x)*(cos(x - pi/4 - alpha(x))
21+
# See modified expansions given in [3]. Exact coefficients are used
22+
#
23+
# Calculation of besselj1 is done in a similar way as besselj0.
24+
# See [3] for details on similarities.
25+
#
26+
# [1] https://github.com/deepmind/torch-cephes
27+
# [2] Cephes Math Library Release 2.8: June, 2000 by Stephen L. Moshier
28+
# [3] Harrison, John. "Fast and accurate Bessel function computation."
29+
# 2009 19th IEEE Symposium on Computer Arithmetic. IEEE, 2009.
30+
31+
function besselj0(x::T) where T
932
x = abs(x)
10-
iszero(x) && return one(x)
1133
isinf(x) && return zero(x)
1234

1335
if x <= 5
1436
z = x * x
1537
if x < 1.0e-5
1638
return 1.0 - z / 4.0
1739
end
18-
19-
DR1 = 5.78318596294678452118E0
20-
DR2 = 3.04712623436620863991E1
21-
40+
DR1 = 5.78318596294678452118e0
41+
DR2 = 3.04712623436620863991e1
2242
p = (z - DR1) * (z - DR2)
2343
p = p * evalpoly(z, RP_j0(T)) / evalpoly(z, RQ_j0(T))
2444
return p
25-
elseif x < 100.0
45+
elseif x < 80.0
2646
w = 5.0 / x
2747
q = 25.0 / (x * x)
2848

@@ -40,8 +60,9 @@ function besselj0(x::Float64)
4060
a = SQ2OPI(T) * sqrt(xinv) * p
4161

4262
q = (-1/8, 25/384, -1073/5120, 375733/229376, -55384775/2359296)
43-
xn = muladd(xinv, evalpoly(x2, q), - PIO4(T))
44-
b = cos(x + xn)
63+
xn = fma(xinv, evalpoly(x2, q), - PIO4(T))
64+
b = cos(x)*cos(xn) - sin(x)*sin(xn)#cos(x + xn)
65+
#b = cos(x + xn)
4566
return a * b
4667
end
4768
end
@@ -187,53 +208,3 @@ function besselj(n::Int, x::Float64)
187208

188209
return sign * ans
189210
end
190-
191-
192-
function b2(v, x)
193-
194-
a = (x/2)^v
195-
out = 1 / gamma(v + 1)
196-
for k in 1:100
197-
out += (-x^2 / 4)^k / factorial(BigFloat(k)) / factorial(v + BigFloat(k))
198-
end
199-
return out*a
200-
end
201-
202-
function b(nu, x::T) where T
203-
coef = (x/2)^nu / gamma(nu + 1)
204-
205-
x2 = (x/2)^2
206-
207-
208-
maxiter = 10000
209-
b = one(T)
210-
for k in 1:maxiter
211-
z = -x2 / (k * (k + nu))
212-
b += z*b
213-
end
214-
return b * coef
215-
end
216-
217-
218-
### for this function dd can be calculated accurately but there is a build up in error for val as we sum
219-
## looks like only works for small arguments and smallish orders....
220-
function b3(v, x::T) where T
221-
MaxIter = 5000
222-
if v < 20
223-
coef = (x / 2)^v / factorial(v)
224-
else
225-
vinv = inv(v)
226-
coef = sqrt(vinv / (2 * π)) * MathConstants.e^(v * (log(x / (2 * v)) + 1))
227-
coef *= evalpoly(vinv, (1, -1/12, 1/288, 139/51840, -571/2488320, -163879/209018880, 5246819/75246796800, 534703531/902961561600))
228-
end
229-
230-
x2 = (x / 2)^2
231-
val = zero(T)
232-
233-
for k in 1:MaxIter
234-
val += coef
235-
coef = -coef * x2 / (k * (v + k))
236-
abs(coef) < eps(T) * abs(val) && break
237-
end
238-
return val
239-
end

src/math_constants.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ const ONEOSQPI(::Type{BigFloat}) = big"5.641895835477562869480794515607725858440
22
const TWOOPI(::Type{BigFloat}) = big"6.3661977236758134307553505349005744813784E-1"
33
#const SQPIO2(::Type{BigFloat}) = big"1.253314137315500251207882642405522626503493370304969158314961788171146827303924"
44
#const SQ1O2PI(::Type{BigFloat}) = big"0.3989422804014326779399460599343818684758586311649346576659258296706579258993008"
5-
5+
const SQ2OPI(::Type{BigFloat}) = big"0.7978845608028653558798921198687637369517172623298693153318516593413158517986017"
6+
const PIO4(::Type{BigFloat}) = big"0.7853981633974483096156608458198757210492923498437764552437361480769541015715495"
67

78
const PIO4(::Type{Float64}) = .78539816339744830962
89
const THPIO4(::Type{Float64}) = 2.35619449019234492885

0 commit comments

Comments
 (0)