What is the proper way of using push to add rows to an existing matrix? I keep getting errors for the below code:

```
LL = fill(NaN, (0,2));
for j ∈ 1:n #180
for i ∈ 1:m #360
push!(LL, [X[i,j], Y[i,j]]);
end
end
```

Many thanks!

What is the proper way of using push to add rows to an existing matrix? I keep getting errors for the below code:

```
LL = fill(NaN, (0,2));
for j ∈ 1:n #180
for i ∈ 1:m #360
push!(LL, [X[i,j], Y[i,j]]);
end
end
```

Many thanks!

You can only push to vectors, but not to multi-dimensional arrays. (See for example here Resize!(matrix) - #2 by StefanKarpinski why it is this way.)

- If you really need to add rows dynamically, you could consider using a
`Vector`

of`Vectors`

```
LL = Vector{Float64}[]
push!(LL, [1.0, 2.0])
```

or maybe you could use Introduction · DataFrames.jl or GitHub - JuliaArrays/ElasticArrays.jl: Resizeable multi-dimensional arrays for Julia

- If you only need to add a few rows/columns, you could use
`vcat`

or`hcat`

. For example

```
LL = [X[:] Y[:]] # or hcat(X[:],Y[:]) or hcat(vec(X),vec(Y))
```

- If you know in advance how many rows you need, that is of course ideal and it can sometimes give great performance benefits.

```
LL = fill(NaN, n*m, 2) # or LL = Array{Float64}(undef, n*m, 2)
k = 1
for j ∈ 1:n #180
for i ∈ 1:m #360
LL[k, :] .= (X[i,j], Y[i,j])
k += 1
end
end
```

2 Likes

Unfortunately, I got the errors as below:

```
LoadError: BoundsError: attempt to access 64800-element Vector{Vector{Float64}} at index [1:64800, 2]
Stacktrace:
[1] throw_boundserror(A::Vector{Vector{Float64}}, I::Tuple{Base.Slice{Base.OneTo{Int64}}, Int64})
@ Base ./abstractarray.jl:691
[2] checkbounds
@ ./abstractarray.jl:656 [inlined]
[3] _getindex
@ ./multidimensional.jl:838 [inlined]
[4] getindex(::Vector{Vector{Float64}}, ::Function, ::Int64)
@ Base ./abstractarray.jl:1218
[5] top-level scope
@ ~/Desktop/Julia_coding/A04_global_projection/XY.jl:41
```

Which method did you try, and can you show your code?

If it is ok to push columns instead, you can use GitHub - JuliaArrays/ElasticArrays.jl: Resizeable multi-dimensional arrays for Julia.

When you use

```
LL = Vector{Float64}[]
push!(LL, [1.0, 2.0])
```

you have to access the rows via `LL[1]`

(first row) or `LL[1][2] `

first row, second element.

1 Like

Keep in mind that Julia arrays are ‘column-major’, so adding rows is highly disadvantageous. Can you change your data layout so that you are adding columns instead?

1 Like

```
LL = Vector{Float64}[]
push!(LL, [1.0, 2.0])
```

That will work. All I need to do is to transpose the matrix after it is generated.

Is there an easier way to do so without relying on an external program package like “Elastic Arrays”? I mean in Matlab, it is as easy as `A = [A; B];`

It’s equally easy in Julia.

```
m = 360
n = 180
X = rand(m, n)
Y = rand(m, n)
LL = fill(NaN, (0,2));
for j ∈ 1:n #180
for i ∈ 1:m #360
LL = [LL; X[i, j] Y[i, j]]
end
end
```

The performance of doing it this way is horrible but that’s the case for Matlab as well, or at least it was when I last used Matlab.

1 Like

Does anyone know why the code below does not work? Thanks

```
m = 360
n = 180
X = rand(m, n)
Y = rand(m, n)
LL = fill(NaN, (0,2));
for j ∈ 1:n #180
for i ∈ 1:m #360
var = [X[i,j] Y[i,j]];
global LL = reduce((x, y) -> cat(x, y; dims = 2), [LL, var]);
end
end
```

Mostly because you try to concatenate along the wrong dimension. But there’s nothing you can gain by using `reduce`

on two elements.

```
reduce((x, y) -> cat(x, y; dims = 2), [LL, var])
```

is just a more complicated way, with some amount of overhead, to write

```
cat(LL, var; dims = 2)
```

1 Like

Or just using concatenation syntax directly:

```
[LL var] # cat along dim 2
[LL; var] # cat along dim 1
```

2 Likes

BTW, using `global`

is discouraged (in all programming languages, not just Julia). Instead, you can put your code inside a function.

Here’s one way:

```
function mycat(X, Y)
LL = similar(X, 0, 2)
for i in eachindex(X, Y)
LL = [LL; [X[i] Y[i]]]
end
return LL
end
```

But here’s a much better way:

```
function mycat2(X, Y)
LL = similar(X, length(X), 2)
for i in eachindex(X, Y)
LL[i, 1] = X[i]
LL[i, 2] = Y[i]
end
return LL
end
```

The last one is 200.000 times faster, and runs in 80us instead of 16 seconds.

2 Likes