Skip to content

Commit bd99404

Browse files
Support for eigen of dual operator (#1670)
Co-authored-by: Matt Fishman <[email protected]>
1 parent 0c95078 commit bd99404

File tree

3 files changed

+53
-8
lines changed

3 files changed

+53
-8
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ITensors"
22
uuid = "9136182c-28ba-11e9-034c-db9fb085ebd5"
33
authors = ["Matthew Fishman <[email protected]>", "Miles Stoudenmire <[email protected]>"]
4-
version = "0.9.10"
4+
version = "0.9.11"
55

66
[deps]
77
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"

src/tensor_operations/matrix_decomposition.jl

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -353,17 +353,22 @@ function eigen(
353353
end
354354

355355
# <fermions>
356+
L_arrow_dir = Out
356357
if hasqns(A) && using_auto_fermion()
357-
if !all(i -> dir(i) == Out, Lis)
358-
error("With auto_fermion enabled, left inds in eigen must have Out arrows")
359-
end
360-
if !all(i -> dir(i) == In, Ris)
361-
error("With auto_fermion enabled, right inds in eigen must have Out arrows")
358+
# Make arrows of combined ITensor match those of index sets
359+
if all(i -> dir(i) == Out, Lis) && all(i -> dir(i) == In, Ris)
360+
L_arrow_dir = Out
361+
elseif all(i -> dir(i) == In, Lis) && all(i -> dir(i) == Out, Ris)
362+
L_arrow_dir = In
363+
else
364+
error(
365+
"With auto_fermion enabled, index sets in eigen must have all arrows the same, and opposite between the sets",
366+
)
362367
end
363368
end
364369

365-
CL = combiner(Lis...; dir=Out, tags="CMB,left")
366-
CR = combiner(dag(Ris)...; dir=Out, tags="CMB,right")
370+
CL = combiner(Lis...; dir=L_arrow_dir, tags="CMB,left")
371+
CR = combiner(dag(Ris)...; dir=L_arrow_dir, tags="CMB,right")
367372

368373
AC = A * dag(CR) * CL
369374

test/base/test_decomp.jl

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,4 +500,44 @@ end
500500
@test norm(U * B - phi) < 1E-5
501501
@test dim(commonind(U, B)) <= 4
502502
end
503+
504+
@testset "Eigen of Fermionic Matrices" begin
505+
ITensors.enable_auto_fermion()
506+
s = Index([QN("Nf", 0, -1)=>2, QN("Nf", 1, -1)=>2], "s,Site,Fermion")
507+
t = Index([QN("Nf", 0, -1)=>2, QN("Nf", 1, -1)=>2], "t,Site,Fermion")
508+
509+
#
510+
# HPSD Operator (Out,In) case
511+
#
512+
M = random_itensor(s, dag(t))
513+
O = prime(M, s)*dag(M)
514+
515+
@test dir(inds(O)[1]) == ITensors.Out
516+
@test dir(inds(O)[2]) == ITensors.In
517+
linds = [s']
518+
rinds = [dag(s)]
519+
D_O, U = eigen(O, linds, rinds; ishermitian=true)
520+
@test norm(prime(U)*D_O*dag(U)-O) < 1E-10
521+
@test all(>=(0.0), diag(array(D_O)))
522+
523+
#
524+
# HPSD Dual operator (In,Out) case
525+
#
526+
# Make ρ out of two squared states
527+
# to populate both blocks: (0,0) and (1,1)
528+
ψ0 = random_itensor(t, s)
529+
ρ0 = prime(dag(ψ0), s)*ψ0
530+
531+
ψ2 = random_itensor(QN("Nf", 2, -1), t, s)
532+
ρ2 = prime(dag(ψ2), s)*ψ2
533+
534+
ρ = ρ0/2 + ρ2/2
535+
@test dir(inds(ρ)[1]) == ITensors.In
536+
@test dir(inds(ρ)[2]) == ITensors.Out
537+
538+
D_ρ, U = eigen(ρ, [dag(s)'], [s]; ishermitian=true)
539+
@test all(>=(0.0), diag(array(D_ρ)))
540+
@test norm(prime(U)*D_ρ*dag(U)-ρ) < 1E-10
541+
ITensors.disable_auto_fermion()
542+
end
503543
end

0 commit comments

Comments
 (0)