Skip to content

Commit 7abbefa

Browse files
authored
allow identity matrices of types with alternative unity (#732)
Closes #731
1 parent 896723a commit 7abbefa

2 files changed

Lines changed: 32 additions & 6 deletions

File tree

src/sparsematrix.jl

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,7 +2205,7 @@ end
22052205
import Base._one
22062206
function Base._one(unit::T, S::AbstractSparseMatrixCSC) where T
22072207
size(S, 1) == size(S, 2) || throw(DimensionMismatch("multiplicative identity only defined for square matrices"))
2208-
return SparseMatrixCSC{T}(I, size(S, 1), size(S, 2))
2208+
return _spscaling(T, Int, unit, size(S, 1), size(S, 2))
22092209
end
22102210

22112211
## SparseMatrixCSC construction from UniformScaling
@@ -2217,13 +2217,19 @@ SparseMatrixCSC(s::UniformScaling, dims::Dims{2}) = SparseMatrixCSC{eltype(s)}(s
22172217
function SparseMatrixCSC{Tv,Ti}(s::UniformScaling, dims::Dims{2}) where {Tv,Ti}
22182218
@boundscheck first(dims) < 0 && throw(ArgumentError("first dimension invalid ($(first(dims)) < 0)"))
22192219
@boundscheck last(dims) < 0 && throw(ArgumentError("second dimension invalid ($(last(dims)) < 0)"))
2220-
iszero(s.λ) && return spzeros(Tv, Ti, dims...)
2221-
m, n, k = dims..., min(dims...)
2222-
nzval = fill!(Vector{Tv}(undef, k), Tv(s.λ))
2220+
return _spscaling(Tv, Ti, s.λ, dims...)
2221+
end
2222+
2223+
function _spscaling(::Type{Tv}, ::Type{Ti}, λ, m, n) where {Tv,Ti<:Integer}
2224+
iszero(λ) && return spzeros(Tv, Ti, m, n)
2225+
k = min(m, n)
2226+
nzval = fill!(Vector{Tv}(undef, k), Tv(λ))
22232227
rowval = copyto!(Vector{Ti}(undef, k), 1:k)
22242228
colptr = copyto!(Vector{Ti}(undef, n + 1), 1:(k + 1))
2225-
for i in (k + 2):(n + 1) colptr[i] = (k + 1) end
2226-
SparseMatrixCSC{Tv,Ti}(dims..., colptr, rowval, nzval)
2229+
for i in (k + 2):(n + 1)
2230+
colptr[i] = (k + 1)
2231+
end
2232+
return SparseMatrixCSC{Tv,Ti}(m, n, colptr, rowval, nzval)
22272233
end
22282234

22292235
Base.iszero(A::AbstractSparseMatrixCSC) = iszero(nzvalview(A))

test/sparsematrix_constructors_indexing.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,26 @@ end
976976
@test one(sparse([1 1; 1 1]))::SparseMatrixCSC == [1 0; 0 1]
977977
end
978978

979+
struct MockTropical{T} <: Number begin
980+
n::T
981+
end
982+
end
983+
MockTropical{T}(x::MockTropical{T}) where {T} = x
984+
Base.zero(::Type{MockTropical{T}}) where {T} = MockTropical{T}(typemin(T))
985+
Base.zero(x::MockTropical{T}) where {T} = zero(MockTropical{T})
986+
Base.one(::Type{MockTropical{T}}) where {T} = MockTropical{T}(zero(T))
987+
Base.one(x::MockTropical{T}) where {T} = one(MockTropical{T})
988+
Base.:*(a::MockTropical{T}, b::MockTropical{T}) where {T} = MockTropical{T}(a.n + b.n)
989+
Base.:+(a::MockTropical{T}, b::MockTropical{T}) where {T} = MockTropical{T}(max(a.n, b.n))
990+
991+
@testset "issue #731" begin
992+
x = MockTropical{Float64}(1.0)
993+
B = sparse([1, 2], [1,2], [x, x])
994+
C = [one(x) zero(x); zero(x) one(x)]
995+
@test one(B) == C
996+
@test B^0 == C
997+
end
998+
979999
@testset "sparsevec" begin
9801000
local A = sparse(fill(1, 5, 5))
9811001
@test sparsevec(A) == fill(1, 25)

0 commit comments

Comments
 (0)