Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: sort eigenvalues in a canonical order #21598

Merged
merged 15 commits into from
Feb 5, 2019
Prev Previous commit
Next Next commit
no sortby for special matrix types
  • Loading branch information
stevengj committed Jan 10, 2019
commit c49310060996510df0e4a347c5ff48013eca0652
8 changes: 3 additions & 5 deletions stdlib/LinearAlgebra/src/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -690,8 +690,8 @@ end
factorize(A::Bidiagonal) = A

# Eigensystems
eigvals(M::Bidiagonal; sortby::Union{Function,Nothing}=eigsortby) = sortby===nothing ? M.dv : sort(M.dv, by=sortby)
function eigvecs_(M::Bidiagonal{T}) where T # non-sorted
eigvals(M::Bidiagonal) = M.dv
function eigvecs(M::Bidiagonal{T}) where T
n = length(M.dv)
Q = Matrix{T}(undef, n,n)
blks = [0; findall(x -> x == 0, M.ev); n]
Expand Down Expand Up @@ -723,6 +723,4 @@ function eigvecs_(M::Bidiagonal{T}) where T # non-sorted
end
Q #Actually Triangular
end
eigvecs(M::Bidiagonal{T}; sortby::Union{Function,Nothing}=eigsortby) =
sorteigvecs!(M.dv, eigvecs_(M), sortby)
eigen(M::Bidiagonal) = Eigen(sorteig!(copy(M.dv), eigvecs_(M), sortby)...)
eigen(M::Bidiagonal) = Eigen(eigvals(M), eigvecs(M))
13 changes: 6 additions & 7 deletions stdlib/LinearAlgebra/src/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -524,16 +524,15 @@ function pinv(D::Diagonal{T}, tol::Real) where T
end

#Eigensystem
eigvals(D::Diagonal{<:Number}; permute::Bool=true, scale::Bool=true, sortby::Union{Function,Nothing}=eigsortby) = sortby === nothing ? D.diag : sort(D.diag, by=sortby)
eigvals_(D::Diagonal) = [eigvals(x) for x in D.diag] # non-sorted copy, for block matrices etc.
eigvals(D::Diagonal; permute::Bool=true, scale::Bool=true, sortby::Union{Function,Nothing}=eigsortby) =
sorteigvals!(eigvals_(D), sortby)
eigvecs(D::Diagonal; sortby::Union{Function,Nothing}=eigsortby) = sorteigvecs!(D.diag, Matrix{eltype(D)}(I, size(D)), sortby)
function eigen(D::Diagonal; permute::Bool=true, scale::Bool=true, sortby::Union{Function,Nothing}=eigsortby)
eigvals(D::Diagonal{<:Number}; permute::Bool=true, scale::Bool=true) = D.diag
eigvals(D::Diagonal; permute::Bool=true, scale::Bool=true) =
[eigvals(x) for x in D.diag] #For block matrices, etc.
eigvecs(D::Diagonal) = Matrix{eltype(D)}(I, size(D))
function eigen(D::Diagonal; permute::Bool=true, scale::Bool=true)
if any(!isfinite, D.diag)
throw(ArgumentError("matrix contains Infs or NaNs"))
end
Eigen(sorteig!(eigvals_(D), Matrix{eltype(D)}(I, size(D)))...)
Eigen(eigvals(D), eigvecs(D))
end

#Singular system
Expand Down
7 changes: 5 additions & 2 deletions stdlib/LinearAlgebra/src/eigen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ make rows and columns more equal in norm. The default is `true` for both options

By default, the eigenvalues and vectors are sorted lexicographically by `(real(λ),imag(λ))`.
A different comparison function `by(λ)` can be passed to `sortby`, or you can pass
`sortby=nothing` to leave the eigenvalues in an arbitrary order.
`sortby=nothing` to leave the eigenvalues in an arbitrary order. Some special matrix types
(e.g. `Diagonal` or `SymTridiagonal`) may implement their own sorting convention and not
accept a `sortby` keyword.

# Examples
```jldoctest
Expand Down Expand Up @@ -372,7 +374,8 @@ Iterating the decomposition produces the components `F.values` and `F.vectors`.

By default, the eigenvalues and vectors are sorted lexicographically by `(real(λ),imag(λ))`.
A different comparison function `by(λ)` can be passed to `sortby`, or you can pass
`sortby=nothing` to leave the eigenvalues in an arbitrary order.
`sortby=nothing` to leave the eigenvalues in an arbitrary order. Some special matrix types
may implement their own sorting convention and not accept a `sortby` keyword.

# Examples
```jldoctest
Expand Down