Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Operations with Eye do not preserve sparsity #265

Open
amilsted opened this issue Jun 22, 2023 · 6 comments
Open

Operations with Eye do not preserve sparsity #265

amilsted opened this issue Jun 22, 2023 · 6 comments

Comments

@amilsted
Copy link

Hi, I've noticed that SquareEye, since it is a LinearAlgebra.Diagonal preserves sparsity in many operations. For example:

julia> using FillArrays

julia> using SparseArrays

julia> E = Eye(2)
2×2 Eye{Float64}

julia> M = sprand(2,2, 0.5)
2×2 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
 0.906128   0.408236
 0.0285949    

julia> E + M
2×2 SparseMatrixCSC{Float64, Int64} with 4 stored entries:
 1.90613    0.408236
 0.0285949  1.0

julia> kron(E, E)  # although it would be nice is this were another SquareEye!
4×4 Diagonal{Float64, Vector{Float64}}:
 1.0            
     1.0        
         1.0    
             1.0

However, general Eye typically converts to a dense matrix:

julia> E = Eye(2,2)
2×2 Eye{Float64}

julia> E + M
2×2 Matrix{Float64}:
 1.90613    0.408236
 0.0285949  1.0

julia> kron(E,E)
4×4 Matrix{Float64}:
 1.0  0.0  0.0  0.0
 0.0  1.0  0.0  0.0
 0.0  0.0  1.0  0.0
 0.0  0.0  0.0  1.0

This was quite surprising to me. Could we add some operator overloads to keep things sparse in the Eye case?

@jishnub
Copy link
Member

jishnub commented Jun 30, 2023

The broadcast is actually a bit involved, and defining everything here might not be the best idea. The interplay between the structured matrix broadcast style and the sparse matrix style is handled by SparseArrays, so perhaps that is the package that should provide a hook to access that functionality for custom structured matrix types.

Regarding kron, note that the result is not an Eye in general for rectangular matrices, although perhaps we may express this as a sparse matrix

julia> E = Eye(2,3)
2×3 Eye{Float64}

julia> kron(E, E)
4×9 Matrix{Float64}:
 1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  1.0  0.0  0.0  0.0  0.0

The Diagonal case should be fixed in #268

@amilsted
Copy link
Author

amilsted commented Jun 30, 2023

Right, I realize you can't make kron of rectangular Eye still be an Eye, but that result is very sparse, so having kron(Eye(m,n), Eye(x,y)) return a sparse matrix seems reasonable. I don't think this case can be handles in SparseArrays.

I guess another alternative is to return a SciMLOperators lazy tensor product...

@jishnub
Copy link
Member

jishnub commented Jul 1, 2023

Now the rectangular kron is also addressed in #268, and it'll return a sparse array

@putianyi889
Copy link
Contributor

getindex also doesn't preserve sparsity

julia> Eye(5)[:,:]
5×5 Matrix{Float64}:
 1.0  0.0  0.0  0.0  0.0
 0.0  1.0  0.0  0.0  0.0
 0.0  0.0  1.0  0.0  0.0
 0.0  0.0  0.0  1.0  0.0
 0.0  0.0  0.0  0.0  1.0

I'm not sure if it's worth adding BandedMatrices to the dependency.

@dlfivefifty
Copy link
Member

Adding banded matrices as a dependency won’t work

we could add a new type called OffDiagonal

@dlfivefifty
Copy link
Member

Note layout_getindex(D, :, :) will produce a BandedMatrix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants