# TArray push in Turing.jl

Just trying to convert the “Infinite Mixture” tutorial example to work with bivariate (as opposed to univariate) clusters: https://turing.ml/dev/tutorials/6-infinitemixturemodel/

In the tutorial, one has:

``````    # Locations of the infinitely many clusters.
μ = tzeros(Float64, 0)
``````

and then applies push! as

``````# Create a new cluster?
if z[i] > K
push!(μ, 0.0)
``````

I now have

``````   # bivariate case
μ = tzeros(Float64, (0,2))
...
# Create a new cluster?
if z[i] > K
push!(μ, zeros(2))
``````

I’m getting the following error:
MethodError: no method matching push!(::Array{Float64,2}, ::Array{Float64,1})
Closest candidates are:
push!(::Any, ::Any, !Matched::Any) at abstractarray.jl:2158
push!(::Any, ::Any, !Matched::Any, !Matched::Any…) at abstractarray.jl:2159
push!(!Matched::Array{Any,1}, ::Any) at array.jl:920

What’s the correct syntax to use here?
Thanks

Can you try something like

``````mu = TArray{TArray{Float64, 2}, 1}(undef, (0,2))

. . .
if z[i] > k
push!(mu, tzeros(2))
``````

No idea if this’ll work, can’t quite test it right now.

Doesn’t seem to work. I’m getting the following error message this time:

``````MethodError: no method matching TArray{TArray{Float64,2},1}(::UndefInitializer, ::Tuple{Int64,Int64})
Closest candidates are:
TArray{TArray{Float64,2},1}(::Any, !Matched::Integer...) where {T, N} at C:\Users\.julia\packages\Libtask\Q1ugc\src\tarray.jl:36
``````

FWIW, I’m using Turing.jl v0.12.0 and IJulia 1.21.2

Thnks

Try

``````mu = TArray{TArray{Float64, 1}, 1}(undef, 0)

if z[i] > K
push!(mu, zeros(2))
``````

Still doesn’t work.
So with:

``````μ = TArray{TArray{Float64, 1}, 1}(undef, 0)
...
if z[i] > K
push!(μ, zeros(2))
``````

I get error:

``````MethodError: Cannot `convert` an object of type Array{Float64,1} to an object of type TArray{Float64,1}
Closest candidates are:
convert(::Type{T}, !Matched::T) where T<:AbstractArray at abstractarray.jl:14
convert(::Type{T}, !Matched::Factorization) where T<:AbstractArray at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.4\LinearAlgebra\src\factorization.jl:55
convert(::Type{T}, !Matched::T) where T at essentials.jl:171
``````

If I replace push! with push!(μ, tzeros(2))
then the error message is:

``````MethodError: Cannot `convert` an object of type Float64 to an object of type TArray{Float64,1}
Closest candidates are:
convert(::Type{T}, !Matched::T) where T<:AbstractArray at abstractarray.jl:14
convert(::Type{T}, !Matched::Factorization) where T<:AbstractArray at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.4\LinearAlgebra\src\factorization.jl:55
convert(::Type{T}, !Matched::T) where T at essentials.jl:171
``````

Mistyped again. As indicated by the errors, this

``````push!(μ, zeros(2))
``````

should be

``````push!(μ, tzeros(2))
``````

Actually I tried that already, see the 2nd error message above. Still doesn’t work, mismatched type or something. Anything else to try?

Works for me:

``````julia> μ = TArray{TArray{Float64, 1}, 1}(undef, 0);

julia> push!(μ, tzeros(2));
``````

Ah yes. This seems to work actually.

So here’s the bivariate version of the model:

``````@model infiniteGMM(x) = begin

# Hyper-parameters, i.e. concentration parameter and parameters of H.
α = 1.0
μ0 = [0.0, 0.0]
σ0 = 1.0

# Define random measure, e.g. Dirichlet process.
rpm = DirichletProcess(α)

# Define the base distribution, i.e. expected value of the Dirichlet process.
H = MvNormal(μ0, σ0)

# Latent assignment.
z = tzeros(Int, length(x))

# Locations of the infinitely many clusters.
μ = TArray{TArray{Float64, 1}, 1}(undef, 0);

for i in 1:length(x)

# Number of clusters.
K = maximum(z)
nk = Vector{Int}(map(k -> sum(z .== k), 1:K))

# Draw the latent assignment.
z[i] ~ ChineseRestaurantProcess(rpm, nk)

# Create a new cluster?
if z[i] > K
push!(μ, tzeros(2))
# Draw location of new cluster.
μ[z[i]] ~ H
end

# Draw observation.
x[i] ~ MvNormal(μ[z[i]], 1.0)
end
end
``````

If I try to sample from it:

``````model = infiniteGMM(x);
chains = sample(model, MH(), 10);
``````

I get the following error:

``````MethodError: Cannot `convert` an object of type Array{Float64,1} to an object of type TArray{Float64,1}
Closest candidates are:
convert(::Type{T}, !Matched::T) where T<:AbstractArray at abstractarray.jl:14
convert(::Type{T}, !Matched::Factorization) where T<:AbstractArray at
``````

Any ideas where this is coming from? Looks like again some dimensional/indexing mismatch.
I’m using a sample bivariate mixture as follows:

``````y1 = rand(MvNormal([1., 3.], 0.5), 250);
y2 = rand(MvNormal([-1., 0.], 0.5), 400);
x = reduce(hcat, [y1, y2])
``````

Thanks