|
| 1 | +""" |
| 2 | + besseli0(x::T) where T <: Union{Float32, Float64} |
| 3 | +
|
| 4 | +Modified Bessel function of the first kind of order zero, ``I_0(x)``. |
| 5 | +""" |
| 6 | +function besseli0(z::Complex{T}) where T <: Union{Float64} |
| 7 | + check = false |
| 8 | + if real(z) < 0.0 |
| 9 | + z = -z |
| 10 | + end |
| 11 | + if imag(z) < 0.0 |
| 12 | + z = conj(z) |
| 13 | + check = true |
| 14 | + end |
| 15 | + |
| 16 | + if abs(z) > 20.0 |
| 17 | + zinv = 1 / z |
| 18 | + e = exp(z) |
| 19 | + s = sqrt(2 * z * π) |
| 20 | + p = evalpoly(zinv*zinv, (1.0, 0.0703125, 0.112152099609375, 0.5725014209747314, 6.074042001273483, 110.01714026924674, 3038.090510922384, 118838.42625678325, 6.252951493434797e6, 4.259392165047669e8, 3.646840080706556e10, 3.8335346613939443e12)) |
| 21 | + p2 = zinv*evalpoly(zinv*zinv, (0.125, 0.0732421875, 0.22710800170898438, 1.7277275025844574, 24.380529699556064, 551.3358961220206, 18257.755474293175, 832859.3040162893, 5.0069589531988926e7, 3.8362551802304335e9, 3.6490108188498334e11)) |
| 22 | + r = e / s * (p + p2) + im * (p - p2) / (e * s) |
| 23 | + elseif abs(z) < 5.0 |
| 24 | + r = evalpoly(z*z, (1.0, 0.25, 0.015625, 0.00043402777777777775, 6.781684027777777e-6, 6.781684027777778e-8, 4.709502797067901e-10, 2.4028075495244395e-12, 9.385966990329842e-15, 2.896903392077112e-17, 7.242258480192779e-20, 1.4963343967340453e-22, 2.5978027721077174e-25, 3.842903509035085e-28, 4.9016626390753635e-31, 5.4462918211948485e-34, 5.318644356635594e-37)) |
| 25 | + else |
| 26 | + if angle(z) <= pi/5 |
| 27 | + #r = besseli_power_series(0.0, z) |
| 28 | + r = evalpoly(z*z, (1.0, 0.25, 0.015625, 0.00043402777777777775, 6.781684027777777e-6, 6.781684027777778e-8, 4.709502797067901e-10, 2.4028075495244395e-12, 9.385966990329842e-15, 2.896903392077112e-17, 7.242258480192779e-20, 1.4963343967340453e-22, 2.5978027721077174e-25, 3.842903509035085e-28, 4.9016626390753635e-31, 5.4462918211948485e-34, 5.318644356635594e-37, 4.60090342269515e-40, 3.5500798014623073e-43, 2.458504017633177e-46, 1.5365650110207356e-49, 8.71068600351891e-53, 4.499321282809354e-56, 2.1263333094562166e-59, 9.228877211181495e-63, 3.691550884472598e-66, 1.3652185223641266e-69, 4.681819349671216e-73, 1.4929270885431173e-76, 4.4379521062518346e-80, 1.232764473958843e-83, 3.206983543077115e-87, 7.829549665715613e-91, 1.7974172786307652e-94, 3.887148093924665e-98, 7.932955293723807e-102)) |
| 29 | + else |
| 30 | + zz = [ |
| 31 | + -1.678231235746891147897486007423140108585 + 20.29678265316490737291132973041385412216im, |
| 32 | + -1.523025526043160660094599734293296933174 + 18.74439925781758020661982300225645303726im, |
| 33 | + -1.602232319163288343233375599083956331015 + 19.57994203993233739424795203376561403275im, |
| 34 | + -1.297548314533615521071396869956515729427 + 15.67962995660580283185936423251405358315im, |
| 35 | + -1.083284426743612138821504231600556522608 + 13.2089741880721351918737127562053501606im, |
| 36 | + -0.8756326508559164611966707525425590574741 + 10.59162940924948692611451406264677643776im, |
| 37 | + -0.6632096279193985255417942425992805510759 + 8.104093334608059251422673696652054786682im, |
| 38 | + -0.420162057582130654687091464438708499074 + 5.169659732326902457089090603403747081757im, |
| 39 | + -0.5248407961081728023700065932644065469503 + 6.352576446680355815033180988393723964691im, |
| 40 | + 16.81912545211429588221108133438974618912 + 11.61870568962804384227638365700840950012im, |
| 41 | + 3.956891894434294787430417272844351828098 + 2.733954688042517844337453425396233797073im, |
| 42 | + 0.1577160301669917608080595528008416295052 + 20.49513202616177309778322523925453424454im, |
| 43 | + -0.390590921015831871176970935266581363976 + 4.825951828615894889651372068328782916069im, |
| 44 | + 5.086291973430167701053505879826843738556 + 19.856103426521318766617696383036673069im, |
| 45 | + -1.393155126117511022343364857078995555639 + 16.86197099455173997739620972424745559692im, |
| 46 | + 12.05655555056696748295053112087771296501 + 16.57204880191947538037311460357159376144im, |
| 47 | + 2.460344943558517627479886868968605995178 + 4.13151392233745973214809055207297205925im, |
| 48 | + -1.582576281040411148026691989798564463854 + 20.43576085524474805765748897101730108261im, |
| 49 | + 8.550688367994505156843842996750026941299 + 5.903012749617017718151146254967898130417im, |
| 50 | + -0.9675432524019281776972434272465761750937 + 11.81279027041785312235333549324423074722im, |
| 51 | + 4.703843537806423391600674221990630030632 + 3.252480256589709295411694256472401320934im, |
| 52 | + 16.06349030987121295765973627567291259766 + 12.69219331974861475487159623298794031143im, |
| 53 | + 1.937834775724029512389279261697083711624 + 20.39705296333508854900173901114612817764im, |
| 54 | + -1.594679144973751627745173209405038505793 + 19.93238790107540125973173417150974273682im |
| 55 | + ] |
| 56 | + |
| 57 | + |
| 58 | + w = [ -0.006546682597891755918395606528292773873545 + 0.0im, |
| 59 | + -0.008478994639378135619867116190562228439376 - 0.006865842132444678960756512253738037543371im, |
| 60 | + -0.04084417105131761538405754663472180254757 - 0.06528666329071823593022116938300314359367im, |
| 61 | + -0.04712461267953402949126839871496486011893 + 0.01452078721700496635738097950252267764881im, |
| 62 | + -0.007118804602080300823752079253381452872418 + 0.06492808208351363852273152588168159127235im, |
| 63 | + -0.06116738548641747347245356536404869984835 - 0.02725053730346357894198661142581840977073im, |
| 64 | + -0.02494387696913849192248413544348295545205 + 0.02277714123083315542195315117623977130279im, |
| 65 | + -0.04245963986977926291066509634219983126968 + 0.004116793595813594310028893374919789494015im, |
| 66 | + -0.02406420353735235287406801774068298982456 + 0.02715441509989760873744479852121003204957im, |
| 67 | + -0.4904880414270129662668296077754348516464 + 0.1081159025127441941638295475058839656413im, |
| 68 | + -0.03348344660847365344968906697431521024555 + 0.05785977178570968909587790562909503933042im, |
| 69 | + 0.003536996149578506415389611561295168939978 + 0.07752104476498027085806796776523697189987im, |
| 70 | + 0.01586745997824464543546341133151145186275 - 0.01721172123513132687366855577693058876321im, |
| 71 | + 0.1214650011644559657320030510163633152843 + 0.0199244295229646650735588764291605912149im, |
| 72 | + -0.01413089963393250950152157940920005785301 + 0.03915878901517700488854600848753761965781im, |
| 73 | + 0.1940642102318209105682456083741271868348 + 0.189125716371402241566812563178245909512im, |
| 74 | + -0.0629596993796838894086320692622393835336 + 0.03943410994216315496041502797197608742863im, |
| 75 | + 0.02664896602239549827650932911637937650084 + 0.007480078058428093340515019349368230905384im, |
| 76 | + -0.01891162412416614799215430764434131560847 - 0.224558251516702916950052326683362480253im, |
| 77 | + -0.07674844370101535639960843582230154424906 + 0.06062885086104936177564539434570178855211im, |
| 78 | + -0.05865831566992357748446806908759754151106 - 0.1487332818764729724936302091009565629065im, |
| 79 | + 0.5977968397140664968958390090847387909889 - 0.3921463933084315400812158713961252942681im, |
| 80 | + 0.09468179551658635617616965873821754939854 + 0.06801353116428925094094637415764736942947im, |
| 81 | + -0.03593292611744278858276757659950817469507 + 0.08129780087330089333175209276305395178497im] |
| 82 | + |
| 83 | + |
| 84 | + f = [ 3.267431673967855942919413791969418525696 - 11.08592268019023485692287067649886012077im, |
| 85 | + -1.408157475121772916892837201885413378477 + 8.194246359208529284501310030464082956314im, |
| 86 | + 10.16651031219827316931514360476285219193 + 1.139462837357397617665810685139149427414im, |
| 87 | + 0.05333588002795774246633797588401648681611 + 5.332849960825335244862799299880862236023im, |
| 88 | + 3.731512177678290687055095986579544842243 + 1.009153918438497665732711539021693170071im, |
| 89 | + 2.079126843703456906098381296033039689064 - 1.574054723602581251640231130295433104038im, |
| 90 | + -0.3027225201326076420293986757314996793866 - 1.336196815913121005436892119178082793951im, |
| 91 | + -0.321207149871566732812766531424131244421 - 0.5904585480867294844387060948065482079983im, |
| 92 | + 0.5332409552090798809942384650639723986387 + 1.12410228905475118033052694954676553607im, |
| 93 | + 0.4009721205547844280481228906864998862147 - 0.001452802358581500212844628272534919233294im, |
| 94 | + 0.4076248719737363135351415621698834002018 - 0.007221143389127381538583616560345035395585im, |
| 95 | + 0.3572930776018199416910192667273804545403 - 0.2904023883125960159290457340830471366644im, |
| 96 | + 0.2227466624325098176750969969361904077232 - 0.86310886714297674338070009980583563447im, |
| 97 | + 0.3994990829482118477322671878937399014831 - 0.002392663621286134686266811044674795994069im, |
| 98 | + 5.223429579451738469231258932268247008324 - 4.319291202018760600367386359721422195435im, |
| 99 | + 0.4003498255225810820157050784473540261388 - 0.002032103233714888101957285471144132316113im, |
| 100 | + 0.4060493902079563288687324984493898227811 - 0.01098448458664161297981820553104626014829im, |
| 101 | + 0.164972906678356817655739519068447407335 - 9.454457188929774602570432762149721384048im, |
| 102 | + 0.4029739937090559553922730628983117640018 - 0.002997378292125214404445499027929145086091im, |
| 103 | + -2.361384545672124968263005939661525189877 + 0.1425123166686921016843569987031514756382im, |
| 104 | + 0.406335503077652593351132281895843334496 - 0.005903178413394780457701394027481001103297im, |
| 105 | + 0.4008673043752389864025076349207665771246 - 0.001578422845174482381375158368541633535642im, |
| 106 | + 0.3995411619962026539276678249734686687589 - 0.01068906314642052712837738681628252379596im, |
| 107 | + 8.455251786581097661610328941605985164642 - 5.380704447124407430180781375383958220482im |
| 108 | + ] |
| 109 | + |
| 110 | + |
| 111 | + C = 1 ./ (z .- transpose(zz)) |
| 112 | + r = ((C*(w.*f))./(C*w)) |
| 113 | + |
| 114 | + r = r[1] / (sqrt(z) * exp(-z)) |
| 115 | + end |
| 116 | + end |
| 117 | + check && (r = conj(r)) |
| 118 | + return r |
| 119 | +end |
| 120 | + |
| 121 | +_besselj0(z::Complex{T}) where T <: Float64 = besseli0(z/im) |
| 122 | + |
| 123 | +#= |
| 124 | +# works for x > 20.0 |
| 125 | +function i0_large_argument(z::T) where T |
| 126 | + c = exp(z) / sqrt(2 * pi * z) |
| 127 | + p = evalpoly(1/z, (1.0, 1/8, 9/128, 75/1024, 3675/32768, 59535/262144, 2401245/4194304, 57972915/33554432, 13043905875/2147483648, 418854310875/17179869184, 30241281245175/274877906944, 1212400457192925/2199023255552, 213786613951685775/70368744177664, 10278202593831046875/562949953421312, 1070401384414690453125/9007199254740992, 60013837619516978071875/72057594037927936, 57673297952355815927071875/9223372036854775808, 3694483615889146090857721875/73786976294838206464, 502860269940467106811189921875/1180591620717411303424, 36232405765710498380237842265625/9444732965739290427392, 11021897833929133607268351617203125/302231454903657293676544, 882276678992136837800861860405640625/2417851639229258349412352, T(148302689041496455735799416353639046875)/T(38685626227668133590597632))) |
| 128 | + return c*p |
| 129 | +end |
| 130 | +function i1_large_argument(z::T) where T |
| 131 | + c = exp(z) / sqrt(2 * pi * z) |
| 132 | + p = evalpoly(1/z, (1.0, -3/8, -15/128, -105/1024, -4725/32768, -72765/262144, -2837835/4194304, -66891825/33554432, -14783093325/2147483648, -468131288625/17179869184, -33424574007825/274877906944, -1327867167401775/2199023255552, -232376754295310625/70368744177664, -11100458801337530625/562949953421312, -1149690375852815671875/9007199254740992, -64152722972587114490625/72057594037927936, -61394155884765868567528125/9223372036854775808, -3918391713821821611515765625/73786976294838206464, -531595142508493798628972203125/1180591620717411303424, -38190914185478633427818266171875/9444732965739290427392, -11587123363874217382000061956546875/302231454903657293676544, -925314565772241073791147804815671875/2417851639229258349412352, -155200488531798616467697063625901328125/38685626227668133590597632)) |
| 133 | + return c*p |
| 134 | +end |
| 135 | +
|
| 136 | +function i0_small_argument(z::T) where T |
| 137 | + return evalpoly(z*z, (1.0, 1/4, 1/64, 1/2304, 1/147456, 1/14745600, 1/2123366400, 1/416179814400, 1/106542032486400, 1/34519618525593600, 1/13807847410237440000, 1/6682998146554920960000, 1/3849406932415634472960000, 1/2602199086312968903720960000, 1/2040124083669367620517232640000, 1/1836111675302430858465509376000000, 1/1880178355509689199068681601024000000, 1/2173486178969200714123395930783744000000, 1/2816838087944084125503921126295732224000000, 1/4067514198991257477227662106371037331456000000, 1/6508022718386011963564259370193659730329600000000, 1/11480152075232925103727353529021615764301414400000000, 1/22225574417650943000816156432185848119687538278400000000, 1/47029315467749395389726987010505254621258830997094400000000, 1/108355542837694606977930978072204106647380346617305497600000000, 1/270888857094236517444827445180510266618450866543263744000000000000, 1/732483469582815543170813411768099760936291143132985163776000000000000, 1/2135921797303490123886091908715778902890224973375784737570816000000000000, 1/6698250756343745028506784225732682639463745516506460937022078976000000000000, 1/22532915544340358275896822135364744399156039917527734592142273675264000000000000, 1/81118495959625289793228559687313079836961743703099844531712185230950400000000000000, 1/311819498468799613965170583438031478893280942794715802379901640027773337600000000000000, 1/1277212665728203218801338709762176937546878741687155926548077117553759590809600000000000000, 1/5563538371912053221098631419724042739954203798789251216043423924064176777566617600000000000000, 1/25725801431721334094360071684803973629548238365601497622984792224872753419468039782400000000000000, 1/126056427015434537062364351255539470784786367991447338352625481901876491755393394933760000000000000000)) |
| 138 | +end |
| 139 | +
|
| 140 | +function k0_large_argument(z::T) where T |
| 141 | + c = exp(-z) * sqrt(pi / (2*z)) |
| 142 | + p = evalpoly(1/z, (1.0, -1/8, 9/128, -75/1024, 3675/32768, -59535/262144, 2401245/4194304, -57972915/33554432, 13043905875/2147483648, -418854310875/17179869184, 30241281245175/274877906944, -1212400457192925/2199023255552, 213786613951685775/70368744177664, -10278202593831046875/562949953421312, 1070401384414690453125/9007199254740992, -60013837619516978071875/72057594037927936, 57673297952355815927071875/9223372036854775808, -3694483615889146090857721875/73786976294838206464, 502860269940467106811189921875/1180591620717411303424, -36232405765710498380237842265625/9444732965739290427392, 11021897833929133607268351617203125/302231454903657293676544, -882276678992136837800861860405640625/2417851639229258349412352, T(148302689041496455735799416353639046875)/T(38685626227668133590597632))) |
| 143 | + return c*p |
| 144 | +end |
| 145 | +=# |
0 commit comments