Add *(::Diagonal, ::Diagonal, ::Diagonal) (#49005)#49007
Add *(::Diagonal, ::Diagonal, ::Diagonal) (#49005)#49007dkarrasch merged 6 commits intoJuliaLang:masterfrom
Conversation
|
Currently, this uses broadcasting, and I wonder if it might not be better to make the result of the broadcast operation return a julia> (1:4) .* Diagonal(1:4) .* (1:4)' # may return a Diagonal
4×4 Matrix{Int64}:
1 0 0 0
0 8 0 0
0 0 27 0
0 0 0 64In fact, each component may be evaluated to a julia> (1:4) .* Diagonal(1:4)
4×4 Matrix{Int64}:
1 0 0 0
0 4 0 0
0 0 9 0
0 0 0 16
julia> Diagonal(1:4) .* (1:4)'
4×4 Matrix{Int64}:
1 0 0 0
0 4 0 0
0 0 9 0
0 0 0 16 |
|
That would require special case-ing broadcast for |
|
This is tricky with floating-point values, as julia> Diagonal([1,NaN]) * Diagonal(1:2) * Diagonal([1,NaN])
2×2 Matrix{Float64}:
1.0 NaN
NaN NaN |
This is already the case with e.g. sparse arrays. And it was like that on 1.8 as well. |
|
How does |
julia> Diagonal(1:2) * Diagonal(1:2) * Diagonal(1:2) * Diagonal(1:2)
2×2 Diagonal{Int64, Vector{Int64}}:
1 ⋅
⋅ 16The 4-term multiplication, as implemented, uses combinations of 2-term multiplications, which returns a |
|
I added a 4-term test so any future regressions will be picked up |
(cherry picked from commit c37fc27)
This adds a special case for triple multiplication of diagonals to ensure that the result is a
Diagonal, see JuliaLang/LinearAlgebra.jl#992.