Skip to content

Commit

Permalink
LinearAlgebra: Allow arrays to be zero-preserving (#46340)
Browse files Browse the repository at this point in the history
  • Loading branch information
eschnett authored Sep 13, 2022
1 parent e8a2eb1 commit 85fac87
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
1 change: 1 addition & 0 deletions stdlib/LinearAlgebra/src/structuredbroadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ fails as `zero(::Tuple{Int})` is not defined. However,
"""
iszerodefined(::Type) = false
iszerodefined(::Type{<:Number}) = true
iszerodefined(::Type{<:AbstractArray{T}}) where T = iszerodefined(T)

fzeropreserving(bc) = (v = fzero(bc); !ismissing(v) && (iszerodefined(typeof(v)) ? iszero(v) : v == 0))
# Like sparse matrices, we assume that the zero-preservation property of a broadcasted
Expand Down
23 changes: 23 additions & 0 deletions stdlib/LinearAlgebra/test/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1106,4 +1106,27 @@ end
@test outTri === mul!(outTri, UTriA, D, 2, 1)::Tri == mul!(out, Matrix(UTriA), D, 2, 1)
end

struct SMatrix1{T} <: AbstractArray{T,2}
elt::T
end
Base.:(==)(A::SMatrix1, B::SMatrix1) = A.elt == B.elt
Base.zero(::Type{SMatrix1{T}}) where {T} = SMatrix1(zero(T))
Base.iszero(A::SMatrix1) = iszero(A.elt)
Base.getindex(A::SMatrix1, inds...) = A.elt
Base.size(::SMatrix1) = (1, 1)
@testset "map for Diagonal matrices (#46292)" begin
A = Diagonal([1])
@test A isa Diagonal{Int,Vector{Int}}
@test 2*A isa Diagonal{Int,Vector{Int}}
@test A.+1 isa Matrix{Int}
# Numeric element types remain diagonal
B = map(SMatrix1, A)
@test B == fill(SMatrix1(1), 1, 1)
@test B isa Diagonal{SMatrix1{Int},Vector{SMatrix1{Int}}}
# Non-numeric element types become dense
C = map(a -> SMatrix1(string(a)), A)
@test C == fill(SMatrix1(string(1)), 1, 1)
@test C isa Matrix{SMatrix1{String}}
end

end # module TestDiagonal

0 comments on commit 85fac87

Please sign in to comment.