Skip to content

Commit 78de77e

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 4976d05 commit 78de77e

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
@@ -226,10 +226,10 @@ end
226226
(-)(Da::Diagonal, Db::Diagonal) = Diagonal(Da.diag - Db.diag)
227227

228228
for f in (:+, :-)
229-
@eval function $f(D::Diagonal, S::Symmetric)
229+
@eval function $f(D::Diagonal{<:Number}, S::Symmetric)
230230
return Symmetric($f(D, S.data), sym_uplo(S.uplo))
231231
end
232-
@eval function $f(S::Symmetric, D::Diagonal)
232+
@eval function $f(S::Symmetric, D::Diagonal{<:Number})
233233
return Symmetric($f(S.data, D), sym_uplo(S.uplo))
234234
end
235235
@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
@@ -1193,4 +1193,16 @@ end
11931193
end
11941194
end
11951195

1196+
@testset "+/- with block Symmetric/Hermitian" begin
1197+
for p in ([1 2; 3 4], [1 2+im; 2-im 4+2im])
1198+
m = SizedArrays.SizedArray{(2,2)}(p)
1199+
D = Diagonal(fill(m, 2))
1200+
for T in (Symmetric, Hermitian)
1201+
S = T(fill(m, 2, 2))
1202+
@test D + S == Array(D) + Array(S)
1203+
@test S + D == Array(S) + Array(D)
1204+
end
1205+
end
1206+
end
1207+
11961208
end # module TestDiagonal

0 commit comments

Comments
 (0)