|
90 | 90 | # ========================== |
91 | 91 | # IMPLEMENTATIONS |
92 | 92 | # ========================== |
93 | | -for f! in (:geev!, :geevx!) |
94 | | - @eval $f!(driver::Driver, args...) = throw(ArgumentError("$driver does not provide $f!")) |
| 93 | + |
| 94 | +geev!(driver::Driver, args...; kwargs...) = throw(ArgumentError("$driver does not provide $f!")) |
| 95 | +function geevx!(driver::Driver, A, Dd, V; kwargs...) |
| 96 | + @warn "$driver does not provide `geevx!`, falling back to `geev!`" maxlog = 1 |
| 97 | + return geev!(driver, A, Dd, V; kwargs...) |
95 | 98 | end |
| 99 | +_has_geevx!(::Driver) = false |
96 | 100 |
|
97 | 101 | # LAPACK implementations |
98 | 102 | for f! in (:geev!, :geevx!) |
99 | 103 | @eval $f!(::LAPACK, args...; kwargs...) = YALAPACK.$f!(args...; kwargs...) |
100 | 104 | end |
| 105 | +_has_geevx!(::LAPACK) = true |
101 | 106 |
|
102 | | -supports_eig(::Driver, ::Symbol) = false |
103 | | -supports_eig(::LAPACK, f::Symbol) = f in (:simple, :expert) |
104 | | - |
105 | | -for (f, f_lapack!, Alg) in ( |
106 | | - (:simple, :geev!, :Simple), |
107 | | - (:expert, :geevx!, :Expert), |
108 | | - ) |
109 | | - f_eig_full! = Symbol(f, :_eig_full!) |
110 | | - f_eig_vals! = Symbol(f, :_eig_vals!) |
| 107 | +# driver dispatch |
| 108 | +@inline qr_iteration_eig_full!(A, Dd, V; driver::Driver = DefaultDriver(), kwargs...) = |
| 109 | + qr_iteration_eig_full!(driver, A, Dd, V; kwargs...) |
| 110 | +@inline qr_iteration_eig_vals!(A, D, V; driver::Driver = DefaultDriver(), kwargs...) = |
| 111 | + qr_iteration_eig_vals!(driver, A, D, V; kwargs...) |
111 | 112 |
|
112 | | - # MatrixAlgebraKit wrappers |
113 | | - @eval begin |
114 | | - function eig_full!(A::AbstractMatrix, DV, alg::$Alg) |
115 | | - check_input(eig_full!, A, DV, alg) |
116 | | - D, V = DV |
117 | | - Dd, V = $f_eig_full!(A, diagview(D), V; alg.kwargs...) |
118 | | - return D, V |
119 | | - end |
120 | | - function eig_vals!(A::AbstractMatrix, D, alg::$Alg) |
121 | | - check_input(eig_vals!, A, D, alg) |
122 | | - V = similar(A, complex(eltype(A)), (size(A, 1), 0)) |
123 | | - $f_eig_vals!(A, D, V; alg.kwargs...) |
124 | | - return D |
125 | | - end |
126 | | - end |
| 113 | +@inline qr_iteration_eig_full!(::DefaultDriver, A, Dd, V; kwargs...) = |
| 114 | + qr_iteration_eig_full!(default_driver(QRIteration, A), A, Dd, V; kwargs...) |
| 115 | +@inline qr_iteration_eig_vals!(::DefaultDriver, A, D, V; kwargs...) = |
| 116 | + qr_iteration_eig_vals!(default_driver(QRIteration, A), A, D, V; kwargs...) |
127 | 117 |
|
128 | | - # driver dispatch |
129 | | - @eval begin |
130 | | - @inline $f_eig_full!(A, Dd, V; driver::Driver = DefaultDriver(), kwargs...) = |
131 | | - $f_eig_full!(driver, A, Dd, V; kwargs...) |
132 | | - @inline $f_eig_vals!(A, D, V; driver::Driver = DefaultDriver(), kwargs...) = |
133 | | - $f_eig_vals!(driver, A, D, V; kwargs...) |
134 | | - |
135 | | - @inline $f_eig_full!(::DefaultDriver, A, Dd, V; kwargs...) = |
136 | | - $f_eig_full!(default_driver($Alg, A), A, Dd, V; kwargs...) |
137 | | - @inline $f_eig_vals!(::DefaultDriver, A, D, V; kwargs...) = |
138 | | - $f_eig_vals!(default_driver($Alg, A), A, D, V; kwargs...) |
139 | | - end |
| 118 | +# Implementation |
| 119 | +function qr_iteration_eig_full!( |
| 120 | + driver::Driver, A, Dd, V; |
| 121 | + fixgauge::Bool = default_fixgauge(), balanced::Bool = _has_geevx!(driver), kwargs... |
| 122 | + ) |
| 123 | + (balanced ? geevx! : geev!)(driver, A, Dd, V; kwargs...) |
| 124 | + fixgauge && gaugefix!(eig_full!, V) |
| 125 | + return Dd, V |
| 126 | +end |
| 127 | +function qr_iteration_eig_vals!( |
| 128 | + driver::Driver, A, D, V; |
| 129 | + fixgauge::Bool = default_fixgauge(), balanced::Bool = _has_geevx!(driver), kwargs... |
| 130 | + ) |
| 131 | + (balanced ? geevx! : geev!)(driver, A, D, V; kwargs...) |
| 132 | + return D |
| 133 | +end |
140 | 134 |
|
141 | | - # Implementation |
142 | | - @eval begin |
143 | | - function $f_eig_full!(driver::Driver, A, Dd, V; fixgauge::Bool = default_fixgauge(), kwargs...) |
144 | | - supports_eig(driver, $(QuoteNode(f))) || |
145 | | - throw(ArgumentError(LazyString("driver ", driver, " does not provide `$($(QuoteNode(f_lapack!)))`"))) |
146 | | - $( |
147 | | - if f == :simple |
148 | | - :(isempty(kwargs) || throw(ArgumentError(LazyString("invalid keyword arguments for ", driver, " simple eig")))) |
149 | | - else |
150 | | - :nothing |
151 | | - end |
152 | | - ) |
153 | | - $f_lapack!(driver, A, Dd, V; kwargs...) |
154 | | - fixgauge && gaugefix!(eig_full!, V) |
155 | | - return Dd, V |
156 | | - end |
157 | | - function $f_eig_vals!(driver::Driver, A, D, V; fixgauge::Bool = default_fixgauge(), kwargs...) |
158 | | - supports_eig(driver, $(QuoteNode(f))) || |
159 | | - throw(ArgumentError(LazyString("driver ", driver, " does not provide `$($(QuoteNode(f_lapack!)))`"))) |
160 | | - $( |
161 | | - if f == :simple |
162 | | - :(isempty(kwargs) || throw(ArgumentError(LazyString("invalid keyword arguments for ", driver, " simple eig")))) |
163 | | - else |
164 | | - :nothing |
165 | | - end |
166 | | - ) |
167 | | - $f_lapack!(driver, A, D, V; kwargs...) |
168 | | - return D |
169 | | - end |
170 | | - end |
| 135 | +# Top-level QRIteration dispatch |
| 136 | +function eig_full!(A::AbstractMatrix, DV, alg::QRIteration) |
| 137 | + check_input(eig_full!, A, DV, alg) |
| 138 | + D, V = DV |
| 139 | + qr_iteration_eig_full!(A, diagview(D), V; alg.kwargs...) |
| 140 | + return D, V |
| 141 | +end |
| 142 | +function eig_vals!(A::AbstractMatrix, D, alg::QRIteration) |
| 143 | + check_input(eig_vals!, A, D, alg) |
| 144 | + V = similar(A, complex(eltype(A)), (size(A, 1), 0)) |
| 145 | + qr_iteration_eig_vals!(A, D, V; alg.kwargs...) |
| 146 | + return D |
171 | 147 | end |
172 | 148 |
|
173 | 149 | function eig_trunc!(A, DV, alg::TruncatedAlgorithm) |
@@ -212,24 +188,23 @@ end |
212 | 188 |
|
213 | 189 | # Deprecations |
214 | 190 | # ------------ |
215 | | -for algtype in (:Simple, :Expert) |
216 | | - lapack_algtype = Symbol(:LAPACK_, algtype) |
| 191 | +for (lapack_algtype, balanced_val) in ((:LAPACK_Simple, false), (:LAPACK_Expert, true)) |
217 | 192 | @eval begin |
218 | 193 | Base.@deprecate( |
219 | 194 | eig_full!(A, DV, alg::$lapack_algtype), |
220 | | - eig_full!(A, DV, $algtype(; driver = LAPACK(), alg.kwargs...)) |
| 195 | + eig_full!(A, DV, QRIteration(; balanced = $balanced_val, alg.kwargs...)) |
221 | 196 | ) |
222 | 197 | Base.@deprecate( |
223 | 198 | eig_vals!(A, D, alg::$lapack_algtype), |
224 | | - eig_vals!(A, D, $algtype(; driver = LAPACK(), alg.kwargs...)) |
| 199 | + eig_vals!(A, D, QRIteration(; balanced = $balanced_val, alg.kwargs...)) |
225 | 200 | ) |
226 | 201 | end |
227 | 202 | end |
228 | 203 | Base.@deprecate( |
229 | 204 | eig_full!(A, DV, alg::CUSOLVER_Simple), |
230 | | - eig_full!(A, DV, Simple(; driver = CUSOLVER(), alg.kwargs...)) |
| 205 | + eig_full!(A, DV, QRIteration(; driver = CUSOLVER(), alg.kwargs...)) |
231 | 206 | ) |
232 | 207 | Base.@deprecate( |
233 | 208 | eig_vals!(A, D, alg::CUSOLVER_Simple), |
234 | | - eig_vals!(A, D, Simple(; driver = CUSOLVER(), alg.kwargs...)) |
| 209 | + eig_vals!(A, D, QRIteration(; driver = CUSOLVER(), alg.kwargs...)) |
235 | 210 | ) |
0 commit comments