# struct/Matrix/Vector/Assign values (structural model)

I am constructing some structural (economic) model. This requires me to write something (a simple version for illustration) like

``````using Parameters

@with_kw struct test_model @deftype Float64
β = 0.98
end

struct test{M}
A::Array{Float64, 3}
B::Matrix{Vector{Float64}}
C::M
end

test(C::test_model) = test(fill(0.0, (131, 51, 21)),
fill([], (131, 21* 51)),
C);

model = test_model()
alloc = test(model)
``````

This gives error

``````ERROR: MethodError: no method matching test(::Array{Float64, 3}, ::Matrix{Vector{Any}}, ::test_model)
``````

I think the error comes from `B` from `test`. I did the same exercise without `B` , and it doesn’t spit error. However, when I do another exercise:

``````struct test2
B1::Matrix{Vector{Float64}}
B2::Matrix{Vector{Float64}}
end

test2() = test2(fill([], (131, 21* 51)),
fill([], (131, 21* 51)))

alloc2 = test2();
``````

This doesn’t give error. What does make this difference? How can I deal with this issue?

This is a vector of elements of `Any` type. Use `Float64[]` for an empty vector that will contain `Float64` numbers (or `Vector{Float64}()`). That will solve the initialization error. The second I think does not error because it is performing an implicit conversion of the two empty matrices.

But there is a deeper problem there, which is that `fill(Float64[], (2,2))` will put the same array of floats in every position in the matrix:

``````julia> m = fill(Float64[], (2,2))
2×2 Matrix{Vector{Float64}}:
[]  []
[]  []

julia> push!(m[1], 1.0)
1-element Vector{Float64}:
1.0

julia> m
2×2 Matrix{Vector{Float64}}:
[1.0]  [1.0]
[1.0]  [1.0]
``````

To have independent vectors at each position, you need a comprehension:

``````julia> m = [ Float64[] for i in 1:2, j in 1:2 ]
2×2 Matrix{Vector{Float64}}:
[]  []
[]  []

julia> push!(m[1], 1.0)
1-element Vector{Float64}:
1.0

julia> m
2×2 Matrix{Vector{Float64}}:
[1.0]  []
[]     []
``````
1 Like

A minimal example of what you are seeing there is:

``````julia> struct test3
B1::Matrix{Vector{Float64}}
x::Float64
end

julia> test3(fill([], (2,2)), 1.0) # converts [] to Float64[] automatically
test3([Float64[] Float64[]; Float64[] Float64[]], 1.0)

julia> struct test4{T}
B1::Matrix{Vector{Float64}}
x::T
end

julia> test4(fill([], (2,2)), 1.0) # does not convert automatically
ERROR: MethodError: no method matching test4(::Matrix{Vector{Any}}, ::Float64)

julia> test4(fill(Float64[], (2,2)), 1.0)
test4{Float64}([Float64[] Float64[]; Float64[] Float64[]], 1.0)
``````

I’m not sure if I like the fact that in `test3` the automatic conversion occurs.

2 Likes