How to use push!() in a two-dimensional matrix

Hi everyone,
I need to put values into a matrix initialized with 2 rows and 0 columns. I have tried the following three ways but without success. Please inform me the correct way.

First

y=zeros(Float16,2,0)
display(y)

for i1 in 1:1:10
     push!(y[1,:],i1)
end

for i2 in 1:1:10
     push!(y[2,:],i2)
end

display(y)

Second

y=zeros(Float16,2,0)
display(y)

for i1 in 1:1:10
     push!(y[1,],i1)
end

for i2 in 1:1:10
     push!(y[2,],i2)
end

display(y)

Third

y=zeros(Float16,2,0)
display(y)

for i1 in 1:1:10
     push!(y[1],i1)
end

for i2 in 1:1:10
     push!(y[2],i2)
end

display(y)

push and append adds element to the array, which is to say that they don’t change the value of existing elements.

To add row or columns to an existing matrix, you need vcat or hcat

1 Like

Note that hcat and vcat will allocate new arrays.

To expand an existing matrix in-place, see GitHub - JuliaArrays/ElasticArrays.jl: Resizeable multi-dimensional arrays for Julia

4 Likes

Ya, I need to add elements to the array.

So, I am able to add elements into a vector

y=zeros(Float16,1)

for i1 in 1:1:10
     push!(y,i1)
end

but can’t do it with a matrix.

Thank you, I go through it.

But it says, “An ElasticArray is a fast, contiguous array that can grow and shrink, but only in its last dimension:”

well, the memory is 1D, so if you need to add in somewhere in the middle, you can’t completely avoid copying.

3 Likes

The problem is that the memory is “linear”, thus it is not possible to simply add a row to a matrix without allocating the matrix again, or making the memory layout discontinuous. Maybe consider the use of an array of arrays.

4 Likes

So, in Julia one does not have a one-to-one equivalent to MATLAB’s following code

y=zeros(2,1)

for i1 in 1:1:10
    y(1,i1) = i1;
end

for i2 in 1:1:10
    y(2,i2) = i2;
end

If this is the case, then I could simply use two vectors. Thanks for your inputs.

No, you could certainly do it, simply by allocating padding in the middle of the array (in a geometrically increasing fashion). It would just act like a view of the underlying data, and you’d even be able to use LAPACK and BLAS (since they support such padding).

See also Restriction to the last dimension · Issue #3 · JuliaArrays/ElasticArrays.jl · GitHub

(Technically, you could also do an in-place matrix transpose to row-major format, add the row by growing the end of the array, and then transpose back, but that’s pretty inefficient.)

5 Likes

You realize that Matlab is just copying the data to a new arrays when you grow it, right? You can do the same thing in Julia.

(Matlab’s matrix data structure assumes contiguous data, just like a Julia Matrix, so you can’t efficiently add rows without copying to a new array.

6 Likes

But the layout of the matrix would be discontinuous, or I am missing something? Even if you can do matrix operations with that, probably they become much less efficient, don’t they?

Edit: just read the GitHub there and it is clear now. Thanks.

1 Like

I actually did not know how Matlab stored data. I learnt the language superficially. Thanks for the link. So (as my first post shows) I did try using push!() on a matrix initialized with 2 rows and a column, but no success.

As others in this post have said, you need to use vcat and hcat, you cannot push! to a multdimenional array.

2 Likes

Okay, I do that. Thanks all.

I think i’m not quite understanding what you are trying to do, but i often have situations where my end array is going to be 2D.

i just push into a linear array and then use reshape

2 Likes

I am trying to extend a 2d array column-wise. I’ll look at your suggestion. Thank you.


julia> a = [1,2];

julia> append!(a, [3,4]);

julia> reshape(a, 2, 2)
2×2 Matrix{Int64}:
 1  3
 2  4

because Julia is column major, for matrix, adding column is trivially copy free (sort of)

1 Like

Sure, but that doesn’t cause any problems.

Even if you can do matrix operations with that, probably they become much less efficient, don’t they?

No. Each column is still contiguous in memory, there is just a gap between the columns. You access A[i,j] in exactly the same way — at a memory offset lda*j + i … the only difference from a contiguous array is the value of the leading-dimension (column stride) lda.

6 Likes