Skip to content

2x2 hermitian eigen method prone to under/overflow #1299

@mikmoore

Description

@mikmoore
julia> eigen(Hermitian(SA[2 1; 1 1] * 1f-30))
Eigen{Float32, Float32, SMatrix{2, 2, Float32, 4}, SVector{2, Float32}}
values:
2-element SVector{2, Float32} with indices SOneTo(2):
 3.8196598f-31
 2.618034f-30
vectors:
2×2 SMatrix{2, 2, Float32, 4} with indices SOneTo(2)×SOneTo(2):
 -Inf  Inf
  Inf  Inf

julia> eigen(Hermitian(SA[2 1; 1 1] * 1f+30))
Eigen{Float32, Float32, SMatrix{2, 2, Float32, 4}, SVector{2, Float32}}
values:
2-element SVector{2, Float32} with indices SOneTo(2):
 3.819661f29
 2.618034f30
vectors:
2×2 SMatrix{2, 2, Float32, 4} with indices SOneTo(2)×SOneTo(2):
 -0.0  0.0
  0.0  0.0

The relevant method appears to be function _eig(::Size{(2,2)}, A::LinearAlgebra.RealHermSymComplexHerm{T}, permute, scale) where {T <: Real}.

It looks like the issue is the lines n1 = sqrt(v11' * v11 + a21 * a21') and n2 = sqrt(v21' * v21 + a21 * a21'), which can under/overflow for small/large values. It appears that replacing them with something like the line tmp = norm(SVector(diag_avg_diff, a21)) (from further up the function) would resolve the issue. Should be very quick.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions