Skip to content

Commit bb652fa

Browse files
committed
fix #29392: HermOrSym should preserve structure when scaled with Numbers.
1 parent 0bab957 commit bb652fa

File tree

2 files changed

+51
-6
lines changed

2 files changed

+51
-6
lines changed

stdlib/LinearAlgebra/src/symmetric.jl

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -440,12 +440,13 @@ mul!(C::StridedMatrix{T}, A::StridedMatrix{T}, B::Hermitian{T,<:StridedMatrix})
440440
*(adjA::Adjoint{<:Any,<:RealHermSymComplexHerm}, B::AbstractTriangular) = adjA.parent * B
441441
*(A::AbstractTriangular, adjB::Adjoint{<:Any,<:RealHermSymComplexHerm}) = A * adjB.parent
442442

443-
for T in (:Symmetric, :Hermitian), op in (:*, :/)
444-
# Deal with an ambiguous case
445-
@eval ($op)(A::$T, x::Bool) = ($T)(($op)(A.data, x), sym_uplo(A.uplo))
446-
S = T == :Hermitian ? :Real : :Number
447-
@eval ($op)(A::$T, x::$S) = ($T)(($op)(A.data, x), sym_uplo(A.uplo))
448-
end
443+
# Scaling with Number
444+
*(A::Symmetric, x::Number) = Symmetric(A.data*x, Symbol(A.uplo))
445+
*(x::Number, A::Symmetric) = Symmetric(x*A.data, Symbol(A.uplo))
446+
*(A::Hermitian, x::Real) = Hermitian(A.data*x, Symbol(A.uplo))
447+
*(x::Real, A::Hermitian) = Hermitian(x*A.data, Symbol(A.uplo))
448+
/(A::Symmetric, x::Number) = Symmetric(A.data/x, Symbol(A.uplo))
449+
/(A::Hermitian, x::Real) = Hermitian(A.data/x, Symbol(A.uplo))
449450

450451
function factorize(A::HermOrSym{T}) where T
451452
TT = typeof(sqrt(oneunit(T)))

stdlib/LinearAlgebra/test/symmetric.jl

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,4 +517,48 @@ end
517517
@test Hermitian(A, :U)[1,1] == Hermitian(A, :L)[1,1] == real(A[1,1])
518518
end
519519

520+
@testset "issue #29392: SymOrHerm scaled with Number" begin
521+
R = rand(Float64, 2, 2); C = rand(ComplexF64, 2, 2)
522+
# Symmetric * Real, Real * Symmetric
523+
A = Symmetric(R); x = 2.0
524+
@test (A * x)::Symmetric == (x * A)::Symmetric
525+
A = Symmetric(C); x = 2.0
526+
@test (A * x)::Symmetric == (x * A)::Symmetric
527+
# Symmetric * Complex, Complex * Symmetrics
528+
A = Symmetric(R); x = 2.0im
529+
@test (A * x)::Symmetric == (x * A)::Symmetric
530+
A = Symmetric(C); x = 2.0im
531+
@test (A * x)::Symmetric == (x * A)::Symmetric
532+
# Hermitian * Real, Real * Hermitian
533+
A = Hermitian(R); x = 2.0
534+
@test (A * x)::Hermitian == (x * A)::Hermitian
535+
A = Hermitian(C); x = 2.0
536+
@test (A * x)::Hermitian == (x * A)::Hermitian
537+
# Hermitian * Complex, Complex * Hermitian
538+
A = Hermitian(R); x = 2.0im
539+
@test (A * x)::Matrix == (x * A)::Matrix
540+
A = Hermitian(C); x = 2.0im
541+
@test (A * x)::Matrix == (x * A)::Matrix
542+
# Symmetric / Real
543+
A = Symmetric(R); x = 2.0
544+
@test (A / x)::Symmetric == Matrix(A) / x
545+
A = Symmetric(C); x = 2.0
546+
@test (A / x)::Symmetric == Matrix(A) / x
547+
# Symmetric / Complex
548+
A = Symmetric(R); x = 2.0im
549+
@test (A / x)::Symmetric == Matrix(A) / x
550+
A = Symmetric(C); x = 2.0im
551+
@test (A / x)::Symmetric == Matrix(A) / x
552+
# Hermitian / Real
553+
A = Hermitian(R); x = 2.0
554+
@test (A / x)::Hermitian == Matrix(A) / x
555+
A = Hermitian(C); x = 2.0
556+
@test (A / x)::Hermitian == Matrix(A) / x
557+
# Hermitian / Complex
558+
A = Hermitian(R); x = 2.0im
559+
@test (A / x)::Matrix == Matrix(A) / x
560+
A = Hermitian(C); x = 2.0im
561+
@test (A / x)::Matrix == Matrix(A) / x
562+
end
563+
520564
end # module TestSymmetric

0 commit comments

Comments
 (0)