From 17280b2c4dcaeb5b2cf3605d2347e3a276714a59 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Tue, 9 Jan 2024 09:41:45 +0530 Subject: [PATCH] Widen eltype in complex hermitian tridiagonal eigen (#52802) Close #52801 by widening the `eltype` appropriately. --- stdlib/LinearAlgebra/src/symmetriceigen.jl | 10 +++++----- stdlib/LinearAlgebra/test/symmetriceigen.jl | 7 +++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/stdlib/LinearAlgebra/src/symmetriceigen.jl b/stdlib/LinearAlgebra/src/symmetriceigen.jl index 246556e88ff02..0c86383685807 100644 --- a/stdlib/LinearAlgebra/src/symmetriceigen.jl +++ b/stdlib/LinearAlgebra/src/symmetriceigen.jl @@ -309,12 +309,12 @@ function eigen(A::Hermitian{Complex{T}, <:Tridiagonal}; kwargs...) where {T} E = dl Er = abs.(E) end - S = Vector{Complex{T}}(undef, N) + S = Vector{eigtype(eltype(A))}(undef, N) S[1] = 1 for i ∈ 1:N-1 - S[i+1] = iszero(Er[i]) ? one(Complex{T}) : S[i] * sign(E[i]) + S[i+1] = iszero(Er[i]) ? oneunit(eltype(S)) : S[i] * sign(E[i]) end - B = SymTridiagonal(real(d), Er) + B = SymTridiagonal(float.(real.(d)), Er) Λ, Φ = eigen(B; kwargs...) return Eigen(Λ, Diagonal(S) * Φ) end @@ -322,6 +322,6 @@ end function eigvals(A::Hermitian{Complex{T}, <:Tridiagonal}; kwargs...) where {T} (; dl, d, du) = parent(A) - E = A.uplo == 'U' ? abs.(du) : abs.(dl) - eigvals(SymTridiagonal(real.(d), E); kwargs...) + Er = A.uplo == 'U' ? abs.(du) : abs.(dl) + eigvals(SymTridiagonal(float.(real.(d)), Er); kwargs...) end diff --git a/stdlib/LinearAlgebra/test/symmetriceigen.jl b/stdlib/LinearAlgebra/test/symmetriceigen.jl index e2f475323b292..b3a5472c511f4 100644 --- a/stdlib/LinearAlgebra/test/symmetriceigen.jl +++ b/stdlib/LinearAlgebra/test/symmetriceigen.jl @@ -144,4 +144,11 @@ end @test e0 ≈ eu end +@testset "Hermitian tridiagonal eigen with Complex{Int} elements (#52801)" begin + dv, ev = fill(complex(2), 4), fill(3-4im, 3) + HT = Hermitian(Tridiagonal(ev, dv, ev)) + λ, V = eigen(HT) + @test HT * V ≈ V * Diagonal(λ) +end + end # module TestSymmetricEigen