Skip to content

Commit 8cf041f

Browse files
lkdvosborisdevos
andauthored
Refactor quasiparticle regularization (#318)
* Fix off-by-one error * centralize regularization calls * avoid braiding in regularize * remove unused code * Add `istrivial` and `istopological` * add Z2 Ising model * test sectors in quasiparticle ansatz * Merge transverse field ising implementations * small tests alterations --------- Co-authored-by: Boris De Vos <[email protected]>
1 parent df76b90 commit 8cf041f

File tree

8 files changed

+102
-141
lines changed

8 files changed

+102
-141
lines changed

src/algorithms/excitation/exci_transfer_system.jl

Lines changed: 19 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,3 @@
1-
function left_excitation_transfer_system(
2-
lBs, H, exci; mom = exci.momentum,
3-
solver = Defaults.linearsolver
4-
)
5-
len = length(H)
6-
found = zero.(lBs)
7-
odim = length(lBs)
8-
9-
for i in 1:odim
10-
# this operation can in principle be even further optimized for larger unit cells
11-
# as we only require the terms that end at level i.
12-
# this would require to check the finite state machine, and discard non-connected
13-
# terms.
14-
H_partial = map(site -> H.data[site, 1:i, 1:i], 1:len)
15-
T = TransferMatrix(exci.right_gs.AR, H_partial, exci.left_gs.AL)
16-
start = scale!(last(found[1:i] * T), cis(-mom * len))
17-
if exci.trivial && isid(H, i)
18-
@plansor start[-1 -2; -3 -4] -= start[1 4; -3 2] * r_RL(exci.right_gs)[2; 3] *
19-
τ[3 4; 5 1] * l_RL(exci.right_gs)[-1; 6] * τ[5 6; -4 -2]
20-
end
21-
22-
found[i] = add!(start, lBs[i])
23-
24-
if reduce(&, contains.(H.data, i, i))
25-
if isid(H, i)
26-
tm = TransferMatrix(exci.right_gs.AR, exci.left_gs.AL)
27-
if exci.trivial
28-
tm = regularize(tm, l_RL(exci.right_gs), r_RL(exci.right_gs))
29-
end
30-
else
31-
tm = TransferMatrix(
32-
exci.right_gs.AR, getindex.(H.data, i, i), exci.left_gs.AL
33-
)
34-
end
35-
36-
found[i], convhist = linsolve(
37-
flip(tm), found[i], found[i], solver, 1, -cis(-mom * len)
38-
)
39-
convhist.converged == 0 &&
40-
@warn "GBL$i failed to converge: normres = $(convhist.normres)"
41-
end
42-
end
43-
return found
44-
end
451
function left_excitation_transfer_system(
462
GBL, H::InfiniteMPOHamiltonian, exci;
473
mom = exci.momentum, solver = Defaults.linearsolver
@@ -50,6 +6,11 @@ function left_excitation_transfer_system(
506
found = zerovector(GBL)
517
odim = length(GBL)
528

9+
if istrivial(exci)
10+
ρ_left = l_RL(exci.right_gs)
11+
ρ_right = r_RL(exci.right_gs)
12+
end
13+
5314
for i in 1:odim
5415
# this operation can in principle be even further optimized for larger unit cells
5516
# as we only require the terms that end at level i.
@@ -58,18 +19,17 @@ function left_excitation_transfer_system(
5819
H_partial = map(h -> getindex(h, 1:i, 1, 1, 1:i), parent(H))
5920
T = TransferMatrix(exci.right_gs.AR, H_partial, exci.left_gs.AL)
6021
start = scale!(last(found[1:i] * T), cis(-mom * len))
61-
if exci.trivial && isidentitylevel(H, i)
62-
@plansor start[-1 -2; -3 -4] -= start[1 4; -3 2] * r_RL(exci.right_gs)[2; 3] *
63-
τ[3 4; 5 1] * l_RL(exci.right_gs)[-1; 6] * τ[5 6; -4 -2]
22+
if istrivial(exci) && isidentitylevel(H, i)
23+
regularize!(start, ρ_right, ρ_left)
6424
end
6525

6626
found[i] = add!(start, GBL[i])
6727

6828
if !isemptylevel(H, i)
6929
if isidentitylevel(H, i)
7030
T = TransferMatrix(exci.right_gs.AR, exci.left_gs.AL)
71-
if exci.trivial
72-
T = regularize(T, l_RL(exci.right_gs), r_RL(exci.right_gs))
31+
if istrivial(exci)
32+
T = regularize(T, ρ_left, ρ_right)
7333
end
7434
else
7535
T = TransferMatrix(
@@ -86,49 +46,7 @@ function left_excitation_transfer_system(
8646
end
8747
return found
8848
end
89-
function right_excitation_transfer_system(
90-
rBs, H, exci; mom = exci.momentum, solver = Defaults.linearsolver
91-
)
92-
len = length(H)
93-
found = zero.(rBs)
94-
odim = length(rBs)
95-
96-
for i in odim:-1:1
97-
# this operation can in principle be even further optimized for larger unit cells
98-
# as we only require the terms that end at level i.
99-
# this would require to check the finite state machine, and discard non-connected
100-
# terms.
101-
H_partial = map(site -> H.data[site, i:odim, i:odim], 1:len)
102-
T = TransferMatrix(exci.left_gs.AL, H_partial, exci.right_gs.AR)
103-
start = scale!(first(T * found[i:odim]), cis(mom * len))
104-
if exci.trivial && isid(H, i)
105-
@plansor start[-1 -2; -3 -4] -= τ[6 2; 3 4] * start[3 4; -3 5] *
106-
l_LR(exci.right_gs)[5; 2] * r_LR(exci.right_gs)[-1; 1] * τ[-2 -4; 1 6]
107-
end
108-
109-
found[i] = add!(start, rBs[i])
11049

111-
if reduce(&, contains.(H.data, i, i))
112-
if isid(H, i)
113-
tm = TransferMatrix(exci.left_gs.AL, exci.right_gs.AR)
114-
if exci.trivial
115-
tm = regularize(tm, l_LR(exci.left_gs), r_LR(exci.right_gs))
116-
end
117-
else
118-
tm = TransferMatrix(
119-
exci.left_gs.AL, getindex.(H.data, i, i), exci.right_gs.AR
120-
)
121-
end
122-
123-
found[i], convhist = linsolve(
124-
tm, found[i], found[i], solver, 1, -cis(mom * len)
125-
)
126-
convhist.converged < 1 &&
127-
@warn "GBR$i failed to converge: normres = $(convhist.normres)"
128-
end
129-
end
130-
return found
131-
end
13250
function right_excitation_transfer_system(
13351
GBR, H::InfiniteMPOHamiltonian, exci;
13452
mom = exci.momentum,
@@ -138,6 +56,11 @@ function right_excitation_transfer_system(
13856
found = zerovector(GBR)
13957
odim = length(GBR)
14058

59+
if istrivial(exci)
60+
ρ_left = l_LR(exci.right_gs)
61+
ρ_right = r_LR(exci.right_gs)
62+
end
63+
14164
for i in odim:-1:1
14265
# this operation can in principle be even further optimized for larger unit cells
14366
# as we only require the terms that end at level i.
@@ -146,18 +69,17 @@ function right_excitation_transfer_system(
14669
H_partial = map(h -> h[i:end, 1, 1, i:end], parent(H))
14770
T = TransferMatrix(exci.left_gs.AL, H_partial, exci.right_gs.AR)
14871
start = scale!(first(T * found[i:odim]), cis(mom * len))
149-
if exci.trivial && isidentitylevel(H, i)
150-
@plansor start[-1 -2; -3 -4] -= τ[6 2; 3 4] * start[3 4; -3 5] *
151-
l_LR(exci.right_gs)[5; 2] * r_LR(exci.right_gs)[-1; 1] * τ[-2 -4; 1 6]
72+
if istrivial(exci) && isidentitylevel(H, i)
73+
regularize!(start, ρ_left, ρ_right)
15274
end
15375

15476
found[i] = add!(start, GBR[i])
15577

15678
if !isemptylevel(H, i)
15779
if isidentitylevel(H, i)
15880
tm = TransferMatrix(exci.left_gs.AL, exci.right_gs.AR)
159-
if exci.trivial
160-
tm = regularize(tm, l_LR(exci.left_gs), r_LR(exci.right_gs))
81+
if istrivial(exci)
82+
tm = regularize(tm, ρ_left, ρ_right)
16183
end
16284
else
16385
tm = TransferMatrix(
@@ -166,8 +88,7 @@ function right_excitation_transfer_system(
16688
end
16789

16890
found[i], convhist = linsolve(
169-
tm, found[i], found[i], solver, 1,
170-
-cis(mom * len)
91+
tm, found[i], found[i], solver, 1, -cis(mom * len)
17192
)
17293
convhist.converged < 1 &&
17394
@warn "GBR$i failed to converge: normres = $(convhist.normres)"

src/algorithms/excitation/quasiparticleexcitation.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ function excitations(H, alg::QuasiparticleAnsatz, ϕ₀::InfiniteQP, lenvs, renv
5757
end
5858
function excitations(H, alg::QuasiparticleAnsatz, ϕ₀::InfiniteQP, lenvs; num = 1, kwargs...)
5959
# Infer `renvs` in function body as it depends on `solver`.
60-
renvs = ϕ₀.trivial ? lenvs : environments(ϕ₀.right_gs, H; kwargs...)
60+
renvs = !istopological(ϕ₀) ? lenvs : environments(ϕ₀.right_gs, H; kwargs...)
6161
return excitations(H, alg, ϕ₀, lenvs, renvs; num, kwargs...)
6262
end
6363
function excitations(H, alg::QuasiparticleAnsatz, ϕ₀::InfiniteQP; num = 1, kwargs...)
@@ -136,7 +136,7 @@ end
136136
function excitations(
137137
H, alg::QuasiparticleAnsatz, ϕ₀::FiniteQP,
138138
lenvs = environments(ϕ₀.left_gs, H),
139-
renvs = ϕ₀.trivial ? lenvs : environments(ϕ₀.right_gs, H);
139+
renvs = !istopological(ϕ₀) ? lenvs : environments(ϕ₀.right_gs, H);
140140
num = 1
141141
)
142142
E = effective_excitation_renormalization_energy(H, ϕ₀, lenvs, renvs)
@@ -223,7 +223,7 @@ function excitations(
223223
kwargs...
224224
)
225225
# Infer `renvs` in function body as it depends on `solver`.
226-
renvs = ϕ₀.trivial ? lenvs : environments(ϕ₀.right_gs, H; kwargs...)
226+
renvs = !istopological(ϕ₀) ? lenvs : environments(ϕ₀.right_gs, H; kwargs...)
227227
return excitations(H, alg, ϕ₀, lenvs, renvs; kwargs...)
228228
end
229229
function excitations(
@@ -372,7 +372,7 @@ function effective_excitation_renormalization_energy(H, ϕ, lenvs, renvs)
372372
E[i] = contract_mpo_expval(
373373
ψ_left.AC[i], leftenv(lenvs, i, ψ_left), H[i], rightenv(lenvs, i, ψ_left)
374374
)
375-
if !ϕ.trivial
375+
if istopological(ϕ)
376376
E[i] += contract_mpo_expval(
377377
ψ_right.AC[i], leftenv(renvs, i, ψ_right), H[i], rightenv(renvs, i, ψ_right)
378378
)

src/algorithms/toolbox.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ end
225225

226226
function variance(state::InfiniteQP, H::InfiniteMPOHamiltonian, envs = environments(state, H))
227227
# I remember there being an issue here @gertian?
228-
state.trivial ||
228+
istopological(state) &&
229229
throw(ArgumentError("variance of domain wall excitations is not implemented"))
230230
gs = state.left_gs
231231

src/environments/qp_envs.jl

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function environments(exci::Union{InfiniteQP, MultilineQP}, H; kwargs...)
3333
return environments(exci, H, lenvs; kwargs...)
3434
end
3535
function environments(exci::Union{InfiniteQP, MultilineQP}, H, lenvs; kwargs...)
36-
renvs = exci.trivial ? lenvs : environments(exci.right_gs, H; kwargs...)
36+
renvs = !istopological(exci) ? lenvs : environments(exci.right_gs, H; kwargs...)
3737
return environments(exci, H, lenvs, renvs; kwargs...)
3838
end
3939

@@ -46,7 +46,7 @@ function environments(qp::MultilineQP, operator::MultilineMPO, lenvs, renvs; kwa
4646
end
4747

4848
function environments(exci::InfiniteQP, H::InfiniteMPOHamiltonian, lenvs, renvs; kwargs...)
49-
ids = findall(Base.Fix1(isidentitylevel, H), 2:(size(H[1], 1) - 1))
49+
ids = findall(Base.Fix1(isidentitylevel, H), 2:(size(H[1], 1) - 1)) .+ 1
5050
solver = environment_alg(exci, H, exci; kwargs...)
5151

5252
AL = exci.left_gs.AL
@@ -62,11 +62,11 @@ function environments(exci::InfiniteQP, H::InfiniteMPOHamiltonian, lenvs, renvs;
6262
lBs[pos + 1] += leftenv(lenvs, pos, exci.left_gs) *
6363
TransferMatrix(exci[pos], H[pos], AL[pos]) / cis(exci.momentum)
6464

65-
if exci.trivial # regularization of trivial excitations
65+
if istrivial(exci) && !isempty(ids) # regularization of trivial excitations
66+
ρ_left = l_RL(exci.left_gs, pos + 1)
67+
ρ_right = r_RL(exci.left_gs, pos)
6668
for i in ids
67-
@plansor lBs[pos + 1][i][-1 -2; -3 -4] -= lBs[pos + 1][i][1 4; -3 2] *
68-
r_RL(exci.left_gs, pos)[2; 3] * τ[3 4; 5 1] *
69-
l_RL(exci.left_gs, pos + 1)[ -1; 6 ] * τ[5 6; -4 -2]
69+
regularize!(lBs[pos + 1][i], ρ_right, ρ_left)
7070
end
7171
end
7272
end
@@ -78,12 +78,11 @@ function environments(exci::InfiniteQP, H::InfiniteMPOHamiltonian, lenvs, renvs;
7878
rBs[pos - 1] += TransferMatrix(exci[pos], H[pos], AR[pos]) *
7979
rightenv(renvs, pos, exci.right_gs) * cis(exci.momentum)
8080

81-
if exci.trivial
81+
if istrivial(exci) && !isempty(ids)
82+
ρ_left = l_LR(exci.left_gs, pos)
83+
ρ_right = r_LR(exci.left_gs, pos - 1)
8284
for i in ids
83-
ρ_left = l_LR(exci.left_gs, pos)
84-
ρ_right = r_LR(exci.left_gs, pos - 1)
85-
@plansor rBs[pos - 1][i][-1 -2; -3 -4] -= τ[6 4; 1 3] *
86-
rBs[pos - 1][i][1 3; -3 2] * ρ_left[2; 4] * ρ_right[-1; 5] * τ[-2 -4; 5 6]
85+
regularize!(rBs[pos - 1][i], ρ_left, ρ_right)
8786
end
8887
end
8988
end
@@ -101,12 +100,11 @@ function environments(exci::InfiniteQP, H::InfiniteMPOHamiltonian, lenvs, renvs;
101100
for i in 1:(length(exci) - 1)
102101
lB_cur = lB_cur * TransferMatrix(AR[i], H[i], AL[i]) / cis(exci.momentum)
103102

104-
if exci.trivial
103+
if istrivial(exci) && !isempty(ids)
104+
ρ_left = l_RL(exci.left_gs, i + 1)
105+
ρ_right = r_RL(exci.left_gs, i)
105106
for k in ids
106-
ρ_left = l_RL(exci.left_gs, i + 1)
107-
ρ_right = r_RL(exci.left_gs, i)
108-
@plansor lB_cur[k][-1 -2; -3 -4] -= lB_cur[k][1 4; -3 2] *
109-
ρ_right[2; 3] * τ[3 4; 5 1] * ρ_left[-1; 6] * τ[5 6; -4 -2]
107+
regularize!(lB_cur[k], ρ_right, ρ_left)
110108
end
111109
end
112110

@@ -117,12 +115,11 @@ function environments(exci::InfiniteQP, H::InfiniteMPOHamiltonian, lenvs, renvs;
117115
for i in length(exci):-1:2
118116
rB_cur = TransferMatrix(AL[i], H[i], AR[i]) * rB_cur * cis(exci.momentum)
119117

120-
if exci.trivial
118+
if istrivial(exci) && !isempty(ids)
119+
ρ_left = l_LR(exci.left_gs, i)
120+
ρ_right = r_LR(exci.left_gs, i - 1)
121121
for k in ids
122-
ρ_left = l_LR(exci.left_gs, i)
123-
ρ_right = r_LR(exci.left_gs, i - 1)
124-
@plansor rB_cur[k][-1 -2; -3 -4] -= τ[6 4; 1 3] *
125-
rB_cur[k][1 3; -3 2] * ρ_left[2; 4] * ρ_right[-1; 5] * τ[-2 -4; 5 6]
122+
regularize!(rB_cur[k], ρ_left, ρ_right)
126123
end
127124
end
128125

@@ -135,7 +132,7 @@ end
135132
function environments(
136133
exci::FiniteQP, H::FiniteMPOHamiltonian,
137134
lenvs = environments(exci.left_gs, H),
138-
renvs = exci.trivial ? lenvs : environments(exci.right_gs, H);
135+
renvs = !istopological(exci) ? lenvs : environments(exci.right_gs, H);
139136
kwargs...
140137
)
141138
AL = exci.left_gs.AL
@@ -164,7 +161,7 @@ function environments(
164161
end
165162

166163
function environments(exci::InfiniteQP, O::InfiniteMPO, lenvs, renvs; kwargs...)
167-
exci.trivial ||
164+
istopological(exci) &&
168165
@warn "there is a phase ambiguity in topologically nontrivial statmech excitations"
169166
solver = environment_alg(exci, O, exci; kwargs...)
170167

@@ -206,7 +203,7 @@ function environments(exci::InfiniteQP, O::InfiniteMPO, lenvs, renvs; kwargs...)
206203
T_RL = TransferMatrix(right_gs.AR, O, left_gs.AL)
207204
T_LR = TransferMatrix(left_gs.AL, O, right_gs.AR)
208205

209-
if exci.trivial
206+
if istrivial(exci)
210207
@plansor rvec[-1 -2; -3] := rightenv(lenvs, 0, left_gs)[-1 -2; 1] *
211208
conj(left_gs.C[0][-3; 1])
212209
@plansor lvec[-1 -2; -3] := leftenv(lenvs, 1, left_gs)[-1 -2; 1] *

0 commit comments

Comments
 (0)