Skip to content

Commit 9d55c3a

Browse files
Change name to sortby and change tests
1 parent d32eb1a commit 9d55c3a

File tree

2 files changed

+67
-39
lines changed

2 files changed

+67
-39
lines changed

src/qobj/eigsolve.jl

Lines changed: 49 additions & 17 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, by, rev)
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 = by, rev = rev)
157+
sortperm!(sorted_vals, values, by = sortby, rev = rev)
158158
_permuteschur!(Tₘ, Uₘ, sorted_vals)
159159
mul!(f, Uₘᵥ, β)
160160

@@ -170,7 +170,7 @@ function _eigsolve(
170170
m::Int = max(20, 2 * k + 1);
171171
tol::Real = 1e-8,
172172
maxiter::Int = 200,
173-
by = abs2,
173+
sortby::Function = abs2,
174174
rev = true,
175175
) where {T<:BlasFloat,ObjType<:Union{Nothing,Operator,SuperOperator}}
176176
n = size(A, 2)
@@ -211,7 +211,7 @@ function _eigsolve(
211211

212212
M = typeof(cache0)
213213

214-
Tₘ, Uₘ = _update_schur_eigs!(Hₘ, Uₘ, Uₘᵥ, f, m, β, sorted_vals, by, rev)
214+
Tₘ, Uₘ = _update_schur_eigs!(Hₘ, Uₘ, Uₘᵥ, f, m, β, sorted_vals, sortby, rev)
215215

216216
numops = m
217217
iter = 0
@@ -237,7 +237,7 @@ function _eigsolve(
237237

238238
# println( A * Vₘ ≈ Vₘ * M(Hₘ) + qₘ * M(transpose(βeₘ)) ) # SHOULD BE TRUE
239239

240-
Tₘ, Uₘ = _update_schur_eigs!(Hₘ, Uₘ, Uₘᵥ, f, m, β, sorted_vals, by, rev)
240+
Tₘ, Uₘ = _update_schur_eigs!(Hₘ, Uₘ, Uₘᵥ, f, m, β, sorted_vals, sortby, rev)
241241

242242
numops += m - k - 1
243243
iter += 1
@@ -265,7 +265,7 @@ end
265265
tol::Real = 1e-8,
266266
maxiter::Int = 200,
267267
solver::Union{Nothing, SciMLLinearSolveAlgorithm} = nothing,
268-
by::Function = abs2,
268+
sortby::Function = abs2,
269269
rev::Bool = true,
270270
kwargs...)
271271
@@ -280,7 +280,7 @@ Solve for the eigenvalues and eigenvectors of a matrix `A` using the Arnoldi met
280280
- `tol::Real`: the tolerance for the Arnoldi method. Default is `1e-8`.
281281
- `maxiter::Int`: the maximum number of iterations for the Arnoldi method. Default is `200`.
282282
- `solver::Union{Nothing, SciMLLinearSolveAlgorithm}`: the linear solver algorithm. Default is `nothing`.
283-
- `by::Function`: the function to sort eigenvalues. Default is `abs2`.
283+
- `sortby::Function`: the function to sort eigenvalues. Default is `abs2`.
284284
- `rev::Bool`: whether to sort in descending order. Default is `true`.
285285
- `kwargs`: Additional keyword arguments passed to the solver.
286286
@@ -299,7 +299,7 @@ function eigsolve(
299299
tol::Real = 1e-8,
300300
maxiter::Int = 200,
301301
solver::Union{Nothing,SciMLLinearSolveAlgorithm} = nothing,
302-
by::Function = abs2,
302+
sortby::Function = abs2,
303303
rev::Bool = true,
304304
kwargs...,
305305
)
@@ -314,7 +314,7 @@ function eigsolve(
314314
tol = tol,
315315
maxiter = maxiter,
316316
solver = solver,
317-
by = by,
317+
sortby = sortby,
318318
rev = rev,
319319
kwargs...,
320320
)
@@ -331,7 +331,7 @@ function eigsolve(
331331
tol::Real = 1e-8,
332332
maxiter::Int = 200,
333333
solver::Union{Nothing,SciMLLinearSolveAlgorithm} = nothing,
334-
by::Function = abs2,
334+
sortby::Function = abs2,
335335
rev::Bool = true,
336336
kwargs...,
337337
)
@@ -340,7 +340,18 @@ function eigsolve(
340340
v0 === nothing && (v0 = normalize!(rand(T, size(A, 1))))
341341

342342
if sigma === nothing
343-
res = _eigsolve(A, v0, type, dimensions, eigvals, krylovdim, tol = tol, maxiter = maxiter, by = by, rev = rev)
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+
)
344355
vals = res.values
345356
else
346357
Aₛ = A - sigma * I
@@ -358,7 +369,18 @@ function eigsolve(
358369

359370
Amap = EigsolveInverseMap(T, size(A), linsolve)
360371

361-
res = _eigsolve(Amap, v0, type, dimensions, eigvals, krylovdim, tol = tol, maxiter = maxiter, by = by, rev = rev)
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+
)
362384
vals = @. (1 + sigma * res.values) / res.values
363385
end
364386

@@ -380,7 +402,7 @@ end
380402
krylovdim::Int = min(10, size(H, 1)),
381403
maxiter::Int = 200,
382404
eigstol::Real = 1e-6,
383-
by::Function = abs2,
405+
sortby::Function = abs2,
384406
rev::Bool = true,
385407
kwargs...,
386408
)
@@ -398,7 +420,7 @@ Solve the eigenvalue problem for a Liouvillian superoperator `L` using the Arnol
398420
- `krylovdim`: The dimension of the Krylov subspace.
399421
- `maxiter`: The maximum number of iterations for the eigsolver.
400422
- `eigstol`: The tolerance for the eigsolver.
401-
- `by::Function`: the function to sort eigenvalues. Default is `abs2`.
423+
- `sortby::Function`: the function to sort eigenvalues. Default is `abs2`.
402424
- `rev::Bool`: whether to sort in descending order. Default is `true`.
403425
- `kwargs`: Additional keyword arguments passed to the differential equation solver.
404426
@@ -423,7 +445,7 @@ function eigsolve_al(
423445
krylovdim::Int = min(10, size(H, 1)),
424446
maxiter::Int = 200,
425447
eigstol::Real = 1e-6,
426-
by::Function = abs2,
448+
sortby::Function = abs2,
427449
rev::Bool = true,
428450
kwargs...,
429451
) where {HOpType<:Union{Operator,SuperOperator}}
@@ -440,8 +462,18 @@ function eigsolve_al(
440462

441463
Lmap = ArnoldiLindbladIntegratorMap(eltype(H), size(L_evo), integrator)
442464

443-
res =
444-
_eigsolve(Lmap, mat2vec(ρ0), L_evo.type, L_evo.dimensions, eigvals, krylovdim, maxiter = maxiter, tol = eigstol, by = by, rev = rev)
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+
)
445477

