11# # eigvals routine
22
33# the symmetric case uses lapack throughout
4- eigvals (A:: Symmetric{T,<:BandedMatrix{T}} ) where T<: Union{Float32, Float64} = eigvals! (copy (A))
5- eigvals (A:: Symmetric{T,<:BandedMatrix{T}} , irange:: UnitRange ) where T<: Union{Float32, Float64} = eigvals! (copy (A), irange)
6- eigvals (A:: Symmetric{T,<:BandedMatrix{T}} , vl:: Real , vu:: Real ) where T<: Union{Float32, Float64} = eigvals! (copy (A), vl, vu)
7-
8- eigvals (A:: RealHermSymComplexHerm{<:Real,<:BandedMatrix} ) = eigvals! (tridiagonalize (A))
9- eigvals (A:: RealHermSymComplexHerm{<:Real,<:BandedMatrix} , irange:: UnitRange ) = eigvals! (tridiagonalize (A), irange)
10- eigvals (A:: RealHermSymComplexHerm{<:Real,<:BandedMatrix} , vl:: Real , vu:: Real ) = eigvals! (tridiagonalize (A), vl, vu)
4+ eigvals (A:: Symmetric{T,<:BandedMatrix{T}} ) where T<: BlasReal =
5+ eigvals! (copy (A))
6+ eigvals (A:: Symmetric{T,<:BandedMatrix{T}} , irange:: UnitRange ) where T<: BlasReal =
7+ eigvals! (copy (A), irange)
8+ eigvals (A:: Symmetric{T,<:BandedMatrix{T}} , vl:: Real , vu:: Real ) where T<: BlasReal =
9+ eigvals! (copy (A), vl, vu)
10+
11+ eigvals (A:: RealHermSymComplexHerm{<:Real,<:BandedMatrix} ) =
12+ eigvals! (tridiagonalize (A))
13+ eigvals (A:: RealHermSymComplexHerm{<:Real,<:BandedMatrix} , irange:: UnitRange ) =
14+ eigvals! (tridiagonalize (A), irange)
15+ eigvals (A:: RealHermSymComplexHerm{<:Real,<:BandedMatrix} , vl:: Real , vu:: Real ) =
16+ eigvals! (tridiagonalize (A), vl, vu)
17+
18+ # This isn't eigvals!(A, args...) to avoid incorrect dispatches
19+ # This is a cautious approach at the moment
20+ eigvals! (A:: RealHermSymComplexHerm{<:Real,<:BandedMatrix} ) = _eigvals! (A)
21+ eigvals! (A:: RealHermSymComplexHerm{<:Real,<:BandedMatrix} , irange:: UnitRange ) = _eigvals! (A, irange)
22+ eigvals! (A:: RealHermSymComplexHerm{<:Real,<:BandedMatrix} , vl:: Real , vu:: Real ) = _eigvals! (A, vl, vu)
23+
24+ _eigvals! (A:: RealHermSymComplexHerm{<:Real,<:BandedMatrix} , args... ) =
25+ eigvals! (tridiagonalize! (A), args... )
26+
27+ function _copy_bandedsym (A, B)
28+ if bandwidth (A) >= bandwidth (B)
29+ copy (A)
30+ else
31+ copyto! (similar (B), A)
32+ end
33+ end
1134
12- eigvals! (A:: RealHermSymComplexHerm{<:Real,<:BandedMatrix} , args... ) = eigvals! (tridiagonalize! (A), args... )
35+ function eigvals (A:: HermOrSym{<:Any,<:BandedMatrix} , B:: HermOrSym{<:Any,<:BandedMatrix} )
36+ AA = _copy_bandedsym (A, B)
37+ eigvals! (AA, copy (B))
38+ end
1339
14- function eigvals! (A:: Symmetric {T,<:BandedMatrix{T}} , B:: Symmetric {T,<:BandedMatrix{T}} ) where T<: Real
40+ function eigvals! (A:: HermOrSym {T,<:BandedMatrix{T}} , B:: HermOrSym {T,<:BandedMatrix{T}} ) where T<: BlasReal
1541 n = size (A, 1 )
1642 @assert n == size (B, 1 )
1743 @assert A. uplo == B. uplo
@@ -29,6 +55,25 @@ function eigvals!(A::Symmetric{T,<:BandedMatrix{T}}, B::Symmetric{T,<:BandedMatr
2955 eigvals! (A)
3056end
3157
58+ function eigvals! (A:: Hermitian{T,<:BandedMatrix{T}} , B:: Hermitian{T,<:BandedMatrix{T}} ) where T<: BlasComplex
59+ n = size (A, 1 )
60+ @assert n == size (B, 1 )
61+ @assert A. uplo == B. uplo
62+ # compute split-Cholesky factorization of B.
63+ kb = bandwidth (B)
64+ B_data = hermbandeddata (B)
65+ pbstf! (B. uplo, n, kb, B_data)
66+ # convert to a regular symmetric eigenvalue problem.
67+ ka = bandwidth (A)
68+ A_data = hermbandeddata (A)
69+ X = Array {T} (undef,0 ,0 )
70+ work = Vector {T} (undef,n)
71+ rwork = Vector {real(T)} (undef,n)
72+ hbgst! (' N' , A. uplo, n, ka, kb, A_data, B_data, X, work, rwork)
73+ # compute eigenvalues of symmetric eigenvalue problem.
74+ eigvals! (A)
75+ end
76+
3277abstract type AbstractBandedEigenvectors{T} <: AbstractMatrix{T} end
3378
3479getindex (B:: AbstractBandedEigenvectors , i, j) = Matrix (B)[i,j]
@@ -57,7 +102,6 @@ struct BandedEigenvectors{T} <: AbstractBandedEigenvectors{T}
57102end
58103
59104size (B:: BandedEigenvectors ) = size (B. Q)
60-
61105_get_scratch (B:: BandedEigenvectors ) = B. z1
62106
63107# V = S⁻¹ Q W
@@ -80,12 +124,16 @@ eigen(A::RealHermSymComplexHerm{<:Real,<:BandedMatrix}) = eigen!(copy(A))
80124eigen (A:: RealHermSymComplexHerm{<:Real,<:BandedMatrix} , irange:: UnitRange ) = eigen! (copy (A), irange)
81125eigen (A:: RealHermSymComplexHerm{<:Real,<:BandedMatrix} , vl:: Real , vu:: Real ) = eigen! (copy (A), vl, vu)
82126
83- function eigen (A:: Symmetric {T,<:BandedMatrix{T}} , B:: Symmetric {T,<:BandedMatrix{T}} ) where T <: Real
127+ function eigen (A:: HermOrSym {T,<:BandedMatrix{T}} , B:: HermOrSym {T,<:BandedMatrix{T}} ) where T
84128 AA = _copy_bandedsym (A, B)
85129 eigen! (AA, copy (B))
86130end
87131
88- function eigen! (A:: HermOrSym{T,<:BandedMatrix{T}} , args... ) where T <: Real
132+ eigen! (A:: HermOrSym{T,<:BandedMatrix{T}} ) where T<: BlasFloat = _eigen! (A)
133+ eigen! (A:: HermOrSym{T,<:BandedMatrix{T}} , irange:: UnitRange ) where T<: BlasFloat = _eigen! (A, irange)
134+ eigen! (A:: HermOrSym{T,<:BandedMatrix{T}} , vl:: Real , vu:: Real ) where T<: BlasFloat = _eigen! (A, vl, vu)
135+
136+ function _eigen! (A:: HermOrSym{T,<:BandedMatrix{T}} , args... ) where T<: BlasReal
89137 N = size (A, 1 )
90138 KD = bandwidth (A)
91139 D = Vector {T} (undef, N)
@@ -98,7 +146,7 @@ function eigen!(A::HermOrSym{T,<:BandedMatrix{T}}, args...) where T <: Real
98146 Eigen (Λ, BandedEigenvectors (G, Q, similar (Q, size (Q,1 ))))
99147end
100148
101- function eigen ! (A:: Hermitian{T,<:BandedMatrix{T}} , args... ) where T <: Complex
149+ function _eigen ! (A:: Hermitian{T,<:BandedMatrix{T}} , args... ) where T <: BlasComplex
102150 N = size (A, 1 )
103151 KD = bandwidth (A)
104152 D = Vector {real(T)} (undef, N)
@@ -111,7 +159,7 @@ function eigen!(A::Hermitian{T,<:BandedMatrix{T}}, args...) where T <: Complex
111159 Eigen (Λ, Q * W)
112160end
113161
114- function eigen! (A:: Symmetric {T,<:BandedMatrix{T}} , B:: Symmetric {T,<:BandedMatrix{T}} ) where T <: Real
162+ function eigen! (A:: HermOrSym {T,<:BandedMatrix{T}} , B:: HermOrSym {T,<:BandedMatrix{T}} ) where T <: BlasReal
115163 isdiag (A) || isdiag (B) || symmetricuplo (A) == symmetricuplo (B) || throw (ArgumentError (" uplo of matrices do not match" ))
116164 S = splitcholesky! (B)
117165 N = size (A, 1 )
@@ -127,6 +175,23 @@ function eigen!(A::Symmetric{T,<:BandedMatrix{T}}, B::Symmetric{T,<:BandedMatrix
127175 GeneralizedEigen (Λ, BandedGeneralizedEigenvectors (S, Q, W))
128176end
129177
178+ function eigen! (A:: Hermitian{T,<:BandedMatrix{T}} , B:: Hermitian{T,<:BandedMatrix{T}} ) where T <: BlasComplex
179+ isdiag (A) || isdiag (B) || symmetricuplo (A) == symmetricuplo (B) || throw (ArgumentError (" uplo of matrices do not match" ))
180+ splitcholesky! (B)
181+ N = size (A, 1 )
182+ KA = bandwidth (A)
183+ KB = bandwidth (B)
184+ X = Matrix {T} (undef, N, N)
185+ WORK = Vector {T} (undef, N)
186+ RWORK = Vector {real(T)} (undef, N)
187+ AB = hermbandeddata (A)
188+ BB = hermbandeddata (B)
189+ hbgst! (' V' , A. uplo, N, KA, KB, AB, BB, X, WORK, RWORK)
190+ any (isnan, A) && throw (ArgumentError (" NaN found in the standard form of A" ))
191+ Λ, W = eigen! (A)
192+ GeneralizedEigen (Λ, X * W)
193+ end
194+
130195function Matrix (B:: BandedEigenvectors )
131196 Q = copy (B. Q)
132197 G = B. G
0 commit comments