Efficiently updating values in a sparse diagonal matrix


#1

Let’s say I have 5 vectors A, B, C, D, E and I build a sparse matrix as follows:

M = spdiagm(0 => A, -1 => B, 1 => C, -10 => D, 10 => E)

So, as you see, all the nonzero entries are on the five diagonals. (So, the number of nonzero entries is fixed.) In my actual usage, the entries in vectors A, B, C are updated repetitively in a loop. Every time the vectors are updated, I need the M matrix to be updated as well. Currently, I just use spdiagm() to generate a new matrix repetitively in the loop. Since the matrix could be quite large sometimes, I thought it would be much more efficient if there is a way to update the nonzero entries of M in-place, without creating a new matrix every time. Is there such a way to update the entries of the sparse matrix without creating a new one? Thanks!


#2

You can directly manipulate the nzval field of the sparse matrix. The manual chapter on SparseArrays describes the storage format.

julia> w
5×5 SparseMatrixCSC{Float64,Int64} with 5 stored entries:
  [1, 1]  =  1.0
  [2, 2]  =  2.0
  [3, 3]  =  3.0
  [4, 4]  =  4.0
  [5, 5]  =  9.0

julia> w.nzval[1] = 7
7

julia> w
5×5 SparseMatrixCSC{Float64,Int64} with 5 stored entries:
  [1, 1]  =  7.0
  [2, 2]  =  2.0
  [3, 3]  =  3.0
  [4, 4]  =  4.0
  [5, 5]  =  9.0

#3

Thanks for your reply.

The issue with directly handling nzval is that the entries are ordered by columns rather than by diagonal. I think I will either need to rewrite the way the diagonals A, B, C, D, E are created to accommodate the column order, or find a function to do the reordering.