Initialize nested arrays

I need to initialize a Matrix, containing Matrices, the latter containing a Vector or Matrices.

I did something like this:

sizeMat11 = 2
sizeMat12 = 3
sizeMat21 = 5
sizeMat22 = 6
sizeVec31 = 9
struct SomeStruct 
    x::Float64 
end
function SomeFunction(l::Int64 , n::Int64 ,m::Int64)::Tuple{Array{Float64,2},Array{Float64,2},Vector{Float64}}
    a = zeros(l,l)
    b = zeros(m,m)
    c = rand(n)
return a,b,c
end

v = Array{Array{Vector{AbstractMatrix{SomeStruct}}, 2} , 2}(undef , sizeMat11 ,  sizeMat12)
for imat11 = 1:sizeMat11
   for imat12 = 1:sizeMat12
      for imat21 = 1:sizeMat21
          for imat22 = 1:sizeMat22
              a,b,c = SomeFunction(10,15,9)
              v[imat11,imat12][imat21,imat22] = [a,b,c]
           end
      end
   end
end

I get an undef error.
I consulted isbits type undef error post, but so far no success.

protip, if you don’t care about flow control like continue and break, you can write nested loops really easily with:

for i=1:I, j=1:J, k=1:K
    # blah
end

the j loop is the most tightly nested, and the i loop is the outer loop.

anyway, I’m too lazy to check if this has the dimensions you’re looking for, but you might consider this:

v = [[SomeFunction(10,15,9) for imat21=1:sizeMat21, imat22=1:sizeMat22] for imat12=1:sizeMat12, imat21=1:sizeMat21]

you can also make a 4-d array, in case that makes things easier in any way:

v = [SomeFunction(10,15,9) for imat21=1:sizeMat21, imat22=1:sizeMat22, imat12=1:sizeMat12, imat21=1:sizeMat21]

list comprehensions have the nice feature of not needing to think through entirely ahead of time the proper allocation structure.

Yeah, this won’t work. Here’s a simpler example:

julia> a = Vector{Vector{Int}}(undef, 2)
2-element Vector{Vector{Int64}}:
 #undef
 #undef

julia> a[1][1] = 3
ERROR: UndefRefError: access to undefined reference

You haven’t allocated any inner vector that you can write to, the outer vector just contains two undef references. You have to pre-allocate the innermost arrays, before you can start accessing and writing to them. Or you can write a[1] = [1,2,3], but you cannot index into an undef, only replace it with a value.

The easiest way is normally to use comprehensions, like @uniment said, then you will also get correct element types. You should definitely avoid having an AbstractMatrix eltype in there, that will harm performance.

1 Like

I would like also to point out that if the sizes of the matrices/vectors are constant, then there is no need to make them nested. You can just make higher dimensional one.

3 Likes

Thank you, it works :slight_smile:
Thanks to everyone

1 Like