# Update matrix block inplace from a sparse array

**URL:** <https://discourse.julialang.org/t/update-matrix-block-inplace-from-a-sparse-array/36360>\
**Category:** General Usage\
**Tags:** sparse\
**Created:** [March 22, 2020, 8:51pm UTC](https://discourse.julialang.org/t/update-matrix-block-inplace-from-a-sparse-array/36360 "2020-03-22T20:51:18Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![rveltz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rveltz/32/2707_2.png) [@rveltz](https://discourse.julialang.org/u/rveltz)\
**Post date:** [March 22, 2020, 8:51pm UTC](https://discourse.julialang.org/t/update-matrix-block-inplace-from-a-sparse-array/36360/1 "2020-03-22T20:51:18Z")

</div>

Hi,

> Edit: sounds like it is related to [BlockSparseMatrices.jl](https://github.com/KristofferC/BlockSparseMatrices.jl) although the docs are quite minimal

I have a sparse matrix `a` which is made of blocks (a few).

```julia
using SparseArrays, LinearAlgebra
N = 100
# this is a completely made up example
a = kron(I(2), spdiagm(0 => ones(N), 1=>ones(N-1)))

```

I want to update the blocks as fast as possible. Let us say that the block (1,2) of size NxN has to be update by `b`. I can do

```julia
a[1:N,N+1:2N] .= b

```

Now, I want to speed this up. From

```julia
I,J,K = findnz(a)

```

I want to be able to extract the indices of I,J and K which correspond to `a[1:N,N+1:2N]`. I thought I could do the following but I get:

```julia
julia> findnz(view(a, 1:N,N+1:2N))
ERROR: MethodError: no method matching findnz(::SubArray{Float64,2,SparseMatrixCSC{Float64,Int64},Tuple{UnitRange{Int64},UnitRange{Int64}},false})
Closest candidates are:
  findnz(::SparseMatrixCSC{Tv,Ti}) where {Tv, Ti} at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.3/SparseArrays/src/sparsematrix.jl:1418
  findnz(::SparseVector{Tv,Ti}) where {Tv, Ti} at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.3/SparseArrays/src/sparsevector.jl:738
Stacktrace:
 [1] top-level scope at REPL[6]:100:

```

Do you have any idea on how to do this?

Thank you a lot for your suggestions…

Best regards,

---

<div class="post-metadata">

**Author:** ![jlchan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlchan/32/10958_2.png) [@jlchan](https://discourse.julialang.org/u/jlchan)\
**Post date:** [April 7, 2020, 8:19pm UTC](https://discourse.julialang.org/t/update-matrix-block-inplace-from-a-sparse-array/36360/2 "2020-04-07T20:19:34Z")

</div>

I’ve been looking for this as well, and it looks like there’s some [related work](https://github.com/JuliaDiff/FiniteDiff.jl/issues/29) and [interest from others](https://discourse.julialang.org/t/a-version-of-sparse-that-updates-a-previously-existing-sparsematrixcsc/31943). There is a related feature `SparseArrays.sparse!` (not exported) which allows you to get halfway there by specifying some pre-allocated arrays for the construction of sparse matrices.

I haven’t found a good solution for full in-place updates, however. As far as I can tell, it’s possible to do fully in-place sparse matrix updates by directly modifying `rowptr,colptr,nzval`, but more complicated when accounting for general sparse matrix functionality like combining repeated entries and sorted/unsorted representations.

---

<div class="post-metadata">

**Author:** ![rveltz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rveltz/32/2707_2.png) [@rveltz](https://discourse.julialang.org/u/rveltz)\
**Post date:** [April 7, 2020, 8:30pm UTC](https://discourse.julialang.org/t/update-matrix-block-inplace-from-a-sparse-array/36360/3 "2020-04-07T20:30:47Z")

</div>

I have done this by looping at the non zero values. First I extract the indices of the sparse matrix in the OO format for each block, [here](https://github.com/rveltz/PseudoArcLengthContinuation.jl/blob/master/src/Utils.jl#L130). Then, I update the blocks [here](https://github.com/rveltz/PseudoArcLengthContinuation.jl/blob/master/src/periodicorbit/PeriodicOrbitFD.jl#L460). For my use case, the problem is solved.