446478
vals = similar(res.values)
447479
vecs = similar(res.vectors)

test/core-test/eigenvalues_and_operators.jl

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@testitem "Eigenvalues and Operators" begin
1+
@testitem "Eigenvalues" begin
22
σx = sigmax()
33
result = eigenstates(σx, sparse = false)
44
λd, ψd, Td = result
@@ -33,12 +33,10 @@
3333

3434
vals_d, vecs_d, mat_d = eigenstates(H_d)
3535
vals_c, vecs_c, mat_c = eigenstates(H_c)
36-
vals2, vecs2, mat2 = eigenstates(H_d, sparse = true, sigma = -0.9, eigvals = 10, krylovdim = 30)
37-
sort!(vals_c, by = real)
38-
sort!(vals2, by = real)
36+
vals2, vecs2, mat2 = eigenstates(H_d, sparse = true, sigma = -0.9, eigvals = 10, krylovdim = 30, by = real)
3937

40-
@test sum(real.(vals_d[1:20]) .- real.(vals_c[1:20])) / 20 < 1e-3
41-
@test sum(real.(vals_d[1:10]) .- real.(vals2[1:10])) / 20 < 1e-3
38+
@test real.(vals_d[1:20]) real.(vals_c[1:20])
39+
@test real.(vals_d[1:10]) real.(vals2[1:10])
4240

