Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the recommended way to iterate a matrix over rows?

Tags:

julia

Given a matrix m = [10i+j for i=1:3, j=1:4], I can iterate over its rows by slicing the matrix:

for i=1:size(m,1)     print(m[i,:]) end 

Is this the only possibility? Is it the recommended way?

And what about comprehensions? Is slicing the only possibility to iterate over the rows of a matrix?

[ sum(m[i,:]) for i=1:size(m,1) ] 
like image 258
Nico Avatar asked Feb 14 '14 11:02

Nico


People also ask

What method can be used to iterate over the elements in a row?

In order to iterate over rows, we can use three function iteritems(), iterrows(), itertuples() . These three function will help in iteration over rows.


2 Answers

The solution you listed yourself, as well as mapslices, both work fine. But if by "recommended" what you really mean is "high-performance", then the best answer is: don't iterate over rows.

The problem is that since arrays are stored in column-major order, for anything other than a small matrix you'll end up with a poor cache hit ratio if you traverse the array in row-major order.

As pointed out in an excellent blog post, if you want to sum over rows, your best bet is to do something like this:

msum = zeros(eltype(m), size(m, 1)) for j = 1:size(m,2)     for i = 1:size(m,1)         msum[i] += m[i,j]     end end 

We traverse both m and msum in their native storage order, so each time we load a cache line we use all the values, yielding a cache hit ratio of 1. You might naively think it's better to traverse it in row-major order and accumulate the result to a tmp variable, but on any modern machine the cache miss is much more expensive than the msum[i] lookup.

Many of Julia's internal algorithms that take a region parameter, like sum(m, 2), handle this for you.

like image 78
tholy Avatar answered Sep 20 '22 05:09

tholy


As of Julia 1.1, there are iterator utilities for iterating over the columns or rows of a matrix. To iterate over rows:

M = [1 2 3; 4 5 6; 7 8 9]  for row in eachrow(af)     println(row) end 

Will output:

[1, 2, 3] [4, 5, 6] [7, 8, 9] 
like image 26
Seanny123 Avatar answered Sep 20 '22 05:09

Seanny123