Stream: helpdesk (published)

Topic: How to handle float-like keys


view this post on Zulip Max Köhler (Apr 21 2022 at 10:49):

I have the typical precision problem with float keys

julia> newstate.phasestree[Tensor{2,2}([1.8 0.0; 0.0 3.5000000000000004])]
ERROR: KeyError: key [1.8 0.0; 0.0 3.5000000000000004] not found
Stacktrace:
 [1] getindex(h::Dict{Tensor{2, 2, Float64, 4}, ConvexDamage.PhaseTree{2, Float64, 4}}, key::Tensor{2, 2, Float64, 4})
   @ Base ./dict.jl:482
 [2] top-level scope
   @ REPL[165]:1
 [3] top-level scope
   @ ~/.julia/packages/CUDA/YpW0k/src/initialization.jl:52

julia> newstate.phasestree[Tensor{2,2}([1.8 0.0; 0.0 3.500000000000000])]
2D Phasetree
k=1 F¯=[1.8 0.0; 0.0 1.2599999999999993], F⁺=[1.8 0.0; 0.0 3.5]
        k=2 F¯=[1.8 0.0; 0.0 1.3039999999999994], F⁺=[1.8 0.0; 0.0 3.5]

Are there other options than just rounding off the key before storing? Ideally I'd like to get some isapprox key, but I'm not sure if this is possible with the underlying hash mechanism (since I don't know much about it)

view this post on Zulip Max Köhler (Apr 21 2022 at 11:26):

searching for findfirst(x->isapprox(x,some_value),collect(keys(mydict))) is also quite expensive in my case. Some workaround while building the dict or accessing it would be best case for me

view this post on Zulip Sebastian Pfitzner (Apr 21 2022 at 11:38):

You could add a tol field to Tensor and then hash/compare based on that

view this post on Zulip Max Köhler (Apr 21 2022 at 13:42):

I think I'm wondering how the hash and equality checks happen in the dict implementation. Is it just isequal and hash that is used?

view this post on Zulip Mason Protter (Apr 21 2022 at 16:10):

You can define a method of Base.hash For your type that has whatever behaviour you like. So probably in this case, you want to round the number to within a certain number of significant digits during the hash.


Last updated: Oct 02 2023 at 04:34 UTC