Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when hashing Measurement{Float64} #103

Closed
jwscook opened this issue Apr 21, 2021 · 5 comments · Fixed by #104
Closed

Error when hashing Measurement{Float64} #103

jwscook opened this issue Apr 21, 2021 · 5 comments · Fixed by #104

Comments

@jwscook
Copy link

jwscook commented Apr 21, 2021

Hello,

I've encountered this error:

julia> hash(1.0 ± 0.1)
ERROR: MethodError: no method matching decompose(::Measurement{Float64})
Closest candidates are:
  decompose(::Integer) at float.jl:555
  decompose(::Float16) at float.jl:557
  decompose(::Float32) at float.jl:568
  ...
Stacktrace:
 [1] hash(x::Measurement{Float64}, h::UInt64)
   @ Base ./float.jl:491
 [2] hash(x::Measurement{Float64})
   @ Base ./hashing.jl:18
 [3] top-level scope
   @ REPL[6]:1

What would the fix be? Declare hash by hand or implement decompose?

Something like:

Base.hash(m::Measurement) = foldr(hash, (m.val, m.err, m.der, m.tag))

or maybe if tag can be hijacked:

Base.hash(m::Measurement) = foldr(hash, (m.val, m.err, m.der); init=m.tag)

Versions:

 [eff96d63] Measurements v2.6.0
 Version 1.6.1-pre.39 (2021-04-17)
@giordano
Copy link
Member

giordano commented Apr 21, 2021

Frankly, I've never implemented hashing because

  1. I don't understand how it's supposed to work for non-standard numbers (and lack of documentation about this doesn't help much)
  2. so far I never had to implement them in practice.

I'm happy to do it if someone can help in particular with point 1, or if they open a pull request 🙂

@jwscook
Copy link
Author

jwscook commented Apr 22, 2021

Taking inspiration from other packages:

@giordano
Copy link
Member

Out of curiosity, did you find a case in practice where the hash method was needed? I'm aware the method isn't implemented, but I couldn't find a real-world case in my applications where this would be needed.

@jwscook
Copy link
Author

jwscook commented Apr 23, 2021

One instance it using a Measurement as a key in a Dict:

julia> using Measurements

julia> m = 1.0 ± 0.1
1.0 ± 0.1

julia> Dict(m=>"anything else here")
ERROR: MethodError: no method matching decompose(::Measurement{Float64})
Closest candidates are:
  decompose(::Integer) at float.jl:555
  decompose(::Float16) at float.jl:557
  decompose(::Float32) at float.jl:568
  ...
Stacktrace:
 [1] hash(x::Measurement{Float64}, h::UInt64)
   @ Base ./float.jl:491
 [2] hash(x::Measurement{Float64})
   @ Base ./hashing.jl:18
 [3] hashindex(key::Measurement{Float64}, sz::Int64)
   @ Base ./dict.jl:169
 [4] ht_keyindex2!(h::Dict{Measurement{Float64}, String}, key::Measurement{Float64})
   @ Base ./dict.jl:310
 [5] setindex!(h::Dict{Measurement{Float64}, String}, v0::String, key::Measurement{Float64})
   @ Base ./dict.jl:383
 [6] Dict{Measurement{Float64}, String}(kv::Tuple{Pair{Measurement{Float64}, String}})
   @ Base ./dict.jl:104
 [7] Dict(ps::Pair{Measurement{Float64}, String})
   @ Base ./dict.jl:124
 [8] top-level scope
   @ REPL[3]:1

julia> Base.hash(m::Measurement) = foldr(hash, (m.val, m.err, m.der, m.tag))

julia> Dict(m=>"anything else here")
Dict{Measurement{Float64}, String} with 1 entry:
  1.0±0.1 => "anything else here"

@giordano
Copy link
Member

I've added the hash method in #104. However, due to the fact isequal(x, y) must imply hash(x) == hash(y) we have this weird situation:

julia> x = 3 ± 0.1
3.0 ± 0.1

julia> a = 3 ± 0.1
3.0 ± 0.1

julia> x === a
false

julia> d = Dict(x => 42)
Dict{Measurement{Float64}, Int64} with 1 entry:
  3.0±0.1 => 42

julia> d[x]
42

julia> d[a]
42

julia> d[a] = 0
0

julia> d[a]
0

julia> d[x]
0

I don't think this can be avoided given the requirement on the relation between isequal and hash

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants