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?

lmiq
June 20, 2024, 11:44am
2

Sihyun_Kim:

`[]`

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

lmiq
June 20, 2024, 11:50am
3
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