Dict issue?

I made a dictionary to store some inputs to a function, see below

    data                    = Dict()
    data["total_time"]      = 0.3
    data["time"]            = 0.
    data["dt"]              = 1e-3
   function f(data)
        Tf    = Float64(data["total_time"])
	dtime = Float64(data["dt"] )        
	t     = Float64(data["time"])      
	fric  = Float64(data["friction"])
   end

Then, I do: @code_warntype(f), and saw this:
t::Any
Tf::Any
fric::Any

My question is why?

%3 = Base.getindex(data, "dt")::Any

notice your Dict is {Any, Any}

you’re converting an Any to Float64, your Dict() (can) contain Anys so compiler won’t know better until actually try converting it

replacing the first line with:
data = Dict{String, Float64}() would fix the instability:

Variables
  #self#::Core.Compiler.Const(f, false)
  data::Dict{String,Float64}
  Tf::Float64
  dtime::Float64
  t::Float64
  fric::Float64
1 Like

Thanks a lot for your prompt reply. Actually, I also stored other things in data, such as

  data                    = Dict()
    data["total_time"]      = dtime#Tf
    data["time"]            = 0.
    data["dt"]              = dtime
    data["friction"]        = fric
    data["dirichlet_grid"]  = [("back", (0,0,1)), 
                               ("front",(1,1,1)),
                               ("bottom",(1,1,1)),
                               ("left",(1,1,1)),
                               ("right",(1,1,1)),
                               ]      # => fix bottom nodes on X/Y/Z     dir             

That was why I went for data=Dict(). Any suggestion to have both flexibility and efficiency?

yes,

function f(data)
    Tf = data["total_time"]::Float64
    dtime = data["dt"]::Float64
...
end

something like this so they have to be Float64 (instead of converting them)

Oh, so easy. Thanks a lot.

I am now facing another issue:

function velo_func(t)
        if t < 1.5e-3
            vx = 0.
            vy = -50.
            vz = 0.
        else
            vx = 50.
            vy = 0.
            vz = 0.
        end
        return (vx,vy,vz)
    end

    data                    = Dict()
    data["total_time"]      = dtime#Tf
    data["time"]            = 0.
    data["dt"]              = dtime
    data["friction"]        = fric                                                         
    data["rigid_body_velo"] = Array{Tuple{Int64,Function},1}([(1,velo_func)])      
function f(data)
        rigid_solids = data["rigid_body_velo"]::Array{Tuple{Int64,Function},1}
	 for (s,f) in rigid_solids
	 		solid       = solids[s]
                       vex,vey,vez = f(t)
     end
end

My problem is (vex, vey,vez) is recognised as Tuple(Any,ANy,Any).
Could u please help me how to make Julia knows it is Tuple(Float,Float,Float)?

Firstly, you are using the same name, f, for both the outer function and the function retrieved from the Dict. I’m not sure if that causes any problems, but it’s confusing and not a good idea, imho.

Secondly, Julia doesn’t know which function is coming out of your Dict. It just knows it’s some function, any function, and therefore it cannot predict what the types of the outputs will be. It doesn’t matter that you name the outputs vex, vey, vez, there’s no way to know that they have anything to do with the function velo_func.

Will data["rigid_body_velo"] contain many functions or just one?

1 Like

Thanks DNF. It just contains one function, but the function is problem-dependent. In other words, it is an input.

It might be difficult to tell the compiler which function to expect. But you can add a type assertion

(vex, vey, vez) = f(t)::Tuple{Float64, Float64, Float64} 

(or something like that - - typing on my phone here)

To simplify, can’t you write

data["rigid_body_velo"] = (1, velo_func) 

?

Thanks again DNF. The thing is that I might have more than one tuple in data[“rigid_body_velo”], so in general, it must be a vector.

Ok, that’s what I meant when I asked if there would be only one function.

But still, I think you can just write

data["rigid_body_velo"] = [(1,velo_func), (2, other_func)]  # etc.

No need for the complicated type info.