Can someone explain what a 2 rows 0 column 2D array is?
I have trouble visualizing a Matrix with 2 rows and 0 columns
itâs just an empty Matrix
It was initialized with no column (instead of a column of zeros) because push!() (which I (wrongly) thought could work) does not replace the existing values, and thus the first column would be having zeros.
array1 = [1; 1; 1]
array2 = [2 3; 2 3; 2 3]
array3 = hcat((array1,array2))
However, what I get is a tuple, which is immutable. Is there any way to get a matrix, because the process happens in a loop.
julia> array3 = hcat(array1,array2)
3Ă3 Matrix{Int64}:
1 2 3
1 2 3
1 2 3
Oh, I had enclosed the arrays in double parenthesis. Thanks a lot jling. I have a long way to go in learning this language. Itâs not gonna be a cakewalk like MATLAB, it seems.
Finally, Iâve been able to get the thing done!
y=zeros(Float16,2,1)
# or y=Array{Float16}(undef,2,1)
for i1 in 1:1:10
global y #without this the code threw a scoping error
y = hcat(y,[f(i1); g(i1)]) #some functions of i1
end
Thanks all.
Usually itâs best to skip the âgrowingâ step and create the matrix with the correct size right away and only modify its contents - e.g. in this case, with
f(x) = 2x
g(x) = 3x
function build_mat()
y = zeros(Float16, 2, 11)
for i1 in 1:10
y[:,i1+1] .= f(i1), g(i1)
end
return y
end
This will be much faster than repeatedly growing/reallocating your matrix:
julia> function build_mat_hcat()
y = zeros(Float16, 2, 1)
for i1 in 1:1:10
y = hcat(y, [f(i1), g(i1)])
end
return y
end
build_mat_hcat (generic function with 1 method)
julia> using BenchmarkTools
julia> @btime build_mat()
65.542 ns (1 allocation: 96 bytes)
2Ă11 Matrix{Float16}:
0.0 2.0 4.0 6.0 8.0 10.0 12.0 14.0 16.0 18.0 20.0
0.0 3.0 6.0 9.0 12.0 15.0 18.0 21.0 24.0 27.0 30.0
julia> @btime build_mat_hcat()
744.828 ns (21 allocations: 1.62 KiB)
2Ă11 Matrix{Float16}:
0.0 2.0 4.0 6.0 8.0 10.0 12.0 14.0 16.0 18.0 20.0
0.0 3.0 6.0 9.0 12.0 15.0 18.0 21.0 24.0 27.0 30.0
This is on the order of nanoseconds (âjustâ a factor 10x) here because the loop in the function is super tiny, but with longer loops it will be much more (Iâm passing in the requested size as a parameter to make it easier to run):
julia> function build_mat_hcat(n)
y = zeros(Float16, 2, 1)
for i1 in 1:1:n
y = hcat(y, [f(i1), g(i1)])
end
return y
end
build_mat_hcat (generic function with 2 methods)
julia> function build_mat(n)
y = zeros(Float16, 2, n+1)
for i1 in 1:n
y[:,i1+1] .= f(i1), g(i1)
end
return y
end
build_mat (generic function with 2 methods)
julia> @btime build_mat_hcat(100);
8.367 Îźs (201 allocations: 33.67 KiB)
julia> @btime build_mat(100);
357.075 ns (1 allocation: 496 bytes)
julia> build_mat(100) â build_mat_hcat(100)
true
As you can see, the repeatedly allocating function is ~23x slower, for the same result. This will become worse with even longer loops, because allocating is a comparatively expensive operation:
julia> @btime build_mat_hcat(1000);
340.100 Îźs (2001 allocations: 2.11 MiB)
julia> @btime build_mat_hcat(10_000);
21.113 ms (25906 allocations: 192.58 MiB)
julia> @btime build_mat(10_000);
32.300 Îźs (2 allocations: 39.17 KiB)
Thatâs ~653 times slower! That ratio is going to continue to get worse.
Reducing or even eliminating allocations is a key idiom for achieving extremely fast julia code - itâs best to try to be conscious of this from the beginning, instead of trying to translate other languages one-to-one. Whatâs good in language A may not be good in language B, after all.
Additionally, putting your code into functions and passing arguments in explicitly will make sure you donât have problems with scoping of variables (global variables are kind of an anti-pattern in julia - they can lead to huge losses in performance).
Also, that is not good in Matlab either, and will be very very slow. It is just that Matlab allows a simple syntax for the bad code.
Yes, now Iâm gonna allocate a large memory and, after the completion of the filling of the array, will remove the trailing part. Thanks a lot for the exposition.
Yes, will do that. But in my VSC not declaring y as a global variable inside the for loop throws an error.