From 785e6252929e1e9fccc7866c4e10ab1bf12a3e78 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sat, 8 Mar 2025 20:29:11 +0530 Subject: [PATCH 1/3] Faster sparse for AbstractFill --- ext/FillArraysSparseArraysExt.jl | 8 ++++++++ test/runtests.jl | 2 ++ 2 files changed, 10 insertions(+) diff --git a/ext/FillArraysSparseArraysExt.jl b/ext/FillArraysSparseArraysExt.jl index 6021296b..393f1623 100644 --- a/ext/FillArraysSparseArraysExt.jl +++ b/ext/FillArraysSparseArraysExt.jl @@ -5,6 +5,7 @@ using SparseArrays: SparseVectorUnion import Base: convert, kron using FillArrays using FillArrays: RectDiagonalFill, RectOrDiagonalFill, ZerosVector, ZerosMatrix, getindex_value, AbstractFillVector, _fill_dot +using FillArrays: AbstractFill # Specifying the full namespace is necessary because of https://github.com/JuliaLang/julia/issues/48533 # See https://github.com/JuliaStats/LogExpFunctions.jl/pull/63 using FillArrays.LinearAlgebra @@ -19,6 +20,13 @@ SparseVector{Tv,Ti}(Z::ZerosVector) where {Tv,Ti} = spzeros(Tv, Ti, length(Z)) convert(::Type{AbstractSparseVector}, Z::ZerosVector{T}) where T = spzeros(T, length(Z)) convert(::Type{AbstractSparseVector{T}}, Z::ZerosVector) where T= spzeros(T, length(Z)) +function SparseMatrixCSC{T,Ti}(F::AbstractFill) where {T, Ti<:Integer} + SparseMatrixCSC{T,Ti}(size(F)..., + Vector(StepRangeLen(1, size(F,1), size(F,2)+1)), + convert(Vector, reduce(vcat, fill(axes(F,1), size(F,2)))), + fill(convert(T, getindex_value(F)), length(F))) +end + SparseMatrixCSC{T}(Z::ZerosMatrix) where T = spzeros(T, size(Z)...) SparseMatrixCSC{Tv,Ti}(Z::Zeros{T,2,Axes}) where {Tv,Ti<:Integer,T,Axes} = spzeros(Tv, Ti, size(Z)...) diff --git a/test/runtests.jl b/test/runtests.jl index 32cd2ed7..267f031a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -591,6 +591,8 @@ end testsparsediag(E) end end + + @test sparse(Fill(3, 4, 4)) == sparse(fill(3, 4, 4)) end @testset "==" begin From 5ebc6084d446d62017c789a172bdcda32d56857f Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sun, 9 Mar 2025 13:03:51 +0530 Subject: [PATCH 2/3] Add Vector conversion --- ext/FillArraysSparseArraysExt.jl | 15 +++++++++++---- test/runtests.jl | 8 +++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/ext/FillArraysSparseArraysExt.jl b/ext/FillArraysSparseArraysExt.jl index 393f1623..1d20fa58 100644 --- a/ext/FillArraysSparseArraysExt.jl +++ b/ext/FillArraysSparseArraysExt.jl @@ -5,7 +5,7 @@ using SparseArrays: SparseVectorUnion import Base: convert, kron using FillArrays using FillArrays: RectDiagonalFill, RectOrDiagonalFill, ZerosVector, ZerosMatrix, getindex_value, AbstractFillVector, _fill_dot -using FillArrays: AbstractFill +using FillArrays: AbstractFillMatrix # Specifying the full namespace is necessary because of https://github.com/JuliaLang/julia/issues/48533 # See https://github.com/JuliaStats/LogExpFunctions.jl/pull/63 using FillArrays.LinearAlgebra @@ -14,16 +14,23 @@ import LinearAlgebra: dot, kron, I ################## ## Sparse arrays ################## +function SparseVector{Tv,Ti}(F::AbstractFillVector) where {Tv,Ti} + SparseVector{Tv,Ti}(length(F), + convert(Vector{Ti}, axes(F,1)), + fill(convert(Tv, getindex_value(F)), length(F)) + ) +end + SparseVector{T}(Z::ZerosVector) where T = spzeros(T, length(Z)) SparseVector{Tv,Ti}(Z::ZerosVector) where {Tv,Ti} = spzeros(Tv, Ti, length(Z)) convert(::Type{AbstractSparseVector}, Z::ZerosVector{T}) where T = spzeros(T, length(Z)) convert(::Type{AbstractSparseVector{T}}, Z::ZerosVector) where T= spzeros(T, length(Z)) -function SparseMatrixCSC{T,Ti}(F::AbstractFill) where {T, Ti<:Integer} +function SparseMatrixCSC{T,Ti}(F::AbstractFillMatrix) where {T, Ti<:Integer} SparseMatrixCSC{T,Ti}(size(F)..., - Vector(StepRangeLen(1, size(F,1), size(F,2)+1)), - convert(Vector, reduce(vcat, fill(axes(F,1), size(F,2)))), + convert(Vector{Ti}, StepRangeLen(1, size(F,1), size(F,2)+1)), + convert(Vector{Ti}, reduce(vcat, fill(axes(F,1), size(F,2)))), fill(convert(T, getindex_value(F)), length(F))) end diff --git a/test/runtests.jl b/test/runtests.jl index 267f031a..4a1a0d69 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -592,7 +592,13 @@ end end end - @test sparse(Fill(3, 4, 4)) == sparse(fill(3, 4, 4)) + F = Fill(3, 4, 4) + @test sparse(F) == sparse(fill(3, size(F)...)) + @test SparseMatrixCSC{Int8,Int16}(F) isa SparseMatrixCSC{Int8,Int16} + + F = Fill(3, 4) + @test sparse(F) == sparse(fill(3, size(F)...)) + @test SparseVector{Int8,Int16}(F) isa SparseVector{Int8,Int16} end @testset "==" begin From 5ad9b7494b681ea7dbdb5640ca1191248a9dd75e Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sun, 9 Mar 2025 13:18:48 +0530 Subject: [PATCH 3/3] Reduce type conversions --- ext/FillArraysSparseArraysExt.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/FillArraysSparseArraysExt.jl b/ext/FillArraysSparseArraysExt.jl index 1d20fa58..b75814b1 100644 --- a/ext/FillArraysSparseArraysExt.jl +++ b/ext/FillArraysSparseArraysExt.jl @@ -29,8 +29,8 @@ convert(::Type{AbstractSparseVector{T}}, Z::ZerosVector) where T= spzeros(T, len function SparseMatrixCSC{T,Ti}(F::AbstractFillMatrix) where {T, Ti<:Integer} SparseMatrixCSC{T,Ti}(size(F)..., - convert(Vector{Ti}, StepRangeLen(1, size(F,1), size(F,2)+1)), - convert(Vector{Ti}, reduce(vcat, fill(axes(F,1), size(F,2)))), + convert(Vector{Ti}, StepRangeLen(oneunit(Ti), Ti(size(F,1)), size(F,2)+1)), + convert(Vector{Ti}, reduce(vcat, fill(map(Ti, axes(F,1)), size(F,2)))), fill(convert(T, getindex_value(F)), length(F))) end