i have recursive function utilizes global dict store values obtained when traversing tree. however, @ least of values stored in dict seem disappear! simplified code shows problem:
type id level::int32 x::int32 end vdict = dict{id,float64}() function getv(w::id) if haskey(vdict,w) return vdict[w] end if w.level == 12 return 1.0 end w.x == -111 && println("dont have: ",w) local vv = 0.0 j = -15:15 local wj = id(w.level+1,w.x+j) vv += getv(wj) end vdict[w] = vv w.x == -111 && println("just stored: ",w) vv end getv(id(0,0)) the output has many lines this:
just stored: id(11,-111) dont have: id(11,-111) stored: id(11,-111) dont have: id(11,-111) stored: id(11,-111) dont have: id(11,-111) ... do have silly error, or there bug in julia's dict?
by default, custom types come implementations of equality , hashing by object identity. since id type mutable, julia conservative , assumes care distinguishing each instance (since potentially diverge):
julia> type id # there's strong convention capitalize type names in julia level::int32 x::int32 end julia> x = id(11, -111) y = id(11, -111) x == y false julia> x.level = 12; (x,y) (id(12,-111),id(11,-111)) julia doesn't know whether care object's long-term behavior or current value.
there 2 ways make behave you'd like:
make custom type immutable. looks don't need mutate contents of
id. simplest , straightforward way solve defineimmutable id.id(11, -111)indistinguishable other construction ofid(11, -111)since values can never change. bonus, may see better performance, too.if need mutate values, alternatively define own implementations of
==,base.hashcare current value:==(a::id, b::id) = a.level == b.level && a.x == b.x base.hash(a::id, h::uint) = hash(a.level, hash(a.x, h))as @stefankarpinski just pointed out on mailing list, isn't default mutable values "since makes easy stick in dict, mutate it, , 'lose it'." is, object's hash value has changed dictionary stored in place based upon old hash value, , can no longer access key/value pair key lookup. if create second object same original properties first won't able find since dictionary checks equality after finding hash match. way lookup key mutate original value or explicitly asking dictionary
base.rehash!contents.
in case, highly recommend option 1.
Comments
Post a Comment