From 55fb76e5c3e3a6863323452294e5e475b729f82b Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sun, 27 Apr 2025 17:00:31 +0530 Subject: [PATCH 1/2] symmetry check in `setindex!` for `Symmetric`/`Hermitian` --- src/symmetric.jl | 14 +++++++++----- test/symmetric.jl | 11 +++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/symmetric.jl b/src/symmetric.jl index 09819325..b6099072 100644 --- a/src/symmetric.jl +++ b/src/symmetric.jl @@ -229,6 +229,12 @@ const SelfAdjoint = Union{Symmetric{<:Real}, Hermitian{<:Number}} wrappertype(::Union{Symmetric, SymTridiagonal}) = Symmetric wrappertype(::Hermitian) = Hermitian +_symherm_wrapperop(::Symmetric) = symmetric +_symherm_wrapperop(::Hermitian) = hermitian + +_conjugation(::Symmetric) = transpose +_conjugation(::Hermitian) = adjoint + size(A::HermOrSym) = size(A.data) axes(A::HermOrSym) = axes(A.data) @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' @propagate_inbounds function setindex!(A::Symmetric, v, i::Integer, j::Integer) i == j || throw(ArgumentError("Cannot set a non-diagonal index in a symmetric matrix")) + issymmetric(v) || throw(ArgumentError("cannot set a diagonal element of a symmetric matrix to an asymmetric value")) setindex!(A.data, v, i, j) return A end @@ -276,8 +283,8 @@ Base._reverse(A::Hermitian, ::Colon) = Hermitian(reverse(A.data), A.uplo == 'U' @propagate_inbounds function setindex!(A::Hermitian, v, i::Integer, j::Integer) if i != j throw(ArgumentError("Cannot set a non-diagonal index in a Hermitian matrix")) - elseif !isreal(v) - throw(ArgumentError("Cannot set a diagonal entry in a Hermitian matrix to a nonreal value")) + elseif !ishermitian(v) + throw(ArgumentError("cannot set a diagonal element of a hermitian matrix to a non-hermitian value")) else setindex!(A.data, v, i, j) end @@ -288,9 +295,6 @@ Base.dataids(A::HermOrSym) = Base.dataids(parent(A)) Base.unaliascopy(A::Hermitian) = Hermitian(Base.unaliascopy(parent(A)), sym_uplo(A.uplo)) Base.unaliascopy(A::Symmetric) = Symmetric(Base.unaliascopy(parent(A)), sym_uplo(A.uplo)) -_conjugation(::Symmetric) = transpose -_conjugation(::Hermitian) = adjoint - diag(A::Symmetric) = symmetric.(diag(parent(A)), sym_uplo(A.uplo)) diag(A::Hermitian) = hermitian.(diag(parent(A)), sym_uplo(A.uplo)) diff --git a/test/symmetric.jl b/test/symmetric.jl index 6e4a5029..c6b6fdc4 100644 --- a/test/symmetric.jl +++ b/test/symmetric.jl @@ -1180,4 +1180,15 @@ end end end +@testset "block-symmetric setindex!" begin + A = fill([1 2; 3 4], 2, 2) + v = [1 2; 3 4] + H = Hermitian(A) + h_msg = "cannot set a diagonal element of a hermitian matrix to a non-hermitian value" + @test_throws h_msg H[1,1] = v + S = Symmetric(A) + s_msg = "cannot set a diagonal element of a symmetric matrix to an asymmetric value" + @test_throws s_msg S[1,1] = v +end + end # module TestSymmetric From 65b85382e1def044a698148944c976df5ee71051 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sun, 27 Apr 2025 18:11:53 +0530 Subject: [PATCH 2/2] Revert unused hunks --- src/symmetric.jl | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/symmetric.jl b/src/symmetric.jl index b6099072..04eaf9f0 100644 --- a/src/symmetric.jl +++ b/src/symmetric.jl @@ -229,12 +229,6 @@ const SelfAdjoint = Union{Symmetric{<:Real}, Hermitian{<:Number}} wrappertype(::Union{Symmetric, SymTridiagonal}) = Symmetric wrappertype(::Hermitian) = Hermitian -_symherm_wrapperop(::Symmetric) = symmetric -_symherm_wrapperop(::Hermitian) = hermitian - -_conjugation(::Symmetric) = transpose -_conjugation(::Hermitian) = adjoint - size(A::HermOrSym) = size(A.data) axes(A::HermOrSym) = axes(A.data) @inline function Base.isassigned(A::HermOrSym, i::Int, j::Int) @@ -295,6 +289,9 @@ Base.dataids(A::HermOrSym) = Base.dataids(parent(A)) Base.unaliascopy(A::Hermitian) = Hermitian(Base.unaliascopy(parent(A)), sym_uplo(A.uplo)) Base.unaliascopy(A::Symmetric) = Symmetric(Base.unaliascopy(parent(A)), sym_uplo(A.uplo)) +_conjugation(::Symmetric) = transpose +_conjugation(::Hermitian) = adjoint + diag(A::Symmetric) = symmetric.(diag(parent(A)), sym_uplo(A.uplo)) diag(A::Hermitian) = hermitian.(diag(parent(A)), sym_uplo(A.uplo))