@@ -149,12 +149,12 @@ function _permuteschur!(
149149 return T, Q
150150end
151151
152- function _update_schur_eigs! (Hₘ, Uₘ, Uₘᵥ, f, m, β, sorted_vals)
152+ function _update_schur_eigs! (Hₘ, Uₘ, Uₘᵥ, f, m, β, sorted_vals, sortby, rev )
153153 F = hessenberg! (Hₘ)
154154 copyto! (Uₘ, Hₘ)
155155 LAPACK. orghr! (1 , m, Uₘ, F. τ)
156156 Tₘ, Uₘ, values = hseqr! (Hₘ, Uₘ)
157- sortperm! (sorted_vals, values, by = abs , rev = true )
157+ sortperm! (sorted_vals, values, by = sortby , rev = rev )
158158 _permuteschur! (Tₘ, Uₘ, sorted_vals)
159159 mul! (f, Uₘᵥ, β)
160160
@@ -170,6 +170,8 @@ function _eigsolve(
170170 m:: Int = max (20 , 2 * k + 1 );
171171 tol:: Real = 1e-8 ,
172172 maxiter:: Int = 200 ,
173+ sortby:: Function = abs2,
174+ rev = true ,
173175) where {T<: BlasFloat ,ObjType<: Union{Nothing,Operator,SuperOperator} }
174176 n = size (A, 2 )
175177 V = similar (b, n, m + 1 )
@@ -209,7 +211,7 @@ function _eigsolve(
209211
210212 M = typeof (cache0)
211213
212- Tₘ, Uₘ = _update_schur_eigs! (Hₘ, Uₘ, Uₘᵥ, f, m, β, sorted_vals)
214+ Tₘ, Uₘ = _update_schur_eigs! (Hₘ, Uₘ, Uₘᵥ, f, m, β, sorted_vals, sortby, rev )
213215
214216 numops = m
215217 iter = 0
@@ -235,7 +237,7 @@ function _eigsolve(
235237
236238 # println( A * Vₘ ≈ Vₘ * M(Hₘ) + qₘ * M(transpose(βeₘ)) ) # SHOULD BE TRUE
237239
238- Tₘ, Uₘ = _update_schur_eigs! (Hₘ, Uₘ, Uₘᵥ, f, m, β, sorted_vals)
240+ Tₘ, Uₘ = _update_schur_eigs! (Hₘ, Uₘ, Uₘᵥ, f, m, β, sorted_vals, sortby, rev )
239241
240242 numops += m - k - 1
241243 iter += 1
263265 tol::Real = 1e-8,
264266 maxiter::Int = 200,
265267 solver::Union{Nothing, SciMLLinearSolveAlgorithm} = nothing,
268+ sortby::Function = abs2,
269+ rev::Bool = true,
266270 kwargs...)
267271
268272Solve for the eigenvalues and eigenvectors of a matrix `A` using the Arnoldi method.
@@ -276,6 +280,8 @@ Solve for the eigenvalues and eigenvectors of a matrix `A` using the Arnoldi met
276280- `tol::Real`: the tolerance for the Arnoldi method. Default is `1e-8`.
277281- `maxiter::Int`: the maximum number of iterations for the Arnoldi method. Default is `200`.
278282- `solver::Union{Nothing, SciMLLinearSolveAlgorithm}`: the linear solver algorithm. Default is `nothing`.
283+ - `sortby::Function`: the function to sort eigenvalues. Default is `abs2`.
284+ - `rev::Bool`: whether to sort in descending order. Default is `true`.
279285- `kwargs`: Additional keyword arguments passed to the solver.
280286
281287# Notes
@@ -293,6 +299,8 @@ function eigsolve(
293299 tol:: Real = 1e-8 ,
294300 maxiter:: Int = 200 ,
295301 solver:: Union{Nothing,SciMLLinearSolveAlgorithm} = nothing ,
302+ sortby:: Function = abs2,
303+ rev:: Bool = true ,
296304 kwargs... ,
297305)
298306 return eigsolve (
@@ -306,6 +314,8 @@ function eigsolve(
306314 tol = tol,
307315 maxiter = maxiter,
308316 solver = solver,
317+ sortby = sortby,
318+ rev = rev,
309319 kwargs... ,
310320 )
311321end
@@ -321,14 +331,27 @@ function eigsolve(
321331 tol:: Real = 1e-8 ,
322332 maxiter:: Int = 200 ,
323333 solver:: Union{Nothing,SciMLLinearSolveAlgorithm} = nothing ,
334+ sortby:: Function = abs2,
335+ rev:: Bool = true ,
324336 kwargs... ,
325337)
326338 T = eltype (A)
327339 isH = ishermitian (A)
328340 v0 === nothing && (v0 = normalize! (rand (T, size (A, 1 ))))
329341
330342 if sigma === nothing
331- res = _eigsolve (A, v0, type, dimensions, eigvals, krylovdim, tol = tol, maxiter = maxiter)
343+ res = _eigsolve (
344+ A,
345+ v0,
346+ type,
347+ dimensions,
348+ eigvals,
349+ krylovdim,
350+ tol = tol,
351+ maxiter = maxiter,
352+ sortby = sortby,
353+ rev = rev,
354+ )
332355 vals = res. values
333356 else
334357 Aₛ = A - sigma * I
@@ -346,7 +369,18 @@ function eigsolve(
346369
347370 Amap = EigsolveInverseMap (T, size (A), linsolve)
348371
349- res = _eigsolve (Amap, v0, type, dimensions, eigvals, krylovdim, tol = tol, maxiter = maxiter)
372+ res = _eigsolve (
373+ Amap,
374+ v0,
375+ type,
376+ dimensions,
377+ eigvals,
378+ krylovdim,
379+ tol = tol,
380+ maxiter = maxiter,
381+ sortby = sortby,
382+ rev = rev,
383+ )
350384 vals = @. (1 + sigma * res. values) / res. values
351385 end
352386
368402 krylovdim::Int = min(10, size(H, 1)),
369403 maxiter::Int = 200,
370404 eigstol::Real = 1e-6,
405+ sortby::Function = abs2,
406+ rev::Bool = true,
371407 kwargs...,
372408 )
373409
@@ -384,6 +420,8 @@ Solve the eigenvalue problem for a Liouvillian superoperator `L` using the Arnol
384420- `krylovdim`: The dimension of the Krylov subspace.
385421- `maxiter`: The maximum number of iterations for the eigsolver.
386422- `eigstol`: The tolerance for the eigsolver.
423+ - `sortby::Function`: the function to sort eigenvalues. Default is `abs2`.
424+ - `rev::Bool`: whether to sort in descending order. Default is `true`.
387425- `kwargs`: Additional keyword arguments passed to the differential equation solver.
388426
389427# Notes
@@ -407,6 +445,8 @@ function eigsolve_al(
407445 krylovdim:: Int = min (10 , size (H, 1 )),
408446 maxiter:: Int = 200 ,
409447 eigstol:: Real = 1e-6 ,
448+ sortby:: Function = abs2,
449+ rev:: Bool = true ,
410450 kwargs... ,
411451) where {HOpType<: Union{Operator,SuperOperator} }
412452 L_evo = _mesolve_make_L_QobjEvo (H, c_ops)
@@ -422,8 +462,18 @@ function eigsolve_al(
422462
423463 Lmap = ArnoldiLindbladIntegratorMap (eltype (H), size (L_evo), integrator)
424464
425- res =
426- _eigsolve (Lmap, mat2vec (ρ0), L_evo. type, L_evo. dimensions, eigvals, krylovdim, maxiter = maxiter, tol = eigstol)
465+ res = _eigsolve (
466+ Lmap,
467+ mat2vec (ρ0),
468+ L_evo. type,
469+ L_evo. dimensions,
470+ eigvals,
471+ krylovdim,
472+ maxiter = maxiter,
473+ tol = eigstol,
474+ sortby = sortby,
475+ rev = rev,
476+ )
427477
428478 vals = similar (res. values)
429479 vecs = similar (res. vectors)
0 commit comments