DoubleFloats.jl icon indicating copy to clipboard operation
DoubleFloats.jl copied to clipboard

isapprox is incorrect for tolerances beyond standard precision

Open tobydriscoll opened this issue 1 year ago • 4 comments

The following is incorrect:

julia> T = Double64
Double64 (alias for DoubleFloat{Float64})

julia> x = Double64(0.9, 1e-20)
9.00000000000000022214460492503130852e-01

julia> abs(x - T(9)/10)
2.22144604925031320405193304841894479e-17

julia> isapprox(x, T(9)/10; rtol=1e-22, atol=1e-22)
true

If I understand the internals, the isapprox function uses HI(x)===HI(y) as a shortcut for the test, which doesn't look right.

tobydriscoll avatar Aug 05 '24 19:08 tobydriscoll

What would you recommend?

On Mon, Aug 5, 2024 at 3:07 PM Toby Driscoll @.***> wrote:

The following is incorrect:

julia> T = Double64 Double64 (alias for DoubleFloat{Float64})

julia> x = Double64(0.9, 1e-20)9.00000000000000022214460492503130852e-01

julia> abs(x - T(9)/10)2.22144604925031320405193304841894479e-17

julia> isapprox(x, T(9)/10; rtol=1e-22, atol=1e-22)true

If I understand the internals, the isapprox function uses HI(x)===HI(y) as a shortcut for the test, which doesn't look right.

— Reply to this email directly, view it on GitHub https://github.com/JuliaMath/DoubleFloats.jl/issues/206, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAM2VRTX44G3MBTT3DCZMETZP7EORAVCNFSM6AAAAABMA3T4U6VHI2DSMVQWIX3LMV43ASLTON2WKOZSGQ2DSMRYGAYTGNQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

JeffreySarnoff avatar Aug 05 '24 20:08 JeffreySarnoff

The most straightforward thing would be to remove HI(x) === HI(y) || from line 20 of misc.jl. I suppose you could keep it by pairing it with a test that rtol is large enough, but I'm skeptical that the potential time savings is worth very much.

And then. of course, adding some relevant unit tests. 😁

tobydriscoll avatar Aug 06 '24 14:08 tobydriscoll

anyplace that HI(x) is appropriate to be used in place of (x) it should be -- the internals of a full isapprox evaluation in Double64s is more involved .. once that happens is everything tends to intermix and that can extend runtimes (just my experience)

On Tue, Aug 6, 2024 at 10:13 AM Toby Driscoll @.***> wrote:

The most straightforward thing would be to remove HI(x) === HI(y) || from line 20 of misc.jl. I suppose you could keep it by pairing it with a test that rtol is large enough, but I'm skeptical that the potential time savings is worth very much.

And then. of course, adding some relevant unit tests. 😁

— Reply to this email directly, view it on GitHub https://github.com/JuliaMath/DoubleFloats.jl/issues/206#issuecomment-2271402334, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAM2VRRCYWQPILS3KPDE77DZQDKZ5AVCNFSM6AAAAABMA3T4U6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENZRGQYDEMZTGQ . You are receiving this because you commented.Message ID: @.***>

JeffreySarnoff avatar Aug 06 '24 15:08 JeffreySarnoff

OK, if the HI parts of x and y are the same, then x-y is equal to x.lo-y.lo, right? So that's cheap.

But I don't know if you can cheat on the rtol*max(abs(x), abs(y)) part if rtol is specified in the same precision as x and y. The chances that you would care about the difference between using, say, abs(x) and abs(x.hi) there seem remote, but you can probably invent a pathological counterexample that would break the implied guarantee.

tobydriscoll avatar Aug 06 '24 18:08 tobydriscoll