Skip to content

Commit 0a0c3f9

Browse files
committed
Refactor InfiniteQPEnvironments
1 parent 3bddc13 commit 0a0c3f9

File tree

3 files changed

+38
-201
lines changed

3 files changed

+38
-201
lines changed

src/algorithms/excitation/quasiparticleexcitation.jl

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ end
168168
# Statmech Excitations #
169169
################################################################################
170170

171-
function excitations(H::MultilineMPO, alg::QuasiparticleAnsatz, ϕ₀::Multiline{<:InfiniteQP},
171+
function excitations(H::MultilineMPO, alg::QuasiparticleAnsatz, ϕ₀::MultilineQP,
172172
lenvs, renvs; num=1, kwargs...)
173173
qp_envs(ϕ) = environments(ϕ, H, lenvs, renvs; kwargs...)
174174
function H_eff(ϕ′)
@@ -214,13 +214,15 @@ function excitations(H::DenseMPO, alg::QuasiparticleAnsatz, momentum::Real,
214214
renvs=lmps === rmps ? lenvs : environments(rmps, H);
215215
sector=one(sectortype(lmps)), num=1, kwargs...)
216216
multiline_lmps = convert(MultilineMPS, lmps)
217+
lenvs′ = Multiline([lenvs])
217218
if lmps === rmps
218-
excitations(convert(MultilineMPO, H), alg, momentum, multiline_lmps, lenvs,
219+
excitations(convert(MultilineMPO, H), alg, momentum, multiline_lmps, lenvs,
219220
multiline_lmps,
220-
lenvs; sector, num, kwargs...)
221+
lenvs; sector, num, kwargs...)
221222
else
222-
excitations(convert(MultilineMPO, H), alg, momentum, multiline_lmps, lenvs,
223-
convert(MultilineMPS, rmps), renvs; sector, num, kwargs...)
223+
renvs′ = Multiline([renvs])
224+
excitations(convert(MultilineMPO, H), alg, momentum, multiline_lmps, lenvs′,
225+
convert(MultilineMPS, rmps), renvs′; sector, num, kwargs...)
224226
end
225227
end
226228

@@ -254,41 +256,10 @@ function effective_excitation_hamiltonian(H::Union{InfiniteMPOHamiltonian,
254256
return ϕ′
255257
end
256258

257-
function effective_excitation_hamiltonian(H::MultilineMPO, ϕ::Multiline{<:InfiniteQP},
259+
function effective_excitation_hamiltonian(H::MultilineMPO, ϕ::MultilineQP,
258260
envs=environments(ϕ, H))
259-
ϕ′ = Multiline(similar.(ϕ.data))
260-
left_gs = ϕ.left_gs
261-
right_gs = ϕ.right_gs
262-
263-
for row in 1:size(H, 1)
264-
Bs = [ϕ[row][i] for i in 1:size(H, 2)]
265-
for col in 1:size(H, 2)
266-
en = @plansor conj(left_gs.AC[row, col][2 6; 4]) *
267-
leftenv(envs.lenvs, row, col, left_gs)[2 5; 3] *
268-
left_gs.AC[row + 1, col][3 7; 1] *
269-
H[row, col][5 6; 7 8] *
270-
rightenv(envs.lenvs, row, col, left_gs)[1 8; 4]
271-
272-
@plansor T[-1 -2; -3 -4] := leftenv(envs.lenvs, row, col, left_gs)[-1 5; 4] *
273-
Bs[col][4 2; -3 1] *
274-
H[row, col][5 -2; 2 3] *
275-
rightenv(envs.renvs, row, col, right_gs)[1 3; -4]
276-
277-
@plansor T[-1 -2; -3 -4] += envs.lBs[row, col - 1][-1 4; -3 5] *
278-
right_gs.AR[row, col][5 2; 1] *
279-
H[row, col][4 -2; 2 3] *
280-
rightenv(envs.renvs, row, col, right_gs)[1 3; -4]
281-
282-
@plansor T[-1 -2; -3 -4] += leftenv(envs.lenvs, row, col, left_gs)[-1 2; 1] *
283-
left_gs.AL[row, col][1 3; 4] *
284-
H[row, col][2 -2; 3 5] *
285-
envs.rBs[row, col + 1][4 5; -3 -4]
286-
287-
ϕ′[row + 1][col] = T / en
288-
end
289-
end
290-
291-
return ϕ′
261+
return Multiline(map(effective_excitation_hamiltonian,
262+
parent(H), parent(ϕ), parent(envs)))
292263
end
293264

294265
function effective_excitation_hamiltonian(H::InfiniteMPO, ϕ::InfiniteQP,

src/environments/qp_envs.jl

Lines changed: 27 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
1-
#=
2-
nothing fancy - only used internally (and therefore cryptic) - stores some partially contracted things
3-
seperates out this bit of logic from effective_excitation_hamiltonian (now more readable)
4-
can also - potentially - partially reuse this in other algorithms
5-
=#
6-
struct QPEnv{A,B} <: AbstractMPSEnvironments
7-
lBs::PeriodicArray{A,2}
8-
rBs::PeriodicArray{A,2}
9-
10-
lenvs::B
11-
renvs::B
12-
end
13-
14-
struct QuasiparticleEnvironments{A,B} <: AbstractMPSEnvironments
1+
"""
2+
InfiniteQPEnvironments <: AbstractMPSEnvironments
3+
4+
Environments for an infinite QP-MPO-QP combination. These solve the corresponding fixedpoint equations:
5+
```math
6+
GLs[i] * T_BL[i] + GBLs[i] * T_RL[i] = GBLs[i + 1]
7+
T_BR[i] * GRs[i] + T_LR[i] * GBRs[i] = GBRs[i - 1]
8+
```
9+
where `T_BL`, `T_BR`, `T_RL` and `T_LR` are the (regularized) transfer matrix operators on a given site for `B-O-AL`, `B-O-AR`, `AR-O-AL` and `AL-O-AR` respectively.
10+
"""
11+
struct InfiniteQPEnvironments{A,B} <: AbstractMPSEnvironments
1512
leftBenvs::PeriodicVector{A}
1613
rightBenvs::PeriodicVector{A}
1714

1815
leftenvs::B
1916
rightenvs::B
2017
end
2118

22-
function leftenv(envs::QuasiparticleEnvironments, site::Int, state)
19+
Base.length(envs::InfiniteQPEnvironments) = length(envs.leftenvs)
20+
21+
function leftenv(envs::InfiniteQPEnvironments, site::Int, state)
2322
return leftenv(envs.leftenvs, site, state)
2423
end
25-
function rightenv(envs::QuasiparticleEnvironments, site::Int, state)
24+
function rightenv(envs::InfiniteQPEnvironments, site::Int, state)
2625
return rightenv(envs.rightenvs, site, state)
2726
end
2827

@@ -39,20 +38,26 @@ function environments(exci::Union{InfiniteQP,MultilineQP}, H, lenvs;
3938
return environments(exci, H, lenvs, renvs; kwargs...)
4039
end
4140

41+
function environments(qp::MultilineQP, operator::MultilineMPO, lenvs, renvs; kwargs...)
42+
(rows = size(qp, 1)) == size(operator, 1) || throw(ArgumentError("Incompatible sizes"))
43+
envs = map(1:rows) do row
44+
return environments(qp[row], operator[row], lenvs[row], renvs[row]; kwargs...)
45+
end
46+
return Multiline(PeriodicVector(envs))
47+
end
48+
4249
function environments(exci::InfiniteQP, H::InfiniteMPOHamiltonian,
4350
lenvs, renvs;
4451
kwargs...)
4552
ids = findall(Base.Fix1(isidentitylevel, H), 2:(size(H[1], 1) - 1))
4653
solver = environment_alg(exci, H, exci; kwargs...)
47-
# ids = collect(Iterators.filter(x -> isidentitylevel(H, x), 2:(H.odim - 1)))
4854

4955
AL = exci.left_gs.AL
5056
AR = exci.right_gs.AR
5157

5258
lBs = PeriodicVector([allocate_GBL(exci, H, exci, i) for i in 1:length(exci)])
5359
rBs = PeriodicVector([allocate_GBR(exci, H, exci, i) for i in 1:length(exci)])
5460

55-
# lBs, rBs = gen_exci_lw_rw(exci.left_gs, H, exci.right_gs, space(exci[1], 3))
5661
zerovector!(lBs[1])
5762
for pos in 1:length(exci)
5863
lBs[pos + 1] = lBs[pos] * TransferMatrix(AR[pos], H[pos], AL[pos]) /
@@ -139,7 +144,7 @@ function environments(exci::InfiniteQP, H::InfiniteMPOHamiltonian,
139144
rBs[i - 1] += rB_cur
140145
end
141146

142-
return QuasiparticleEnvironments(lBs, rBs, lenvs, renvs)
147+
return InfiniteQPEnvironments(lBs, rBs, lenvs, renvs)
143148
end
144149

145150
function environments(exci::FiniteQP,
@@ -168,149 +173,10 @@ function environments(exci::FiniteQP,
168173
rightenv(renvs, pos, exci.right_gs)
169174
end
170175

171-
return QuasiparticleEnvironments(lBs, rBs, lenvs, renvs)
176+
return InfiniteQPEnvironments(lBs, rBs, lenvs, renvs)
172177
end
173178

174-
function environments(exci::Multiline{<:InfiniteQP},
175-
ham::MultilineMPO,
176-
lenvs,
177-
renvs;
178-
kwargs...)
179-
exci.trivial ||
180-
@warn "there is a phase ambiguity in topologically nontrivial statmech excitations"
181-
solver = environment_alg(exci, ham, exci; kwargs...)
182-
183-
left_gs = exci.left_gs
184-
right_gs = exci.right_gs
185-
186-
exci_space = space(exci[1][1], 3)
187-
188-
(numrows, numcols) = size(left_gs)
189-
190-
st = site_type(typeof(left_gs))
191-
B_type = tensormaptype(spacetype(st), 2, 2, storagetype(st))
192-
193-
lBs = PeriodicArray{B_type,2}(undef, size(left_gs, 1), size(left_gs, 2))
194-
rBs = PeriodicArray{B_type,2}(undef, size(left_gs, 1), size(left_gs, 2))
195-
196-
for row in 1:numrows
197-
c_lenvs = broadcast(col -> leftenv(lenvs, col, left_gs)[row], 1:numcols)
198-
c_renvs = broadcast(col -> rightenv(renvs, col, right_gs)[row], 1:numcols)
199-
200-
hamrow = ham[row, :]
201-
202-
left_above = left_gs[row]
203-
left_below = left_gs[row + 1]
204-
right_above = right_gs[row]
205-
right_below = right_gs[row + 1]
206-
207-
left_renorms = fill(zero(scalartype(B_type)), numcols)
208-
right_renorms = fill(zero(scalartype(B_type)), numcols)
209-
210-
for col in 1:numcols
211-
lv = leftenv(lenvs, col, left_gs)[row]
212-
rv = rightenv(lenvs, col, left_gs)[row]
213-
left_renorms[col] = @plansor lv[1 2; 3] *
214-
left_above.AC[col][3 4; 5] *
215-
hamrow[col][2 6; 4 7] *
216-
rv[5 7; 8] *
217-
conj(left_below.AC[col][1 6; 8])
218-
219-
lv = leftenv(renvs, col, right_gs)[row]
220-
rv = rightenv(renvs, col, right_gs)[row]
221-
right_renorms[col] = @plansor lv[1 2; 3] *
222-
right_above.AC[col][3 4; 5] *
223-
hamrow[col][2 6; 4 7] *
224-
rv[5 7; 8] *
225-
conj(right_below.AC[col][1 6; 8])
226-
end
227-
228-
left_renorms = left_renorms .^ -1
229-
right_renorms = right_renorms .^ -1
230-
231-
lB_cur = fill_data!(similar(left_below.AL[1],
232-
left_virtualspace(left_below, 0) *
233-
_firstspace(hamrow[1])',
234-
exci_space' * right_virtualspace(right_above, 0)),
235-
zero)
236-
rB_cur = fill_data!(similar(left_below.AL[1],
237-
left_virtualspace(left_below, 0) *
238-
_firstspace(hamrow[1]),
239-
exci_space' * right_virtualspace(right_above, 0)),
240-
zero)
241-
for col in 1:numcols
242-
lB_cur = lB_cur *
243-
TransferMatrix(right_above.AR[col], hamrow[col], left_below.AL[col])
244-
lB_cur += c_lenvs[col] *
245-
TransferMatrix(exci[row][col], hamrow[col], left_below.AL[col])
246-
lB_cur *= left_renorms[col] * exp(-1im * exci.momentum)
247-
lBs[row, col] = lB_cur
248-
249-
col = numcols - col + 1
250-
251-
rB_cur = TransferMatrix(left_above.AL[col], hamrow[col], right_below.AR[col]) *
252-
rB_cur
253-
rB_cur += TransferMatrix(exci[row][col], hamrow[col], right_below.AR[col]) *
254-
c_renvs[col]
255-
rB_cur *= exp(1im * exci.momentum) * right_renorms[col]
256-
rBs[row, col] = rB_cur
257-
end
258-
259-
tm_RL = TransferMatrix(right_above.AR, hamrow, left_below.AL)
260-
tm_LR = TransferMatrix(left_above.AL, hamrow, right_below.AR)
261-
262-
if exci.trivial
263-
@plansor rvec[-1 -2; -3] := rightenv(lenvs, 0, left_gs)[row][-1 -2; 1] *
264-
conj(left_below.C[0][-3; 1])
265-
@plansor lvec[-1 -2; -3] := leftenv(lenvs, 1, left_gs)[row][-1 -2; 1] *
266-
left_above.C[0][1; -3]
267-
268-
tm_RL = regularize(tm_RL, lvec, rvec)
269-
270-
@plansor rvec[-1 -2; -3] := rightenv(renvs, 0, right_gs)[row][1 -2; -3] *
271-
right_above.C[0][-1; 1]
272-
@plansor lvec[-1 -2; -3] := conj(right_below.C[0][-3; 1]) *
273-
leftenv(renvs, 1, right_gs)[row][-1 -2; 1]
274-
275-
tm_LR = regularize(tm_LR, lvec, rvec)
276-
end
277-
278-
lBs[row, end], convhist = linsolve(flip(tm_RL), lB_cur, lB_cur, solver, 1,
279-
-exp(-1im * numcols * exci.momentum) *
280-
prod(left_renorms))
281-
convhist.converged == 0 &&
282-
@warn "GBL[$row] failed to converge: normres = $(convhist.normres)"
283-
284-
rBs[row, 1], convhist = linsolve(tm_LR, rB_cur, rB_cur, GMRES(), 1,
285-
-exp(1im * numcols * exci.momentum) *
286-
prod(right_renorms))
287-
convhist.converged == 0 &&
288-
@warn "GBR[$row] failed to converge: normres = $(convhist.normres)"
289-
290-
left_cur = lBs[row, end]
291-
right_cur = rBs[row, 1]
292-
for col in 1:(numcols - 1)
293-
left_cur = left_renorms[col] * left_cur *
294-
TransferMatrix(right_above.AR[col], hamrow[col],
295-
left_below.AL[col]) * exp(-1im * exci.momentum)
296-
lBs[row, col] += left_cur
297-
298-
col = numcols - col + 1
299-
right_cur = TransferMatrix(left_above.AL[col], hamrow[col],
300-
right_below.AR[col]) * right_cur *
301-
exp(1im * exci.momentum) * right_renorms[col]
302-
rBs[row, col] += right_cur
303-
end
304-
end
305-
306-
return QPEnv(lBs, rBs, lenvs, renvs)
307-
end
308-
309-
function environments(exci::InfiniteQP,
310-
O::InfiniteMPO,
311-
lenvs,
312-
renvs;
313-
kwargs...)
179+
function environments(exci::InfiniteQP, O::InfiniteMPO, lenvs, renvs; kwargs...)
314180
exci.trivial ||
315181
@warn "there is a phase ambiguity in topologically nontrivial statmech excitations"
316182
solver = environment_alg(exci, O, exci; kwargs...)
@@ -397,5 +263,5 @@ function environments(exci::InfiniteQP,
397263
GBR[col] += right_cur
398264
end
399265

400-
return QuasiparticleEnvironments(GBL, GBR, lenvs, renvs)
266+
return InfiniteQPEnvironments(GBL, GBR, lenvs, renvs)
401267
end

src/states/quasiparticle_state.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ function Base.convert(::Type{<:FiniteMPS}, v::QP{S}) where {S<:FiniteMPS}
351351
return FiniteMPS(Ls + Rs + Bs; normalize=false)
352352
end
353353

354-
function Base.getproperty(exci::Multiline{<:InfiniteQP}, s::Symbol)
354+
function Base.getproperty(exci::MultilineQP, s::Symbol)
355355
if s == :momentum
356356
return first(exci.data).momentum
357357
elseif s == :left_gs

0 commit comments

Comments
 (0)