Skip to content

Commit f8db6d9

Browse files
committed
Add Linds, Rinds test to map_eigvals and factor out make_bosonic code
1 parent 9cb594d commit f8db6d9

File tree

2 files changed

+35
-26
lines changed

2 files changed

+35
-26
lines changed

src/lib/ITensorsExtensions/src/itensor.jl

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -64,32 +64,41 @@ function eigendecomp(A::ITensor, linds, rinds; ishermitian=false, kwargs...)
6464
return Ul, D, dag(U)
6565
end
6666

67+
function make_bosonic(A::ITensor, Linds, Rinds)
68+
# Bring indices into i',j',..,dag(j),dag(i)
69+
# ordering with Out indices coming before In indices
70+
# Resulting tensor acts like a normal matrix (no extra signs
71+
# when taking powers A^n)
72+
if all(j->dir(j)==ITensors.Out, Linds) && all(j->dir(j)==ITensors.In, Rinds)
73+
ordered_inds = [Linds..., reverse(Rinds)...]
74+
elseif all(j->dir(j)==ITensors.Out, Rinds) && all(j->dir(j)==ITensors.In, Linds)
75+
ordered_inds = [Rinds..., reverse(Linds)...]
76+
else
77+
error(
78+
"For fermionic exp, Linds and Rinds must have same directions within each set. Got dir.(Linds)=",
79+
dir.(Linds),
80+
", dir.(Rinds)=",
81+
dir.(Rinds),
82+
)
83+
end
84+
# permuted A^n will be sign free, ok to temporarily disable fermion system
85+
return permute(A, ordered_inds)
86+
end
87+
88+
function check_input(::typeof(map_eigvals), f, A, Linds, Rinds)
89+
all(x -> x isa Index, Linds) || error("Left indices must be a collection of Index")
90+
all(x -> x isa Index, Rinds) || error("Right indices must be a collection of Index")
91+
end
92+
6793
function map_eigvals(f::Function, A::ITensor, Linds, Rinds; kws...)
68-
Linds = isa(Linds, Index) ? [Linds] : collect(Linds)
69-
Rinds = isa(Rinds, Index) ? [Rinds] : collect(Rinds)
94+
check_input(map_eigvals, f, A, Linds, Rinds)
7095

7196
# <fermions>
7297
fermionic_itensor =
7398
ITensors.using_auto_fermion() && ITensors.has_fermionic_subspaces(inds(A))
7499
if fermionic_itensor
75-
# If fermionic, bring indices into i',j',..,dag(j),dag(i)
76-
# ordering with Out indices coming before In indices
77-
# Resulting tensor acts like a normal matrix (no extra signs
78-
# when taking powers A^n)
79-
if all(j->dir(j)==ITensors.Out, Linds) && all(j->dir(j)==ITensors.In, Rinds)
80-
ordered_inds = [Linds..., reverse(Rinds)...]
81-
elseif all(j->dir(j)==ITensors.Out, Rinds) && all(j->dir(j)==ITensors.In, Linds)
82-
ordered_inds = [Rinds..., reverse(Linds)...]
83-
else
84-
error(
85-
"For fermionic exp, Linds and Rinds must have same directions within each set. Got dir.(Linds)=",
86-
dir.(Linds),
87-
", dir.(Rinds)=",
88-
dir.(Rinds),
89-
)
90-
end
91-
A = permute(A, ordered_inds)
92-
# A^n now sign free, ok to temporarily disable fermion system
100+
A = make_bosonic(A::ITensor, Linds, Rinds)
101+
ordered_inds = inds(A)
93102
ITensors.disable_auto_fermion()
94103
end
95104

@@ -102,7 +111,7 @@ function map_eigvals(f::Function, A::ITensor, Linds, Rinds; kws...)
102111

103112
# <fermions>
104113
if fermionic_itensor
105-
# Ensure expA indices in "matrix" form before re-enabling fermion system
114+
# Ensure indices in "matrix" form before re-enabling fermion system
106115
mapped_A = permute(mapped_A, ordered_inds)
107116
ITensors.enable_auto_fermion()
108117
end

test/test_itensorsextensions.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ using Test: @test, @testset
6060
rng = StableRNG(1234)
6161
A = random_itensor(rng, elt, i, j)
6262
P = A * prime(dag(A), i)
63-
sqrtP = map_eigvals(sqrt, P, i, i'; ishermitian=true)
64-
inv_P = dag(map_eigvals(inv, P, i, i'; ishermitian=true))
65-
inv_sqrtP = dag(map_eigvals(inv sqrt, P, i, i'; ishermitian=true))
63+
sqrtP = map_eigvals(sqrt, P, [i], [i']; ishermitian=true)
64+
inv_P = dag(map_eigvals(inv, P, [i], [i']; ishermitian=true))
65+
inv_sqrtP = dag(map_eigvals(inv sqrt, P, [i], [i']; ishermitian=true))
6666

6767
new_ind = noprime(sim(i'))
6868
sqrtPdag = replaceind(dag(sqrtP), i', new_ind)
@@ -109,7 +109,7 @@ using Test: @test, @testset
109109
T = apply(T, swapprime(dag(T), 0=>1))
110110

111111
# Matrix test
112-
sqrtM = map_eigvals(sqrt, M, s1', dag(s1); ishermitian=true)
112+
sqrtM = map_eigvals(sqrt, M, [s1'], [dag(s1)]; ishermitian=true)
113113
@test M apply(sqrtM, sqrtM)
114114

115115
## Tensor test
@@ -133,7 +133,7 @@ using Test: @test, @testset
133133
b = Index([QN("Nb", 0)=>2, QN("Nb", 1)=>2])
134134
T = random_itensor(b', dag(b))
135135
T = apply(T, swapprime(dag(T), 0=>1))
136-
sqrtT = map_eigvals(sqrt, T, b', dag(b); ishermitian=true)
136+
sqrtT = map_eigvals(sqrt, T, [b'], [dag(b)]; ishermitian=true)
137137
@test T apply(sqrtT, sqrtT)
138138

139139
ITensors.disable_auto_fermion()

0 commit comments

Comments
 (0)