How to do in place concatenation of matrices

Hi there. I have a matrix a that I want to maintain and accumilate more data points to over time. Assume I have a given below and I want to append b to it without having to do a new assignment on a. How do I do so?

a = rand(2, 100)
b = rand(2, 10)
push!(a, b) # Does not work
append!(a, b) #Does not work
cat(a, b, dims=2) #Works but does not work in place i.e change a
cat!(a, b, dims=2) # is not defined

See GitHub - JuliaArrays/ElasticArrays.jl: Resizeable multi-dimensional arrays for Julia

2 Likes

Thank you for the reply! I will look into that, but just wanted to confirm is there no (perhaps even sub-optimal way) to this using plain Arrays? I am working off a repo that I do not fully control and if I changed the arrays to elastic arrays I would have to change a lot of the code and make keeping up with new changes in the main repo very difficult.

Maybe you could explain a little bit further the problem. Of course you can (not in-place) do

a = cat(a,b,dims=2)

and go on.

That could only be in place while keeping a contiguous in memory if there was some memory reserved for that growth in advance (is that what ElasticArrays does?). If there isn’t, either a has to be reallocated, or it would become split in memory, requiring multiple pointers, like a vector of arrays. If one or the other is best for performance depends on what is going to be made with a afterwards, but if it is going to be any heavy computation, probably reallocating it is the best choice.

ElasticArrays, like the built in push! for 1d arrays, reserves memory in advance by geometrically increasing (e.g. doubling) the allocation each time it runs out of space. This allows you to simply push! or concatenate repeatedly with amortized linear cost.

5 Likes

Do you know (approximately) how large your array will get?
Reserving memory in advance is probably the only way to truly avoid multiple allocations.

Depending on your use case a Vector of Vectors is a good option.