Skip to content

Commit d32eb1a

Browse files
Add by and rev keyword arguments to eigsolve
1 parent f0693e3 commit d32eb1a

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

src/qobj/eigsolve.jl

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,12 @@ function _permuteschur!(
149149
return T, Q
150150
end
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
@@ -263,6 +265,8 @@ end
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
268272
Solve 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
)
311321
end
@@ -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

@@ -368,6 +380,8 @@ end
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

Comments
 (0)