Hello,
Following the performance tips, I'm trying to let the compiler know all types in my turing model in advance.
Anyway, I'm facing problems trying to make it infer the type of arrays ( here p) that appear inside the model in the form
@model mymodel(x, y, priors)
...
p ~ arraydist(priors)
...
end
What follows is a more explicit example inspired by the tutorials, modified to reflect the structure of the more complex model I'm trying to build.
# Imports
using Turing, DifferentialEquations, Distributions
using MCMCChains, Plots, StatsPlots
using Random
Random.seed!(14);
# deterministic model definition
function lotka_volterra(du,u,p,t)
x, y = u
ฮฑ, ฮฒ, ฮณ, ฮด = p
du[1] = (ฮฑ - ฮฒ*y)x # dx =
du[2] = (ฮด*x - ฮณ)y # dy =
end
p = [1.5, 1.0, 3.0, 1.0]
u0 = [1.0,1.0]
prob1 = ODEProblem(lotka_volterra,u0,(0.0,10.0),p)
fast_prob1 = ODEProblem(modelingtoolkitize(prob1),u0,(0.0,10.0),p )
sol = solve(fast_prob1,Tsit5());
# generate fake data
sol1 = solve(fast_prob1,Tsit5(),saveat=0.1)
odedata = Array(sol1) + 0.8 * randn(size(Array(sol1)))
plot(sol1, alpha = 0.3, legend = false); scatter!(sol1.t, odedata')
# define priors
priors = [Uniform(0.1, 0.3), LogNormal(1.63, 0.5), truncated(Normal(3.0,0.5),1,4),truncated(Normal(1.0,0.5),0,2)]
# define turing model
@model function fitlv2(data::Array{Float64,2}, prob1::ODEProblem, priors::Array{Distribution{Univariate,Continuous},1})
ฯ ~ InverseGamma(2, 3)
p ~ arraydist(priors)
prob = remake(prob1, p=p)::ODEProblem
predicted = solve(prob,Tsit5(),saveat=0.1).u::Array{Array{Float64,1},1}
for i = 1:length(predicted)
data[:,i] ~ MvNormal(predicted[i], ฯ)
end
end
# instantiate model
model2 = fitlv2(odedata, fast_prob1, priors)
Then if I inspect the type inference, I get:
# inspect type inference
@code_warntype model2.f(
Random.GLOBAL_RNG,
model2,
Turing.VarInfo(model2),
Turing.SampleFromPrior(),
Turing.DefaultContext(),
model2.args...,
)
Variables
#self#::Core.Compiler.Const(var"#1#2"(), false)
_rng::Core.Compiler.Const(Random._GLOBAL_RNG(), false)
_model::DynamicPPL.Model{var"#1#2",(:data, :prob1, :priors),(),(),Tuple{Array{Float64,2},ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,Array{Float64,1},ODEFunction{true,ModelingToolkit.var"#f#198"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##MTKArg#267"), Symbol("##MTKArg#268"), Symbol("##MTKArg#269")),ModelingToolkit.var"#_RGF_ModTag",(0x675c4d77, 0x05b2dfd8, 0x3d03ded5, 0x73dfb8d9, 0x864d24da)},RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##MTIIPVar#271"), Symbol("##MTKArg#267"), Symbol("##MTKArg#268"), Symbol("##MTKArg#269")),ModelingToolkit.var"#_RGF_ModTag",(0xda0ef279, 0xca85e7cf, 0xcf7fc331, 0x44a7018d, 0x67545bf7)}},LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Array{Symbol,1},Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem},Array{Distribution{Univariate,Continuous},1}},Tuple{}}
_varinfo::DynamicPPL.VarInfo{NamedTuple{(:ฯ, :p),Tuple{DynamicPPL.Metadata{Dict{DynamicPPL.VarName{:ฯ,Tuple{}},Int64},Array{InverseGamma{Float64},1},Array{DynamicPPL.VarName{:ฯ,Tuple{}},1},Array{Float64,1},Array{Set{DynamicPPL.Selector},1}},DynamicPPL.Metadata{Dict{DynamicPPL.VarName{:p,Tuple{}},Int64},Array{Product{Continuous,Distribution{Univariate,Continuous},Array{Distribution{Univariate,Continuous},1}},1},Array{DynamicPPL.VarName{:p,Tuple{}},1},Array{Float64,1},Array{Set{DynamicPPL.Selector},1}}}},Float64}
_sampler::Core.Compiler.Const(DynamicPPL.SampleFromPrior(), false)
_context::Core.Compiler.Const(DynamicPPL.DefaultContext(), false)
data::Array{Float64,2}
prob1::ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,Array{Float64,1},ODEFunction{true,ModelingToolkit.var"#f#198"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##MTKArg#267"), Symbol("##MTKArg#268"), Symbol("##MTKArg#269")),ModelingToolkit.var"#_RGF_ModTag",(0x675c4d77, 0x05b2dfd8, 0x3d03ded5, 0x73dfb8d9, 0x864d24da)},RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##MTIIPVar#271"), Symbol("##MTKArg#267"), Symbol("##MTKArg#268"), Symbol("##MTKArg#269")),ModelingToolkit.var"#_RGF_ModTag",(0xda0ef279, 0xca85e7cf, 0xcf7fc331, 0x44a7018d, 0x67545bf7)}},LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Array{Symbol,1},Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem}
priors::Array{Distribution{Univariate,Continuous},1}
tmpright#275::InverseGamma{Float64}
vn#277::DynamicPPL.VarName{:ฯ,Tuple{}}
inds#278::Tuple{}
ฯ::Float64
tmpright#279::Product{Continuous,Distribution{Univariate,Continuous},Array{Distribution{Univariate,Continuous},1}}
vn#281::DynamicPPL.VarName{:p,Tuple{}}
inds#282::Tuple{}
- p::Any
- prob::ODEProblem{_A,_B,true,_C,_D,_E,_F} where _F where _E where _D where _C where _B where _A
predicted::Array{Array{Float64,1},1}
! @_20::Union{Nothing, Tuple{Int64,Int64}}
@_21::TypeVar
@_22::TypeVar
i::Int64
tmpright#283::MvNormal{Float64,PDMats.ScalMat{Float64},Array{Float64,1}}
vn#285::DynamicPPL.VarName{:data,Tuple{Tuple{Colon,Int64}}}
inds#286::Tuple{Tuple{Colon,Int64}}
isassumption#287::Bool
@_28::TypeVar
vn#288::DynamicPPL.VarName{:data,Tuple{Tuple{Colon,Int64}}}
@_30::Bool
@_31::Bool
Body::Nothing
1 โโ Core.NewvarNode(:(vn#277))
โ Core.NewvarNode(:(inds#278))
โ Core.NewvarNode(:(ฯ))
โ Core.NewvarNode(:(tmpright#279))
โ Core.NewvarNode(:(vn#281))
โ Core.NewvarNode(:(inds#282))
โ Core.NewvarNode(:(p))
โ Core.NewvarNode(:(prob))
โ Core.NewvarNode(:(predicted))
โ Core.NewvarNode(:(@_20))
โ (tmpright#275 = Main.InverseGamma(2, 3))
โ %12 = tmpright#275::Core.Compiler.Const(InverseGamma{Float64}(
invd: Gamma{Float64}(ฮฑ=2.0, ฮธ=0.3333333333333333)
ฮธ: 3.0
)
, false)::Core.Compiler.Const(InverseGamma{Float64}(
invd: Gamma{Float64}(ฮฑ=2.0, ฮธ=0.3333333333333333)
ฮธ: 3.0
)
, false)
โ (@_21 = Core.TypeVar(Symbol("#s196"), Distribution))
โ %14 = @_21::Core.Compiler.PartialTypeVar(var"#s196"<:Distribution, true, true)::Core.Compiler.PartialTypeVar(var"#s196"<:Distribution, true, true)
โ %15 = Core.apply_type(Main.AbstractVector, @_21::Core.Compiler.PartialTypeVar(var"#s196"<:Distribution, true, true))::Type{AbstractArray{var"#s196"<:Distribution,1}}
โ %16 = Core.UnionAll(%14, %15)::Type{AbstractArray{var"#s196",1} where var"#s196"<:Distribution}
โ %17 = Core.apply_type(Main.Union, Distribution, %16)::Type{Union{AbstractArray{var"#s196",1} where var"#s196"<:Distribution, Distribution}}
โ %18 = (%12 isa %17)::Core.Compiler.Const(true, false)
โ %18
โโโโ goto #3
2 โโ Core.Compiler.Const(:(Main.ArgumentError("Right-hand side of a ~ must be subtype of Distribution or a vector of Distributions.")), false)
โโโโ Core.Compiler.Const(:(Main.throw(%21)), false)
3 โโ (vn#277 = ฯ)
โ (inds#278 = ())
โ (ฯ = (DynamicPPL.tilde_assume)(_rng, _context, _sampler, tmpright#275::Core.Compiler.Const(InverseGamma{Float64}(
invd: Gamma{Float64}(ฮฑ=2.0, ฮธ=0.3333333333333333)
ฮธ: 3.0
)
, false), vn#277, inds#278, _varinfo))
โ (tmpright#279 = Main.arraydist(priors))
โ %27 = tmpright#279::Product{Continuous,Distribution{Univariate,Continuous},Array{Distribution{Univariate,Continuous},1}}
โ (@_22 = Core.TypeVar(Symbol("#s195"), Distribution))
โ %29 = @_22::Core.Compiler.PartialTypeVar(var"#s195"<:Distribution, true, true)::Core.Compiler.PartialTypeVar(var"#s195"<:Distribution, true, true)
โ %30 = Core.apply_type(Main.AbstractVector, @_22::Core.Compiler.PartialTypeVar(var"#s195"<:Distribution, true, true))::Type{AbstractArray{var"#s195"<:Distribution,1}}
โ %31 = Core.UnionAll(%29, %30)::Type{AbstractArray{var"#s196",1} where var"#s196"<:Distribution}
โ %32 = Core.apply_type(Main.Union, Distribution, %31)::Type{Union{AbstractArray{var"#s196",1} where var"#s196"<:Distribution, Distribution}}
โ %33 = (%27 isa %32)::Core.Compiler.Const(true, false)
โ %33
โโโโ goto #5
4 โโ Core.Compiler.Const(:(Main.ArgumentError("Right-hand side of a ~ must be subtype of Distribution or a vector of Distributions.")), false)
โโโโ Core.Compiler.Const(:(Main.throw(%36)), false)
5 โโ (vn#281 = p)
โ (inds#282 = ())
โ (p = (DynamicPPL.tilde_assume)(_rng, _context, _sampler, tmpright#279, vn#281, inds#282, _varinfo))
โ %41 = (:p,)::Core.Compiler.Const((:p,), false)
โ %42 = Core.apply_type(Core.NamedTuple, %41)::Core.Compiler.Const(NamedTuple{(:p,),T} where T<:Tuple, false)
โ %43 = Core.tuple(p)::Tuple{Any}
โ %44 = (%42)(%43)::NamedTuple{(:p,),_A} where _A<:Tuple
โ %45 = Core.kwfunc(Main.remake)::Core.Compiler.Const(DiffEqBase.var"#remake##kw"(), false)
โ %46 = (%45)(%44, Main.remake, prob1)::ODEProblem{_A,_B,true,_C,_D,_E,_F} where _F where _E where _D where _C where _B where _A
โ (prob = Core.typeassert(%46, Main.ODEProblem))
โ %48 = Main.Tsit5()::Core.Compiler.Const(Tsit5(), false)
โ %49 = (:saveat,)::Core.Compiler.Const((:saveat,), false)
โ %50 = Core.apply_type(Core.NamedTuple, %49)::Core.Compiler.Const(NamedTuple{(:saveat,),T} where T<:Tuple, false)
โ %51 = Core.tuple(0.1)::Core.Compiler.Const((0.1,), false)
โ %52 = (%50)(%51)::Core.Compiler.Const((saveat = 0.1,), false)
โ %53 = Core.kwfunc(Main.solve)::Core.Compiler.Const(DiffEqBase.var"#solve##kw"(), false)
โ %54 = prob::ODEProblem{_A,_B,true,_C,_D,_E,_F} where _F where _E where _D where _C where _B where _A
โ %55 = (%53)(%52, Main.solve, %54, %48)::Any
โ %56 = Base.getproperty(%55, :u)::Any
โ %57 = Core.apply_type(Main.Array, Main.Float64, 1)::Core.Compiler.Const(Array{Float64,1}, false)
โ %58 = Core.apply_type(Main.Array, %57, 1)::Core.Compiler.Const(Array{Array{Float64,1},1}, false)
โ (predicted = Core.typeassert(%56, %58))
โ %60 = Main.length(predicted)::Int64
โ %61 = (1:%60)::Core.Compiler.PartialStruct(UnitRange{Int64}, Any[Core.Compiler.Const(1, false), Int64])
โ (@_20 = Base.iterate(%61))
โ %63 = (@_20 === nothing)::Bool
โ %64 = Base.not_int(%63)::Bool
โโโโ goto #17 if not %64
6 โโ Core.NewvarNode(:(vn#285))
โ Core.NewvarNode(:(inds#286))
โ Core.NewvarNode(:(isassumption#287))
โ %69 = @_20::Tuple{Int64,Int64}::Tuple{Int64,Int64}
โ (i = Core.getfield(%69, 1))
โ %71 = Core.getfield(%69, 2)::Int64
โ %72 = Base.getindex(predicted, i)::Array{Float64,1}
โ (tmpright#283 = Main.MvNormal(%72, ฯ))
โ %74 = tmpright#283::MvNormal{Float64,PDMats.ScalMat{Float64},Array{Float64,1}}
โ (@_28 = Core.TypeVar(Symbol("#s193"), Distribution))
โ %76 = @_28::TypeVar
โ %77 = Core.apply_type(Main.AbstractVector, @_28)::Type{AbstractArray{_A,1}} where _A
โ %78 = Core.UnionAll(%76, %77)::Any
โ %79 = Core.apply_type(Main.Union, Distribution, %78)::Type
โ %80 = (%74 isa %79)::Bool
โโโโ goto #8 if not %80
7 โโ goto #9
8 โโ %83 = Main.ArgumentError("Right-hand side of a ~ must be subtype of Distribution or a vector of Distributions.")::ArgumentError
โโโโ Main.throw(%83)
9 โโ %85 = Core.tuple(Main.:(:), i)::Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])
โ %86 = Core.tuple(%85)::Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])
โ (vn#285 = (DynamicPPL.VarName)(:data, %86))
โ %88 = Core.tuple(Main.:(:), i)::Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])
โ (inds#286 = Core.tuple(%88))
โ %90 = Core.tuple(Main.:(:), i)::Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])
โ %91 = Core.tuple(%90)::Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])
โ (vn#288 = (DynamicPPL.VarName)(:data, %91))
โ %93 = (DynamicPPL.inargnames)(vn#288::Core.Compiler.PartialStruct(DynamicPPL.VarName{:data,Tuple{Tuple{Colon,Int64}}}, Any[Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])]), _model)::Core.Compiler.Const(true, false)
โ %94 = !%93::Core.Compiler.Const(false, true)
โโโโ goto #11 if not %94
10 โ Core.Compiler.Const(:(@_30 = %94), false)
โโโโ Core.Compiler.Const(:(goto %99), false)
11 โ (@_30 = (DynamicPPL.inmissings)(vn#288::Core.Compiler.PartialStruct(DynamicPPL.VarName{:data,Tuple{Tuple{Colon,Int64}}}, Any[Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])]), _model))
โโโโ goto #13 if not @_30::Core.Compiler.Const(false, false)
12 โ Core.Compiler.Const(:(@_31 = true), false)
โโโโ Core.Compiler.Const(:(goto %104), false)
13 โ %102 = Base.getindex(data, Main.:(:), i)::Array{Float64,1}
โ (@_31 = %102 === Main.missing)
โ (isassumption#287 = @_31::Core.Compiler.Const(false, false))
โโโโ goto #15 if not isassumption#287::Core.Compiler.Const(false, false)
14 โ Core.Compiler.Const(:((DynamicPPL.tilde_assume)(_rng, _context, _sampler, tmpright#283, vn#285, inds#286, _varinfo)), false)
โ Core.Compiler.Const(:(Base.setindex!(data, %106, Main.:(:), i)), false)
โโโโ Core.Compiler.Const(:(goto %114), false)
15 โ %109 = tmpright#283::MvNormal{Float64,PDMats.ScalMat{Float64},Array{Float64,1}}
โ %110 = Base.getindex(data, Main.:(:), i)::Array{Float64,1}
โ %111 = vn#285::Core.Compiler.PartialStruct(DynamicPPL.VarName{:data,Tuple{Tuple{Colon,Int64}}}, Any[Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])])::Core.Compiler.PartialStruct(DynamicPPL.VarName{:data,Tuple{Tuple{Colon,Int64}}}, Any[Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])])
โ %112 = inds#286::Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])::Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])
โ (DynamicPPL.tilde_observe)(_context, _sampler, %109, %110, %111, %112, _varinfo)
โ (@_20 = Base.iterate(%61, %71))
โ %115 = (@_20 === nothing)::Bool
โ %116 = Base.not_int(%115)::Bool
โโโโ goto #17 if not %116
16 โ goto #6
17 โ return
( I did my best trying to color the text as @code_warntype would, with the caveat that if a line is colored, then @code_warntype would have colored only the type after the :: . I didn't color all lines not to ruin indentation, since I'm using this trick to color the text. I just colored the first ones )
So how may i fix the type inference?
I know that I could be using a for loop instead of the arraydist as seen here, but the model we are developing is a bit complicated ( ~ 60 parameters), so it may benefit from switching to TrackerAD or Zygote backend, which doesn't like loops.
Side question: in case we had to choose between
TrackerAD or ZygoteTrackerAD or ZygoteReverseDiffWhich would you suggest?
Thank you very much for your attention.
I'd benchmark all approaches and then choose the fastest ๐ More seriously, it's really problem and model dependent.
Maybe another alternative would be to break up the priors (and p) into multiple groups with thr same type of prior since the problems arise from priors not being concretely typed.
Alternatively, maybe you can add a type assertion on p such as p::Vector{Float64} (I guess Turing might not support this) or with an additional variable _p::Vector{Float64} = p that you use then in the ODE solver. BTW if I'm not mistaken, your type annotations such as ::Array... in the function body are basically equivalent to convert calls but for actual type assertions (that error if not satisfied and are guarantees to the compiler) you have to annotate the assigned variable, i.e., something like x::Vector{Float64} = .... The annotation ::ODEProblem is probably not helpful since ODEProblem is not a concrete type (generally, the output of remake should be inferrable if the inputs such as pare inferred). However, IIRC you can just call solve(prob1, Tsit5(); p=p, saveat=0.1) (or with p=_p) without constructing prob explicitly. The Bayesian DiffEq tutorial also contains examples of how to set the sensitivity mode and AD system of the ODE solver (which is independent from the Turing settings).
Hello @devmotion ,
Thanks for your suggestions. I tried to implement them.
Now the model looks like:
# define turing model
@model function fitlv2(data::Array{Float64,2}, prob1, priors::Array{Distribution{Univariate,Continuous},1})
ฯ ~ InverseGamma(2, 3)
p ~ arraydist(priors)
_p::Vector{Float64} = p
predicted::Vector{Vector{Float64}} = solve(prob1,Tsit5(); p = _p, saveat=0.1 ).u
for i= 1:length(predicted)
data[:,i] ~ MvNormal(predicted[i], ฯ)
end
end
And if I @code_warntype it,I get:
model2 = fitlv2(odedata, fast_prob1, priors)
# inspect type inference
@code_warntype model2.f(
Random.GLOBAL_RNG,
model2,
Turing.VarInfo(model2),
Turing.SampleFromPrior(),
Turing.DefaultContext(),
model2.args...,
)
Variables
#self#::Core.Compiler.Const(var"#29#30"(), false)
_rng::Core.Compiler.Const(Random._GLOBAL_RNG(), false)
_model::DynamicPPL.Model{var"#29#30",(:data, :prob1, :priors),(),(),Tuple{Array{Float64,2},ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,Array{Float64,1},ODEFunction{true,ModelingToolkit.var"#f#198"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##MTKArg#267"), Symbol("##MTKArg#268"), Symbol("##MTKArg#269")),ModelingToolkit.var"#_RGF_ModTag",(0x675c4d77, 0x05b2dfd8, 0x3d03ded5, 0x73dfb8d9, 0x864d24da)},RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##MTIIPVar#271"), Symbol("##MTKArg#267"), Symbol("##MTKArg#268"), Symbol("##MTKArg#269")),ModelingToolkit.var"#_RGF_ModTag",(0xda0ef279, 0xca85e7cf, 0xcf7fc331, 0x44a7018d, 0x67545bf7)}},LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Array{Symbol,1},Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem},Array{Distribution{Univariate,Continuous},1}},Tuple{}}
_varinfo::DynamicPPL.VarInfo{NamedTuple{(:ฯ, :p),Tuple{DynamicPPL.Metadata{Dict{DynamicPPL.VarName{:ฯ,Tuple{}},Int64},Array{InverseGamma{Float64},1},Array{DynamicPPL.VarName{:ฯ,Tuple{}},1},Array{Float64,1},Array{Set{DynamicPPL.Selector},1}},DynamicPPL.Metadata{Dict{DynamicPPL.VarName{:p,Tuple{}},Int64},Array{Product{Continuous,Distribution{Univariate,Continuous},Array{Distribution{Univariate,Continuous},1}},1},Array{DynamicPPL.VarName{:p,Tuple{}},1},Array{Float64,1},Array{Set{DynamicPPL.Selector},1}}}},Float64}
_sampler::Core.Compiler.Const(DynamicPPL.SampleFromPrior(), false)
_context::Core.Compiler.Const(DynamicPPL.DefaultContext(), false)
data::Array{Float64,2}
prob1::ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,Array{Float64,1},ODEFunction{true,ModelingToolkit.var"#f#198"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##MTKArg#267"), Symbol("##MTKArg#268"), Symbol("##MTKArg#269")),ModelingToolkit.var"#_RGF_ModTag",(0x675c4d77, 0x05b2dfd8, 0x3d03ded5, 0x73dfb8d9, 0x864d24da)},RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##MTIIPVar#271"), Symbol("##MTKArg#267"), Symbol("##MTKArg#268"), Symbol("##MTKArg#269")),ModelingToolkit.var"#_RGF_ModTag",(0xda0ef279, 0xca85e7cf, 0xcf7fc331, 0x44a7018d, 0x67545bf7)}},LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Array{Symbol,1},Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem}
priors::Array{Distribution{Univariate,Continuous},1}
tmpright#485::InverseGamma{Float64}
vn#487::DynamicPPL.VarName{:ฯ,Tuple{}}
inds#488::Tuple{}
ฯ::Float64
tmpright#489::Product{Continuous,Distribution{Univariate,Continuous},Array{Distribution{Univariate,Continuous},1}}
vn#491::DynamicPPL.VarName{:p,Tuple{}}
inds#492::Tuple{}
- p::Any
_p::Array{Float64,1}
predicted::Array{Array{Float64,1},1}
! @_20::Union{Nothing, Tuple{Int64,Int64}}
@_21::TypeVar
@_22::TypeVar
i::Int64
tmpright#493::MvNormal{Float64,PDMats.ScalMat{Float64},Array{Float64,1}}
vn#495::DynamicPPL.VarName{:data,Tuple{Tuple{Colon,Int64}}}
inds#496::Tuple{Tuple{Colon,Int64}}
isassumption#497::Bool
@_28::TypeVar
vn#498::DynamicPPL.VarName{:data,Tuple{Tuple{Colon,Int64}}}
@_30::Bool
@_31::Bool
Body::Nothing
1 โโ Core.NewvarNode(:(vn#487))
โ Core.NewvarNode(:(inds#488))
โ Core.NewvarNode(:(ฯ))
โ Core.NewvarNode(:(tmpright#489))
โ Core.NewvarNode(:(vn#491))
โ Core.NewvarNode(:(inds#492))
โ Core.NewvarNode(:(p))
โ Core.NewvarNode(:(_p))
โ Core.NewvarNode(:(predicted))
โ Core.NewvarNode(:(@_20))
โ (tmpright#485 = Main.InverseGamma(2, 3))
โ %12 = tmpright#485::Core.Compiler.Const(InverseGamma{Float64}(
invd: Gamma{Float64}(ฮฑ=2.0, ฮธ=0.3333333333333333)
ฮธ: 3.0
)
, false)::Core.Compiler.Const(InverseGamma{Float64}(
invd: Gamma{Float64}(ฮฑ=2.0, ฮธ=0.3333333333333333)
ฮธ: 3.0
)
, false)
โ (@_21 = Core.TypeVar(Symbol("#s196"), Distribution))
โ %14 = @_21::Core.Compiler.PartialTypeVar(var"#s196"<:Distribution, true, true)::Core.Compiler.PartialTypeVar(var"#s196"<:Distribution, true, true)
-โ %15 = Core.apply_type(Main.AbstractVector, @_21::Core.Compiler.PartialTypeVar(var"#s196"<:Distribution, true, true))::Type{AbstractArray{var"#s196"<:Distribution,1}}
โ %16 = Core.UnionAll(%14, %15)::Type{AbstractArray{var"#s196",1} where var"#s196"<:Distribution}
โ %17 = Core.apply_type(Main.Union, Distribution, %16)::Type{Union{AbstractArray{var"#s196",1} where var"#s196"<:Distribution, Distribution}}
โ %18 = (%12 isa %17)::Core.Compiler.Const(true, false)
โ %18
โโโโ goto #3
2 โโ Core.Compiler.Const(:(Main.ArgumentError("Right-hand side of a ~ must be subtype of Distribution or a vector of Distributions.")), false)
โโโโ Core.Compiler.Const(:(Main.throw(%21)), false)
3 โโ (vn#487 = ฯ)
โ (inds#488 = ())
โ (ฯ = (DynamicPPL.tilde_assume)(_rng, _context, _sampler, tmpright#485::Core.Compiler.Const(InverseGamma{Float64}(
invd: Gamma{Float64}(ฮฑ=2.0, ฮธ=0.3333333333333333)
ฮธ: 3.0
)
, false), vn#487, inds#488, _varinfo))
โ (tmpright#489 = Main.arraydist(priors))
โ %27 = tmpright#489::Product{Continuous,Distribution{Univariate,Continuous},Array{Distribution{Univariate,Continuous},1}}
โ (@_22 = Core.TypeVar(Symbol("#s195"), Distribution))
โ %29 = @_22::Core.Compiler.PartialTypeVar(var"#s195"<:Distribution, true, true)::Core.Compiler.PartialTypeVar(var"#s195"<:Distribution, true, true)
-โ %30 = Core.apply_type(Main.AbstractVector, @_22::Core.Compiler.PartialTypeVar(var"#s195"<:Distribution, true, true))::Type{AbstractArray{var"#s195"<:Distribution,1}}
โ %31 = Core.UnionAll(%29, %30)::Type{AbstractArray{var"#s196",1} where var"#s196"<:Distribution}
โ %32 = Core.apply_type(Main.Union, Distribution, %31)::Type{Union{AbstractArray{var"#s196",1} where var"#s196"<:Distribution, Distribution}}
โ %33 = (%27 isa %32)::Core.Compiler.Const(true, false)
โ %33
โโโโ goto #5
4 โโ Core.Compiler.Const(:(Main.ArgumentError("Right-hand side of a ~ must be subtype of Distribution or a vector of Distributions.")), false)
โโโโ Core.Compiler.Const(:(Main.throw(%36)), false)
5 โโ (vn#491 = p)
โ (inds#492 = ())
โ (p = (DynamicPPL.tilde_assume)(_rng, _context, _sampler, tmpright#489, vn#491, inds#492, _varinfo))
-โ %41 = p::Any
โ %42 = Core.apply_type(Main.Vector, Main.Float64)::Core.Compiler.Const(Array{Float64,1}, false)
-โ %43 = Base.convert(%42, %41)::Any
โ (_p = Core.typeassert(%43, %42))
โ %45 = Main.Tsit5()::Core.Compiler.Const(Tsit5(), false)
โ %46 = (:p, :saveat)::Core.Compiler.Const((:p, :saveat), false)
โ %47 = Core.apply_type(Core.NamedTuple, %46)::Core.Compiler.Const(NamedTuple{(:p, :saveat),T} where T<:Tuple, false)
โ %48 = Core.tuple(_p, 0.1)::Core.Compiler.PartialStruct(Tuple{Array{Float64,1},Float64}, Any[Array{Float64,1}, Core.Compiler.Const(0.1, false)])
โ %49 = (%47)(%48)::Core.Compiler.PartialStruct(NamedTuple{(:p, :saveat),Tuple{Array{Float64,1},Float64}}, Any[Array{Float64,1}, Core.Compiler.Const(0.1, false)])
โ %50 = Core.kwfunc(Main.solve)::Core.Compiler.Const(DiffEqBase.var"#solve##kw"(), false)
โ %51 = (%50)(%49, Main.solve, prob1, %45)::ODESolution{Float64,2,Array{Array{Float64,1},1},Nothing,Nothing,Array{Float64,1},Array{Array{Array{Float64,1},1},1},ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,Array{Float64,1},ODEFunction{true,ModelingToolkit.var"#f#198"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##MTKArg#267"), Symbol("##MTKArg#268"), Symbol("##MTKArg#269")),ModelingToolkit.var"#_RGF_ModTag",(0x675c4d77, 0x05b2dfd8, 0x3d03ded5, 0x73dfb8d9, 0x864d24da)},RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##MTIIPVar#271"), Symbol("##MTKArg#267"), Symbol("##MTKArg#268"), Symbol("##MTKArg#269")),ModelingToolkit.var"#_RGF_ModTag",(0xda0ef279, 0xca85e7cf, 0xcf7fc331, 0x44a7018d, 0x67545bf7)}},LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Array{Symbol,1},Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem},Tsit5,OrdinaryDiffEq.InterpolationData{ODEFunction{true,ModelingToolkit.var"#f#198"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##MTKArg#267"), Symbol("##MTKArg#268"), Symbol("##MTKArg#269")),ModelingToolkit.var"#_RGF_ModTag",(0x675c4d77, 0x05b2dfd8, 0x3d03ded5, 0x73dfb8d9, 0x864d24da)},RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##MTIIPVar#271"), Symbol("##MTKArg#267"), Symbol("##MTKArg#268"), Symbol("##MTKArg#269")),ModelingToolkit.var"#_RGF_ModTag",(0xda0ef279, 0xca85e7cf, 0xcf7fc331, 0x44a7018d, 0x67545bf7)}},LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Array{Symbol,1},Nothing},Array{Array{Float64,1},1},Array{Float64,1},Array{Array{Array{Float64,1},1},1},OrdinaryDiffEq.Tsit5Cache{Array{Float64,1},Array{Float64,1},Array{Float64,1},OrdinaryDiffEq.Tsit5ConstantCache{Float64,Float64}}},DiffEqBase.DEStats}
โ %52 = Base.getproperty(%51, :u)::Array{Array{Float64,1},1}
โ %53 = Core.apply_type(Main.Array, Main.Float64, 1)::Core.Compiler.Const(Array{Float64,1}, false)
โ %54 = Core.apply_type(Main.Array, %53, 1)::Core.Compiler.Const(Array{Array{Float64,1},1}, false)
โ %55 = Base.convert(%54, %52)::Array{Array{Float64,1},1}
โ (predicted = Core.typeassert(%55, %54))
โ %57 = Main.length(predicted)::Int64
โ %58 = (1:%57)::Core.Compiler.PartialStruct(UnitRange{Int64}, Any[Core.Compiler.Const(1, false), Int64])
โ (@_20 = Base.iterate(%58))
โ %60 = (@_20 === nothing)::Bool
โ %61 = Base.not_int(%60)::Bool
โโโโ goto #17 if not %61
6 โโ Core.NewvarNode(:(vn#495))
โ Core.NewvarNode(:(inds#496))
โ Core.NewvarNode(:(isassumption#497))
โ %66 = @_20::Tuple{Int64,Int64}::Tuple{Int64,Int64}
โ (i = Core.getfield(%66, 1))
โ %68 = Core.getfield(%66, 2)::Int64
โ %69 = Base.getindex(predicted, i)::Array{Float64,1}
โ (tmpright#493 = Main.MvNormal(%69, ฯ))
โ %71 = tmpright#493::MvNormal{Float64,PDMats.ScalMat{Float64},Array{Float64,1}}
โ (@_28 = Core.TypeVar(Symbol("#s193"), Distribution))
โ %73 = @_28::TypeVar
-โ %74 = Core.apply_type(Main.AbstractVector, @_28)::Type{AbstractArray{_A,1}} where _A
-โ %75 = Core.UnionAll(%73, %74)::Any
-โ %76 = Core.apply_type(Main.Union, Distribution, %75)::Type
โ %77 = (%71 isa %76)::Bool
โโโโ goto #8 if not %77
7 โโ goto #9
8 โโ %80 = Main.ArgumentError("Right-hand side of a ~ must be subtype of Distribution or a vector of Distributions.")::ArgumentError
โโโโ Main.throw(%80)
9 โโ %82 = Core.tuple(Main.:(:), i)::Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])
โ %83 = Core.tuple(%82)::Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])
โ (vn#495 = (DynamicPPL.VarName)(:data, %83))
โ %85 = Core.tuple(Main.:(:), i)::Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])
โ (inds#496 = Core.tuple(%85))
โ %87 = Core.tuple(Main.:(:), i)::Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])
โ %88 = Core.tuple(%87)::Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])
โ (vn#498 = (DynamicPPL.VarName)(:data, %88))
โ %90 = (DynamicPPL.inargnames)(vn#498::Core.Compiler.PartialStruct(DynamicPPL.VarName{:data,Tuple{Tuple{Colon,Int64}}}, Any[Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])]), _model)::Core.Compiler.Const(true, false)
โ %91 = !%90::Core.Compiler.Const(false, true)
โโโโ goto #11 if not %91
10 โ Core.Compiler.Const(:(@_30 = %91), false)
โโโโ Core.Compiler.Const(:(goto %96), false)
11 โ (@_30 = (DynamicPPL.inmissings)(vn#498::Core.Compiler.PartialStruct(DynamicPPL.VarName{:data,Tuple{Tuple{Colon,Int64}}}, Any[Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])]), _model))
โโโโ goto #13 if not @_30::Core.Compiler.Const(false, false)
12 โ Core.Compiler.Const(:(@_31 = true), false)
โโโโ Core.Compiler.Const(:(goto %101), false)
13 โ %99 = Base.getindex(data, Main.:(:), i)::Array{Float64,1}
โ (@_31 = %99 === Main.missing)
โ (isassumption#497 = @_31::Core.Compiler.Const(false, false))
โโโโ goto #15 if not isassumption#497::Core.Compiler.Const(false, false)
14 โ Core.Compiler.Const(:((DynamicPPL.tilde_assume)(_rng, _context, _sampler, tmpright#493, vn#495, inds#496, _varinfo)), false)
โ Core.Compiler.Const(:(Base.setindex!(data, %103, Main.:(:), i)), false)
โโโโ Core.Compiler.Const(:(goto %111), false)
15 โ %106 = tmpright#493::MvNormal{Float64,PDMats.ScalMat{Float64},Array{Float64,1}}
โ %107 = Base.getindex(data, Main.:(:), i)::Array{Float64,1}
โ %108 = vn#495::Core.Compiler.PartialStruct(DynamicPPL.VarName{:data,Tuple{Tuple{Colon,Int64}}}, Any[Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])])::Core.Compiler.PartialStruct(DynamicPPL.VarName{:data,Tuple{Tuple{Colon,Int64}}}, Any[Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])])
โ %109 = inds#496::Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])::Core.Compiler.PartialStruct(Tuple{Tuple{Colon,Int64}}, Any[Core.Compiler.PartialStruct(Tuple{Colon,Int64}, Any[Core.Compiler.Const(Colon(), false), Int64])])
โ (DynamicPPL.tilde_observe)(_context, _sampler, %106, %107, %108, %109, _varinfo)
โ (@_20 = Base.iterate(%58, %68))
โ %112 = (@_20 === nothing)::Bool
โ %113 = Base.not_int(%112)::Bool
โโโโ goto #17 if not %113
16 โ goto #6
17 โ return
I checked that i get the same result even if i use a concrete type for the priors argument ( therefore modifying the priors array to be , for example, an array of truncated normals).
Do you think it is ok now?
Most helpful comment
Hello @devmotion ,
Thanks for your suggestions. I tried to implement them.
Now the model looks like:
And if I @code_warntype it,I get:
I checked that i get the same result even if i use a concrete type for the
priorsargument ( therefore modifying the priors array to be , for example, an array of truncated normals).Do you think it is ok now?