Indexing of vector of arrays

Hi!

How do I index vector vector of arrays?
Of course, I can easily index them in some cases. But I don’t know how to index them in specific cases.

For example,

A = Vector{Vector{Matrix{Int64}}}()
for i = 1:10
    push!(A, i*[[1 2 ; 3 4], [5 6; 7 8]])
end
julia> A
10-element Vector{Vector{Matrix{Int64}}}:
 [[1 2; 3 4], [5 6; 7 8]]
 [[2 4; 6 8], [10 12; 14 16]]
 [[3 6; 9 12], [15 18; 21 24]]
 [[4 8; 12 16], [20 24; 28 32]]
 ⋮
 [[8 16; 24 32], [40 48; 56 64]]
 [[9 18; 27 36], [45 54; 63 72]]
 [[10 20; 30 40], [50 60; 70 80]]

To index the following vector of matrix,

10-element Vector{Matrix{Int64}}:
 [1 2; 3 4]
 [2 4; 6 8]
 [3 6; 9 12]
 [4 8; 12 16]
 ⋮
 [8 16; 24 32]
 [9 18; 27 36]
 [10 20; 30 40]

I did try the following way.

A[:][1]
->
2-element Vector{Matrix{Int64}}:
 [1 2; 3 4]
 [5 6; 7 8]

A[:,1]
->
10-element Vector{Vector{Matrix{Int64}}}:
 [[1 2; 3 4], [5 6; 7 8]]
 [[2 4; 6 8], [10 12; 14 16]]
 [[3 6; 9 12], [15 18; 21 24]]
 [[4 8; 12 16], [20 24; 28 32]]
 ⋮
 [[8 16; 24 32], [40 48; 56 64]]
 [[9 18; 27 36], [45 54; 63 72]]
 [[10 20; 30 40], [50 60; 70 80]]


reduce(hcat,A)[1,:]
->
10-element Vector{Matrix{Int64}}:
 [1 2; 3 4]
 [2 4; 6 8]
 [3 6; 9 12]
 [4 8; 12 16]
 ⋮
 [8 16; 24 32]
 [9 18; 27 36]
 [10 20; 30 40]

reduce(hcat,A)[1,:] is successful. But if the object is vector of vector of vector of … of vector, then this way is maybe too complicate to index the object.

Is there an easy way to index such a object?

Try first.(A)

2 Likes

Or getindex.(A, 1), or [a[1] for a in A], or …

You shouldn’t try syntax at random — try to understand how the language works. This expression first does A[:], which makes a copy of the whole 1d array A, and then takes the first element [1] of this copy (which is the same as the first element of A, i.e. a 2-element array of two 2x2 matrices).

reduce(hcat,A) copies the whole array into a completely different data structure (see also the stack function). If you are doing something like this over and over, you should copy into another data structure (e.g. a 3d array) once.

An advantage of using a 3d or 4d array for something like this (as opposed to an array of 2d arrays, or an array of arrays of 2d arrays) is that then slices like A[:, : , 1] can use views (by adding the @views macro) rather than making copies of the data into new arrays.

Alternatively, if you have a 1d array of 2x2 matrices, and you know ahead of time that all your matrices will be 2x2 (e.g. you are doing 2d graphics), you should consider using StaticArrays.jl for the 2x2 matrices (e.g. a Vector{SMatrix{2,2,Int,4}}) which tends to be much more efficient than Matrix for small fixed sizes (and arrays thereof). (Or for an array of pairs of 2x2 matrices as in your example above, use an array of tuples of SMatrix.)

But without knowing what you want to do with your arrays (and whether you care about performance), it’s hard to give more advice about data structures.

6 Likes