Skip to content

Commit e638579

Browse files
ericphansonandreasnoack
authored andcommitted
Redirect for ishermitian==true and match Base sorting (#56)
1 parent 19b6c8d commit e638579

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

src/eigenGeneral.jl

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -247,13 +247,41 @@ function doubleShiftQR!(HH::StridedMatrix, τ::Rotation, shiftTrace::Number, shi
247247
end
248248

249249
_eigvals!(A::StridedMatrix; kwargs...) = _eigvals!(_schur!(A; kwargs...))
250-
_eigvals!(H::HessenbergMatrix; kwargs...) = _eigvals!(_schur!(H, kwargs...))
251-
_eigvals!(H::HessenbergFactorization; kwargs...) = _eigvals!(_schur!(H, kwargs...))
250+
_eigvals!(H::HessenbergMatrix; kwargs...) = _eigvals!(_schur!(H; kwargs...))
251+
_eigvals!(H::HessenbergFactorization; kwargs...) = _eigvals!(_schur!(H; kwargs...))
252252

253253
# Overload methods from LinearAlgebra to make them work generically
254-
LinearAlgebra.eigvals!(A::StridedMatrix; kwargs...) = _eigvals!(A; kwargs...)
255-
LinearAlgebra.eigvals!(H::HessenbergMatrix; kwargs...) = _eigvals!(H, kwargs...)
256-
LinearAlgebra.eigvals!(H::HessenbergFactorization; kwargs...) = _eigvals!(H, kwargs...)
254+
if VERSION > v"1.2.0-DEV.0"
255+
function LinearAlgebra.eigvals!(A::StridedMatrix;
256+
sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby,
257+
kwargs...)
258+
if ishermitian(A)
259+
return LinearAlgebra.sorteig!(eigvals!(Hermitian(A)), sortby)
260+
end
261+
LinearAlgebra.sorteig!(_eigvals!(A; kwargs...), sortby)
262+
end
263+
264+
LinearAlgebra.eigvals!(H::HessenbergMatrix;
265+
sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby,
266+
kwargs...) = LinearAlgebra.sorteig!(_eigvals!(H; kwargs...), sortby)
267+
268+
LinearAlgebra.eigvals!(H::HessenbergFactorization;
269+
sortby::Union{Function,Nothing}=LinearAlgebra.eigsortby,
270+
kwargs...) = LinearAlgebra.sorteig!(_eigvals!(H; kwargs...), sortby)
271+
else
272+
273+
function LinearAlgebra.eigvals!(A::StridedMatrix; kwargs...)
274+
if ishermitian(A)
275+
return eigvals!(Hermitian(A))
276+
end
277+
_eigvals!(A; kwargs...)
278+
end
279+
280+
LinearAlgebra.eigvals!(H::HessenbergMatrix; kwargs...) = _eigvals!(H; kwargs...)
281+
282+
LinearAlgebra.eigvals!(H::HessenbergFactorization; kwargs...) = _eigvals!(H; kwargs...)
283+
end
284+
257285

258286
function _eigvals!(S::Schur{T}; tol = eps(real(T))) where T
259287
HH = S.data

test/eigengeneral.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ cplxord = t -> (real(t), imag(t))
1414
vBig = eigvals(big.(A)) # not defined in LinearAlgebra so will dispatch to the version in GenericLinearAlgebra
1515
@test sort(vGLA, by = cplxord) sort(vLAPACK, by = cplxord)
1616
@test sort(vGLA, by = cplxord) sort(complex(eltype(A)).(vBig), by = cplxord)
17+
if VERSION > v"1.2.0-DEV.0"
18+
@test issorted(vBig, by = cplxord)
19+
end
1720
end
1821

1922
@testset "make sure that solver doesn't hang" begin
@@ -54,4 +57,4 @@ end
5457
@test sum(eigvals(schur(A).Schur)) sum(eigvals(Float64.(schur(big.(A)).Schur)))
5558
end
5659

57-
end
60+
end

test/eigenselfadjoint.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Base.isreal(q::Quaternion) = q.v1 == q.v2 == q.v3 == 0
99
# LinearAlgebra
1010
T = SymTridiagonal(big.(randn(n)), big.(randn(n - 1)))
1111
vals, vecs = eigen(T)
12+
@test issorted(vals)
1213
@testset "default" begin
1314
@test (vecs'*T)*vecs Diagonal(vals)
1415
@test eigvals(T) vals
@@ -17,13 +18,15 @@ Base.isreal(q::Quaternion) = q.v1 == q.v2 == q.v3 == 0
1718

1819
@testset "eigen2" begin
1920
vals2, vecs2 = GenericLinearAlgebra.eigen2(T)
21+
@test issorted(vals2)
2022
@test vals vals2
2123
@test vecs[[1,n],:] == vecs2
2224
@test vecs2*vecs2' Matrix(I, 2, 2)
2325
end
2426

2527
@testset "QR version (QL is default)" begin
2628
vals, vecs = GenericLinearAlgebra.eigQR!(copy(T), vectors = Matrix{eltype(T)}(I, n, n))
29+
@test issorted(vals)
2730
@test (vecs'*T)*vecs Diagonal(vals)
2831
@test eigvals(T) vals
2932
@test vecs'vecs Matrix(I, n, n)
@@ -37,13 +40,15 @@ Base.isreal(q::Quaternion) = q.v1 == q.v2 == q.v3 == 0
3740
@test vecs'*A*vecs diagm(0 => vals)
3841
@test eigvals(A) vals
3942
@test vecs'vecs Matrix(I, n, n)
43+
@test issorted(vals)
4044
end
4145

4246
@testset "eigen2" begin
4347
vals2, vecs2 = GenericLinearAlgebra.eigen2(A)
4448
@test vals vals2
4549
@test vecs[[1,n],:] vecs2
4650
@test vecs2*vecs2' Matrix(I, 2, 2)
51+
@test issorted(vals2)
4752
end
4853
end
4954

@@ -52,6 +57,8 @@ Base.isreal(q::Quaternion) = q.v1 == q.v2 == q.v3 == 0
5257
λ = 10 .^ range(-8, stop=0, length=n)
5358
A = Hermitian(V*Diagonal(λ)*V' |> t -> (t + t')/2, uplo)
5459
vals, vecs = eigen(A)
60+
@test issorted(vals)
61+
5562
@testset "default" begin
5663
if uplo == :L # FixMe! Probably an conjugation is off somewhere. Don't have time to check now.
5764
@test_broken vecs'*A*vecs diagm(0=> vals)
@@ -65,6 +72,7 @@ Base.isreal(q::Quaternion) = q.v1 == q.v2 == q.v3 == 0
6572

6673
@testset "eigen2" begin
6774
vals2, vecs2 = GenericLinearAlgebra.eigen2(A)
75+
@test issorted(vals2)
6876
@test vals vals2
6977
@test vecs[[1,n],:] vecs2
7078
@test vecs2*vecs2' Matrix(I, 2, 2)
@@ -102,4 +110,10 @@ Base.isreal(q::Quaternion) = q.v1 == q.v2 == q.v3 == 0
102110
@test eigen(M1).values == GenericLinearAlgebra._eigen!(copy(M1)).values
103111
@test eigen(M2).values == GenericLinearAlgebra._eigen!(copy(M2)).values
104112
end
113+
114+
@testset "Sorting of `ishermitian(T)==true` matrices on pre-1.2" begin
115+
T = big.(randn(5, 5))
116+
T = T + T'
117+
@test issorted(eigvals(T))
118+
end
105119
end

0 commit comments

Comments
 (0)