Skip to content

Commit 44fc535

Browse files
jishnubKristofferC
authored andcommitted
Restrict binary ops for Diagonal and Symmetric to Number eltypes (#55251)
The `(::Diagonal) + (::Symmetric)` and analogous methods were specialized in #35333 to return a `Symmetric`, but these only work if the `Diagonal` is also symmetric. This typically holds for arrays of numbers, but may not hold for block-diagonal and other types for which symmetry isn't guaranteed. This PR restricts the methods to arrays of `Number`s. Fixes, e.g.: ```julia julia> using StaticArrays, LinearAlgebra julia> D = Diagonal(fill(SMatrix{2,2}(1:4), 2)) 2×2 Diagonal{SMatrix{2, 2, Int64, 4}, Vector{SMatrix{2, 2, Int64, 4}}}: [1 3; 2 4] ⋅ ⋅ [1 3; 2 4] julia> S = Symmetric(D) 2×2 Symmetric{AbstractMatrix, Diagonal{SMatrix{2, 2, Int64, 4}, Vector{SMatrix{2, 2, Int64, 4}}}}: [1 3; 3 4] ⋅ ⋅ [1 3; 3 4] julia> S + D 2×2 Symmetric{AbstractMatrix, Diagonal{SMatrix{2, 2, Int64, 4}, Vector{SMatrix{2, 2, Int64, 4}}}}: [2 6; 6 8] ⋅ ⋅ [2 6; 6 8] julia> S[1,1] + D[1,1] 2×2 SMatrix{2, 2, Int64, 4} with indices SOneTo(2)×SOneTo(2): 2 6 5 8 julia> (S + D)[1,1] == S[1,1] + D[1,1] false ``` After this, ```julia julia> S + D 2×2 Matrix{AbstractMatrix{Int64}}: [2 6; 5 8] [0 0; 0 0] [0 0; 0 0] [2 6; 5 8] ``` Even with `Number`s as elements, there might be an issue with `NaN`s along the diagonal as `!issymmetric(NaN)`, but that may be a different PR. (cherry picked from commit 197295c)
1 parent 4e7648f commit 44fc535

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

stdlib/LinearAlgebra/src/diagonal.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,10 @@ end
251251
(-)(Da::Diagonal, Db::Diagonal) = Diagonal(Da.diag - Db.diag)
252252

253253
for f in (:+, :-)
254-
@eval function $f(D::Diagonal, S::Symmetric)
254+
@eval function $f(D::Diagonal{<:Number}, S::Symmetric)
255255
return Symmetric($f(D, S.data), sym_uplo(S.uplo))
256256
end
257-
@eval function $f(S::Symmetric, D::Diagonal)
257+
@eval function $f(S::Symmetric, D::Diagonal{<:Number})
258258
return Symmetric($f(S.data, D), sym_uplo(S.uplo))
259259
end
260260
@eval function $f(D::Diagonal{<:Real}, H::Hermitian)

stdlib/LinearAlgebra/test/diagonal.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,4 +1300,16 @@ end
13001300
@test lmul!(D, copy(B)) D * B DA * BA
13011301
end
13021302
end
1303+
@testset "+/- with block Symmetric/Hermitian" begin
1304+
for p in ([1 2; 3 4], [1 2+im; 2-im 4+2im])
1305+
m = SizedArrays.SizedArray{(2,2)}(p)
1306+
D = Diagonal(fill(m, 2))
1307+
for T in (Symmetric, Hermitian)
1308+
S = T(fill(m, 2, 2))
1309+
@test D + S == Array(D) + Array(S)
1310+
@test S + D == Array(S) + Array(D)
1311+
end
1312+
end
1313+
end
1314+
13031315
end # module TestDiagonal

0 commit comments

Comments
 (0)