Skip to content

Commit 8c975a1

Browse files
committed
clean up besselj structure
1 parent f9ec12d commit 8c975a1

File tree

2 files changed

+45
-52
lines changed

2 files changed

+45
-52
lines changed

src/U_polynomials.jl

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,12 @@ function Uk_poly_In(p, v, p2, ::Type{Float32})
4343
u13 = -1 / 955134445051714068660879360000 * evalpoly(p2, (17438611142828905996129258798828125, -3698121486504259988094897605296209375, 136735019134677724428035696765082813750, -2069933923586966756183324291232117362250, 16843538631795795357786827345307534156063, -83924867223075156862785921508524155665245, 274983827478138958623041508409195988431140, -616410216242554698436702353237166008656700, 962926533925253374359704288384340809260875, -1049095945162229046324321461816274931715625, 782463969315283937856703223178540650343750, -381190503845282445953419057314665534156250, 109361210755577700442544717509565392265625, -14020668045586884672121117629431460546875))
4444
u14 = 1 / 45846453362482275295722209280000 * evalpoly(p2, (5448320367052402487647812713291015625, -1338184074771428116079233795614103631250, 57170953417612444837142230812990944671875, -1000503839668383458999731491914516564625300, 9440449669103391509091075981237243128469201, -54857705817658080981995319669299096598482382, 211477117385619365164298957821904115470535555, -564850830044980230366140582063618983657685400, 1070439683260179398514645952824098811025619475, -1451823699927947602004297385351260623500372750, 1401302601668131482630653233972052729323190625, -940627071986145750405920450097257805227812500, 417630985812040040477569028872405152769921875, -110320224449895843354117801955418504167031250, 13133360053559028970728309756597440972265625))
4545
u15 = -1 / 9820310310243703368343697227776000000 * evalpoly(p2, (8178936810213560828419581728001773291015625, -2303431987527333128955769182299845911305390625, 112597271053778779753048514469995937998172890625, -2254933495791765108580529087615802250458013685625, 24403480234538299231733883413666768614198435948125, -163359140754958502896104062604202934925448173291477, 730367145705123976114617970888707594104468177381925, -2284251621937242886581917667066122422330060024456125, 5136561256208409671660362298619778869859994724706875, -8420533422834140468835467666391400380550043688871875, 10085018700249896522602267572484630409640764997271875, -8735135969643867540297524795790262235822823374296875, 5329871927856528282113994744458999865006055974609375, -2173722139119126857509156976742601742357422740234375, 532039967451707060045861997017872377315039521484375, -59115551939078562227317999668652486368337724609375))
46-
47-
return evalpoly(-p/v, (u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11, u12, u13, u14, u15))
46+
u16 = evalpoly(p2, (6.252951493434797e6, -2.0016469281917763e9, 1.1099740513917902e11, -2.5215584749128545e12, 3.100743647289646e13, -2.3665253045164925e14, 1.2126758042503475e15, -4.3793258383640155e15, 1.1486706978449752e16, -2.2268225133911144e16, 3.213827526858624e16, -3.4447226006485144e16, 2.705471130619708e16, -1.5129826322457682e16, 5.705782159023671e15, -1.3010127235496995e15, 1.3552215870309369e14))
47+
u17 = -evalpoly(p2, (5.0069589531988926e7, -1.8078220384658062e10, 1.128709145410874e12, -2.886383763141476e13, 4.0004445704303625e14, -3.4503855118462725e15, 2.0064271476309532e16, -8.270945651585064e16, 2.4960365126160426e17, -5.62631788074636e17, 9.575335098169139e17, -1.2336116931960694e18, 1.1961991142756308e18, -8.592577980317548e17, 4.4347954614171904e17, -1.5552983504313904e17, 3.3192764720355224e16, -3.254192619642669e15))
48+
u18 = evalpoly(p2, (4.259392165047669e8, -1.722832387173505e11, 1.2030115826419191e13, -3.4396530474307594e14, 5.335106978708839e15, -5.1605093193485224e16, 3.37667624979061e17, -1.5736434765189599e18, 5.402894876715982e18, -1.3970803516443374e19, 2.757282981650519e19, -4.178861444656839e19, 4.859942729324836e19, -4.301555703831444e19, 2.846521225167657e19, -1.3639420410571592e19, 4.47020096401231e18, -8.966114215270463e17, 8.30195760673191e16))
49+
u19 = -evalpoly(p2, (3.8362551802304335e9, -1.7277040123529995e12, 1.3412416915180639e14, -4.2619355104268985e15, 7.351663610930971e16, -7.921651119323832e17, 5.789887667664653e18, -3.025566598990372e19, 1.1707490535797259e20, -3.434621399768417e20, 7.756704953461136e20, -1.360203777284994e21, 1.8571089321463453e21, -1.9677247077053125e21, 1.6016898573693598e21, -9.824438427689858e20, 4.392792200888712e20, -1.351217503435996e20, 2.5563802960529236e19, -2.242438856186775e18))
50+
u20 = evalpoly(p2, (3.646840080706556e10, -1.818726203851104e13, 1.5613123930484672e15, -5.48403360388329e16, 1.0461721131134344e18, -1.2483700995047234e19, 1.0126774169536592e20, -5.8917941350694964e20, 2.548961114664972e21, -8.405915817108351e21, 2.1487414815055883e22, -4.302534303482379e22, 6.783661642951883e22, -8.423222750084323e22, 8.19433100543513e22, -6.173206302884415e22, 3.528435843903409e22, -1.4787743528433614e22, 4.285296082829494e21, -7.671943936729004e20, 6.393286613940837e19))
51+
return evalpoly(-p/v, (u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11, u12, u13, u14, u15, u16, u17, u18, u19, u20))
4852
end
4953

5054
function Uk_poly_Jn(p, v, p2, ::Type{T}) where T <: Float64
@@ -66,11 +70,12 @@ function Uk_poly_Jn(p, v, p2, ::Type{T}) where T <: Float64
6670
u15 = -evalpoly(p2, (832859.3040162893, -2.3455796352225152e8, 1.1465754899448236e10, -2.2961937296824646e11, 2.4850009280340854e12, -1.663482472489248e13, 7.437312290867914e13, -2.3260483118893994e14, 5.230548825784446e14, -8.57461032982895e14, 1.0269551960827625e15, -8.894969398810265e14, 5.4273966498765975e14, -2.213496387025252e14, 5.417751075510605e13, -6.019723417234006e12))
6771
u16 = evalpoly(p2, (6.252951493434797e6, -2.0016469281917763e9, 1.1099740513917902e11, -2.5215584749128545e12, 3.100743647289646e13, -2.3665253045164925e14, 1.2126758042503475e15, -4.3793258383640155e15, 1.1486706978449752e16, -2.2268225133911144e16, 3.213827526858624e16, -3.4447226006485144e16, 2.705471130619708e16, -1.5129826322457682e16, 5.705782159023671e15, -1.3010127235496995e15, 1.3552215870309369e14))
6872
u17 = -evalpoly(p2, (5.0069589531988926e7, -1.8078220384658062e10, 1.128709145410874e12, -2.886383763141476e13, 4.0004445704303625e14, -3.4503855118462725e15, 2.0064271476309532e16, -8.270945651585064e16, 2.4960365126160426e17, -5.62631788074636e17, 9.575335098169139e17, -1.2336116931960694e18, 1.1961991142756308e18, -8.592577980317548e17, 4.4347954614171904e17, -1.5552983504313904e17, 3.3192764720355224e16, -3.254192619642669e15))
69-
70-
return evalpoly(-p/v, (u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11, u12, u13, u14, u15, u16, u17))
73+
u18 = evalpoly(p2, (4.259392165047669e8, -1.722832387173505e11, 1.2030115826419191e13, -3.4396530474307594e14, 5.335106978708839e15, -5.1605093193485224e16, 3.37667624979061e17, -1.5736434765189599e18, 5.402894876715982e18, -1.3970803516443374e19, 2.757282981650519e19, -4.178861444656839e19, 4.859942729324836e19, -4.301555703831444e19, 2.846521225167657e19, -1.3639420410571592e19, 4.47020096401231e18, -8.966114215270463e17, 8.30195760673191e16))
74+
u19 = -evalpoly(p2, (3.8362551802304335e9, -1.7277040123529995e12, 1.3412416915180639e14, -4.2619355104268985e15, 7.351663610930971e16, -7.921651119323832e17, 5.789887667664653e18, -3.025566598990372e19, 1.1707490535797259e20, -3.434621399768417e20, 7.756704953461136e20, -1.360203777284994e21, 1.8571089321463453e21, -1.9677247077053125e21, 1.6016898573693598e21, -9.824438427689858e20, 4.392792200888712e20, -1.351217503435996e20, 2.5563802960529236e19, -2.242438856186775e18))
75+
u20 = evalpoly(p2, (3.646840080706556e10, -1.818726203851104e13, 1.5613123930484672e15, -5.48403360388329e16, 1.0461721131134344e18, -1.2483700995047234e19, 1.0126774169536592e20, -5.8917941350694964e20, 2.548961114664972e21, -8.405915817108351e21, 2.1487414815055883e22, -4.302534303482379e22, 6.783661642951883e22, -8.423222750084323e22, 8.19433100543513e22, -6.173206302884415e22, 3.528435843903409e22, -1.4787743528433614e22, 4.285296082829494e21, -7.671943936729004e20, 6.393286613940837e19))
76+
return evalpoly(-p/v, (u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11, u12, u13, u14, u15, u16, u17, u18, u19, u20))
7177
end
7278

73-
7479
#=
7580
function Uk_poly_Kn(p, v, p2, ::Type{T}) where T <: BigFloat
7681
u0 = one(T)

src/besselj.jl

