55eigencopy_oftype (A:: Hermitian , S) = Hermitian (copytrito! (similar (parent (A), S, size (A)), A. data, A. uplo), sym_uplo (A. uplo))
66eigencopy_oftype (A:: Symmetric , S) = Symmetric (copytrito! (similar (parent (A), S, size (A)), A. data, A. uplo), sym_uplo (A. uplo))
77
8- # Eigensolvers for symmetric and Hermitian matrices
9- eigen! (A:: RealHermSymComplexHerm{<:BlasReal,<:StridedMatrix} ; sortby:: Union{Function,Nothing} = nothing ) =
10- Eigen (sorteig! (LAPACK. syevr! (' V' , ' A' , A. uplo, A. data, 0.0 , 0.0 , 0 , 0 , - 1.0 )... , sortby)... )
8+ default_eigen_alg (A) = DivideAndConquer ()
119
12- function eigen (A:: RealHermSymComplexHerm ; sortby:: Union{Function,Nothing} = nothing )
13- S = eigtype (eltype (A))
14- eigen! (eigencopy_oftype (A, S), sortby= sortby)
10+ # Eigensolvers for symmetric and Hermitian matrices
11+ function eigen! (A:: RealHermSymComplexHerm{<:BlasReal,<:StridedMatrix} , alg:: Algorithm = default_eigen_alg (A); sortby:: Union{Function,Nothing} = nothing )
12+ if alg === DivideAndConquer ()
13+ Eigen (sorteig! (LAPACK. syevd! (' V' , A. uplo, A. data)... , sortby)... )
14+ elseif alg === QRIteration ()
15+ Eigen (sorteig! (LAPACK. syev! (' V' , A. uplo, A. data)... , sortby)... )
16+ elseif alg === RobustRepresentations ()
17+ Eigen (sorteig! (LAPACK. syevr! (' V' , ' A' , A. uplo, A. data, 0.0 , 0.0 , 0 , 0 , - 1.0 )... , sortby)... )
18+ else
19+ throw (ArgumentError (" Unsupported value for `alg` keyword." ))
20+ end
1521end
1622function eigen (A:: RealHermSymComplexHerm{Float16} ; sortby:: Union{Function,Nothing} = nothing )
1723 S = eigtype (eltype (A))
@@ -21,6 +27,36 @@ function eigen(A::RealHermSymComplexHerm{Float16}; sortby::Union{Function,Nothin
2127 return Eigen (values, vectors)
2228end
2329
30+ """
31+ eigen(A::Union{Hermitian, Symmetric}, alg::Algorithm = default_eigen_alg(A)) -> Eigen
32+
33+ Compute the eigenvalue decomposition of `A`, returning an [`Eigen`](@ref) factorization object `F`
34+ which contains the eigenvalues in `F.values` and the eigenvectors in the columns of the
35+ matrix `F.vectors`. (The `k`th eigenvector can be obtained from the slice `F.vectors[:, k]`.)
36+
37+ Iterating the decomposition produces the components `F.values` and `F.vectors`.
38+
39+ `alg` specifies which algorithm and LAPACK method to use for eigenvalue decomposition:
40+ - `alg = DivideAndConquer()` (default): Calls `LAPACK.syevd!`.
41+ - `alg = QRIteration()`: Calls `LAPACK.syev!`.
42+ - `alg = RobustRepresentations()`: Multiple relatively robust representations method, Calls `LAPACK.syevr!`.
43+
44+ See James W. Demmel et al, SIAM J. Sci. Comput. 30, 3, 1508 (2008) for
45+ a comparison of the accuracy and performance of different algorithms.
46+
47+ The default `alg` used may change in the future.
48+
49+ !!! compat "Julia 1.12"
50+ The `alg` keyword argument requires Julia 1.12 or later.
51+
52+ The following functions are available for `Eigen` objects: [`inv`](@ref), [`det`](@ref), and [`isposdef`](@ref).
53+ """
54+ function eigen (A:: RealHermSymComplexHerm , alg:: Algorithm = default_eigen_alg (A); sortby:: Union{Function,Nothing} = nothing )
55+ S = eigtype (eltype (A))
56+ eigen! (eigencopy_oftype (A, S), alg; sortby)
57+ end
58+
59+
2460eigen! (A:: RealHermSymComplexHerm{<:BlasReal,<:StridedMatrix} , irange:: UnitRange ) =
2561 Eigen (LAPACK. syevr! (' V' , ' I' , A. uplo, A. data, 0.0 , 0.0 , irange. start, irange. stop, - 1.0 )... )
2662
@@ -71,17 +107,42 @@ function eigen(A::RealHermSymComplexHerm, vl::Real, vh::Real)
71107 eigen! (eigencopy_oftype (A, S), vl, vh)
72108end
73109
74- function eigvals! (A:: RealHermSymComplexHerm{<:BlasReal,<:StridedMatrix} ; sortby:: Union{Function,Nothing} = nothing )
75- vals = LAPACK. syevr! (' N' , ' A' , A. uplo, A. data, 0.0 , 0.0 , 0 , 0 , - 1.0 )[1 ]
110+
111+ function eigvals! (A:: RealHermSymComplexHerm{<:BlasReal,<:StridedMatrix} , alg:: Algorithm = default_eigen_alg (A); sortby:: Union{Function,Nothing} = nothing )
112+ vals:: Vector{real(eltype(A))} = if alg === DivideAndConquer ()
113+ LAPACK. syevd! (' N' , A. uplo, A. data)
114+ elseif alg === QRIteration ()
115+ LAPACK. syev! (' N' , A. uplo, A. data)
116+ elseif alg === RobustRepresentations ()
117+ LAPACK. syevr! (' N' , ' A' , A. uplo, A. data, 0.0 , 0.0 , 0 , 0 , - 1.0 )[1 ]
118+ else
119+ throw (ArgumentError (" Unsupported value for `alg` keyword." ))
120+ end
76121 ! isnothing (sortby) && sort! (vals, by= sortby)
77122 return vals
78123end
79124
80- function eigvals (A:: RealHermSymComplexHerm ; sortby:: Union{Function,Nothing} = nothing )
125+ """
126+ eigvals(A::Union{Hermitian, Symmetric}, alg::Algorithm = default_eigen_alg(A))) -> values
127+
128+ Return the eigenvalues of `A`.
129+
130+ `alg` specifies which algorithm and LAPACK method to use for eigenvalue decomposition:
131+ - `alg = DivideAndConquer()` (default): Calls `LAPACK.syevd!`.
132+ - `alg = QRIteration()`: Calls `LAPACK.syev!`.
133+ - `alg = RobustRepresentations()`: Multiple relatively robust representations method, Calls `LAPACK.syevr!`.
134+
135+ See James W. Demmel et al, SIAM J. Sci. Comput. 30, 3, 1508 (2008) for
136+ a comparison of the accuracy and performance of different methods.
137+
138+ The default `alg` used may change in the future.
139+ """
140+ function eigvals (A:: RealHermSymComplexHerm , alg:: Algorithm = default_eigen_alg (A); sortby:: Union{Function,Nothing} = nothing )
81141 S = eigtype (eltype (A))
82- eigvals! (eigencopy_oftype (A, S), sortby = sortby)
142+ eigvals! (eigencopy_oftype (A, S), alg; sortby)
83143end
84144
145+
85146"""
86147 eigvals!(A::Union{SymTridiagonal, Hermitian, Symmetric}, irange::UnitRange) -> values
87148
0 commit comments