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
2017end
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)
2423end
25- function rightenv (envs:: QuasiparticleEnvironments , site:: Int , state)
24+ function rightenv (envs:: InfiniteQPEnvironments , site:: Int , state)
2625 return rightenv (envs. rightenvs, site, state)
2726end
2827
@@ -39,20 +38,26 @@ function environments(exci::Union{InfiniteQP,MultilineQP}, H, lenvs;
3938 return environments (exci, H, lenvs, renvs; kwargs... )
4039end
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+
4249function 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)
143148end
144149
145150function 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)
172177end
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)
401267end
0 commit comments