From 4d15843d53b20134b577f6b899ff7a6b81e974ba Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Thu, 23 Nov 2023 12:22:17 +0100 Subject: [PATCH 1/7] Fix `getcolptr` for sparse matrix views --- test/linalg.jl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/linalg.jl b/test/linalg.jl index a9396ebf..759913aa 100644 --- a/test/linalg.jl +++ b/test/linalg.jl @@ -158,8 +158,8 @@ begin MAW = tr(wr(MA)) @test AW * B ≈ MAW * B # and for SparseMatrixCSCView - a view of all rows and unit range of cols - vAW = tr(wr(view(A, :, 1:n))) - vMAW = tr(wr(view(MA, :, 1:n))) + vAW = tr(wr(view([zero(A) A], :, (n+1):2n))) + vMAW = tr(wr(view([zero(MA) MA], :, (n+1):2n))) @test vAW * B ≈ vMAW * B end a = sprand(rng, ComplexF64, n, n, 0.01) @@ -170,8 +170,8 @@ begin MAW = tr(wr(ma)) @test AW * B ≈ MAW * B # and for SparseMatrixCSCView - a view of all rows and unit range of cols - vAW = tr(wr(view(a, :, 1:n))) - vMAW = tr(wr(view(ma, :, 1:n))) + vAW = tr(wr(view([zero(a) a], :, (n+1):2n))) + vMAW = tr(wr(view([zero(ma) ma], :, (n+1):2n))) @test vAW * B ≈ vMAW * B end A = A - Diagonal(diag(A)) + 2I # avoid rounding errors by division @@ -181,6 +181,10 @@ begin AW = tr(wr(A)) MAW = tr(wr(MA)) @test AW \ B ≈ MAW \ B + # and for SparseMatrixCSCView - a view of all rows and unit range of cols + vAW = tr(wr(view([zero(A) A], :, (n+1):2n))) + vMAW = tr(wr(view([zero(MA) MA], :, (n+1):2n))) + @test vAW \ B ≈ vMAW \ B end @testset "triangular singular exceptions" begin A = LowerTriangular(sparse([0 2.0;0 1])) From 4bceb3ec74f46ace31397856445faaa7a4b82e14 Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Thu, 23 Nov 2023 14:52:17 +0100 Subject: [PATCH 2/7] better tests --- test/linalg.jl | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/test/linalg.jl b/test/linalg.jl index 759913aa..d1825a82 100644 --- a/test/linalg.jl +++ b/test/linalg.jl @@ -158,9 +158,8 @@ begin MAW = tr(wr(MA)) @test AW * B ≈ MAW * B # and for SparseMatrixCSCView - a view of all rows and unit range of cols - vAW = tr(wr(view([zero(A) A], :, (n+1):2n))) - vMAW = tr(wr(view([zero(MA) MA], :, (n+1):2n))) - @test vAW * B ≈ vMAW * B + vAW = tr(wr(view([zero(A)+I A], :, (n+1):2n))) + @test vAW * B ≈ AW * B end a = sprand(rng, ComplexF64, n, n, 0.01) ma = Matrix(a) @@ -170,9 +169,8 @@ begin MAW = tr(wr(ma)) @test AW * B ≈ MAW * B # and for SparseMatrixCSCView - a view of all rows and unit range of cols - vAW = tr(wr(view([zero(a) a], :, (n+1):2n))) - vMAW = tr(wr(view([zero(ma) ma], :, (n+1):2n))) - @test vAW * B ≈ vMAW * B + vAW = tr(wr(view([zero(a)+I a], :, (n+1):2n))) + @test vAW * B ≈ AW * B end A = A - Diagonal(diag(A)) + 2I # avoid rounding errors by division MA = Matrix(A) @@ -182,9 +180,8 @@ begin MAW = tr(wr(MA)) @test AW \ B ≈ MAW \ B # and for SparseMatrixCSCView - a view of all rows and unit range of cols - vAW = tr(wr(view([zero(A) A], :, (n+1):2n))) - vMAW = tr(wr(view([zero(MA) MA], :, (n+1):2n))) - @test vAW \ B ≈ vMAW \ B + vAW = tr(wr(view([zero(A)+I A], :, (n+1):2n))) + @test vAW \ B ≈ AW \ B end @testset "triangular singular exceptions" begin A = LowerTriangular(sparse([0 2.0;0 1])) From 40927ccadfc728a8412566dce92f3969b472474d Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Thu, 23 Nov 2023 14:53:27 +0100 Subject: [PATCH 3/7] add actual fixes --- src/linalg.jl | 30 +++++++++++++++--------------- src/sparsematrix.jl | 22 +++++++++++++++------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/linalg.jl b/src/linalg.jl index 7ef517ab..67909d9c 100644 --- a/src/linalg.jl +++ b/src/linalg.jl @@ -28,11 +28,11 @@ for op ∈ (:+, :-) end end -LinearAlgebra.generic_matmatmul!(C::StridedMatrix, tA, tB, A::SparseMatrixCSCUnion, B::DenseMatrixUnion, _add::MulAddMul) = +LinearAlgebra.generic_matmatmul!(C::StridedMatrix, tA, tB, A::SparseMatrixCSCUnion2, B::DenseMatrixUnion, _add::MulAddMul) = spdensemul!(C, tA, tB, A, B, _add) -LinearAlgebra.generic_matmatmul!(C::StridedMatrix, tA, tB, A::SparseMatrixCSCUnion, B::AbstractTriangular, _add::MulAddMul) = +LinearAlgebra.generic_matmatmul!(C::StridedMatrix, tA, tB, A::SparseMatrixCSCUnion2, B::AbstractTriangular, _add::MulAddMul) = spdensemul!(C, tA, tB, A, B, _add) -LinearAlgebra.generic_matvecmul!(C::StridedVecOrMat, tA, A::SparseMatrixCSCUnion, B::DenseInputVector, _add::MulAddMul) = +LinearAlgebra.generic_matvecmul!(C::StridedVecOrMat, tA, A::SparseMatrixCSCUnion2, B::DenseInputVector, _add::MulAddMul) = spdensemul!(C, tA, 'N', A, B, _add) Base.@constprop :aggressive function spdensemul!(C, tA, tB, A, B, _add) @@ -75,7 +75,7 @@ function _spmatmul!(C, A, B, α, β) C end -*(A::SparseMatrixCSCUnion{TA}, B::DenseTriangular) where {TA} = +*(A::SparseMatrixCSCUnion2{TA}, B::DenseTriangular) where {TA} = (T = promote_op(matprod, TA, eltype(B)); mul!(similar(B, T, (size(A, 1), size(B, 2))), A, B)) function _At_or_Ac_mul_B!(tfun::Function, C, A, B, α, β) @@ -100,10 +100,10 @@ function _At_or_Ac_mul_B!(tfun::Function, C, A, B, α, β) C end -*(A::AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC}, B::DenseTriangular) = +*(A::AdjOrTrans{<:Any,<:SparseMatrixCSCUnion2}, B::DenseTriangular) = (T = promote_op(matprod, eltype(A), eltype(B)); mul!(similar(B, T, (size(A, 1), size(B, 2))), A, B)) -Base.@constprop :aggressive function LinearAlgebra.generic_matmatmul!(C::StridedMatrix, tA, tB, A::DenseMatrixUnion, B::AbstractSparseMatrixCSC, _add::MulAddMul) +Base.@constprop :aggressive function LinearAlgebra.generic_matmatmul!(C::StridedMatrix, tA, tB, A::DenseMatrixUnion, B::SparseMatrixCSCUnion2, _add::MulAddMul) transA = tA == 'N' ? identity : tA == 'T' ? transpose : adjoint if tB == 'N' _spmul!(C, transA(A), B, _add.alpha, _add.beta) @@ -114,7 +114,7 @@ Base.@constprop :aggressive function LinearAlgebra.generic_matmatmul!(C::Strided end return C end -function _spmul!(C::StridedMatrix, X::DenseMatrixUnion, A::AbstractSparseMatrixCSC, α::Number, β::Number) +function _spmul!(C::StridedMatrix, X::DenseMatrixUnion, A::SparseMatrixCSCUnion2, α::Number, β::Number) mX, nX = size(X) nX == size(A, 1) || throw(DimensionMismatch("second dimension of X, $nX, does not match the first dimension of A, $(size(A,1))")) @@ -134,7 +134,7 @@ function _spmul!(C::StridedMatrix, X::DenseMatrixUnion, A::AbstractSparseMatrixC end C end -function _spmul!(C::StridedMatrix, X::AdjOrTrans{<:Any,<:DenseMatrixUnion}, A::AbstractSparseMatrixCSC, α::Number, β::Number) +function _spmul!(C::StridedMatrix, X::AdjOrTrans{<:Any,<:DenseMatrixUnion}, A::SparseMatrixCSCUnion2, α::Number, β::Number) mX, nX = size(X) nX == size(A, 1) || throw(DimensionMismatch("second dimension of X, $nX, does not match the first dimension of A, $(size(A,1))")) @@ -152,14 +152,14 @@ function _spmul!(C::StridedMatrix, X::AdjOrTrans{<:Any,<:DenseMatrixUnion}, A::A end C end -*(X::StridedMaybeAdjOrTransMat, A::SparseMatrixCSCUnion{TvA}) where {TvA} = +*(X::StridedMaybeAdjOrTransMat, A::SparseMatrixCSCUnion2{TvA}) where {TvA} = (T = promote_op(matprod, eltype(X), TvA); mul!(similar(X, T, (size(X, 1), size(A, 2))), X, A, true, false)) -*(X::Union{BitMatrix,AdjOrTrans{<:Any,BitMatrix}}, A::SparseMatrixCSCUnion{TvA}) where {TvA} = +*(X::Union{BitMatrix,AdjOrTrans{<:Any,BitMatrix}}, A::SparseMatrixCSCUnion2{TvA}) where {TvA} = (T = promote_op(matprod, eltype(X), TvA); mul!(similar(X, T, (size(X, 1), size(A, 2))), X, A, true, false)) -*(X::DenseTriangular, A::SparseMatrixCSCUnion{TvA}) where {TvA} = +*(X::DenseTriangular, A::SparseMatrixCSCUnion2{TvA}) where {TvA} = (T = promote_op(matprod, eltype(X), TvA); mul!(similar(X, T, (size(X, 1), size(A, 2))), X, A, true, false)) -function _A_mul_Bt_or_Bc!(tfun::Function, C::StridedMatrix, A::AbstractMatrix, B::AbstractSparseMatrixCSC, α::Number, β::Number) +function _A_mul_Bt_or_Bc!(tfun::Function, C::StridedMatrix, A::AbstractMatrix, B::SparseMatrixCSCUnion2, α::Number, β::Number) mA, nA = size(A) nA == size(B, 2) || throw(DimensionMismatch("second dimension of A, $nA, does not match the second dimension of B, $(size(B,2))")) @@ -179,11 +179,11 @@ function _A_mul_Bt_or_Bc!(tfun::Function, C::StridedMatrix, A::AbstractMatrix, B end C end -*(X::StridedMaybeAdjOrTransMat, A::AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC}) = +*(X::StridedMaybeAdjOrTransMat, A::AdjOrTrans{<:Any,<:SparseMatrixCSCUnion2}) = (T = promote_op(matprod, eltype(X), eltype(A)); mul!(similar(X, T, (size(X, 1), size(A, 2))), X, A, true, false)) -*(X::Union{BitMatrix,AdjOrTrans{<:Any,BitMatrix}}, A::AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC}) = +*(X::Union{BitMatrix,AdjOrTrans{<:Any,BitMatrix}}, A::AdjOrTrans{<:Any,<:SparseMatrixCSCUnion2}) = (T = promote_op(matprod, eltype(X), eltype(A)); mul!(similar(X, T, (size(X, 1), size(A, 2))), X, A, true, false)) -*(X::DenseTriangular, A::AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC}) = +*(X::DenseTriangular, A::AdjOrTrans{<:Any,<:SparseMatrixCSCUnion2}) = (T = promote_op(matprod, eltype(X), eltype(A)); mul!(similar(X, T, (size(X, 1), size(A, 2))), X, A, true, false)) # Sparse matrix multiplication as described in [Gustavson, 1978]: diff --git a/src/sparsematrix.jl b/src/sparsematrix.jl index 34f1e9d6..f123a270 100644 --- a/src/sparsematrix.jl +++ b/src/sparsematrix.jl @@ -181,13 +181,21 @@ const SparseMatrixCSCView{Tv,Ti} = SubArray{Tv,2,<:AbstractSparseMatrixCSC{Tv,Ti}, Tuple{Base.Slice{Base.OneTo{Int}},I}} where {I<:AbstractUnitRange} const SparseMatrixCSCUnion{Tv,Ti} = Union{AbstractSparseMatrixCSC{Tv,Ti}, SparseMatrixCSCView{Tv,Ti}} +# Define an alias for views of a SparseMatrixCSC which include all rows and a selection of the columns. +# Also define a union of SparseMatrixCSC and this view since many methods can be defined efficiently for +# this union by extracting the fields via the get function: getrowval, and getnzval, BUT NOT getcolptr! +const SparseMatrixCSCView2{Tv,Ti} = + SubArray{Tv,2,<:AbstractSparseMatrixCSC{Tv,Ti}, + Tuple{Base.Slice{Base.OneTo{Int}},I}} where {I<:AbstractVector{<:Integer}} +const SparseMatrixCSCUnion2{Tv,Ti} = Union{AbstractSparseMatrixCSC{Tv,Ti}, SparseMatrixCSCView2{Tv,Ti}} getcolptr(S::SorF) = getfield(S, :colptr) -getcolptr(S::SparseMatrixCSCView) = view(getcolptr(parent(S)), first(axes(S, 2)):(last(axes(S, 2)) + 1)) +getcolptr(S::SparseMatrixCSCView) = view(getcolptr(parent(S)), first(S.indices[2]):(last(S.indices[2]) + 1)) +getcolptr(S::SparseMatrixCSCView2) = error("just to make sure") getrowval(S::AbstractSparseMatrixCSC) = rowvals(S) -getrowval(S::SparseMatrixCSCView) = rowvals(parent(S)) +getrowval(S::SparseMatrixCSCView2) = rowvals(parent(S)) getnzval( S::AbstractSparseMatrixCSC) = nonzeros(S) -getnzval( S::SparseMatrixCSCView) = nonzeros(parent(S)) +getnzval( S::SparseMatrixCSCView2) = nonzeros(parent(S)) nzvalview(S::AbstractSparseMatrixCSC) = view(nonzeros(S), 1:nnz(S)) """ @@ -212,7 +220,7 @@ nnz(S::ReshapedArray{<:Any,1,<:AbstractSparseMatrixCSC}) = nnz(parent(S)) nnz(S::AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC}) = nnz(parent(S)) nnz(S::UpperTriangular{<:Any,<:AbstractSparseMatrixCSC}) = nnz1(S) nnz(S::LowerTriangular{<:Any,<:AbstractSparseMatrixCSC}) = nnz1(S) -nnz(S::SparseMatrixCSCView) = nnz1(S) +nnz(S::SparseMatrixCSCView2) = nnz1(S) nnz1(S) = sum(length.(nzrange.(Ref(S), axes(S, 2)))) function Base._simple_count(pred, S::AbstractSparseMatrixCSC, init::T) where T @@ -244,7 +252,7 @@ julia> nonzeros(A) ``` """ nonzeros(S::SorF) = getfield(S, :nzval) -nonzeros(S::SparseMatrixCSCView) = nonzeros(S.parent) +nonzeros(S::SparseMatrixCSCView2) = nonzeros(S.parent) nonzeros(S::UpperTriangular{<:Any,<:SparseMatrixCSCUnion}) = nonzeros(S.data) nonzeros(S::LowerTriangular{<:Any,<:SparseMatrixCSCUnion}) = nonzeros(S.data) @@ -272,7 +280,7 @@ julia> rowvals(A) ``` """ rowvals(S::SorF) = getfield(S, :rowval) -rowvals(S::SparseMatrixCSCView) = rowvals(S.parent) +rowvals(S::SparseMatrixCSCView2) = rowvals(S.parent) rowvals(S::UpperTriangular{<:Any,<:SparseMatrixCSCUnion}) = rowvals(S.data) rowvals(S::LowerTriangular{<:Any,<:SparseMatrixCSCUnion}) = rowvals(S.data) @@ -299,7 +307,7 @@ column. In conjunction with [`nonzeros`](@ref) and Adding or removing nonzero elements to the matrix may invalidate the `nzrange`, one should not mutate the matrix while iterating. """ nzrange(S::AbstractSparseMatrixCSC, col::Integer) = getcolptr(S)[col]:(getcolptr(S)[col+1]-1) -nzrange(S::SparseMatrixCSCView, col::Integer) = nzrange(S.parent, S.indices[2][col]) +nzrange(S::SparseMatrixCSCView2, col::Integer) = nzrange(S.parent, S.indices[2][col]) nzrange(S::UpperTriangular{<:Any,<:SparseMatrixCSCUnion}, i::Integer) = nzrangeup(S.data, i) nzrange(S::LowerTriangular{<:Any,<:SparseMatrixCSCUnion}, i::Integer) = nzrangelo(S.data, i) From daa03640fc5227f817b7bbfbee76fdbf09bca6c8 Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Thu, 23 Nov 2023 21:00:19 +0100 Subject: [PATCH 4/7] add test, better error message --- src/sparsematrix.jl | 2 +- test/linalg.jl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sparsematrix.jl b/src/sparsematrix.jl index f123a270..76d8023e 100644 --- a/src/sparsematrix.jl +++ b/src/sparsematrix.jl @@ -191,7 +191,7 @@ const SparseMatrixCSCUnion2{Tv,Ti} = Union{AbstractSparseMatrixCSC{Tv,Ti}, Spars getcolptr(S::SorF) = getfield(S, :colptr) getcolptr(S::SparseMatrixCSCView) = view(getcolptr(parent(S)), first(S.indices[2]):(last(S.indices[2]) + 1)) -getcolptr(S::SparseMatrixCSCView2) = error("just to make sure") +getcolptr(S::SparseMatrixCSCView2) = error("getcolptr not well-defined for $(typeof(S))") getrowval(S::AbstractSparseMatrixCSC) = rowvals(S) getrowval(S::SparseMatrixCSCView2) = rowvals(parent(S)) getnzval( S::AbstractSparseMatrixCSC) = nonzeros(S) diff --git a/test/linalg.jl b/test/linalg.jl index d1825a82..19028877 100644 --- a/test/linalg.jl +++ b/test/linalg.jl @@ -152,6 +152,7 @@ begin A = sprand(rng, n, n, 0.01) MA = Matrix(A) lA = sprand(rng, n, n+10, 0.01) + @test nnz(lA[:, n+1:n+10]) == nnz(view(lA, :, n+1:n+10)) @testset "triangular multiply with $tr($wr)" for tr in (identity, adjoint, transpose), wr in (UpperTriangular, LowerTriangular, UnitUpperTriangular, UnitLowerTriangular) AW = tr(wr(A)) From a8b1ed8456a708d6c3fb800610f5f581ce03f157 Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Fri, 1 Dec 2023 19:58:14 +0100 Subject: [PATCH 5/7] rename alias --- src/sparsematrix.jl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sparsematrix.jl b/src/sparsematrix.jl index 76d8023e..c27cceec 100644 --- a/src/sparsematrix.jl +++ b/src/sparsematrix.jl @@ -184,18 +184,18 @@ const SparseMatrixCSCUnion{Tv,Ti} = Union{AbstractSparseMatrixCSC{Tv,Ti}, Sparse # Define an alias for views of a SparseMatrixCSC which include all rows and a selection of the columns. # Also define a union of SparseMatrixCSC and this view since many methods can be defined efficiently for # this union by extracting the fields via the get function: getrowval, and getnzval, BUT NOT getcolptr! -const SparseMatrixCSCView2{Tv,Ti} = +const SparseMatrixCSCColumnSubset{Tv,Ti} = SubArray{Tv,2,<:AbstractSparseMatrixCSC{Tv,Ti}, Tuple{Base.Slice{Base.OneTo{Int}},I}} where {I<:AbstractVector{<:Integer}} -const SparseMatrixCSCUnion2{Tv,Ti} = Union{AbstractSparseMatrixCSC{Tv,Ti}, SparseMatrixCSCView2{Tv,Ti}} +const SparseMatrixCSCUnion2{Tv,Ti} = Union{AbstractSparseMatrixCSC{Tv,Ti}, SparseMatrixCSCColumnSubset{Tv,Ti}} getcolptr(S::SorF) = getfield(S, :colptr) getcolptr(S::SparseMatrixCSCView) = view(getcolptr(parent(S)), first(S.indices[2]):(last(S.indices[2]) + 1)) -getcolptr(S::SparseMatrixCSCView2) = error("getcolptr not well-defined for $(typeof(S))") +getcolptr(S::SparseMatrixCSCColumnSubset) = error("getcolptr not well-defined for $(typeof(S))") getrowval(S::AbstractSparseMatrixCSC) = rowvals(S) -getrowval(S::SparseMatrixCSCView2) = rowvals(parent(S)) +getrowval(S::SparseMatrixCSCColumnSubset) = rowvals(parent(S)) getnzval( S::AbstractSparseMatrixCSC) = nonzeros(S) -getnzval( S::SparseMatrixCSCView2) = nonzeros(parent(S)) +getnzval( S::SparseMatrixCSCColumnSubset) = nonzeros(parent(S)) nzvalview(S::AbstractSparseMatrixCSC) = view(nonzeros(S), 1:nnz(S)) """ @@ -220,7 +220,7 @@ nnz(S::ReshapedArray{<:Any,1,<:AbstractSparseMatrixCSC}) = nnz(parent(S)) nnz(S::AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC}) = nnz(parent(S)) nnz(S::UpperTriangular{<:Any,<:AbstractSparseMatrixCSC}) = nnz1(S) nnz(S::LowerTriangular{<:Any,<:AbstractSparseMatrixCSC}) = nnz1(S) -nnz(S::SparseMatrixCSCView2) = nnz1(S) +nnz(S::SparseMatrixCSCColumnSubset) = nnz1(S) nnz1(S) = sum(length.(nzrange.(Ref(S), axes(S, 2)))) function Base._simple_count(pred, S::AbstractSparseMatrixCSC, init::T) where T @@ -252,7 +252,7 @@ julia> nonzeros(A) ``` """ nonzeros(S::SorF) = getfield(S, :nzval) -nonzeros(S::SparseMatrixCSCView2) = nonzeros(S.parent) +nonzeros(S::SparseMatrixCSCColumnSubset) = nonzeros(S.parent) nonzeros(S::UpperTriangular{<:Any,<:SparseMatrixCSCUnion}) = nonzeros(S.data) nonzeros(S::LowerTriangular{<:Any,<:SparseMatrixCSCUnion}) = nonzeros(S.data) @@ -280,7 +280,7 @@ julia> rowvals(A) ``` """ rowvals(S::SorF) = getfield(S, :rowval) -rowvals(S::SparseMatrixCSCView2) = rowvals(S.parent) +rowvals(S::SparseMatrixCSCColumnSubset) = rowvals(S.parent) rowvals(S::UpperTriangular{<:Any,<:SparseMatrixCSCUnion}) = rowvals(S.data) rowvals(S::LowerTriangular{<:Any,<:SparseMatrixCSCUnion}) = rowvals(S.data) @@ -307,7 +307,7 @@ column. In conjunction with [`nonzeros`](@ref) and Adding or removing nonzero elements to the matrix may invalidate the `nzrange`, one should not mutate the matrix while iterating. """ nzrange(S::AbstractSparseMatrixCSC, col::Integer) = getcolptr(S)[col]:(getcolptr(S)[col+1]-1) -nzrange(S::SparseMatrixCSCView2, col::Integer) = nzrange(S.parent, S.indices[2][col]) +nzrange(S::SparseMatrixCSCColumnSubset, col::Integer) = nzrange(S.parent, S.indices[2][col]) nzrange(S::UpperTriangular{<:Any,<:SparseMatrixCSCUnion}, i::Integer) = nzrangeup(S.data, i) nzrange(S::LowerTriangular{<:Any,<:SparseMatrixCSCUnion}, i::Integer) = nzrangelo(S.data, i) From 6e5cdf01aeef107a0e659899e712b8389e4d6a61 Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Sun, 7 Jan 2024 17:59:23 +0100 Subject: [PATCH 6/7] make `SparseMatrixCSCView <: SparseMatrixCSCColumnSubset` --- src/sparsematrix.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sparsematrix.jl b/src/sparsematrix.jl index c27cceec..ea16ace7 100644 --- a/src/sparsematrix.jl +++ b/src/sparsematrix.jl @@ -179,7 +179,7 @@ end # underlying SparseMatrixCSC const SparseMatrixCSCView{Tv,Ti} = SubArray{Tv,2,<:AbstractSparseMatrixCSC{Tv,Ti}, - Tuple{Base.Slice{Base.OneTo{Int}},I}} where {I<:AbstractUnitRange} + Tuple{Base.Slice{Base.OneTo{Int}},I}} where {I<:AbstractUnitRange{<:Integer}} const SparseMatrixCSCUnion{Tv,Ti} = Union{AbstractSparseMatrixCSC{Tv,Ti}, SparseMatrixCSCView{Tv,Ti}} # Define an alias for views of a SparseMatrixCSC which include all rows and a selection of the columns. # Also define a union of SparseMatrixCSC and this view since many methods can be defined efficiently for From b6a88024dcba23b14852cdb2aa8611090b89c451 Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Sun, 7 Jan 2024 19:30:34 +0100 Subject: [PATCH 7/7] remove obsolete line --- src/linalg.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/linalg.jl b/src/linalg.jl index 225b816e..5dd9e9a3 100644 --- a/src/linalg.jl +++ b/src/linalg.jl @@ -114,7 +114,6 @@ function _At_or_Ac_mul_B!(tfun::Function, C, A, B, α, β) C end - Base.@constprop :aggressive function LinearAlgebra.generic_matmatmul!(C::StridedMatrix, tA, tB, A::DenseMatrixUnion, B::SparseMatrixCSCUnion2, _add::MulAddMul) transA = tA == 'N' ? identity : tA == 'T' ? transpose : adjoint if tB == 'N'