Skip to content

Commit c433eb9

Browse files
authored
Increase test coverage for CTMRG contractions (#358)
* Try to trick coverage into covering * Start testing more CTMRG contractions * Test, fix, repeat * Try to avoid LAPACK error * Don't add unused methods when trying to increase coverage * Remove accidental `return`s which were skipping some tests * Remove unused `rrule`s for now * Implement sparse environment application as proper multiplication, `env * x`
1 parent 3c4185a commit c433eb9

11 files changed

Lines changed: 877 additions & 278 deletions

File tree

src/algorithms/contractions/ctmrg/enlarge_corner.jl

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function enlarge_northwest_corner(
3636
E_west::CTMRG_PEPS_EdgeTensor, C_northwest::CTMRGCornerTensor,
3737
E_north::CTMRG_PEPS_EdgeTensor, A::PEPSSandwich,
3838
)
39-
return @tensor begin
39+
@tensor begin
4040
EC[χS DWt DWb; χ2] := E_west[χS DWt DWb; χ1] * C_northwest[χ1; χ2]
4141
# already putting χE in front here to make next permute cheaper
4242
ECE[χS χE DWb DNb; DWt DNt] := EC[χS DWt DWb; χ2] * E_north[χ2 DNt DNb; χE]
@@ -45,16 +45,18 @@ function enlarge_northwest_corner(
4545
corner[χS DSt DSb; χE DEt DEb] :=
4646
ECEket[χS χE DEt DSt; DWb DNb d] * conj(bra(A)[d; DNb DEb DSb DWb])
4747
end
48+
return corner
4849
end
4950
function enlarge_northwest_corner(
5051
E_west::CTMRG_PF_EdgeTensor, C_northwest::CTMRGCornerTensor,
5152
E_north::CTMRG_PF_EdgeTensor, A::PFTensor,
5253
)
53-
return @tensor begin
54+
@tensor begin
5455
EC[χ_S DW; χ2] := E_west[χ_S DW; χ1] * C_northwest[χ1; χ2]
5556
ECE[χ_S χ_E; DW DN] := EC[χ_S DW; χ2] * E_north[χ2 DN; χ_E]
5657
corner[χ_S D_S; χ_E D_E] := ECE[χ_S χ_E; DW DN] * A[DW D_S; DN D_E]
5758
end
59+
return corner
5860
end
5961

6062
@generated function enlarge_northwest_corner(
@@ -103,7 +105,7 @@ function enlarge_northeast_corner(
103105
E_north::CTMRG_PEPS_EdgeTensor, C_northeast::CTMRGCornerTensor,
104106
E_east::CTMRG_PEPS_EdgeTensor, A::PEPSSandwich,
105107
)
106-
return @tensor begin
108+
@tensor begin
107109
EC[χW DNt DNb; χ2] := E_north[χW DNt DNb; χ1] * C_northeast[χ1; χ2]
108110
# already putting χE in front here to make next permute cheaper
109111
ECE[χW χS DNb DEb; DNt DEt] := EC[χW DNt DNb; χ2] * E_east[χ2 DEt DEb; χS]
@@ -112,16 +114,18 @@ function enlarge_northeast_corner(
112114
corner[χW DWt DWb; χS DSt DSb] :=
113115
ECEket[χW χS DSt DWt; DNb DEb d] * conj(bra(A)[d; DNb DEb DSb DWb])
114116
end
117+
return corner
115118
end
116119
function enlarge_northeast_corner(
117120
E_north::CTMRG_PF_EdgeTensor, C_northeast::CTMRGCornerTensor,
118121
E_east::CTMRG_PF_EdgeTensor, A::PFTensor,
119122
)
120-
return @tensor begin
123+
@tensor begin
121124
EC[DN χ_W; χ2] := E_north[χ_W DN; χ1] * C_northeast[χ1; χ2]
122125
ECE[DN DE; χ_S χ_W] := EC[DN χ_W; χ2] * E_east[χ2 DE; χ_S]
123126
corner[χ_W D_W; χ_S D_S] := A[D_W D_S; DN DE] * ECE[DN DE; χ_S χ_W]
124127
end
128+
return corner
125129
end
126130

127131
@generated function enlarge_northeast_corner(
@@ -170,7 +174,7 @@ function enlarge_southeast_corner(
170174
E_east::CTMRG_PEPS_EdgeTensor, C_southeast::CTMRGCornerTensor,
171175
E_south::CTMRG_PEPS_EdgeTensor, A::PEPSSandwich,
172176
)
173-
return @tensor begin
177+
@tensor begin
174178
EC[χN DEt DEb; χ2] := E_east[χN DEt DEb; χ1] * C_southeast[χ1; χ2]
175179
# already putting χE in front here to make next permute cheaper
176180
ECE[χN χW DEb DSb; DEt DSt] := EC[χN DEt DEb; χ2] * E_south[χ2 DSt DSb; χW]
@@ -179,16 +183,18 @@ function enlarge_southeast_corner(
179183
corner[χN DNt DNb; χW DWt DWb] :=
180184
ECEket[χN χW DNt DWt; DEb DSb d] * conj(bra(A)[d; DNb DEb DSb DWb])
181185
end
186+
return corner
182187
end
183188
function enlarge_southeast_corner(
184189
E_east::CTMRG_PF_EdgeTensor, C_southeast::CTMRGCornerTensor,
185190
E_south::CTMRG_PF_EdgeTensor, A::PFTensor,
186191
)
187-
return @tensor begin
192+
@tensor begin
188193
EC[χ_N D1; χ2] := E_east[χ_N D1; χ1] * C_southeast[χ1; χ2]
189194
ECE[χ_N χ_W; D1 D2] := EC[χ_N D1; χ2] * E_south[χ2 D2; χ_W]
190195
corner[χ_N D_N; χ_W D_W] := ECE[χ_N χ_W; D1 D2] * A[D_W D2; D_N D1]
191196
end
197+
return corner
192198
end
193199

194200
@generated function enlarge_southeast_corner(
@@ -237,7 +243,7 @@ function enlarge_southwest_corner(
237243
E_south::CTMRG_PEPS_EdgeTensor, C_southwest::CTMRGCornerTensor,
238244
E_west::CTMRG_PEPS_EdgeTensor, A::PEPSSandwich,
239245
)
240-
return @tensor begin
246+
@tensor begin
241247
EC[χE DSt DSb; χ2] := E_south[χE DSt DSb; χ1] * C_southwest[χ1; χ2]
242248
# already putting χE in front here to make next permute cheaper
243249
ECE[χE χN DSb DWb; DSt DWt] := EC[χE DSt DSb; χ2] * E_west[χ2 DWt DWb; χN]
@@ -246,16 +252,18 @@ function enlarge_southwest_corner(
246252
corner[χE DEt DEb; χN DNt DNb] :=
247253
ECEket[χE χN DNt DEt; DSb DWb d] * conj(bra(A)[d; DNb DEb DSb DWb])
248254
end
255+
return corner
249256
end
250257
function enlarge_southwest_corner(
251258
E_south::CTMRG_PF_EdgeTensor, C_southwest::CTMRGCornerTensor,
252259
E_west::CTMRG_PF_EdgeTensor, A::PFTensor,
253260
)
254-
return @tensor begin
261+
@tensor begin
255262
EC[χ_E D1; χ2] := E_south[χ_E D1; χ1] * C_southwest[χ1; χ2]
256263
ECE[χ_E χ_N; D2 D1] := EC[χ_E D1; χ2] * E_west[χ2 D2; χ_N]
257264
corner[χ_E D_E; χ_N D_N] := ECE[χ_E χ_N; D2 D1] * A[D2 D1; D_N D_E]
258265
end
266+
return corner
259267
end
260268

261269
@generated function enlarge_southwest_corner(

src/algorithms/contractions/ctmrg/expr.jl

Lines changed: 153 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,12 @@ function _pepo_edge_expr(edgename, codom_label, dom_label, dir, H::Int, args...)
7373
return tensorexpr(
7474
edgename,
7575
(
76-
envlabel(codom_label, args...),
76+
envlabel(codom_label),
7777
virtuallabel(dir, :top, args...),
7878
ntuple(i -> virtuallabel(dir, :mid, i, args...), H)...,
7979
virtuallabel(dir, :bot, args...),
8080
),
81-
(envlabel(dom_label, args...),),
81+
(envlabel(dom_label),),
8282
)
8383
end
8484

@@ -146,9 +146,9 @@ function _pepo_codomain_projector_expr(
146146
)
147147
return tensorexpr(
148148
projname,
149-
(envlabel(codom_label, args...),),
149+
(envlabel(codom_label),),
150150
(
151-
envlabel(dom_label, args...),
151+
envlabel(dom_label),
152152
virtuallabel(dom_dir, :top, args...),
153153
ntuple(i -> virtuallabel(dom_dir, :mid, i, args...), H)...,
154154
virtuallabel(dom_dir, :bot, args...),
@@ -162,11 +162,158 @@ function _pepo_domain_projector_expr(
162162
return tensorexpr(
163163
projname,
164164
(
165-
envlabel(codom_label, args...),
165+
envlabel(codom_label),
166166
virtuallabel(codom_dir, :top, args...),
167167
ntuple(i -> virtuallabel(codom_dir, :mid, i, args...), H)...,
168168
virtuallabel(codom_dir, :bot, args...),
169169
),
170-
(envlabel(dom_label, args...),),
170+
(envlabel(dom_label),),
171+
)
172+
end
173+
174+
## HalfInfiniteEnv expressions
175+
176+
function _half_infinite_environment_expr_parts(H)
177+
# site 1 (codomain)
178+
C1_e = _corner_expr(:C_1, :WNW, :NNW)
179+
E1_e = _pepo_edge_expr(:E_1, :SW, :WNW, :W, H, 1)
180+
E2_e = _pepo_edge_expr(:E_2, :NNW, :NC, :N, H, 1)
181+
ket1_e, bra1_e, pepo1_es = _pepo_sandwich_expr(:A_1, H, 1; contract_east = :NC)
182+
183+
# site 2 (domain)
184+
C2_e = _corner_expr(:C_2, :NNE, :ENE)
185+
E3_e = _pepo_edge_expr(:E_3, :NC, :NNE, :N, H, 2)
186+
E4_e = _pepo_edge_expr(:E_4, :ENE, :SE, :E, H, 2)
187+
ket2_e, bra2_e, pepo2_es = _pepo_sandwich_expr(:A_2, H, 2; contract_west = :NC)
188+
189+
return C1_e, E1_e, E2_e, ket1_e, bra1_e, pepo1_es, C2_e, E3_e, E4_e, ket2_e, bra2_e, pepo2_es
190+
end
191+
192+
function _half_infinite_environment_expr(H)
193+
194+
C1_e, E1_e, E2_e, ket1_e, bra1_e, pepo1_es, C2_e, E3_e, E4_e, ket2_e, bra2_e, pepo2_es =
195+
_half_infinite_environment_expr_parts(H)
196+
197+
partial_expr = Expr(
198+
:call, :*,
199+
E1_e, C1_e, E2_e,
200+
ket1_e, Expr(:call, :conj, bra1_e), pepo1_es...,
201+
E3_e, C2_e, E4_e,
202+
ket2_e, Expr(:call, :conj, bra2_e), pepo2_es...,
203+
)
204+
205+
return partial_expr
206+
end
207+
208+
function _half_infinite_environment_conj_expr(H)
209+
210+
C1_e, E1_e, E2_e, ket1_e, bra1_e, pepo1_es, C2_e, E3_e, E4_e, ket2_e, bra2_e, pepo2_es =
211+
_half_infinite_environment_expr_parts(H)
212+
213+
partial_expr = Expr(
214+
:call, :*,
215+
Expr(:call, :conj, E1_e), Expr(:call, :conj, C1_e), Expr(:call, :conj, E2_e),
216+
Expr(:call, :conj, ket1_e), bra1_e, map(x -> Expr(:call, :conj, x), pepo1_es)...,
217+
Expr(:call, :conj, E3_e), Expr(:call, :conj, C2_e), Expr(:call, :conj, E4_e),
218+
Expr(:call, :conj, ket2_e), bra2_e, map(x -> Expr(:call, :conj, x), pepo2_es)...,
219+
)
220+
221+
return partial_expr
222+
end
223+
224+
## FullInfiniteEnv expressions
225+
226+
function _full_infinite_environment_expr_parts(H)
227+
# site 1 (codomain)
228+
C1_e = _corner_expr(:C_1, :WNW, :NNW)
229+
E1_e = _pepo_edge_expr(:E_1, :SW, :WNW, :W, H, 1)
230+
E2_e = _pepo_edge_expr(:E_2, :NNW, :NC, :N, H, 1)
231+
ket1_e, bra1_e, pepo1_es = _pepo_sandwich_expr(:A_1, H, 1; contract_east = :NC)
232+
233+
# site 2
234+
C2_e = _corner_expr(:C_2, :NNE, :ENE)
235+
E3_e = _pepo_edge_expr(:E_3, :NC, :NNE, :N, H, 2)
236+
E4_e = _pepo_edge_expr(:E_4, :ENE, :EC, :E, H, 2)
237+
ket2_e, bra2_e, pepo2_es = _pepo_sandwich_expr(
238+
:A_2, H, 2; contract_west = :NC, contract_south = :EC
239+
)
240+
241+
# site 3
242+
C3_e = _corner_expr(:C_3, :ESE, :SSE)
243+
E5_e = _pepo_edge_expr(:E_5, :EC, :ESE, :E, H, 3)
244+
E6_e = _pepo_edge_expr(:E_6, :SSE, :SC, :S, H, 3)
245+
ket3_e, bra3_e, pepo3_es = _pepo_sandwich_expr(
246+
:A_3, H, 3; contract_north = :EC, contract_west = :SC
247+
)
248+
249+
# site 4 (domain)
250+
C4_e = _corner_expr(:C_4, :SSW, :WSW)
251+
E7_e = _pepo_edge_expr(:E_7, :SC, :SSW, :S, H, 4)
252+
E8_e = _pepo_edge_expr(:E_8, :WSW, :NW, :W, H, 4)
253+
ket4_e, bra4_e, pepo4_es = _pepo_sandwich_expr(:A_4, H, 4; contract_east = :SC)
254+
255+
return (
256+
E1_e, C1_e, E2_e,
257+
ket1_e, bra1_e, pepo1_es,
258+
E3_e, C2_e, E4_e,
259+
ket2_e, bra2_e, pepo2_es,
260+
E5_e, C3_e, E6_e,
261+
ket3_e, bra3_e, pepo3_es,
262+
E7_e, C4_e, E8_e,
263+
ket4_e, bra4_e, pepo4_es,
171264
)
172265
end
266+
267+
function _full_infinite_environment_expr(H)
268+
(
269+
E1_e, C1_e, E2_e,
270+
ket1_e, bra1_e, pepo1_es,
271+
E3_e, C2_e, E4_e,
272+
ket2_e, bra2_e, pepo2_es,
273+
E5_e, C3_e, E6_e,
274+
ket3_e, bra3_e, pepo3_es,
275+
E7_e, C4_e, E8_e,
276+
ket4_e, bra4_e, pepo4_es,
277+
) = _full_infinite_environment_expr_parts(H)
278+
279+
partial_expr = Expr(
280+
:call, :*,
281+
E1_e, C1_e, E2_e,
282+
ket1_e, Expr(:call, :conj, bra1_e), pepo1_es...,
283+
E3_e, C2_e, E4_e,
284+
ket2_e, Expr(:call, :conj, bra2_e), pepo2_es...,
285+
E5_e, C3_e, E6_e,
286+
ket3_e, Expr(:call, :conj, bra3_e), pepo3_es...,
287+
E7_e, C4_e, E8_e,
288+
ket4_e, Expr(:call, :conj, bra4_e), pepo4_es...,
289+
)
290+
291+
return partial_expr
292+
end
293+
294+
function _full_infinite_environment_conj_expr(H)
295+
(
296+
E1_e, C1_e, E2_e,
297+
ket1_e, bra1_e, pepo1_es,
298+
E3_e, C2_e, E4_e,
299+
ket2_e, bra2_e, pepo2_es,
300+
E5_e, C3_e, E6_e,
301+
ket3_e, bra3_e, pepo3_es,
302+
E7_e, C4_e, E8_e,
303+
ket4_e, bra4_e, pepo4_es,
304+
) = _full_infinite_environment_expr_parts(H)
305+
306+
partial_expr = Expr(
307+
:call, :*,
308+
Expr(:call, :conj, E1_e), Expr(:call, :conj, C1_e), Expr(:call, :conj, E2_e),
309+
Expr(:call, :conj, ket1_e), bra1_e, map(x -> Expr(:call, :conj, x), pepo1_es)...,
310+
Expr(:call, :conj, E3_e), Expr(:call, :conj, C2_e), Expr(:call, :conj, E4_e),
311+
Expr(:call, :conj, ket2_e), bra2_e, map(x -> Expr(:call, :conj, x), pepo2_es)...,
312+
Expr(:call, :conj, E5_e), Expr(:call, :conj, C3_e), Expr(:call, :conj, E6_e),
313+
Expr(:call, :conj, ket3_e), bra3_e, map(x -> Expr(:call, :conj, x), pepo3_es)...,
314+
Expr(:call, :conj, E7_e), Expr(:call, :conj, C4_e), Expr(:call, :conj, E8_e),
315+
Expr(:call, :conj, ket4_e), bra4_e, map(x -> Expr(:call, :conj, x), pepo4_es)...,
316+
)
317+
318+
return partial_expr
319+
end

0 commit comments

Comments
 (0)