Skip to content
36 changes: 14 additions & 22 deletions src/algorithms/contractions/ctmrg/enlarge_corner.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ Contract the enlarged northwest corner of the CTMRG environment, either by speci
coordinates, environments and network, or by directly providing the tensors.

```
C_northwest -- E_north --
C_northwest -- E_north --in
| |
E_west -- A --
| |
out
```
"""
function enlarge_northwest_corner(
Expand All @@ -37,13 +38,10 @@ function enlarge_northwest_corner(
)
return @tensor begin
EC[χS DWt DWb; χ2] := E_west[χS DWt DWb; χ1] * C_northwest[χ1; χ2]

# already putting χE in front here to make next permute cheaper
ECE[χS χE DWb DNb; DWt DNt] := EC[χS DWt DWb; χ2] * E_north[χ2 DNt DNb; χE]

ECEket[χS χE DEt DSt; DWb DNb d] :=
ECE[χS χE DWb DNb; DWt DNt] * ket(A)[d; DNt DEt DSt DWt]

corner[χS DSt DSb; χE DEt DEb] :=
ECEket[χS χE DEt DSt; DWb DNb d] * conj(bra(A)[d; DNb DEb DSb DWb])
end
Expand Down Expand Up @@ -94,10 +92,11 @@ Contract the enlarged northeast corner of the CTMRG environment, either by speci
coordinates, environments and network, or by directly providing the tensors.

```
-- E_north -- C_northeast
| |
-- A -- E_east
| |
out-- E_north -- C_northeast
| |
-- A -- E_east
| |
in
```
"""
function enlarge_northeast_corner(
Expand All @@ -106,13 +105,10 @@ function enlarge_northeast_corner(
)
return @tensor begin
EC[χW DNt DNb; χ2] := E_north[χW DNt DNb; χ1] * C_northeast[χ1; χ2]

# already putting χE in front here to make next permute cheaper
ECE[χW χS DNb DEb; DNt DEt] := EC[χW DNt DNb; χ2] * E_east[χ2 DEt DEb; χS]

ECEket[χW χS DSt DWt; DNb DEb d] :=
ECE[χW χS DNb DEb; DNt DEt] * ket(A)[d; DNt DEt DSt DWt]

corner[χW DWt DWb; χS DSt DSb] :=
ECEket[χW χS DSt DWt; DNb DEb d] * conj(bra(A)[d; DNb DEb DSb DWb])
end
Expand Down Expand Up @@ -163,10 +159,11 @@ Contract the enlarged southeast corner of the CTMRG environment, either by speci
coordinates, environments and network, or by directly providing the tensors.

```
| |
-- A -- E_east
| |
-- E_south -- C_southeast
out
| |
-- A -- E_east
| |
in-- E_south -- C_southeast
```
"""
function enlarge_southeast_corner(
Expand All @@ -175,13 +172,10 @@ function enlarge_southeast_corner(
)
return @tensor begin
EC[χN DEt DEb; χ2] := E_east[χN DEt DEb; χ1] * C_southeast[χ1; χ2]

# already putting χE in front here to make next permute cheaper
ECE[χN χW DEb DSb; DEt DSt] := EC[χN DEt DEb; χ2] * E_south[χ2 DSt DSb; χW]

ECEket[χN χW DNt DWt; DEb DSb d] :=
ECE[χN χW DEb DSb; DEt DSt] * ket(A)[d; DNt DEt DSt DWt]

corner[χN DNt DNb; χW DWt DWb] :=
ECEket[χN χW DNt DWt; DEb DSb d] * conj(bra(A)[d; DNb DEb DSb DWb])
end
Expand Down Expand Up @@ -232,10 +226,11 @@ Contract the enlarged southwest corner of the CTMRG environment, either by speci
coordinates, environments and network, or by directly providing the tensors.

```
in
| |
E_west -- A --
| |
C_southwest -- E_south --
C_southwest -- E_south --out
```
"""
function enlarge_southwest_corner(
Expand All @@ -244,13 +239,10 @@ function enlarge_southwest_corner(
)
return @tensor begin
EC[χE DSt DSb; χ2] := E_south[χE DSt DSb; χ1] * C_southwest[χ1; χ2]

# already putting χE in front here to make next permute cheaper
ECE[χE χN DSb DWb; DSt DWt] := EC[χE DSt DSb; χ2] * E_west[χ2 DWt DWb; χN]

ECEket[χE χN DNt DEt; DSb DWb d] :=
ECE[χE χN DSb DWb; DSt DWt] * ket(A)[d; DNt DEt DSt DWt]

corner[χE DEt DEb; χN DNt DNb] :=
ECEket[χE χN DNt DEt; DSb DWb d] * conj(bra(A)[d; DNb DEb DSb DWb])
end
Expand Down
39 changes: 23 additions & 16 deletions src/algorithms/contractions/ctmrg/fullinf_env.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ Contract four quadrants (enlarged corners) to form a full-infinite environment.
|quadrant1| |quadrant2|
|~~~~~~~~~| -- |~~~~~~~~~|
| | | |
out | |
| |
in | |
| | | |
|~~~~~~~~~| -- |~~~~~~~~~|
|quadrant4| |quadrant3|
Expand All @@ -26,7 +28,9 @@ In the same manner two halfs can be used to contract the full-infinite environme
| half1 |
|~~~~~~~~~~~~~~~~~~~~~~~~|
| | | |
out | |
| |
in | |
| | | |
|~~~~~~~~~~~~~~~~~~~~~~~~|
| half2 |
Expand All @@ -40,7 +44,9 @@ The environment can also be contracted directly from all its constituent tensors
| | | |
E_1 -- A_1 -- A_2 -- E_4
| | | |
out | |
| |
in | | |
| | | |
E_8 -- A_4 -- A_3 -- E_5
| | | |
Expand All @@ -54,6 +60,7 @@ Alternatively, contract the environment with a vector `x` acting on it
| | | |
E_1 -- A_1 -- A_2 -- E_4
| | | |
out | |
| |
[~~~~x~~~] | |
| | | |
Expand Down Expand Up @@ -112,25 +119,25 @@ function full_infinite_environment(
E_1, E_2, E_3, E_4, E_5, E_6, E_7, E_8,
A_1::P, A_2::P, A_3::P, A_4::P,
) where {P <: PEPSSandwich}
return @autoopt @tensor env[χ_in D_inabove D_inbelow; χ_out D_outabove D_outbelow] :=
E_1[χ_in D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
ket(A_1)[d1; D3 D11 D_inabove D1] * conj(bra(A_1)[d1; D4 D12 D_inbelow D2]) *
return @autoopt @tensor env[χ_out D_outabove D_outbelow; χ_in D_inabove D_inbelow] :=
E_1[χ_out D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
ket(A_1)[d1; D3 D11 D_outabove D1] * conj(bra(A_1)[d1; D4 D12 D_outbelow D2]) *
ket(A_2)[d2; D5 D7 D9 D11] * conj(bra(A_2)[d2; D6 D8 D10 D12]) *
E_3[χ3 D5 D6; χ4] * C_2[χ4; χ5] * E_4[χ5 D7 D8; χ6] *
E_5[χ6 D13 D14; χ7] * C_3[χ7; χ8] * E_6[χ8 D15 D16; χ9] *
ket(A_3)[d3; D9 D13 D15 D17] * conj(bra(A_3)[d3; D10 D14 D16 D18]) *
ket(A_4)[d4; D_outabove D17 D19 D21] * conj(bra(A_4)[d4; D_outbelow D18 D20 D22]) *
E_7[χ9 D19 D20; χ10] * C_4[χ10; χ11] * E_8[χ11 D21 D22; χ_out]
ket(A_4)[d4; D_inabove D17 D19 D21] * conj(bra(A_4)[d4; D_inbelow D18 D20 D22]) *
E_7[χ9 D19 D20; χ10] * C_4[χ10; χ11] * E_8[χ11 D21 D22; χ_in]
end
function full_infinite_environment(
C_1, C_2, C_3, C_4,
E_1, E_2, E_3, E_4, E_5, E_6, E_7, E_8,
x::AbstractTensor{T, S, 3},
A_1::P, A_2::P, A_3::P, A_4::P,
) where {T, S, P <: PEPSSandwich}
return @autoopt @tensor env_x[χ_in D_inabove D_inbelow] :=
E_1[χ_in D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
ket(A_1)[d1; D3 D11 D_inabove D1] * conj(bra(A_1)[d1; D4 D12 D_inbelow D2]) *
return @autoopt @tensor env_x[χ_out D_outabove D_outbelow] :=
E_1[χ_out D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
ket(A_1)[d1; D3 D11 D_outabove D1] * conj(bra(A_1)[d1; D4 D12 D_outbelow D2]) *
ket(A_2)[d2; D5 D7 D9 D11] * conj(bra(A_2)[d2; D6 D8 D10 D12]) *
E_3[χ3 D5 D6; χ4] * C_2[χ4; χ5] * E_4[χ5 D7 D8; χ6] *
E_5[χ6 D13 D14; χ7] * C_3[χ7; χ8] * E_6[χ8 D15 D16; χ9] *
Expand Down Expand Up @@ -161,25 +168,25 @@ function full_infinite_environment(
E_1, E_2, E_3, E_4, E_5, E_6, E_7, E_8,
A_1::P, A_2::P, A_3::P, A_4::P,
) where {P <: PFTensor}
return @autoopt @tensor env[χ_in D_in; χ_out D_out] :=
E_1[χ_in D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
A_1[D1 D_in; D3 D11] *
return @autoopt @tensor env[χ_out D_out; χ_in D_in] :=
E_1[χ_out D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
A_1[D1 D_out; D3 D11] *
A_2[D11 D9; D5 D7] *
E_3[χ3 D5; χ4] * C_2[χ4; χ5] * E_4[χ5 D7; χ6] *
E_5[χ6 D13; χ7] * C_3[χ7; χ8] * E_6[χ8 D15; χ9] *
A_3[D17 D15; D9 D13] *
A_4[D21 D19; D_out D17] *
E_7[χ9 D19; χ10] * C_4[χ10; χ11] * E_8[χ11 D21; χ_out]
A_4[D21 D19; D_in D17] *
E_7[χ9 D19; χ10] * C_4[χ10; χ11] * E_8[χ11 D21; χ_in]
end
function full_infinite_environment(
C_1, C_2, C_3, C_4,
E_1, E_2, E_3, E_4, E_5, E_6, E_7, E_8,
x::AbstractTensor{T, S, 2},
A_1::P, A_2::P, A_3::P, A_4::P,
) where {T, S, P <: PFTensor}
return @autoopt @tensor env_x[χ_in D_in] :=
E_1[χ_in D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
A_1[D1 D_in; D3 D11] *
return @autoopt @tensor env_x[χ_out D_out] :=
E_1[χ_out D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
A_1[D1 D_out; D3 D11] *
A_2[D11 D9; D5 D7] *
E_3[χ3 D5; χ4] * C_2[χ4; χ5] * E_4[χ5 D7; χ6] *
E_5[χ6 D13; χ7] * C_3[χ7; χ8] * E_6[χ8 D15; χ9] *
Expand Down
26 changes: 14 additions & 12 deletions src/algorithms/contractions/ctmrg/gaugefix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ $(SIGNATURES)
Multiply corner tensor with incoming and outgoing gauge signs.

```
corner -- σ_out --
corner -- σ_in --in
|
σ_in
σ_out
|
out
```
"""
function fix_gauge_corner(
corner::CTMRGCornerTensor, σ_in::CTMRGCornerTensor, σ_out::CTMRGCornerTensor
corner::CTMRGCornerTensor, σ_out::CTMRGCornerTensor, σ_in::CTMRGCornerTensor
)
return @autoopt @tensor corner_fix[χ_in; χ_out] :=
σ_in[χ_in; χ1] * corner[χ1; χ2] * conj(σ_out[χ_out; χ2])
return @autoopt @tensor corner_fix[χ_out; χ_in] :=
σ_out[χ_out; χ1] * corner[χ1; χ2] * conj(σ_in[χ_in; χ2])
end

"""
Expand Down Expand Up @@ -82,25 +83,26 @@ $(SIGNATURES)
Multiply edge tensor with incoming and outgoing gauge signs.

```
-- σ_in -- edge -- σ_out --
out-- σ_out -- edge -- σ_in --in
|
```
"""
@generated function fix_gauge_edge(
edge::CTMRGEdgeTensor{T, S, N}, σ_in::CTMRGCornerTensor, σ_out::CTMRGCornerTensor
edge::CTMRGEdgeTensor{T, S, N}, σ_out::CTMRGCornerTensor, σ_in::CTMRGCornerTensor
) where {T, S, N}
edge_fix_e = tensorexpr(
:edge_fix,
(envlabel(:in), ntuple(i -> virtuallabel(i), N - 1)...),
(envlabel(:out),),
(envlabel(:out), ntuple(i -> virtuallabel(i), N - 1)...),
(envlabel(:in),),
)
edge_e = tensorexpr(
:edge, (envlabel(1), ntuple(i -> virtuallabel(i), N - 1)...), (envlabel(2),)
)
σ_in_e = tensorexpr(:σ_in, (envlabel(:in),), (envlabel(1),))
σ_out_e = tensorexpr(:σ_out, (envlabel(:out),), (envlabel(2),))
σ_out_e = tensorexpr(:σ_out, (envlabel(:out),), (envlabel(1),))
σ_in_e = tensorexpr(:σ_in, (envlabel(:in),), (envlabel(2),))
return macroexpand(
@__MODULE__,
:(return @autoopt @tensor $edge_fix_e := $σ_in_e * $edge_e * conj($σ_out_e)),
:(return @autoopt @tensor $edge_fix_e := $σ_out_e * $edge_e * conj($σ_in_e)),
)
end

Expand Down
34 changes: 18 additions & 16 deletions src/algorithms/contractions/ctmrg/halfinf_env.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Contract two quadrants (enlarged corners) to form a half-infinite environment.
|quadrant1| |quadrant2|
|~~~~~~~~~| -- |~~~~~~~~~|
| | | |
out in
```

The environment can also be contracted directly from all its constituent tensors.
Expand All @@ -20,6 +21,7 @@ The environment can also be contracted directly from all its constituent tensors
| | | |
E_1 -- A_1 -- A_2 -- E_4
| | | |
out in
```

Alternatively, contract the environment with a vector `x` acting on it
Expand All @@ -29,7 +31,7 @@ Alternatively, contract the environment with a vector `x` acting on it
| | | |
E_1 -- A_1 -- A_2 -- E_4
| | | |
[~~~x~~~~]
out [~~~x~~~~]
```

or contract the adjoint environment with `x`, e.g. as needed for iterative solvers.
Expand All @@ -43,18 +45,18 @@ end
function half_infinite_environment(
C_1, C_2, E_1, E_2, E_3, E_4, A_1::P, A_2::P
) where {P <: PEPSSandwich}
return @autoopt @tensor env[χ_in D_inabove D_inbelow; χ_out D_outabove D_outbelow] :=
E_1[χ_in D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
ket(A_1)[d1; D3 D9 D_inabove D1] * conj(bra(A_1)[d1; D4 D10 D_inbelow D2]) *
ket(A_2)[d2; D5 D7 D_outabove D9] * conj(bra(A_2)[d2; D6 D8 D_outbelow D10]) *
return @autoopt @tensor env[χ_out D_outabove D_outbelow; χ_in D_inabove D_inbelow] :=
E_1[χ_out D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
ket(A_1)[d1; D3 D9 D_outabove D1] * conj(bra(A_1)[d1; D4 D10 D_outbelow D2]) *
ket(A_2)[d2; D5 D7 D_inabove D9] * conj(bra(A_2)[d2; D6 D8 D_inbelow D10]) *
E_3[χ3 D5 D6; χ4] * C_2[χ4; χ5] * E_4[χ5 D7 D8; χ_out]
end
function half_infinite_environment(
C_1, C_2, E_1, E_2, E_3, E_4, x::AbstractTensor{T, S, 3}, A_1::P, A_2::P
) where {T, S, P <: PEPSSandwich}
return @autoopt @tensor env_x[χ_in D_inabove D_inbelow] :=
E_1[χ_in D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
ket(A_1)[d1; D3 D9 D_inabove D1] * conj(bra(A_1)[d1; D4 D10 D_inbelow D2]) *
return @autoopt @tensor env_x[χ_out D_outabove D_outbelow] :=
E_1[χ_out D1 D2; χ1] * C_1[χ1; χ2] * E_2[χ2 D3 D4; χ3] *
ket(A_1)[d1; D3 D9 D_outabove D1] * conj(bra(A_1)[d1; D4 D10 D_outbelow D2]) *
ket(A_2)[d2; D5 D7 D11 D9] * conj(bra(A_2)[d2; D6 D8 D12 D10]) *
E_3[χ3 D5 D6; χ4] * C_2[χ4; χ5] * E_4[χ5 D7 D8; χ6] *
x[χ6 D11 D12]
Expand All @@ -72,18 +74,18 @@ end
function half_infinite_environment(
C_1, C_2, E_1, E_2, E_3, E_4, A_1::P, A_2::P
) where {P <: PFTensor}
return @autoopt @tensor env[χ_in D_in; χ_out D_out] :=
E_1[χ_in D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
A_1[D1 D_in; D3 D9] *
A_2[D9 D_out; D5 D7] *
E_3[χ3 D5; χ4] * C_2[χ4; χ5] * E_4[χ5 D7; χ_out]
return @autoopt @tensor env[χ_out D_out; χ_in D_in] :=
E_1[χ_out D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
A_1[D1 D_out; D3 D9] *
A_2[D9 D_in; D5 D7] *
E_3[χ3 D5; χ4] * C_2[χ4; χ5] * E_4[χ5 D7; χ_in]
end
function half_infinite_environment(
C_1, C_2, E_1, E_2, E_3, E_4, x::AbstractTensor{T, S, 2}, A_1::P, A::P
) where {T, S, P <: PFTensor}
return @autoopt @tensor env_x[χ_in D_in] :=
E_1[χ_in D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
A_1[D1 D_in; D3 D9] *
return @autoopt @tensor env_x[χ_out D_out] :=
E_1[χ_out D1; χ1] * C_1[χ1; χ2] * E_2[χ2 D3; χ3] *
A_1[D1 D_out; D3 D9] *
A_2[D9 D11; D5 D7] *
E_3[χ3 D5; χ4] * C_2[χ4; χ5] * E_4[χ5 D7; χ6] *
x[χ6 D11]
Expand Down
Loading