Skip to content

eigen not working properly for 2x2 Hermitian SMatrices #956

Closed
@guberger

Description

@guberger

Hello! I noticed an incorrect behavior using eigen() on 2x2 Hermitian SMatrices:

using LinearAlgebra
using StaticArrays
A = @SMatrix [1.0 1e-10; 1e-10 1.0]
eigen(A)

outputs

Eigen{Float64, Float64, SMatrix{2, 2, Float64, 4}, SVector{2, Float64}}        
values:
2-element SVector{2, Float64} with indices SOneTo(2):
 1.0
 1.0
vectors:
2×2 SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):
 0.0  0.0
 1.0  1.0

The problem seems to be a numerical instability in

t_half = real(a[1] + a[4]) / 2
d = real(a[1] * a[4] - a[3]' * a[3]) # Should be real
tmp2 = t_half * t_half - d
tmp = tmp2 < 0 ? zero(tmp2) : sqrt(tmp2) # Numerically stable for identity matrices, etc.
vals = SVector(t_half - tmp, t_half + tmp)
v11 = vals[1] - a[4]
n1 = sqrt(v11' * v11 + a[3]' * a[3])
v11 = v11 / n1
v12 = a[3]' / n1
v21 = vals[2] - a[4]
n2 = sqrt(v21' * v21 + a[3]' * a[3])
v21 = v21 / n2
v22 = a[3]' / n2
where vals should be [-1e-10, 1e-10] instead of [0.0, 0.0]. This has consequences on the rest of the evaluations, e.g., v11 is evaluated to 0.0 instead of -1e-10 and n1 is evaluated to 1e-10 instead of 2e-10 etc.

More info:

julia> versioninfo()
Julia Version 1.6.2
Commit 1b93d53fc4 (2021-07-14 15:36 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, skylake)
(@v1.6) pkg> status StaticArrays
      Status `~\v1.6\Project.toml`
  [90137ffa] StaticArrays v1.2.12

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