# Sample \`arraydist\` of \`filldist\`s in Turing

**URL:** <https://discourse.julialang.org/t/sample-arraydist-of-filldist-s-in-turing/90225>\
**Category:** Probabilistic Programming\
**Tags:** turing\
**Created:** [November 14, 2022, 8:35am UTC](https://discourse.julialang.org/t/sample-arraydist-of-filldist-s-in-turing/90225 "2022-11-14T08:35:09Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [November 14, 2022, 8:35am UTC](https://discourse.julialang.org/t/sample-arraydist-of-filldist-s-in-turing/90225/1 "2022-11-14T08:35:09Z")

</div>

Is it possible to sample many `filldists`s using `arraydist` in `Turing.jl`?

For example, say I have data of the following structure:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/0/906f2c05e015eec11fe921767a7324f102f4eaba.png)  
and every key-value comes from an Exponential distribution.  
I know of a prior for each key-value vector.

For now I sample this model as following:

```julia
@model function arrfilldist(data, ks, nlendat=missing)
	if data === missing # for prior analysis
		data = [Vector{Int}(undef, x) for x in nlendat]
	end
	μs = calculate_prior.(ks)
	σ = 500

	priors ~ arraydist([truncated(Normal(μ,σ),0,Inf) for μ in μs])
	for d in 1:length(data)
		data[d] ~ filldist(Exponential(priors[d]), 20)
	end
end

calculate_prior(k) = k*10

```

and it works fine.

**However I was wondering if I can avoid the for loop by using again an `arraydist` and if that would generally accelerate the MCMC.**  
So, I tried substituting the for loop with

```julia
data ~ arraydist([filldist(Exponential(priors[d]), 20) for d in 1:length(data)])

```

The prior analysis keeps working fine but the sampling given data throws the following error:

```julia-repl
MethodError: no method matching loglikelihood(::DistributionsAD.VectorOfMultivariate{Distributions.Continuous, Distributions.Product{Distributions.Continuous, Distributions.Exponential{Float64}, FillArrays.Fill{Distributions.Exponential{Float64}, 1, Tuple{Base.OneTo{Int64}}}}, Vector{Distributions.Product{Distributions.Continuous, Distributions.Exponential{Float64}, FillArrays.Fill{Distributions.Exponential{Float64}, 1, Tuple{Base.OneTo{Int64}}}}}}, ::Vector{Vector{Float64}})
Closest candidates are:
loglikelihood(!Matched::EllipticalSliceSampling.ESSModel, ::Any) at ~/.julia/packages/EllipticalSliceSampling/1R0Nc/src/model.jl:23
loglikelihood(!Matched::DynamicPPL.Model, ::Any) at ~/.julia/packages/DynamicPPL/zPOYL/src/simple_varinfo.jl:603
loglikelihood(::Distributions.Distribution{Distributions.ArrayLikeVariate{N}}, !Matched::AbstractArray{<:AbstractArray{<:Real, N}}) where N at ~/.julia/packages/Distributions/0Nl1l/src/common.jl:466

```

Is there another way to do this or does it even make sense performance-wise ?

> **Reproducability**
>
> Use following code to generate data:
> 
> ```julia
> using DataStructures
> reallinear(pars) = 10 .+ 50 .* pars
> function gen_data(pars, count; rng = MersenneTwister(1))
> mypars = reallinear(pars) #secret system internal operation
> (OrderedDict(par => rand(rng, Exponential(mp), count) for (par,mp) in zip(pars,mypars)),
> mypars)
> end
> data, internalpars = gen_data(5:3:20, 20)
> 
> ```
> 
> Prior analysis by doing:
> 
> ```julia
> arrfilldist_pr = arrfilldist(missing, 10:10:60, fill(20,6))
> prch = sample(arrfilldist_pr, Prior(), 10);
> 
> ```
> 
> Giving someting like:
> 
> ![image](https://global.discourse-cdn.com/julialang/original/3X/f/9/f9d2bfa379730ad987be542361993c0ebbb53d0b.png)
> 
> Sample posterior:
> 
> ```julia
> arrfilldist_pt = arrfilldist(collect(values(data)), collect(keys(data)))
> postch = sample(arrfilldist_pt, NUTS(), 100);
> 
> ```
