@@ -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, by, 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 = by , 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+ by = 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, by, 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, by, 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+ by::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+ - `by::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+ by:: 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+ by = by,
318+ rev = rev,
309319 kwargs... ,
310320 )
311321end
@@ -321,14 +331,16 @@ function eigsolve(
321331 tol:: Real = 1e-8 ,
322332 maxiter:: Int = 200 ,
323333 solver:: Union{Nothing,SciMLLinearSolveAlgorithm} = nothing ,
334+ by:: 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 (A, v0, type, dimensions, eigvals, krylovdim, tol = tol, maxiter = maxiter, by = by, rev = rev )
332344 vals = res. values
333345 else
334346 Aₛ = A - sigma * I
@@ -346,7 +358,7 @@ function eigsolve(
346358
347359 Amap = EigsolveInverseMap (T, size (A), linsolve)
348360
349- res = _eigsolve (Amap, v0, type, dimensions, eigvals, krylovdim, tol = tol, maxiter = maxiter)
361+ res = _eigsolve (Amap, v0, type, dimensions, eigvals, krylovdim, tol = tol, maxiter = maxiter, by = by, rev = rev )
350362 vals = @. (1 + sigma * res. values) / res. values
351363 end
352364
368380 krylovdim::Int = min(10, size(H, 1)),
369381 maxiter::Int = 200,
370382 eigstol::Real = 1e-6,
383+ by::Function = abs2,
384+ rev::Bool = true,
371385 kwargs...,
372386 )
373387
@@ -384,6 +398,8 @@ Solve the eigenvalue problem for a Liouvillian superoperator `L` using the Arnol
384398- `krylovdim`: The dimension of the Krylov subspace.
385399- `maxiter`: The maximum number of iterations for the eigsolver.
386400- `eigstol`: The tolerance for the eigsolver.
401+ - `by::Function`: the function to sort eigenvalues. Default is `abs2`.
402+ - `rev::Bool`: whether to sort in descending order. Default is `true`.
387403- `kwargs`: Additional keyword arguments passed to the differential equation solver.
388404
389405# Notes
@@ -407,6 +423,8 @@ function eigsolve_al(
407423 krylovdim:: Int = min (10 , size (H, 1 )),
408424 maxiter:: Int = 200 ,
409425 eigstol:: Real = 1e-6 ,
426+ by:: Function = abs2,
427+ rev:: Bool = true ,
410428 kwargs... ,
411429) where {HOpType<: Union{Operator,SuperOperator} }
412430 L_evo = _mesolve_make_L_QobjEvo (H, c_ops)
@@ -423,7 +441,7 @@ function eigsolve_al(
423441 Lmap = ArnoldiLindbladIntegratorMap (eltype (H), size (L_evo), integrator)
424442
425443 res =
426- _eigsolve (Lmap, mat2vec (ρ0), L_evo. type, L_evo. dimensions, eigvals, krylovdim, maxiter = maxiter, tol = eigstol)
444+ _eigsolve (Lmap, mat2vec (ρ0), L_evo. type, L_evo. dimensions, eigvals, krylovdim, maxiter = maxiter, tol = eigstol, by = by, rev = rev )
427445
428446 vals = similar (res. values)
429447 vecs = similar (res. vectors)
0 commit comments