Correctly initializing collection of matrices

Hello!

I am following suggestions from another post and, instead of having a 3-D array, I am refactoring my code to use a Vector of Matrix so I can use broadcasting on the matrices.

Is there a way to initialize the whole structure so I can fill its values later?

I could do this for 3D case:

S = Array{ComplexF64,3}(undef,4,4,1000)

But I can’t find a way to do it for the new code. Is it possible? Is there lack of performance if I don’t initialize it? The advantage is that I guess I could always push new matrices to the array, but that doesn’t sound as well-performing to me :frowning:

You can use a list comprehension if you know the number of matrices in your vector. For example,

x = [Array{Complex,3}(undef,4,4,1000) for _ in 1:5]

With this approach you can add values to the matrices later. As you suggested, if you do not know the size, you define an empty vector and push arrays into it as follows:

x = Vector{Array{Complex,3}}()
push!(x, rand(4, 4, 4))

With more context about your problem, we might be able to provide more specific advice.

2 Likes

For example (vector of undefed 3x3 matrices):

v = [ Matrix{ComplexF64}(undef,3,3) for _ in 1:5 ]

or (inititalized with 0+0im):

v = collect( (reshape(zeros(ComplexF64,9),3,3) for _ in 1:5) )

The first one (comprehension) is twice as fast as the second one (generator).

1 Like

Thanks for the answers!!

My inner matrices are 4x4. Does using MMatrix instead of Matrix pay off?

Sorry. I am not familiar with MMatrix. What is that?

For StaticArrays the performance is somehow equal and in between the non-static examples above:

julia> using StaticArrays

julia> @btime v = MVector{5}( [ MMatrix{4,4}(zeros(ComplexF64,4*4)) for _ in 1:5 ] );
  262.812 ns (12 allocations: 3.14 KiB)

julia> @btime v = MVector{5}( collect( (MMatrix{4,4}(zeros(ComplexF64,4*4)) for _ in 1:5) ) );
  278.275 ns (12 allocations: 3.14 KiB)

It may pay off, depending on your complete code.

1 Like