Lines changed: 35 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -159,55 +159,42 @@ Nu must be real.
159159
function _besselj(nu, x)
160160
nu == 0 && return besselj0(x)
161161
nu == 1 && return besselj1(x)
162-
if x < 4.0
163-
if nu > 60.0
164-
return log_besselj_small_arguments_orders(nu, x)
165-
else
166-
return besselj_small_arguments_orders(nu, x)
167-
end
168-
elseif x < 20.0
169-
if nu > 45
170-
return besselj_debye(nu, x)
171-
else
172-
v = nu + 45
173-
jnu = besselj_debye(v, x)
174-
jnup1 = besselj_debye(v+1, x)
175-
return besselj_down_recurrence(x, jnu, jnup1, v, nu)[2]
176-
end
177-
elseif x > 1.65*nu
178-
return besselj_large_argument(nu, x)
179-
end
180-
if nu <= 100
181-
if 2.5*x < nu
182-
return besselj_debye(nu, x)
183-
elseif x <= nu
184-
# this can produce inaccurate results when x is close to root of J0 or J1
185-
#if isinteger(nu)
186-
# jnu = besselj1(x)
187-
# jnum1 = besselj0(x)
188-
# return besselj_up_recurrence(x, jnu, jnum1, 1.0, nu)[2]
189-
#else
190-
v = nu + ceil(nu*1.3)
191-
jnu = besselj_debye(v, x)
192-
jnup1 = besselj_debye(v+1, x)
193-
return besselj_down_recurrence(x, jnu, jnup1, v, nu)[2]
194-
#end
195-
else
196-
v = floor(nu - x/3)
197-
v2 = nu - v
198-
jnu = besselj_large_argument(v2, x)
199-
jnum1 = besselj_large_argument(v2 -1, x)
200-
return besselj_up_recurrence(x, jnu, jnum1, v2, nu)[2]
201-
end
202-
elseif 1.5*x < nu
203-
return besselj_debye(nu, x)
204-
elseif nu < 1000
205-
v = nu + ceil(nu*1.3)
162+
163+
x < 4.0 && return besselj_small_arguments_orders(nu, x)
164+
165+
large_arg_cutoff = 1.65*nu
166+
(x > large_arg_cutoff && x > 20.0) && return besselj_large_argument(nu, x)
167+
168+
169+
debye_cutoff = 2.0 + 1.00035*x + (302.681*x)^(1/3)
170+
nu > debye_cutoff && return besselj_debye(nu, x)
171+
172+
if nu >= x
173+
nu_shift = ceil(7.0 + 1.00033*x + (1427.61*x)^(1/3))
174+
v = nu + nu_shift
206175
jnu = besselj_debye(v, x)
207176
jnup1 = besselj_debye(v+1, x)
208177
return besselj_down_recurrence(x, jnu, jnup1, v, nu)[2]
178+
end
179+
180+
# at this point x > nu and x < nu * 1.65
181+
# in this region forward recurrence is stable
182+
# we must decide if we should do backward recurrence if we are closer to debye accuracy
183+
# or if we should do forward recurrence if we are closer to large argument expansion
184+
debye_cutoff = 5.0 + 1.00033*x + (1427.61*x)^(1/3)
185+
186+
debye_diff = debye_cutoff - nu
187+
large_arg_diff = nu - x / 2.0
188+
189+
if (debye_diff > large_arg_diff && x > 20.0)
190+
nu_shift = ceil(large_arg_diff)
191+
v2 = nu - nu_shift
192+
jnu = besselj_large_argument(v2, x)
193+
jnum1 = besselj_large_argument(v2 - 1, x)
194+
return besselj_up_recurrence(x, jnu, jnum1, v2, nu)[2]
209195
else
210-
v = nu + 500
196+
nu_shift = ceil(debye_diff)
197+
v = nu + nu_shift
211198
jnu = besselj_debye(v, x)
212199
jnup1 = besselj_debye(v+1, x)
213200
return besselj_down_recurrence(x, jnu, jnup1, v, nu)[2]
@@ -227,8 +214,9 @@ end
227214
# this needs a better way to sum these as it produces large errors
228215
# only valid in non-oscillatory regime (v>1/2, 0<t<sqrt(v^2 - 0.25))
229216
# power series has premature underflow for large orders
230-
# gives wrong answers for x > 20.0 (might want to fix this)
231217
function besselj_small_arguments_orders(v, x::T) where T
218+
v > 60 && return log_besselj_small_arguments_orders(v, x)
219+
232220
MaxIter = 2000
233221
out = zero(T)
234222
a = (x/2)^v / gamma(v + one(T))
@@ -245,7 +233,7 @@ end
245233
# use when v is large and x is small
246234
# need for bessely
247235
function log_besselj_small_arguments_orders(v, x::T) where T
248-
MaxIter = 1000
236+
MaxIter = 2000
249237
out = zero(T)
250238
a = one(T)
251239
x2 = (x/2)^2

0 commit comments

Comments
 (0)