I have a 2D array, and want to treat each row (or column) as a vector and find norm of it
a = [1 2 3 ; 4 5 6]
1 2 3
4 5 6
The following is what I have tried and their results.
1 2 3
4 5 6
For now, to get what I want, I have to do the following
a = [[1,2,3],[4, 5, 6]]
[1, 2, 3]
[4, 5, 6]
I would like to know how can I have something similar to this matlab example directly from a 2D array.
There is currently no direct function to take the norm of a 2D array by dimension. The easiest way would probably be to do either of the 2 functions below:
julia> A = rand(5,4);
julia> f1(A,d=1) = sqrt.(sum(abs2,A,d))
f1 (generic function with 1 method)
julia> f2(A) = [vecnorm(A[:,i]) for i=1:size(A,2)]
f2 (generic function with 1 method)
julia> @btime f1($A)
128.103 ns (2 allocations: 224 bytes)
1.08137 1.1315 1.23828 1.35529
julia> @btime f2($A)
327.377 ns (11 allocations: 736 bytes)
f1 is faster because it acts mostly in place. It also allows you to change the dimension more easily.
f1 is likely to always be the best,
f2 can be made slightly faster by replacing
@view A[:,i] to avoid the copy operation.
Another alternative is to use
mapslices which applies a specified function to slices through the matrix (much like is being done manually with
julia> f3(A) = mapslices(norm, A, dims=1)
f3 (generic function with 1 method)
julia> @btime f3($A)
5.358 μs (73 allocations: 3.22 KiB)
0.824996 1.40544 1.19838 1.6095
but it is painfully slow in comparison with either
Thanks for your additional info. I also found this discussion. Good to learn another new thing.
Maybe it is more intuitive think about list comprehension in this kind of problem (any problem with operation across matrices and vectors, really).
My favorite way to get a list of norms of the vectors represented as lines in a matrix is :
norms = [norm(m[i,:]) for i=1:size(m)]
It is not super compact as it would be in matlab, but perhaps more understandable as you can see that you are calculating some norm for each line of the matrix and getting a list of those norms. When I do this in matlab I always have to check if I’m calculating the norm “vertically” or “horizontally” in the matrix to make sure I’ll get what I want.