```
a = sparse(b)
a.rowvals
```

rowvals only gives the indices of the rows and not the column.

How to get the row and column indices as a pair, the way it is displayed when entire vector is called

```
a = sparse(b)
a.rowvals
```

rowvals only gives the indices of the rows and not the column.

How to get the row and column indices as a pair, the way it is displayed when entire vector is called

1 Like

Have a look at this and the body of the involved functions (use @edit):

```
help?> nzrange
search: nzrange
nzrange(A::SparseMatrixCSC, col::Integer)
Return the range of indices to the structural nonzero values of a sparse matrix column. In conjunction with nonzeros and rowvals, 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
```

Yes, I found that later. But I didnâ€™t quite understand how it gives the i,j location pair of the element as is desired.

Loop over the columns as `j`

, and `nzrange(A,j)`

gives you the rows for column `j`

which have nonzeros.

No, it gives you the indices into `A.rowval`

, which contains the rows, e.g.

```
julia> A = [1 0 0;
1 8 7;
2 9 0] |> sparse;
julia> A.rowval[nzrange(A, 2)]
2-element Array{Int64,1}:
2
3
julia> A.rowval[nzrange(A, 3)]
1-element Array{Int64,1}:
2
```

2 Likes

I never get this rightâ€¦ this can really be improved. I opened an issue to see if not only this can be improved, but also see if it can be standardized beyond `SparseMatrixCSC`

:

SparseMatrices are not good to index with Cartesian indices and if you want to apply something to do something to all items, why not use the higher level functions like `map`

?.

Working efficiently with sparse matrices will in many cases mean working directly with the internal representation.

2 Likes

Maybe you can just multiply by the vector `(0,0,...0,1,0,...,0)`

Sorry, I donâ€™t understand.

Who asked to index sparse matrices with a Cartesian? I specifically asked for efficient iterators to avoid looping through non-zero elements with Cartesians. Of course those iterators have be specialized to the internal representation to be efficient, but thatâ€™s well within the realm of whatâ€™s possible if the iterator could return some indexing type. I am not asking for something to write matrix multiplications with, of course that needs to be really specialized to the sparse array. But I think that the ability to write a loop over the non-zero elements without having to make it a `map`

would be helpful in a lot of cases.

2 Likes

Agreed. One reason is the growing use of sparse representations in ML. Performing quick iterations is necessary.

Anyway, the answer to the question in OP is:

```
julia> A = sprand(5, 5, 0.2);
julia> I, J, V = findnz(A);
julia> indices = collect(zip(I,J));
julia> indices
6-element Array{Tuple{Int64,Int64},1}:
(1, 1)
(2, 1)
(3, 2)
(3, 4)
(1, 5)
(5, 5)
julia> V
6-element Array{Float64,1}:
0.0129232
0.187362
0.713473
0.595695
0.415127
0.640516
```

3 Likes

Yes! That works. Thank you @kristoffer.carlsson!

And here is an iterator that gives the cartesian indices and the values:

```
struct SparseMatrixCSC_StoredValuesIterator{T}
A::T
end
Base.start(S::SparseMatrixCSC_StoredValuesIterator) = 1, 1
function Base.next(S::SparseMatrixCSC_StoredValuesIterator, state)
i, col = state
while i > S.A.colptr[col+1] - 1
col += 1
end
return (S.A.rowval[i], col, S.A.nzval[i]), (i + 1, col)
end
function Base.done(S::SparseMatrixCSC_StoredValuesIterator, state)
i, col = state
return i > S.A.colptr[end] - 1
end
stored_indvals(S::SparseMatrixCSC) = SparseMatrixCSC_StoredValuesIterator(S)
```

Used as:

```
julia> A = sprand(6, 6, 0.4);
julia> full(A)
6Ă—6 Array{Float64,2}:
0.0 0.0 0.0 0.056908 0.0 0.0
0.0 0.328863 0.0 0.0 0.522739 0.0
0.0 0.0 0.0 0.0 0.559482 0.498087
0.0 0.0360203 0.0 0.302467 0.0 0.111877
0.0 0.489175 0.77902 0.117499 0.0 0.0
0.0 0.513361 0.0 0.801586 0.0 0.0582955
julia> for (i, j, v) in stored_indvals(A)
println("A[$i, $j] = $v")
end
A[2, 2] = 0.32886263776211333
A[4, 2] = 0.03602034051160041
A[5, 2] = 0.489174826870322
A[6, 2] = 0.5133613097745331
A[5, 3] = 0.7790200708345987
A[1, 4] = 0.0569080303985654
A[4, 4] = 0.30246686231168973
A[5, 4] = 0.11749932772395755
A[6, 4] = 0.8015857984258852
A[2, 5] = 0.5227388963966788
A[3, 5] = 0.5594820109904008
A[3, 6] = 0.49808711016882445
A[4, 6] = 0.1118766615390987
A[6, 6] = 0.05829550762538971
```

Note, havenâ€™t tested this one properly, it might have some off by one or fail on other edge cases.

5 Likes

Check out https://github.com/timholy/ArrayIteration.jl which has an awesome proof of concept.

1 Like