Search code examples
matrixjulialinear-algebranumerical-methods

Efficient/Cheap way to concatenate arrays in Julia?


In Julia, I would like to concatenate several arrays (and also multiply them). Within my program, I have written it as follows:

[Uᵣ Qₐ]*Uₖ
[Vᵣ Qᵦ]*Vₖ

However, this array concatenation is very expensive compared to the rest of the program I have written. Is there any way in Julia to cheaply/efficiently concatenate arrays other than what I have done (or just using hcat, vcat functions)?


Solution

  • The problem is that whenever you combine matrices all data are getting copied. This happens because matrices cannot grow in the way vectors do.

    However if you matrices are big enough you can avoid copying data by using BlockArrays. A non-materializing function combining matrices is called mortar.

    Have a look at this code:

    using BlockArrays, BenchmarkTools
    a = rand(1000,100)
    b = rand(1000,120)
    z = rand(220,7)
    

    Now let's run benchmarks:

    julia> @btime [$a $b]*$z;
      1.234 ms (4 allocations: 1.73 MiB)
    
    julia> @btime mortar(($a, $b)) * $z;
      573.100 μs (11 allocations: 55.33 KiB)
    
    julia> all([a b]*z .≈ mortar((a, b)) * z)
    true
    

    You can see that the speedup is 2x and the difference in memory allocation is 30x. However the results will vary depending on size and shape of matrices so you should run your own benchmark.