How can I fill an array with empty 2D arrays?

Hello,
I am going into a loop which will produce N 2D arrays. I want to store them in an array, so I want to define it beforehand. I know the syntax for filling with empty 1D arrays but I can’t figure our the 2D version. Can you help me out?
Thanks

1D version that works
mat3Dtt = fill(Float64[],1, N);

2D version I can’t get to work

mat3Dtt = fill(Array{Float64,2},1, N);
julia> mat3Dtt[1]=rand(3,3)
ERROR: MethodError: Cannot `convert` an object of type Array{Float64,2} to an object of type DataType

You can do this, but be warned that fill repeats the same element, it doesn’t make copies.

julia> x = fill(Matrix{Float64}(undef,0,0), 3);

julia> x[1] = reshape(1:6,2,3);

julia> x  # ok!
3-element Vector{Matrix{Float64}}:
 [1.0 3.0 5.0; 2.0 4.0 6.0]
 0×0 Matrix{Float64}
 0×0 Matrix{Float64}

julia> y = fill(Matrix{Float64}(undef,2,3), 3);

julia> y[1] === y[2]
true

julia> y[1] .= reshape(1:6,2,3);

julia> y
3-element Vector{Matrix{Float64}}:
 [1.0 3.0 5.0; 2.0 4.0 6.0]
 [1.0 3.0 5.0; 2.0 4.0 6.0]
 [1.0 3.0 5.0; 2.0 4.0 6.0]

But you may be better off just letting a comprehension, or map, create the output for you. Or doing z = Matrix{Float64}[]; push!(z, reshape(1:6,2,3)).

i will go with that, thank you very much!

If you’re replacing the entire array that’s fine, but if you intend to predefine and then fill them, it’s still a problem:

x = fill(Matrix{Float64}(undef,2,2), 3);

julia> x
3-element Vector{Matrix{Float64}}:
 [2.75859452845e-313 3.3951932658e-313; 2.33419537065e-313 6.94677762088306e-310]
 [2.75859452845e-313 3.3951932658e-313; 2.33419537065e-313 6.94677762088306e-310]
 [2.75859452845e-313 3.3951932658e-313; 2.33419537065e-313 6.94677762088306e-310]

julia> x[1][1,1] = 5
5

julia> x
3-element Vector{Matrix{Float64}}:
 [5.0 3.3951932658e-313; 2.33419537065e-313 6.94677762088306e-310]
 [5.0 3.3951932658e-313; 2.33419537065e-313 6.94677762088306e-310]
 [5.0 3.3951932658e-313; 2.33419537065e-313 6.94677762088306e-310]

Make sure you understand @mcabbott’s warning:

That means you will get an array consisting of the same matrix 3 times. Modifying any one of those will modify all of them because they are all the same value. This is almost certainly not what you want in any application.

Yeah, although if you’re doing that then pre-allocating the individual arrays is pointless, since they’ll be replaced regardless.

Yes, I am replacing the entire array, using it a bit like this:

julia> a=fill(Array{Float32,2}(undef,0,0),1,3);

julia> a[1]=rand(2,2); a[2]=rand(3,3);

julia> a[:]
3-element Array{Array{Float32,2},1}:
 [0.92491776 0.93883944; 0.9667731 0.9894779]
 [0.13091879 0.37846377 0.07404064; 0.71520746 0.9362733 0.41508183; 0.8309387 0.73587126 0.0631132]      
 Array{Float32}(undef,0,0)

I understand that I could just push the new one as it is generated, however I think pre-allocating makes the code more readable as you know where each array is going to go beforehand, instead of counting how many pushes there are.

I see. Then perhaps what you actually need is:

a = Array{Array{Float32, 2}, 1}(undef, 3)

which is a Vector (a 1-D Array) whose elements are themselves matrices, with space allocated to hold 3 elements.

You can write that more simply as: Vector{Matrix{Float32}}(undef, 3) if you prefer.