How To Create a 2D Array of Arrays?

Is it possible to create a 2D array of (2D) arrays in Julia? If so, how can I do it?

I scoured the internet but I did not manage to find out whether this is possible or not. I only managed to find information on creating 1D arrays of arrays. E.g.

A = Array[ [1, 0], [0, 1] ]

creates a 2-element vector whose elements are 2-element vectors of type Int.

1 Like

Yes, you can do it!

Suppose you want to create a 2×2 matrix, where each element of the matrix is a 1×1 submatrix.

> a=[1;;]
1×1 Matrix{Int64}:
 1

> b=[a for i=1:2,j=1:2]
2×2 Matrix{Matrix{Int64}}:
 [1;;]  [1;;]
 [1;;]  [1;;]
1 Like

Note that with the construction given above, all the elements of the big array will point to the same location in memory, so modifying the elements of a will modify each entry of b

2 Likes

You can use comprehensions to create arrays, for example

julia> [i+j+1 for i=1:2, j=1:2]
2×2 Matrix{Int64}:
 3  4
 4  5

which creates a matrix of integers. We can either nest these, or find other ways to create a matrix per entry, for example we could create the same with constant entries

julia> [ (i+j+1)*ones(2,2) for i=1:2, j=1:2]
2×2 Matrix{Matrix{Float64}}:
 [3.0 3.0; 3.0 3.0]  [4.0 4.0; 4.0 4.0]
 [4.0 4.0; 4.0 4.0]  [5.0 5.0; 5.0 5.0]

Then every entry is a 2x2 matrix, where each 2x2 matrix has the value from before.
You can also see in the type Matrix{Matrix{Float64}} that this is a matrix of matrices.

Creating a matrix of matrices is not a problem and can be done in many ways. In addition to other answers,

julia> Array{Matrix{Int}}(undef, 2, 3)
2×3 Matrix{Matrix{Int64}}:
 #undef  #undef  #undef
 #undef  #undef  #undef

gives you one that you can later fill in with the element matrices.

If you want to write it as a literal it becomes a little trickier since Julia’s matrix literals perform concatenation. E.g.

julia> [[1 1; 1 1] [2 2; 2 2]; [3 3; 3 3] [4 4; 4 4]]
4×4 Matrix{Int64}:
 1  1  2  2
 1  1  2  2
 3  3  4  4
 3  3  4  4

You can work around this by wrapping your small matrices in intermediate arrays

julia> [[[1 1; 1 1]] [[2 2; 2 2]]; [[3 3; 3 3]] [[4 4; 4 4]]]
2×2 Matrix{Matrix{Int64}}:
 [1 1; 1 1]  [2 2; 2 2]
 [3 3; 3 3]  [4 4; 4 4]

So not super elegant, but possible.

Note that this is actually incorrect:

julia> A = Array[ [1, 0], [0, 1] ]
2-element Vector{Array}:
 [1, 0]
 [0, 1]

It creates a vector of Array, where Array has not specification of either dimensionality or element type. To get Vector{Vector{Int}}, remove the type specification at the start:

julia> [ [1, 0], [0, 1] ]
2-element Vector{Vector{Int64}}:
 [1, 0]
 [0, 1]

What happens is that if you write SomeType[a, b, c] then you will get a Vector{SomeType}.

1 Like