jw3126 / Setfield.jl

Update deeply nested immutable structs.
Other
167 stars 17 forks source link

FunctionLens for SparseMatrixCSC accessor functions #78

Open tkf opened 5 years ago

tkf commented 5 years ago

Once AbstractSparseMatrixCSC API for accessors https://github.com/JuliaLang/julia/pull/33054 is settled, I'd like to add set definitions for them. It'll let us use something like

@set nonzeros(A) = xs

The definition would be something like simply

set(A::SparseMatrixCSC, ::typeof(@lens nonzeros(_)), xs) = @set A.nzval = xs

@jw3126 Does it sound reasonable?

jw3126 commented 5 years ago

Yeah sounds good. I guess this is a case, where you would really like to have a mutating @set most of the time?

tkf commented 5 years ago

SparseMatrixCSC is a non-mutable struct so I think re-constructing lens is all we can do. If you want to reuse existing underlying vectors, you can just do:

nonzeros(A) .= xs

A concrete scenario I have in mind is to construct CSC matrices with shared nonzero structure like this

B = spzeros(size(A)...)
@set coloffsets(B) = coloffsets(A)
@set rowvals(B) = rowvals(A)
@set nonzeros(B) = similar(nonzeros(A))
compute!(nonzeros(B))

In this case, the above lens does what I need.

A scenario I can think of where the mutating lens is usable is something like

A = sprandn(ComplexF64, 100, 100, 0.1)
B = @set!! real(nonzeros(A)[1]) = x

where you'd want it to do

a = nonzeros(A)
b = a[1]
c = @set b.re = x
a[1] = c  # typeof(c) == typeof(b) so mutate `a`
B = @set nonzeros(A) = a  # `A` is immutable so use normal lens
jw3126 commented 5 years ago

I see thanks. Out of curiosity, do you want to share nonzero structure for PDE discretization?

tkf commented 5 years ago

It's sparse (somewhat biological) neural network simulation. I found fusing Y = Y β + D₁ S₁' X₁ + ... + Dₙ Sₙ' Xₙ is beneficial when sparse matrices Sᵢs share nonzero structures: https://github.com/tkf/SparseXX.jl