Skip to content

Commit 55fb76e

Browse files
committed
symmetry check in setindex! for Symmetric/Hermitian
1 parent 5d3d02a commit 55fb76e

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

src/symmetric.jl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,12 @@ const SelfAdjoint = Union{Symmetric{<:Real}, Hermitian{<:Number}}
229229
wrappertype(::Union{Symmetric, SymTridiagonal}) = Symmetric
230230
wrappertype(::Hermitian) = Hermitian
231231

232+
_symherm_wrapperop(::Symmetric) = symmetric
233+
_symherm_wrapperop(::Hermitian) = hermitian
234+
235+
_conjugation(::Symmetric) = transpose
236+
_conjugation(::Hermitian) = adjoint
237+
232238
size(A::HermOrSym) = size(A.data)
233239
axes(A::HermOrSym) = axes(A.data)
234240
@inline function Base.isassigned(A::HermOrSym, i::Int, j::Int)
@@ -266,6 +272,7 @@ Base._reverse(A::Symmetric, ::Colon) = Symmetric(reverse(A.data), A.uplo == 'U'
266272

267273
@propagate_inbounds function setindex!(A::Symmetric, v, i::Integer, j::Integer)
268274
i == j || throw(ArgumentError("Cannot set a non-diagonal index in a symmetric matrix"))
275+
issymmetric(v) || throw(ArgumentError("cannot set a diagonal element of a symmetric matrix to an asymmetric value"))
269276
setindex!(A.data, v, i, j)
270277
return A
271278
end
@@ -276,8 +283,8 @@ Base._reverse(A::Hermitian, ::Colon) = Hermitian(reverse(A.data), A.uplo == 'U'
276283
@propagate_inbounds function setindex!(A::Hermitian, v, i::Integer, j::Integer)
277284
if i != j
278285
throw(ArgumentError("Cannot set a non-diagonal index in a Hermitian matrix"))
279-
elseif !isreal(v)
280-
throw(ArgumentError("Cannot set a diagonal entry in a Hermitian matrix to a nonreal value"))
286+
elseif !ishermitian(v)
287+
throw(ArgumentError("cannot set a diagonal element of a hermitian matrix to a non-hermitian value"))
281288
else
282289
setindex!(A.data, v, i, j)
283290
end
@@ -288,9 +295,6 @@ Base.dataids(A::HermOrSym) = Base.dataids(parent(A))
288295
Base.unaliascopy(A::Hermitian) = Hermitian(Base.unaliascopy(parent(A)), sym_uplo(A.uplo))
289296
Base.unaliascopy(A::Symmetric) = Symmetric(Base.unaliascopy(parent(A)), sym_uplo(A.uplo))
290297

291-
_conjugation(::Symmetric) = transpose
292-
_conjugation(::Hermitian) = adjoint
293-
294298
diag(A::Symmetric) = symmetric.(diag(parent(A)), sym_uplo(A.uplo))
295299
diag(A::Hermitian) = hermitian.(diag(parent(A)), sym_uplo(A.uplo))
296300

test/symmetric.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,4 +1180,15 @@ end
11801180
end
11811181
end
11821182

1183+
@testset "block-symmetric setindex!" begin
1184+
A = fill([1 2; 3 4], 2, 2)
1185+
v = [1 2; 3 4]
1186+
H = Hermitian(A)
1187+
h_msg = "cannot set a diagonal element of a hermitian matrix to a non-hermitian value"
1188+
@test_throws h_msg H[1,1] = v
1189+
S = Symmetric(A)
1190+
s_msg = "cannot set a diagonal element of a symmetric matrix to an asymmetric value"
1191+
@test_throws s_msg S[1,1] = v
1192+
end
1193+
11831194
end # module TestSymmetric

0 commit comments

Comments
 (0)