Skip to content

Avoid explicitly evaluating zero elements in certain structured matrix broadcast operations #985

Closed
JuliaLang/julia
#53909
@jishnub

Description

@jishnub

For block-banded structured matrix types, the zero elements may not be well-defined, e.g:

julia> D = Diagonal([Float64[1 2; 3 4], Float64[5 6; 7 8]])
2×2 Diagonal{Matrix{Float64}, Vector{Matrix{Float64}}}:
 [1.0 2.0; 3.0 4.0]                   
                    [5.0 6.0; 7.0 8.0]

julia> D .+ D
ERROR: MethodError: no method matching zero(::Type{Matrix{Float64}})

Closest candidates are:
  zero(::Union{Type{P}, P}) where P<:Dates.Period
   @ Dates ~/packages/julias/julia-latest/share/julia/stdlib/v1.10/Dates/src/periods.jl:51
  zero(::AbstractIrrational)
   @ Base irrationals.jl:151
  zero(::Diagonal)
   @ LinearAlgebra ~/packages/julias/julia-latest/share/julia/stdlib/v1.10/LinearAlgebra/src/special.jl:324
  ...

Stacktrace:
 [1] fzero(S::Diagonal{Matrix{Float64}, Vector{Matrix{Float64}}})
   @ LinearAlgebra ~/packages/julias/julia-latest/share/julia/stdlib/v1.10/LinearAlgebra/src/structuredbroadcast.jl:146
 [2] map
   @ ./tuple.jl:290 [inlined]
 [3] fzero(bc::Base.Broadcast.Broadcasted{LinearAlgebra.StructuredMatrixStyle{Diagonal}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, typeof(+), Tuple{Diagonal{Matrix{Float64}, Vector{Matrix{Float64}}}, Diagonal{Matrix{Float64}, Vector{Matrix{Float64}}}}})
   @ LinearAlgebra ~/packages/julias/julia-latest/share/julia/stdlib/v1.10/LinearAlgebra/src/structuredbroadcast.jl:149
 [4] fzeropreserving(bc::Base.Broadcast.Broadcasted{LinearAlgebra.StructuredMatrixStyle{Diagonal}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, typeof(+), Tuple{Diagonal{Matrix{Float64}, Vector{Matrix{Float64}}}, Diagonal{Matrix{Float64}, Vector{Matrix{Float64}}}}})
   @ LinearAlgebra ~/packages/julias/julia-latest/share/julia/stdlib/v1.10/LinearAlgebra/src/structuredbroadcast.jl:137
 [5] similar(bc::Base.Broadcast.Broadcasted{LinearAlgebra.StructuredMatrixStyle{Diagonal}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, typeof(+), Tuple{Diagonal{Matrix{Float64}, Vector{Matrix{Float64}}}, Diagonal{Matrix{Float64}, Vector{Matrix{Float64}}}}}, #unused#::Type{Matrix{Float64}})
   @ LinearAlgebra ~/packages/julias/julia-latest/share/julia/stdlib/v1.10/LinearAlgebra/src/structuredbroadcast.jl:155
 [6] copy(bc::Base.Broadcast.Broadcasted{LinearAlgebra.StructuredMatrixStyle{Diagonal}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, typeof(+), Tuple{Diagonal{Matrix{Float64}, Vector{Matrix{Float64}}}, Diagonal{Matrix{Float64}, Vector{Matrix{Float64}}}}})
   @ Base.Broadcast ./broadcast.jl:912
 [7] materialize(bc::Base.Broadcast.Broadcasted{LinearAlgebra.StructuredMatrixStyle{Diagonal}, Nothing, typeof(+), Tuple{Diagonal{Matrix{Float64}, Vector{Matrix{Float64}}}, Diagonal{Matrix{Float64}, Vector{Matrix{Float64}}}}})
   @ Base.Broadcast ./broadcast.jl:887
 [8] top-level scope
   @ REPL[3]:1

However, in this case, the result may be obtained without any reference to the zeros.

julia> D + D
2×2 Diagonal{Matrix{Float64}, Vector{Matrix{Float64}}}:
 [2.0 4.0; 6.0 8.0]                   
                    [10.0 12.0; 14.0 16.0]

I wonder if it might be possible to evaluate the result using broadcasting without explicitly evaluating the zero elements?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions