iterate over rows of sparse matrix and get index of nonzeros?

1,972 views
Skip to first unread message

Florian Oswald

unread,
Jul 19, 2014, 1:58:37 PM7/19/14
to julia...@googlegroups.com
i am looking for a way to do something like 


s=sprand(3,5,0.6)

for i in 1:size(s,1)

      mySparseRowFunction(s[i, ])

end

I guess I'm looking for an iterator over the nonzero elements, ideally by row. Does something like this exist? I know julia uses a different format, but I'm looking for something similar to Eigen's InnerIterator (http://eigen.tuxfamily.org/dox/group__TutorialSparse.html). 

Context: I have a very large tensor product of univariate B-Spline Basis functions - this forms a sparse matrix. I need to take each row of this product and multiply it with a vector.

Odd Andersen

unread,
Jul 20, 2014, 6:44:17 PM7/20/14
to julia...@googlegroups.com
Sparse matrices in Julia are to my understanding stored as compressed sparse columns.  So it is very easy to get the nonzero elements for a given column, but not so easy for rows.

To get the indices of nonzeros rows for column 'c' in sparse matrix M, one can use (at least in the current implementation):

 M.rowval[a.colptr[col] : M.colptr[col+1]-1]

To do the same by rows would be more complicated (a quick-and-dirty solution would of course be to transpose your matrix first).
I am however not a Julia expert, so perhaps there's a solution I am not aware of.

Florian Oswald

unread,
Jul 21, 2014, 2:45:46 AM7/21/14
to julia...@googlegroups.com
Transposing is fine! Thanks for that!

Viral Shah

unread,
Jul 22, 2014, 5:25:11 AM7/22/14
to julia...@googlegroups.com
Julia 0.4 will have both compressed sparse column as well as compressed sparse row sparse matrices. We should probably write some iterators to work with cases such as these too. They will be convenient to use for sure, but may not give the best performance.

-viral

Florian Oswald

unread,
Jul 22, 2014, 5:41:49 AM7/22/14
to julia...@googlegroups.com
beautiful! can't wait. 
cheers
florian

Jerzy Głowacki

unread,
Jun 18, 2015, 5:59:04 PM6/18/15
to julia...@googlegroups.com
You can get non-zero indexes of a sparse matrix using find(sparseMatrix), then you can iterate over them.

Mauro

unread,
Jun 19, 2015, 3:23:19 AM6/19/15
to julia...@googlegroups.com
I think the nzrange function (new to 0.4 function) is best to do
that:

Base.nzrange(A, col)

Return the range of indices to the structural nonzero values of a
sparse matrix column. In conjunction with "nonzeros(A)" and
"rowvals(A)", this allows for convenient iterating over a sparse
matrix

A = sparse(I,J,V)
rows = rowvals(A)
vals = nonzeros(A)
m, n = size(A)
for i = 1:n
for j in nzrange(A, i)
row = rows[j]
val = vals[j]
# perform sparse wizardry...
end
end

If you're on 0.3 just add these two definitions from 0.4:

rowvals(S::SparseMatrixCSC) = S.rowval
nzrange(S::SparseMatrixCSC, col::Integer) = S.colptr[col]:(S.colptr[col+1]-1)

(this is just what Odd suggested)

And yes, transposing is likely the fastest for doing this over rows as
indexing into columns is very expensive.
Reply all
Reply to author
Forward
0 new messages