Generic way to apply function to a dimension of a matrix

Hello!
The mean function from statistics has the “dims” option, which lets me average a matrix into a vector by averaging the rows or columns.
Is there a generic way to do this without for loops? Say I want to do the same thing with the dot function, where I have a 1x3 array and a 10x3 matrix and I want to do the dot product of the array by each line of the matrix. Using dot.(a,b) wouldn’t really work as Julia doesn’t know which dims to use.
Thanks!

1 Like

This particular computation is exactly a matrix product, so just doing M * v' will be the best approach.

More generally, you can use the eachslice, eachrow, or eachcol iterators.

Is there a generic way to do this without for loops?

Note also that there’s nothing wrong with a loop in Julia. Loops are fast, and are sometimes the simplest and clearest way to code something.

6 Likes

Thanks, Steven.
You’re right, bad example. Say I want the norm of the 10x3 matrix as a 10 element array (i.e., norm of each line).
I’d like to know how to do it without for loops to be able to easily use CUDA.
Thanks!

Yep, combining eachrow with the . (say norm.(eachrow(matrix))) worked! Thanks!

It is a bit more efficient to do map(norm, eachrow(matrix)) or [norm(v) for v in eachrow(matrix)] instead of norm.(eachrow(matrix)) here — with the dot syntax, if you apply it to an iterator like eachrow(matrix) then it first runs collect (to form an explicit array of the row views).

6 Likes

Just be aware that eachrow iterate over Vectors not Arrays{T, 2} of dimensions 1xN, this confused a colleague of mine when he started using Julia.

Thanks, guys. This is all very helpful.
I tested norm.(eachrow(matrix)) and map(norm, eachrow(matrix)) and the latter is indeed much more efficient in terms of number of allocations (measured with @time).
Thanks again!

2 Likes