4341
N = 5
4442
a = kron(destroy(N), qeye(N))
@@ -58,16 +56,15 @@
5856

5957
# eigen solve for general matrices
6058
vals, _, vecs = eigsolve(L.data, sigma = 0.01, eigvals = 10, krylovdim = 50)
61-
vals2, _, vecs2 = eigenstates(L)
59+
vals2, _, vecs2 = eigenstates(L; sortby = abs)
6260
vals3, state3, vecs3 = eigsolve_al(L, 1 \ (40 * κ), eigvals = 10, krylovdim = 50)
63-
idxs = sortperm(vals2, by = abs)
64-
vals2 = vals2[idxs][1:10]
65-
vecs2 = vecs2[:, idxs][:, 1:10]
61+
vals2 = vals2[1:10]
62+
vecs2 = vecs2[:, 1:10]
6663

67-
@test isapprox(sum(abs2, vals), sum(abs2, vals2), atol = 1e-7)
68-
@test isapprox(abs2(vals2[1]), abs2(vals3[1]), atol = 1e-7)
69-
@test isapprox(vec2mat(vecs[:, 1]) * exp(-1im * angle(vecs[1, 1])), vec2mat(vecs2[:, 1]), atol = 1e-7)
70-
@test isapprox(vec2mat(vecs[:, 1]) * exp(-1im * angle(vecs[1, 1])), vec2mat(vecs3[:, 1]), atol = 1e-5)
64+
@test sum(abs2, vals) sum(abs2, vals2)
65+
@test abs2(vals2[1]) abs2(vals3[1]) atol=1e-7
66+
@test vec2mat(vecs[:, 1]) * exp(-1im * angle(vecs[1, 1])) vec2mat(vecs2[:, 1]) atol=1e-7
67+
@test vec2mat(vecs[:, 1]) * exp(-1im * angle(vecs[1, 1])) vec2mat(vecs3[:, 1]) atol=1e-5
7168

7269
# eigen solve for QuantumObject
7370
result = eigenstates(L, sparse = true, sigma = 0.01, eigvals = 10, krylovdim = 50)
@@ -78,19 +75,18 @@
7875
@test resstring ==
7976
"EigsolveResult: type=$(SuperOperator()) dims=$(result.dims)\nvalues:\n$(valstring)\nvectors:\n$vecsstring"
8077

81-
vals2, vecs2 = eigenstates(L, sparse = false)
82-
idxs = sortperm(vals2, by = abs)
83-
vals2 = vals2[idxs][1:10]
84-
vecs2 = vecs2[idxs][1:10]
78+
vals2, vecs2 = eigenstates(L, sortby = abs)
79+
vals2 = vals2[1:10]
80+
vecs2 = vecs2[1:10]
8581

8682
@test result.type isa SuperOperator
8783
@test result.dims == L.dims
8884
@test all([v.type isa OperatorKet for v in vecs])
8985
@test typeof(result.vectors) <: AbstractMatrix
90-
@test isapprox(sum(abs2, vals), sum(abs2, vals2), atol = 1e-7)
91-
@test isapprox(abs2(vals2[1]), abs2(vals3[1]), atol = 1e-7)
92-
@test isapprox(vec2mat(vecs[1]).data * exp(-1im * angle(vecs[1][1])), vec2mat(vecs2[1]).data, atol = 1e-7)
93-
@test isapprox(vec2mat(vecs[1]).data * exp(-1im * angle(vecs[1][1])), vec2mat(state3[1]).data, atol = 1e-5)
86+
@test sum(abs2, vals) sum(abs2, vals2)
87+
@test abs2(vals2[1]) abs2(vals3[1]) atol=1e-7
88+
@test vec2mat(vecs[1]).data * exp(-1im * angle(vecs[1][1])) vec2mat(vecs2[1]).data
89+
@test vec2mat(vecs[1]).data * exp(-1im * angle(vecs[1][1])) vec2mat(state3[1]).data atol=1e-5
9490

9591
@testset "Type Inference (eigen)" begin
9692
N = 5

0 commit comments

Comments
 (0)