Skip to content

Commit 8d4d19d

Browse files
pbrehmerleburgel
andauthored
Fix CTMRG contraction inconsistencies (#327)
* Fix fullinf_env * Fix gaugefix * Fix halfinf_env * Fix projector * Fix renormalizations * Fix renormalization part II * Add in and out labels * Rename bottom and top corner contractions to southwest and northwest * Actually replace bottom/top corner with southwest/northwest * Fix gaugefix test Co-authored-by: Lander Burgelman <39218680+leburgel@users.noreply.github.com> * Apply rest of suggestions --------- Co-authored-by: Lander Burgelman <39218680+leburgel@users.noreply.github.com>
1 parent 18703b2 commit 8d4d19d

8 files changed

Lines changed: 254 additions & 240 deletions

File tree

src/algorithms/contractions/ctmrg/enlarge_corner.jl

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ Contract the enlarged northwest corner of the CTMRG environment, either by speci
2525
coordinates, environments and network, or by directly providing the tensors.
2626
2727
```
28-
C_northwest -- E_north --
28+
C_northwest -- E_north --in
2929
| |
3030
E_west -- A --
3131
| |
32+
out
3233
```
3334
"""
3435
function enlarge_northwest_corner(
@@ -37,13 +38,10 @@ function enlarge_northwest_corner(
3738
)
3839
return @tensor begin
3940
EC[χS DWt DWb; χ2] := E_west[χS DWt DWb; χ1] * C_northwest[χ1; χ2]
40-
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]
43-
4443
ECEket[χS χE DEt DSt; DWb DNb d] :=
4544
ECE[χS χE DWb DNb; DWt DNt] * ket(A)[d; DNt DEt DSt DWt]
46-
4745
corner[χS DSt DSb; χE DEt DEb] :=
4846
ECEket[χS χE DEt DSt; DWb DNb d] * conj(bra(A)[d; DNb DEb DSb DWb])
4947
end
@@ -94,10 +92,11 @@ Contract the enlarged northeast corner of the CTMRG environment, either by speci
9492
coordinates, environments and network, or by directly providing the tensors.
9593
9694
```
97-
-- E_north -- C_northeast
98-
| |
99-
-- A -- E_east
100-
| |
95+
out-- E_north -- C_northeast
96+
| |
97+
-- A -- E_east
98+
| |
99+
in
101100
```
102101
"""
103102
function enlarge_northeast_corner(
@@ -106,13 +105,10 @@ function enlarge_northeast_corner(
106105
)
107106
return @tensor begin
108107
EC[χW DNt DNb; χ2] := E_north[χW DNt DNb; χ1] * C_northeast[χ1; χ2]
109-
110108
# already putting χE in front here to make next permute cheaper
111109
ECE[χW χS DNb DEb; DNt DEt] := EC[χW DNt DNb; χ2] * E_east[χ2 DEt DEb; χS]
112-
113110
ECEket[χW χS DSt DWt; DNb DEb d] :=
114111
ECE[χW χS DNb DEb; DNt DEt] * ket(A)[d; DNt DEt DSt DWt]
115-
116112
corner[χW DWt DWb; χS DSt DSb] :=
117113
ECEket[χW χS DSt DWt; DNb DEb d] * conj(bra(A)[d; DNb DEb DSb DWb])
118114
end
@@ -163,10 +159,11 @@ Contract the enlarged southeast corner of the CTMRG environment, either by speci
163159
coordinates, environments and network, or by directly providing the tensors.
164160
165161
```
166-
| |
167-
-- A -- E_east
168-
| |
169-
-- E_south -- C_southeast
162+
out
163+
| |
164+
-- A -- E_east
165+
| |
166+
in-- E_south -- C_southeast
170167
```
171168
"""
172169
function enlarge_southeast_corner(
@@ -175,13 +172,10 @@ function enlarge_southeast_corner(
175172
)
176173
return @tensor begin
177174
EC[χN DEt DEb; χ2] := E_east[χN DEt DEb; χ1] * C_southeast[χ1; χ2]
178-
179175
# already putting χE in front here to make next permute cheaper
180176
ECE[χN χW DEb DSb; DEt DSt] := EC[χN DEt DEb; χ2] * E_south[χ2 DSt DSb; χW]
181-
182177
ECEket[χN χW DNt DWt; DEb DSb d] :=
183178
ECE[χN χW DEb DSb; DEt DSt] * ket(A)[d; DNt DEt DSt DWt]
184-
185179
corner[χN DNt DNb; χW DWt DWb] :=
186180
ECEket[χN χW DNt DWt; DEb DSb d] * conj(bra(A)[d; DNb DEb DSb DWb])
187181
end
@@ -232,10 +226,11 @@ Contract the enlarged southwest corner of the CTMRG environment, either by speci
232226
coordinates, environments and network, or by directly providing the tensors.
233227
234228
```
229+
in
235230
| |
236231
E_west -- A --
237232
| |
238-
C_southwest -- E_south --
233+
C_southwest -- E_south --out
239234
```
240235
"""
241236
function enlarge_southwest_corner(
@@ -244,13 +239,10 @@ function enlarge_southwest_corner(
244239
)
245240
return @tensor begin
246241
EC[χE DSt DSb; χ2] := E_south[χE DSt DSb; χ1] * C_southwest[χ1; χ2]
247-
248242
# already putting χE in front here to make next permute cheaper
249243
ECE[χE χN DSb DWb; DSt DWt] := EC[χE DSt DSb; χ2] * E_west[χ2 DWt DWb; χN]
250-
251244
ECEket[χE χN DNt DEt; DSb DWb d] :=
252245
ECE[χE χN DSb DWb; DSt DWt] * ket(A)[d; DNt DEt DSt DWt]
253-
254246
corner[χE DEt DEb; χN DNt DNb] :=
255247
ECEket[χE χN DNt DEt; DSb DWb d] * conj(bra(A)[d; DNb DEb DSb DWb])
256248
end

src/algorithms/contractions/ctmrg/fullinf_env.jl

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ Contract four quadrants (enlarged corners) to form a full-infinite environment.
1212
|quadrant1| |quadrant2|
1313
|~~~~~~~~~| -- |~~~~~~~~~|
1414
| | | |
15+
out | |
1516
| |
17+
in | |
1618
| | | |
1719
|~~~~~~~~~| -- |~~~~~~~~~|
1820
|quadrant4| |quadrant3|
@@ -26,7 +28,9 @@ In the same manner two halfs can be used to contract the full-infinite environme
2628
| half1 |
2729
|~~~~~~~~~~~~~~~~~~~~~~~~|
2830
| | | |
31+
out | |
2932
| |
33+
in | |
3034
| | | |
3135
|~~~~~~~~~~~~~~~~~~~~~~~~|
3236
| half2 |
@@ -40,7 +44,9 @@ The environment can also be contracted directly from all its constituent tensors
4044
| | | |
4145
E_1 -- A_1 -- A_2 -- E_4
4246
| | | |
47+
out | |
4348
| |
49+
in | | |
4450
| | | |
4551
E_8 -- A_4 -- A_3 -- E_5
4652
| | | |
@@ -54,6 +60,7 @@ Alternatively, contract the environment with a vector `x` acting on it
5460
| | | |
5561
E_1 -- A_1 -- A_2 -- E_4
5662
| | | |
63+
out | |
5764
| |
5865
[~~~~x~~~] | |
5966
| | | |
@@ -112,25 +119,25 @@ function full_infinite_environment(
112119
E_1, E_2, E_3, E_4, E_5, E_6, E_7, E_8,
113120
A_1::P, A_2::P, A_3::P, A_4::P,
114121
) where {P <: PEPSSandwich}
115-
return @autoopt @tensor env[χ_in D_inabove D_inbelow; χ_out D_outabove D_outbelow] :=
116-
E_1[χ_in D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
117-
ket(A_1)[d1; D3 D11 D_inabove D1] * conj(bra(A_1)[d1; D4 D12 D_inbelow D2]) *
122+
return @autoopt @tensor env[χ_out D_outabove D_outbelow; χ_in D_inabove D_inbelow] :=
123+
E_1[χ_out D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
124+
ket(A_1)[d1; D3 D11 D_outabove D1] * conj(bra(A_1)[d1; D4 D12 D_outbelow D2]) *
118125
ket(A_2)[d2; D5 D7 D9 D11] * conj(bra(A_2)[d2; D6 D8 D10 D12]) *
119126
E_3[χ3 D5 D6; χ4] * C_2[χ4; χ5] * E_4[χ5 D7 D8; χ6] *
120127
E_5[χ6 D13 D14; χ7] * C_3[χ7; χ8] * E_6[χ8 D15 D16; χ9] *
121128
ket(A_3)[d3; D9 D13 D15 D17] * conj(bra(A_3)[d3; D10 D14 D16 D18]) *
122-
ket(A_4)[d4; D_outabove D17 D19 D21] * conj(bra(A_4)[d4; D_outbelow D18 D20 D22]) *
123-
E_7[χ9 D19 D20; χ10] * C_4[χ10; χ11] * E_8[χ11 D21 D22; χ_out]
129+
ket(A_4)[d4; D_inabove D17 D19 D21] * conj(bra(A_4)[d4; D_inbelow D18 D20 D22]) *
130+
E_7[χ9 D19 D20; χ10] * C_4[χ10; χ11] * E_8[χ11 D21 D22; χ_in]
124131
end
125132
function full_infinite_environment(
126133
C_1, C_2, C_3, C_4,
127134
E_1, E_2, E_3, E_4, E_5, E_6, E_7, E_8,
128135
x::AbstractTensor{T, S, 3},
129136
A_1::P, A_2::P, A_3::P, A_4::P,
130137
) where {T, S, P <: PEPSSandwich}
131-
return @autoopt @tensor env_x[χ_in D_inabove D_inbelow] :=
132-
E_1[χ_in D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
133-
ket(A_1)[d1; D3 D11 D_inabove D1] * conj(bra(A_1)[d1; D4 D12 D_inbelow D2]) *
138+
return @autoopt @tensor env_x[χ_out D_outabove D_outbelow] :=
139+
E_1[χ_out D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
140+
ket(A_1)[d1; D3 D11 D_outabove D1] * conj(bra(A_1)[d1; D4 D12 D_outbelow D2]) *
134141
ket(A_2)[d2; D5 D7 D9 D11] * conj(bra(A_2)[d2; D6 D8 D10 D12]) *
135142
E_3[χ3 D5 D6; χ4] * C_2[χ4; χ5] * E_4[χ5 D7 D8; χ6] *
136143
E_5[χ6 D13 D14; χ7] * C_3[χ7; χ8] * E_6[χ8 D15 D16; χ9] *
@@ -161,25 +168,25 @@ function full_infinite_environment(
161168
E_1, E_2, E_3, E_4, E_5, E_6, E_7, E_8,
162169
A_1::P, A_2::P, A_3::P, A_4::P,
163170
) where {P <: PFTensor}
164-
return @autoopt @tensor env[χ_in D_in; χ_out D_out] :=
165-
E_1[χ_in D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
166-
A_1[D1 D_in; D3 D11] *
171+
return @autoopt @tensor env[χ_out D_out; χ_in D_in] :=
172+
E_1[χ_out D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
173+
A_1[D1 D_out; D3 D11] *
167174
A_2[D11 D9; D5 D7] *
168175
E_3[χ3 D5; χ4] * C_2[χ4; χ5] * E_4[χ5 D7; χ6] *
169176
E_5[χ6 D13; χ7] * C_3[χ7; χ8] * E_6[χ8 D15; χ9] *
170177
A_3[D17 D15; D9 D13] *
171-
A_4[D21 D19; D_out D17] *
172-
E_7[χ9 D19; χ10] * C_4[χ10; χ11] * E_8[χ11 D21; χ_out]
178+
A_4[D21 D19; D_in D17] *
179+
E_7[χ9 D19; χ10] * C_4[χ10; χ11] * E_8[χ11 D21; χ_in]
173180
end
174181
function full_infinite_environment(
175182
C_1, C_2, C_3, C_4,
176183
E_1, E_2, E_3, E_4, E_5, E_6, E_7, E_8,
177184
x::AbstractTensor{T, S, 2},
178185
A_1::P, A_2::P, A_3::P, A_4::P,
179186
) where {T, S, P <: PFTensor}
180-
return @autoopt @tensor env_x[χ_in D_in] :=
181-
E_1[χ_in D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
182-
A_1[D1 D_in; D3 D11] *
187+
return @autoopt @tensor env_x[χ_out D_out] :=
188+
E_1[χ_out D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
189+
A_1[D1 D_out; D3 D11] *
183190
A_2[D11 D9; D5 D7] *
184191
E_3[χ3 D5; χ4] * C_2[χ4; χ5] * E_4[χ5 D7; χ6] *
185192
E_5[χ6 D13; χ7] * C_3[χ7; χ8] * E_6[χ8 D15; χ9] *

src/algorithms/contractions/ctmrg/gaugefix.jl

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ $(SIGNATURES)
99
Multiply corner tensor with incoming and outgoing gauge signs.
1010
1111
```
12-
corner -- σ_out --
12+
corner -- σ_in --in
1313
|
14-
σ_in
14+
σ_out
1515
|
16+
out
1617
```
1718
"""
1819
function fix_gauge_corner(
19-
corner::CTMRGCornerTensor, σ_in::CTMRGCornerTensor, σ_out::CTMRGCornerTensor
20+
corner::CTMRGCornerTensor, σ_out::CTMRGCornerTensor, σ_in::CTMRGCornerTensor
2021
)
21-
return @autoopt @tensor corner_fix[χ_in; χ_out] :=
22-
σ_in[χ_in; χ1] * corner[χ1; χ2] * conj(σ_out[χ_out; χ2])
22+
return @autoopt @tensor corner_fix[χ_out; χ_in] :=
23+
σ_out[χ_out; χ1] * corner[χ1; χ2] * conj(σ_in[χ_in; χ2])
2324
end
2425

2526
"""
@@ -82,25 +83,26 @@ $(SIGNATURES)
8283
Multiply edge tensor with incoming and outgoing gauge signs.
8384
8485
```
85-
-- σ_in -- edge -- σ_out --
86+
out-- σ_out -- edge -- σ_in --in
87+
|
8688
```
8789
"""
8890
@generated function fix_gauge_edge(
89-
edge::CTMRGEdgeTensor{T, S, N}, σ_in::CTMRGCornerTensor, σ_out::CTMRGCornerTensor
91+
edge::CTMRGEdgeTensor{T, S, N}, σ_out::CTMRGCornerTensor, σ_in::CTMRGCornerTensor
9092
) where {T, S, N}
9193
edge_fix_e = tensorexpr(
9294
:edge_fix,
93-
(envlabel(:in), ntuple(i -> virtuallabel(i), N - 1)...),
94-
(envlabel(:out),),
95+
(envlabel(:out), ntuple(i -> virtuallabel(i), N - 1)...),
96+
(envlabel(:in),),
9597
)
9698
edge_e = tensorexpr(
9799
:edge, (envlabel(1), ntuple(i -> virtuallabel(i), N - 1)...), (envlabel(2),)
98100
)
99-
σ_in_e = tensorexpr(:σ_in, (envlabel(:in),), (envlabel(1),))
100-
σ_out_e = tensorexpr(:σ_out, (envlabel(:out),), (envlabel(2),))
101+
σ_out_e = tensorexpr(:σ_out, (envlabel(:out),), (envlabel(1),))
102+
σ_in_e = tensorexpr(:σ_in, (envlabel(:in),), (envlabel(2),))
101103
return macroexpand(
102104
@__MODULE__,
103-
:(return @autoopt @tensor $edge_fix_e := $σ_in_e * $edge_e * conj($σ_out_e)),
105+
:(return @autoopt @tensor $edge_fix_e := $σ_out_e * $edge_e * conj($σ_in_e)),
104106
)
105107
end
106108

src/algorithms/contractions/ctmrg/halfinf_env.jl

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Contract two quadrants (enlarged corners) to form a half-infinite environment.
1111
|quadrant1| |quadrant2|
1212
|~~~~~~~~~| -- |~~~~~~~~~|
1313
| | | |
14+
out in
1415
```
1516
1617
The environment can also be contracted directly from all its constituent tensors.
@@ -20,6 +21,7 @@ The environment can also be contracted directly from all its constituent tensors
2021
| | | |
2122
E_1 -- A_1 -- A_2 -- E_4
2223
| | | |
24+
out in
2325
```
2426
2527
Alternatively, contract the environment with a vector `x` acting on it
@@ -29,7 +31,7 @@ Alternatively, contract the environment with a vector `x` acting on it
2931
| | | |
3032
E_1 -- A_1 -- A_2 -- E_4
3133
| | | |
32-
[~~~x~~~~]
34+
out [~~~x~~~~]
3335
```
3436
3537
or contract the adjoint environment with `x`, e.g. as needed for iterative solvers.
@@ -43,18 +45,18 @@ end
4345
function half_infinite_environment(
4446
C_1, C_2, E_1, E_2, E_3, E_4, A_1::P, A_2::P
4547
) where {P <: PEPSSandwich}
46-
return @autoopt @tensor env[χ_in D_inabove D_inbelow; χ_out D_outabove D_outbelow] :=
47-
E_1[χ_in D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
48-
ket(A_1)[d1; D3 D9 D_inabove D1] * conj(bra(A_1)[d1; D4 D10 D_inbelow D2]) *
49-
ket(A_2)[d2; D5 D7 D_outabove D9] * conj(bra(A_2)[d2; D6 D8 D_outbelow D10]) *
48+
return @autoopt @tensor env[χ_out D_outabove D_outbelow; χ_in D_inabove D_inbelow] :=
49+
E_1[χ_out D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
50+
ket(A_1)[d1; D3 D9 D_outabove D1] * conj(bra(A_1)[d1; D4 D10 D_outbelow D2]) *
51+
ket(A_2)[d2; D5 D7 D_inabove D9] * conj(bra(A_2)[d2; D6 D8 D_inbelow D10]) *
5052
E_3[χ3 D5 D6; χ4] * C_2[χ4; χ5] * E_4[χ5 D7 D8; χ_out]
5153
end
5254
function half_infinite_environment(
5355
C_1, C_2, E_1, E_2, E_3, E_4, x::AbstractTensor{T, S, 3}, A_1::P, A_2::P
5456
) where {T, S, P <: PEPSSandwich}
55-
return @autoopt @tensor env_x[χ_in D_inabove D_inbelow] :=
56-
E_1[χ_in D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
57-
ket(A_1)[d1; D3 D9 D_inabove D1] * conj(bra(A_1)[d1; D4 D10 D_inbelow D2]) *
57+
return @autoopt @tensor env_x[χ_out D_outabove D_outbelow] :=
58+
E_1[χ_out D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
59+
ket(A_1)[d1; D3 D9 D_outabove D1] * conj(bra(A_1)[d1; D4 D10 D_outbelow D2]) *
5860
ket(A_2)[d2; D5 D7 D11 D9] * conj(bra(A_2)[d2; D6 D8 D12 D10]) *
5961
E_3[χ3 D5 D6; χ4] * C_2[χ4; χ5] * E_4[χ5 D7 D8; χ6] *
6062
x[χ6 D11 D12]
@@ -72,18 +74,18 @@ end
7274
function half_infinite_environment(
7375
C_1, C_2, E_1, E_2, E_3, E_4, A_1::P, A_2::P
7476
) where {P <: PFTensor}
75-
return @autoopt @tensor env[χ_in D_in; χ_out D_out] :=
76-
E_1[χ_in D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
77-
A_1[D1 D_in; D3 D9] *
78-
A_2[D9 D_out; D5 D7] *
79-
E_3[χ3 D5; χ4] * C_2[χ4; χ5] * E_4[χ5 D7; χ_out]
77+
return @autoopt @tensor env[χ_out D_out; χ_in D_in] :=
78+
E_1[χ_out D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
79+
A_1[D1 D_out; D3 D9] *
80+
A_2[D9 D_in; D5 D7] *
81+
E_3[χ3 D5; χ4] * C_2[χ4; χ5] * E_4[χ5 D7; χ_in]
8082
end
8183
function half_infinite_environment(
8284
C_1, C_2, E_1, E_2, E_3, E_4, x::AbstractTensor{T, S, 2}, A_1::P, A::P
8385
) where {T, S, P <: PFTensor}
84-
return @autoopt @tensor env_x[χ_in D_in] :=
85-
E_1[χ_in D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
86-
A_1[D1 D_in; D3 D9] *
86+
return @autoopt @tensor env_x[χ_out D_out] :=
87+
E_1[χ_out D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
88+
A_1[D1 D_out; D3 D9] *
8789
A_2[D9 D11; D5 D7] *
8890
E_3[χ3 D5; χ4] * C_2[χ4; χ5] * E_4[χ5 D7; χ6] *
8991
x[χ6 D11]

0 commit comments

Comments
 (0)