Repository: JuliaLinearAlgebra/GenericLinearAlgebra.jl (julia)

Issue:
`eigen` and `eigvals` not defined for real symmetric matrices
`a = Symmetric(randn(BigFloat,2,2)); eigen(a); eigvals(a)` fails, while
`a = Hermitian(randn(BigFloat,2,2)); eigen(a); eigvals(a)` works.

It would be nice to accept real symmetric arguments, in order to match the behaviour of `LinearAlgebra`.

Pull request:
Closes #144

Patch:
diff --git a/src/eigenSelfAdjoint.jl b/src/eigenSelfAdjoint.jl
index cbf8742..8f82850 100644
--- a/src/eigenSelfAdjoint.jl
+++ b/src/eigenSelfAdjoint.jl
@@ -448,8 +448,7 @@ function singleShiftQR!(
 end
 
 symtri!(A::Hermitian) = A.uplo == 'L' ? symtriLower!(A.data) : symtriUpper!(A.data)
-symtri!(A::Symmetric{T}) where {T<:Real} =
-    A.uplo == 'L' ? symtriLower!(A.data) : symtriUpper!(A.data)
+symtri!(A::Symmetric{<:Real}) = A.uplo == 'L' ? symtriLower!(A.data) : symtriUpper!(A.data)
 
 # Assume that lower triangle stores the relevant part
 function symtriLower!(
@@ -580,6 +579,7 @@ _eigvals!(A::SymTridiagonal; tol = eps(real(eltype(A))), sortby::Union{Function,
 
 _eigvals!(A::Hermitian; tol = eps(real(eltype(A))), sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby) = eigvals!(symtri!(A); tol, sortby)
 
+_eigvals!(A::Symmetric{<:Real}; tol = eps(eltype(A)), sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby) = eigvals!(symtri!(A); tol, sortby)
 
 LinearAlgebra.eigvals!(A::SymmetricTridiagonalFactorization; tol = eps(real(eltype(A))), sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby) =
     _eigvals!(A; tol, sortby)
@@ -589,6 +589,7 @@ LinearAlgebra.eigvals!(A::SymTridiagonal; tol = eps(real(eltype(A))), sortby::Un
 
 LinearAlgebra.eigvals!(A::Hermitian; tol = eps(real(eltype(A))), sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby) = _eigvals!(A; tol, sortby)
 
+LinearAlgebra.eigvals!(A::Symmetric{<:Real}; tol = eps(eltype(A)), sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby) = _eigvals!(A; tol, sortby)
 
 _eigen!(A::SymmetricTridiagonalFactorization; tol = eps(real(eltype(A))), sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby) =
     LinearAlgebra.Eigen(LinearAlgebra.sorteig!(eigQL!(A.diagonals, vectors = Array(A.Q), tol = tol)..., sortby)...)
@@ -599,6 +600,7 @@ _eigen!(A::SymTridiagonal; tol = eps(real(eltype(A))), sortby::Union{Function,No
 
 _eigen!(A::Hermitian; tol = eps(real(eltype(A))), sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby) = _eigen!(symtri!(A), tol = tol)
 
+_eigen!(A::Symmetric{<:Real}; tol = eps(eltype(A)), sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby) = _eigen!(symtri!(A), tol = tol)
 
 LinearAlgebra.eigen!(A::SymmetricTridiagonalFactorization; tol = eps(real(eltype(A))), sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby) =
     _eigen!(A; tol, sortby)
@@ -607,6 +609,8 @@ LinearAlgebra.eigen!(A::SymTridiagonal; tol = eps(real(eltype(A))), sortby::Unio
 
 LinearAlgebra.eigen!(A::Hermitian; tol = eps(real(eltype(A))), sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby) = _eigen!(A; tol, sortby)
 
+LinearAlgebra.eigen!(A::Symmetric{<:Real}; tol = eps(eltype(A)), sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby) = _eigen!(A; tol, sortby)
+
 
 function eigen2!(
     A::SymmetricTridiagonalFactorization;
@@ -628,12 +632,17 @@ end
 eigen2!(A::Hermitian; tol = eps(float(real(one(eltype(A)))))) =
     eigen2!(symtri!(A), tol = tol)
 
+eigen2!(A::Symmetric{<:Real}; tol = eps(float(one(eltype(A))))) =
+    eigen2!(symtri!(A), tol = tol)
+
 
 eigen2(A::SymTridiagonal; tol = eps(float(real(one(eltype(A)))))) =
     eigen2!(copy(A), tol = tol)
 
 eigen2(A::Hermitian, tol = eps(float(real(one(eltype(A)))))) = eigen2!(copy(A), tol = tol)
 
+eigen2(A::Symmetric{<:Real}, tol = eps(float(one(eltype(A))))) = eigen2!(copy(A), tol = tol)
+
 # First method of each type here is identical to the method defined in
 # LinearAlgebra but is needed for disambiguation
 const _eigencopy_oftype = if VERSION >= v"1.9"


Test patch:
diff --git a/test/eigenselfadjoint.jl b/test/eigenselfadjoint.jl
index 847adc0..c5dafd4 100644
--- a/test/eigenselfadjoint.jl
+++ b/test/eigenselfadjoint.jl
@@ -34,7 +34,7 @@ using Test, GenericLinearAlgebra, LinearAlgebra, Quaternions
     end
 
     @testset "(full) Symmetric" for uplo in (:L, :U)
-        A = Hermitian(big.(randn(n, n)), uplo)
+        A = Symmetric(big.(randn(n, n)), uplo)
         vals, vecs = eigen(A)
         @testset "default" begin
             @test vecs' * A * vecs ≈ diagm(0 => vals)