Skip to content

Commit 61906f2

Browse files
committed
update docs
1 parent b5227b8 commit 61906f2

File tree

5 files changed

+51
-121
lines changed

5 files changed

+51
-121
lines changed

src/Bessels.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ include("Float128/constants.jl")
3535

3636
include("math_constants.jl")
3737
include("U_polynomials.jl")
38+
include("recurrence.jl")
3839
#include("parse.jl")
3940
#include("hankel.jl")
4041

src/U_polynomials.jl

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -50,38 +50,8 @@ function Uk_poly_Kn(p, v, p2, ::Type{T}) where T <: BigFloat
5050
u10 = 1 / 88580102706155225088000 * evalpoly(p2, (9745329584487361980740625, -1230031256571145165088463750, 27299183373230345667273718125, -246750339886026017414509498824, 1177120360439828012193658602930, -3327704366990695147540934069220, 5876803711285273203043452095250, -6564241639632418015173104205000, 4513386761946134740461797128125, -1745632061522350031610173343750, 290938676920391671935028890625))
5151
return evalpoly(-p/v, (u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10))
5252
end
53-
function besselk_large_orders(v, x::T) where T <: AbstractFloat
54-
x = Float64(x)
55-
z = x / v
56-
zs = sqrt(1 + z^2)
57-
n = zs + log(z / (1 + zs))
58-
coef = exp(-v * n) * sqrt(pi / (2*v)) / sqrt(zs)
59-
p = inv(zs)
60-
p2 = p*p
61-
u0 = one(Float64)
62-
u1 = 1 / 24 * evalpoly(p2, (3, -5))
63-
u2 = 1 / 1152 * evalpoly(p2, (81, -462, 385))
64-
u3 = 1 / 414720 * evalpoly(p2, (30375, -369603, 765765, -425425))
65-
u4 = 1 / 39813120 * evalpoly(p2, (4465125, -94121676, 349922430, -446185740, 185910725))
66-
u5 = 1 / 6688604160 * evalpoly(p2, (1519035525, -49286948607, 284499769554, -614135872350, 566098157625, -188699385875))
67-
u6 = 1 / 4815794995200 * evalpoly(p2, (2757049477875, -127577298354750, 1050760774457901, -3369032068261860,5104696716244125, -3685299006138750, 1023694168371875))
68-
u7 = 1 / 115579079884800 * evalpoly(p2, (199689155040375, -12493049053044375, 138799253740521843, -613221795981706275, 1347119637570231525, -1570320948552481125, 931766432052080625, -221849150488590625))
69-
u8 = 1 / 22191183337881600 * evalpoly(p2, (134790179652253125, -10960565081605263000, 157768535329832893644, -914113758588905038248, 2711772922412520971550, -4513690624987320777000, 4272845805510421639500, -2152114239059719935000, 448357133137441653125))
70-
u9 = 1 / 263631258054033408000 * evalpoly(p2, (6427469716717690265625, -659033454841709672064375, 11921080954211358275362500, -87432034049652400520788332, 334380732677827878090447630, -741743213039573443221773250, 992115946599792610768672500, -790370708270219620781737500, 345821892003106984030190625, -64041091111686478524109375))
71-
u10 = 1 / 88580102706155225088000 * evalpoly(p2, (9745329584487361980740625, -1230031256571145165088463750, 27299183373230345667273718125, -246750339886026017414509498824, 1177120360439828012193658602930, -3327704366990695147540934069220, 5876803711285273203043452095250, -6564241639632418015173104205000, 4513386761946134740461797128125, -1745632061522350031610173343750, 290938676920391671935028890625))
7253
73-
return coef*evalpoly(-p/v, (u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10))
74-
end
7554
76-
function besselk_large_orders(v, x::T) where T <: AbstractFloat
77-
z = x / v
78-
zs = sqrt(1 + z^2)
79-
80-
n = zs + log(z / (1 + zs))
81-
coef = exp(-v * n) * sqrt(pi / (2*v)) / sqrt(zs)
82-
83-
p = inv(zs)
84-
8555
u0 = one(x)
8656
u1 = p / 24 * (3 - 5*p^2) * -1 / v
8757
u2 = p^2 / 1152 * (81 - 462*p^2 + 385*p^4) / v^2
@@ -109,27 +79,4 @@ function besselk_large_orders(v, x::T) where T <: AbstractFloat
10979
+ 5136561256208409671660362298619778869859994724706875*p^16 - 2284251621937242886581917667066122422330060024456125*p^14 + 730367145705123976114617970888707594104468177381925*p^12 - 163359140754958502896104062604202934925448173291477*p^10
11080
+ 24403480234538299231733883413666768614198435948125*p^8 - 2254933495791765108580529087615802250458013685625*p^6 + 112597271053778779753048514469995937998172890625*p^4 - 2303431987527333128955769182299845911305390625*p^2 + 8178936810213560828419581728001773291015625) * -1 / v^15
11181
112-
113-
out1 = ((u15 + u14 + u13 + u12 + u11 + u10 + u9) + u8) + u7
114-
out2 = ((out1 + u6 + u5) + u4) + u3
115-
out = ((out2 + u2) + u1) + u0
116-
117-
return coef*out
118-
end
119-
120-
u11 = 1 / 27636992044320430227456000 * (-1363312191078326248171914924296875*p^22 + 8997860461116953237934638500359375*p^20 - 25963913760458280822131901737878125*p^18 + 42936745153513007436411401865860625*p^16 - 44801790321820682384740638703320750*p^14 + 30589806122850866110941936529264950*p^12 - 13704902022868787041097596217578170*p^10
121-
+ 3926191452593448964331218647028194*p^8 - 676389476843440422173605288596087*p^6 + 62011003282542082472252466220875*p^4 - 2321657500166464779660536015625*p^2 + 15237265774872558064250728125) * -1 / v^11
122-
u12 = 1 / 39797268543821419527536640000 * (32426380464797989812768996474401171875*p^24 - 233469939346545526651936774615688437500*p^22 + 743739612850105971846901081692858843750*p^20 - 1378260730939829908037976894025628887500*p^18 + 1642838631056253395899341314188134178125*p^16 - 1314368459332124683504418467809129387000*p^14
123-
+ 714528665351965363868467348116538170900*p^12 - 261201165596865827608687437905740780920*p^10 + 62055079517573388459132793029571876461*p^8 - 8958590476947726766450604043798559500*p^6 + 692277766674325563109617997687563750*p^4 - 21882222767154197351962677311437500*p^2 + 120907703923613748239829527671875) * 1 / v^12
124-
u13 = 1 / 955134445051714068660879360000 * (-14020668045586884672121117629431460546875*p^26 + 109361210755577700442544717509565392265625*p^24 - 381190503845282445953419057314665534156250*p^22 + 782463969315283937856703223178540650343750*p^20
125-
- 1049095945162229046324321461816274931715625*p^18 + 962926533925253374359704288384340809260875*p^16 - 616410216242554698436702353237166008656700*p^14 + 274983827478138958623041508409195988431140*p^12 - 83924867223075156862785921508524155665245*p^10
126-
+ 16843538631795795357786827345307534156063*p^8 - 2069933923586966756183324291232117362250*p^6 + 136735019134677724428035696765082813750*p^4 - 3698121486504259988094897605296209375*p^2 + 17438611142828905996129258798828125) * -1 / v^13
127-
u14 = 1 / 45846453362482275295722209280000 * (13133360053559028970728309756597440972265625*p^28 - 110320224449895843354117801955418504167031250*p^26 + 417630985812040040477569028872405152769921875*p^24
128-
- 940627071986145750405920450097257805227812500*p^22 + 1401302601668131482630653233972052729323190625*p^20 - 1451823699927947602004297385351260623500372750*p^18 + 1070439683260179398514645952824098811025619475*p^16
129-
- 564850830044980230366140582063618983657685400*p^14 + 211477117385619365164298957821904115470535555*p^12 - 54857705817658080981995319669299096598482382*p^10 + 9440449669103391509091075981237243128469201*p^8
130-
- 1000503839668383458999731491914516564625300*p^6 + 57170953417612444837142230812990944671875*p^4 - 1338184074771428116079233795614103631250*p^2 + 5448320367052402487647812713291015625) * 1 / v^14
131-
u15 = 1 / 9820310310243703368343697227776000000 * (- 59115551939078562227317999668652486368337724609375*p^30 + 532039967451707060045861997017872377315039521484375*p^28 - 2173722139119126857509156976742601742357422740234375*p^26
132-
+ 5329871927856528282113994744458999865006055974609375*p^24 - 8735135969643867540297524795790262235822823374296875*p^22 + 10085018700249896522602267572484630409640764997271875*p^20 - 8420533422834140468835467666391400380550043688871875*p^18
133-
+ 5136561256208409671660362298619778869859994724706875*p^16 - 2284251621937242886581917667066122422330060024456125*p^14 + 730367145705123976114617970888707594104468177381925*p^12 - 163359140754958502896104062604202934925448173291477*p^10
134-
+ 24403480234538299231733883413666768614198435948125*p^8 - 2254933495791765108580529087615802250458013685625*p^6 + 112597271053778779753048514469995937998172890625*p^4 - 2303431987527333128955769182299845911305390625*p^2 + 8178936810213560828419581728001773291015625) * -1 / v^15
13582
=#

src/besseli.jl

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
# Scaled modified Bessel functions of the first kind of order zero and one
55
# besseli0x, besselix
66
#
7+
# (Scaled) Modified Bessel functions of the first kind of order nu
8+
# besseli, besselix
9+
#
710
# Calculation of besseli0 is done in two branches using polynomial approximations [1]
811
#
912
# Branch 1: x < 7.75
@@ -35,11 +38,18 @@
3538
#
3639
# Horner's scheme is then used to evaluate all polynomials.
3740
# ArbNumerics.jl is used as the reference bessel implementations with 75 digits.
41+
#
42+
# Calculation of besseli and besselkx can be done with downward recursion starting with
43+
# besseli_{nu+1} and besseli_{nu}. Higher orders are determined by a uniform asymptotic
44+
# expansion similar to besselk (see notes there) using Equation 10.41.3 [3].
45+
#
3846
#
3947
# [1] "Rational Approximations for the Modified Bessel Function of the First Kind
4048
# - I0(x) for Computations with Double Precision" by Pavel Holoborodko
4149
# [2] "Rational Approximations for the Modified Bessel Function of the First Kind
42-
# - I1(x) for Computations with Double Precision" by Pavel Holoborodko
50+
# - I1(x) for Computations with Double Precision" by Pavel Holoborodko
51+
# [3] https://dlmf.nist.gov/10.41
52+
4353
"""
4454
besseli0(x::T) where T <: Union{Float32, Float64}
4555
@@ -56,6 +66,7 @@ function besseli0(x::T) where T <: Union{Float32, Float64}
5666
return a * s
5767
end
5868
end
69+
5970
"""
6071
besseli0x(x::T) where T <: Union{Float32, Float64}
6172
@@ -73,6 +84,7 @@ function besseli0x(x::T) where T <: Union{Float32, Float64}
7384
return evalpoly(inv(x), besseli0_large_coefs(T)) / sqrt(x)
7485
end
7586
end
87+
7688
"""
7789
besseli1(x::T) where T <: Union{Float32, Float64}
7890
@@ -94,6 +106,7 @@ function besseli1(x::T) where T <: Union{Float32, Float64}
94106
end
95107
return z
96108
end
109+
97110
"""
98111
besseli1x(x::T) where T <: Union{Float32, Float64}
99112
@@ -136,6 +149,7 @@ function besseli(nu, x::T) where T <: Union{Float32, Float64, BigFloat}
136149
return besseli_large_orders(nu, x)
137150
end
138151
end
152+
139153
"""
140154
besselix(nu, x::T) where T <: Union{Float32, Float64}
141155
@@ -155,24 +169,6 @@ function besselix(nu, x::T) where T <: Union{Float32, Float64, BigFloat}
155169
return besseli_large_orders_scaled(nu, x)
156170
end
157171
end
158-
159-
160-
@inline function down_recurrence(x, in, inp1, nu, branch)
161-
# this prevents us from looping through large values of nu when the loop will always return zero
162-
(iszero(in) || iszero(inp1)) && return zero(x)
163-
(isinf(inp1) || isinf(inp1)) && return in
164-
165-
inm1 = in
166-
x2 = 2 / x
167-
for n in branch:-1:nu+1
168-
a = x2 * n
169-
inm1 = muladd(a, in, inp1)
170-
inp1 = in
171-
in = inm1
172-
end
173-
return inm1
174-
end
175-
176172
function besseli_large_orders(v, x::T) where T <: Union{Float32, Float64, BigFloat}
177173
S = promote_type(T, Float64)
178174
x = S(x)
@@ -196,4 +192,4 @@ function besseli_large_orders_scaled(v, x::T) where T <: Union{Float32, Float64,
196192
p2 = v^2/fma(max(v,x), max(v,x), min(v,x)^2)
197193

198194
return T(coef*Uk_poly_In(p, v, p2, T))
199-
end
195+
end

src/besselk.jl

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -55,34 +55,7 @@
5555
#
5656
# However, calculation of these higher order U polynomials are tedious. These have been hand
5757
# calculated and somewhat crosschecked with symbolic math. There could be errors. They are listed
58-
# here as a reference as higher orders are impossible to find while being needed for any meaningfully accurate calculation.
59-
60-
# u0 = one(x)
61-
# u1 = p / 24 * (3 - 5*p^2) * -1 / v
62-
# u2 = p^2 / 1152 * (81 - 462*p^2 + 385*p^4) / v^2
63-
# u3 = p^3 / 414720 * (30375 - 369603 * p^2 + 765765*p^4 - 425425*p^6) * -1 / v^3
64-
# u4 = p^4 / 39813120 * (4465125 - 94121676*p^2 + 349922430*p^4 - 446185740*p^6 + 185910725*p^8) / v^4
65-
# u5 = p^5 / 6688604160 * (-188699385875*p^10 + 566098157625*p^8 - 614135872350*p^6 + 284499769554*p^4 - 49286948607*p^2 + 1519035525) * -1 / v^5
66-
# u6 = p^6 / 4815794995200 * (1023694168371875*p^12 - 3685299006138750*p^10 + 5104696716244125*p^8 - 3369032068261860*p^6
67-
# + 1050760774457901*p^4 - 127577298354750*p^2 + 2757049477875) * 1 / v^6
68-
# u7 = p^7 / 115579079884800 * (-221849150488590625*p^14 + 931766432052080625*p^12 - 1570320948552481125*p^10 + 1347119637570231525*p^8
69-
# - 613221795981706275*p^6 + 138799253740521843*p^4 - 12493049053044375*p^2 + 199689155040375) * -1 / v^7
70-
# u8 = p^8 / 22191183337881600 * (448357133137441653125*p^16 - 2152114239059719935000*p^14 + 4272845805510421639500*p^12 - 4513690624987320777000*p^10
71-
# + 2711772922412520971550*p^8 - 914113758588905038248*p^6 + 157768535329832893644*p^4 - 10960565081605263000*p^2 + 134790179652253125) * 1 / v^8
72-
# u9 = p^9 / 263631258054033408000 * (-64041091111686478524109375*p^18 + 345821892003106984030190625*p^16 - 790370708270219620781737500*p^14
73-
# + 992115946599792610768672500*p^12 - 741743213039573443221773250*p^10 + 334380732677827878090447630*p^8 - 87432034049652400520788332*p^6
74-
# + 11921080954211358275362500*p^4 - 659033454841709672064375*p^2 + 6427469716717690265625) * -1 / v^9
75-
# u10 = p^10 / 88580102706155225088000 * (290938676920391671935028890625*p^20 - 1745632061522350031610173343750*p^18 + 4513386761946134740461797128125*p^16
76-
# - 6564241639632418015173104205000*p^14 + 5876803711285273203043452095250*p^12 - 3327704366990695147540934069220*p^10 + 1177120360439828012193658602930*p^8
77-
# - 246750339886026017414509498824*p^6 + 27299183373230345667273718125*p^4 - 1230031256571145165088463750*p^2 + 9745329584487361980740625) * 1 / v^10
78-
# u11 = p^11 / 27636992044320430227456000 * (-1363312191078326248171914924296875*p^22 + 8997860461116953237934638500359375*p^20 - 25963913760458280822131901737878125*p^18 + 42936745153513007436411401865860625*p^16 - 44801790321820682384740638703320750*p^14 + 30589806122850866110941936529264950*p^12 - 13704902022868787041097596217578170*p^10
79-
# + 3926191452593448964331218647028194*p^8 - 676389476843440422173605288596087*p^6 + 62011003282542082472252466220875*p^4 - 2321657500166464779660536015625*p^2 + 15237265774872558064250728125) * -1 / v^11
80-
# u12 = p^12 / 39797268543821419527536640000 * (32426380464797989812768996474401171875*p^24 - 233469939346545526651936774615688437500*p^22 + 743739612850105971846901081692858843750*p^20 - 1378260730939829908037976894025628887500*p^18 + 1642838631056253395899341314188134178125*p^16 - 1314368459332124683504418467809129387000*p^14
81-
# + 714528665351965363868467348116538170900*p^12 - 261201165596865827608687437905740780920*p^10 + 62055079517573388459132793029571876461*p^8 - 8958590476947726766450604043798559500*p^6 + 692277766674325563109617997687563750*p^4 - 21882222767154197351962677311437500*p^2 + 120907703923613748239829527671875) * 1 / v^12
82-
# u13 = p^13 / 955134445051714068660879360000 * (-14020668045586884672121117629431460546875*p^26 + 109361210755577700442544717509565392265625*p^24 - 381190503845282445953419057314665534156250*p^22 + 782463969315283937856703223178540650343750*p^20
83-
# - 1049095945162229046324321461816274931715625*p^18 + 962926533925253374359704288384340809260875*p^16 - 616410216242554698436702353237166008656700*p^14 + 274983827478138958623041508409195988431140*p^12 - 83924867223075156862785921508524155665245*p^10
84-
# + 16843538631795795357786827345307534156063*p^8 - 2069933923586966756183324291232117362250*p^6 + 136735019134677724428035696765082813750*p^4 - 3698121486504259988094897605296209375*p^2 + 17438611142828905996129258798828125) * -1 / v^13
85-
#
58+
# in src/U_polynomials.jl as a reference as higher orders are impossible to find while being needed for any meaningfully accurate calculation.
8659
# For large orders these formulas will converge much faster than using upward recurrence.
8760
#
8861
#
@@ -97,6 +70,7 @@
9770
# [6] Abramowitz, Milton, and Irene A. Stegun, eds. Handbook of mathematical functions with formulas, graphs, and mathematical tables.
9871
# Vol. 55. US Government printing office, 1964.
9972
#
73+
10074
"""
10175
besselk0(x::T) where T <: Union{Float32, Float64}
10276
@@ -206,25 +180,6 @@ function besselkx(nu::Int, x::T) where T <: Union{Float32, Float64}
206180
return besselk_large_orders_scaled(nu, x)
207181
end
208182
end
209-
210-
@inline function up_recurrence(x, k0, k1, nu)
211-
nu == 0 && return k0
212-
nu == 1 && return k1
213-
214-
# this prevents us from looping through large values of nu when the loop will always return zero
215-
(iszero(k0) || iszero(k1)) && return zero(x)
216-
217-
k2 = k0
218-
x2 = 2 / x
219-
for n in 1:nu-1
220-
a = x2 * n
221-
k2 = muladd(a, k1, k0)
222-
k0 = k1
223-
k1 = k2
224-
end
225-
return k2
226-
end
227-
228183
function besselk_large_orders(v, x::T) where T <: Union{Float32, Float64, BigFloat}
229184
S = promote_type(T, Float64)
230185
x = S(x)
@@ -237,7 +192,6 @@ function besselk_large_orders(v, x::T) where T <: Union{Float32, Float64, BigFlo
237192

238193
return T(coef*Uk_poly_Kn(p, v, p2, T))
239194
end
240-
241195
function besselk_large_orders_scaled(v, x::T) where T <: Union{Float32, Float64, BigFloat}
242196
S = promote_type(T, Float64)
243197
x = S(x)

src/recurrence.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
@inline function down_recurrence(x, in, inp1, nu, branch)
2+
# this prevents us from looping through large values of nu when the loop will always return zero
3+
(iszero(in) || iszero(inp1)) && return zero(x)
4+
(isinf(inp1) || isinf(inp1)) && return in
5+
6+
inm1 = in
7+
x2 = 2 / x
8+
for n in branch:-1:nu+1
9+
a = x2 * n
10+
inm1 = muladd(a, in, inp1)
11+
inp1 = in
12+
in = inm1
13+
end
14+
return inm1
15+
end
16+
@inline function up_recurrence(x, k0, k1, nu)
17+
nu == 0 && return k0
18+
nu == 1 && return k1
19+
20+
# this prevents us from looping through large values of nu when the loop will always return zero
21+
(iszero(k0) || iszero(k1)) && return zero(x)
22+
23+
k2 = k0
24+
x2 = 2 / x
25+
for n in 1:nu-1
26+
a = x2 * n
27+
k2 = muladd(a, k1, k0)
28+
k0 = k1
29+
k1 = k2
30+
end
31+
return k2
32+
end

0 commit comments

Comments
 (0)