How to get the row AND column value for SparseMatrixCSC elements?

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