@@ -144,11 +144,44 @@ function _update_schur_eigs!(Hₘ, Uₘ, Uₘᵥ, f, k, m, β, sorted_vals, sort
144144 ordschur! (F, select)
145145
146146 copyto! (Hₘ, F. T)
147- Tₘ = Hₘ
148147 copyto! (Uₘ, F. Z)
149148 mul! (f, Uₘᵥ, β)
150149
151- return Tₘ, Uₘ
150+ return nothing
151+ end
152+
153+ # Pure Julia implementation of computing right eigenvectors from Schur form
154+ # Instead of using LAPACK.trevc!('R', 'A', select, Tₘ)
155+ function _schur_right_eigenvectors (Tₘ, k)
156+ n = size (Tₘ, 1 )
157+ vecs = zeros (eltype (Tₘ), n, k)
158+ k == 0 && return vecs
159+
160+ value_tol (λ) = eps (typeof (abs (λ))) * max (one (typeof (abs (λ))), abs (λ))
161+
162+ @inbounds for col in 1 : k
163+ vec = view (vecs, :, col)
164+ fill! (vec, zero (eltype (Tₘ)))
165+ vec[col] = one (eltype (Tₘ))
166+ λ = Tₘ[col, col]
167+
168+ for row in (col- 1 ): - 1 : 1
169+ acc = zero (eltype (Tₘ))
170+ for inner in (row + 1 ): col
171+ acc += Tₘ[row, inner] * vec[inner]
172+ end
173+ denom = Tₘ[row, row] - λ
174+ if abs (denom) <= value_tol (λ)
175+ vec[row] = zero (eltype (Tₘ))
176+ else
177+ vec[row] = - acc / denom
178+ end
179+ end
180+
181+ LinearAlgebra. normalize! (vec)
182+ end
183+
184+ return vecs
152185end
153186
154187function _eigsolve (
@@ -196,12 +229,13 @@ function _eigsolve(
196229 V₁ₖ = view (V, :, 1 : k)
197230 Vₖ₊₁ = view (V, :, k + 1 )
198231 Hₖ₊₁₁ₖ = view (H, k + 1 , 1 : k)
232+ cache0₁ₖ = view (cache0, :, 1 : k)
199233 cache1₁ₖ = view (cache1, :, 1 : k)
200234 cache2₁ₖ = view (cache2, 1 : k)
201235
202236 M = typeof (cache0)
203237
204- Tₘ, Uₘ = _update_schur_eigs! (Hₘ, Uₘ, Uₘᵥ, f, k, m, β, sorted_vals, sortby, rev)
238+ _update_schur_eigs! (Hₘ, Uₘ, Uₘᵥ, f, k, m, β, sorted_vals, sortby, rev)
205239
206240 numops = m
207241 iter = 0
@@ -227,20 +261,18 @@ function _eigsolve(
227261
228262 # println( A * Vₘ ≈ Vₘ * M(Hₘ) + qₘ * M(transpose(βeₘ)) ) # SHOULD BE TRUE
229263
230- Tₘ, Uₘ = _update_schur_eigs! (Hₘ, Uₘ, Uₘᵥ, f, k, m, β, sorted_vals, sortby, rev)
264+ _update_schur_eigs! (Hₘ, Uₘ, Uₘᵥ, f, k, m, β, sorted_vals, sortby, rev)
231265
232266 numops += m - k - 1
233267 iter += 1
234268 end
235269
270+ Tₘ = Hₘ
236271 vals = diag (view (Tₘ, 1 : k, 1 : k))
237- select = Vector {Int} (undef, 0 )
238- VR = LAPACK. trevc! (' R' , ' A' , select, Tₘ)
239- @inbounds for i in 1 : size (VR, 2 )
240- normalize! (view (VR, :, i))
241- end
242- mul! (cache1, Vₘ, M (Uₘ * VR))
243- vecs = cache1[:, 1 : k]
272+ VR = _schur_right_eigenvectors (Tₘ, k)
273+ mul! (cache0₁ₖ, Uₘ, VR)
274+ mul! (cache1₁ₖ, Vₘ, cache0₁ₖ)
275+ vecs = copy (cache1₁ₖ)
244276 settings. auto_tidyup && tidyup! (vecs)
245277
246278 return EigsolveResult (vals, vecs, type, dimensions, iter, numops, (iter < maxiter))
0 commit comments