Skip to content

log(besselk(v, x)) produces nan for a particular range of x #89

@ForceBru

Description

@ForceBru
using ArbNumerics

julia> for x in 10:5:100
        v = ArbReal(1//10, bits=70)
        xarb = ArbReal(x, bits=70)
        println(x, ' ', besselk(v, xarb) |> log, ' ', besselk(Float64(v), Float64(x)) |> log)
       end
10 -10.9369554813063873 -10.936955481306388
15 -16.135983876399 -16.13598387639861 # ArbReal precision declines?
20 -21.277932 -21.27793203227145
25 -26.388 -26.388354323197664 # ArbReal basically lost all precision
30 nan -31.478742870236157
35 nan -36.55526366411494
40 nan -41.62161181328355
45 nan -46.680177591375255
50 -51.73259663432748981301360397 -51.73259663432749 # ArbReal precision fully restored?
55 -56.7800375882572124747639817 -56.780037588257215
60 -61.82336454343572083356862714 -61.82336454343572
65 -66.8632344569057269824934597 -66.86323445690573
70 -71.9001584871871855150523812 -71.90015848718718
75 -76.9345421823775254477208602 -76.93454218237753
80 -81.96671270925342015278438794 -81.96671270925341
85 -86.99693783559781372005348771 -86.99693783559782
90 -92.025439492594551273600477 -92.02543949259456
95 -97.0524036744629762206949937 -97.05240367446298
100 -102.0779878017968542808176242 -102.07798780179685
  1. It's weird that precision of ArbReal seems to decline dramatically, but is then suddenly fully restored. besselk with Float64 inputs doesn't have this issue.
  2. Why do nans suddenly appear and then disappear? I guess besselk switches to some asymptotic expansion for large x?

In a plot, nans form a streak whose position changes depending on bits, while Float64 doesn't have this problem:

julia> import CairoMakie as M

julia> let
        v = 1//1000
        v70 = ArbReal(v, bits=70)
        v90 = ArbReal(v, bits=90)
        xs = range(0.1, 100, 1000)
        xs70 = range(ArbReal(1//10, bits=70), ArbReal(100, bits=70), 1000)
        xs90 = range(ArbReal(1//10, bits=90), ArbReal(100, bits=90), 1000)
        fig, ax1 = M.scatter(xs, log.(besselk.(Float64(v), xs)), markersize=2, label="Float64")
        ax2, = M.scatter(fig[2, 1], xs70, log.(besselk.(v70, xs70)), markersize=2, label="70 bits")
        ax3, = M.scatter(fig[3,1], xs90, log.(besselk.(v90, xs90)), markersize=2, label="90 bits")
        M.axislegend(ax1); M.axislegend(ax2); M.axislegend(ax3); M.linkxaxes!(ax1, ax2, ax3)
        fig
       end
Image

Versions

  • Julia 1.11
  • ArbNumerics v1.6.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions