Skip to content

Commit 197295c

Browse files
authored
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.
1 parent 9d112fb commit 197295c

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

stdlib/LinearAlgebra/src/diagonal.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,10 @@ end
268268
(-)(Da::Diagonal, Db::Diagonal) = Diagonal(Da.diag - Db.diag)
269269

270270
for f in (:+, :-)
271-
@eval function $f(D::Diagonal, S::Symmetric)
271+
@eval function $f(D::Diagonal{<:Number}, S::Symmetric)
272272
return Symmetric($f(D, S.data), sym_uplo(S.uplo))
273273
end
274-
@eval function $f(S::Symmetric, D::Diagonal)
274+
@eval function $f(S::Symmetric, D::Diagonal{<:Number})
275275
return Symmetric($f(S.data, D), sym_uplo(S.uplo))
276276
end
277277
@eval function $f(D::Diagonal{<:Real}, H::Hermitian)

stdlib/LinearAlgebra/test/diagonal.jl

+12
Original file line numberDiff line numberDiff line change
@@ -1335,4 +1335,16 @@ end
13351335
end
13361336
end
13371337

1338+
@testset "+/- with block Symmetric/Hermitian" begin
1339+
for p in ([1 2; 3 4], [1 2+im; 2-im 4+2im])
1340+
m = SizedArrays.SizedArray{(2,2)}(p)
1341+
D = Diagonal(fill(m, 2))
1342+
for T in (Symmetric, Hermitian)
1343+
S = T(fill(m, 2, 2))
1344+
@test D + S == Array(D) + Array(S)
1345+
@test S + D == Array(S) + Array(D)
1346+
end
1347+
end
1348+
end
1349+
13381350
end # module TestDiagonal

0 commit comments

Comments
 (0)