For example, following the previous tips of the other thread:
With a parametric struct:
julia> struct ModelA{T}
σ::Vector{Float64}
ϵ::Vector{Float64}
σ_Priors::Matrix{T}
ϵ_Priors::Matrix{T}
end
julia> function logPost(model)
# return 3.0
thesum = 0.0 # simplified version
for i in eachindex(model.σ)
thesum += logpdf(model.σ_Priors[i],model.σ[i])
thesum += logpdf(model.ϵ_Priors[i],model.ϵ[i])
end
return thesum
end
logPost (generic function with 2 methods)
julia> m = ModelA(rand(100), rand(100), fill(Gamma(10,0.1), 10, 10), fill(Gamma(10,0.1), 10, 10));
julia> typeof(m)
ModelA{Gamma{Float64}}
julia> @btime logPost($m)
3.100 μs (0 allocations: 0 bytes)
-675.8052525561492
With the abstract field, instead:
julia> struct ModelB
σ::Vector{Float64}
ϵ::Vector{Float64}
σ_Priors::Matrix{Distribution}
ϵ_Priors::Matrix{Distribution}
end
julia> mB = ModelB(m.σ, m.ϵ, m.σ_Priors, m.ϵ_Priors);
julia> typeof(mB)
ModelB
julia> @btime logPost($mB)
6.455 μs (600 allocations: 9.38 KiB)
-675.8052525561492
FWIW, I think this blog post might be helpful: New blog post about Julia parametric types and constructors