# Concatenating matrices

I have a list of matrices passed into a function. I want to vertically concatenate them into a single matrix. I used to be able to do this:

``````foo = [[1 2; 3 4; 5 6], [7 8; 9 10; 11 12]]
A = []
for m in foo
A = [A; m]
end
``````

which, ok, is inefficient, but in this particular code I only have to do it once so I don’t care. And it has the advantage of being fairly readable and compact.

As of 1.0, this throws an error:

``````ERROR: DimensionMismatch("All inputs to vcat should have the same number of columns")
``````

Actually, in the REPL the error is different:

``````ERROR: UndefVarError: A not defined
``````

The preferred idiom appears to be something along the lines of:

``````foo = [[1 2; 3 4; 5 6], [7 8; 9 10; 11 12]]
A = []
for m in foo
append!(A, m)
end
A = reshape(A, :, size(foo[1], 2))
``````

…because append! doesn’t preserve the shape of multidimensional arrays. This is ugly. And it doesn’t work if foo is empty, or if the first element in foo is one-dimensional or if the elements in foo are scalars. Which, of course, means that now I have to write lots of error checking code, making this even uglier.

In this particular case I’d gladly trade efficiency for compactness. Is there a better way to do this?

Does this accomplish what you want?

``````julia> vcat(foo...)
6×2 Array{Int64,2}:
1   2
3   4
5   6
7   8
9  10
11  12
``````

The performant idiom for this is `reduce(vcat, foo)`, which is efficient due to a specialization of `reduce` for `vcat` that avoids unnecessary intermediate allocations.

1 Like

Huh. Yes, that’s brilliant.

1 Like

I have a vague memory of Stefan karpinski mentioning in a post somewhere that splatting is not the best solution if the input list is long since it effectively results in high-dimensional multiple dispatch. Not sure if this still applies to v1.0 but would be interested to find out since I use this syntax in my code quite a bit (and I also have a dedicated function for long list inputs that preallocates the output matrix and then assigns the inputs to it sequentially)