Skip to content

Commit b6aeff3

Browse files
committed
Replace _qr_bond with bond_tensor functions
1 parent 99e3e48 commit b6aeff3

9 files changed

Lines changed: 111 additions & 85 deletions

File tree

src/algorithms/contractions/bondenv/benv_ctm.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ Construct the environment (norm) tensor
99
-1 0 1 2
1010
```
1111
with `X` at position `[row, col]`.
12-
`X, Y` are unitary tensors produced when finding the reduced site tensors
13-
with `_qr_bond`; and `XX = X' X` and `YY = Y' Y` (stacked together).
12+
`X, Y` are unitary tensors produced when finding the reduced site tensors,
13+
and `XX = X' X` and `YY = Y' Y` (stacked together).
1414
1515
Axis order: `[DX1 DY1; DX0 DY0]`, as in
1616
```

src/algorithms/contractions/bondenv/benv_tools.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const BondEnv{T, S} = AbstractTensorMap{T, S, 2, 2} where {T <: Number, S <: Ele
99
const BondEnv3site{T, S} = AbstractTensorMap{T, S, 4, 4} where {T <: Number, S <: ElementarySpace}
1010
const Hair{T, S} = AbstractTensor{T, S, 2} where {T <: Number, S <: ElementarySpace}
1111
# Orthogonal tensors obtained PEPSTensor/PEPOTensor
12-
# with one physical leg factored out by `_qr_bond`
12+
# with one physical leg factored out by `bond_tensor_...`
1313
const PEPSOrth{T, S} = AbstractTensor{T, S, 4} where {T <: Number, S <: ElementarySpace}
1414
const PEPOOrth{T, S} = AbstractTensor{T, S, 5} where {T <: Number, S <: ElementarySpace}
1515

src/algorithms/contractions/bondenv/gaugefix.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,7 @@ Reference:
4444
- Physical Review B 92, 035142 (2015)
4545
"""
4646
function fixgauge_benv(
47-
Z::AbstractTensorMap{T, S, 1, 2},
48-
a::AbstractTensorMap{T, S, 1, 2},
49-
b::AbstractTensorMap{T, S, 2, 1},
47+
Z::AbstractTensorMap{T, S, 1, 2}, a::MPSTensor, b::MPSTensor
5048
) where {T <: Number, S <: ElementarySpace}
5149
@assert !isdual(space(Z, 1))
5250
@assert !isdual(space(a, 2))
@@ -83,7 +81,7 @@ function fixgauge_benv(
8381
8482
-1
8583
=#
86-
@plansor a[-1; -2 -3] := R[-1; 1] * a[1; -2 -3]
84+
@plansor a[-1 -2; -3] := R[-1; 1] * a[1 -2; -3]
8785
@plansor b[-1 -2; -3] := b[-1 -2; 1] * L[-3; 1]
8886
@plansor Z[-1; -2 -3] := Z[-1; 1 2] * Rinv[1; -2] * Linv[2; -3]
8987
(isdual(space(R, 1)) == isdual(space(R, 2))) && twist!(a, 1)

src/algorithms/time_evolution/apply_gate.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,7 @@ Apply 2-site `gate` on the reduced bond tensors `a`, `b`
3434
-2 -3 -1← a --- 3 --- b ← -4
3535
```
3636
"""
37-
function _apply_gate(
38-
a::AbstractTensorMap, b::AbstractTensorMap,
39-
gate::NNGate, trunc::TruncationStrategy
40-
)
37+
function _apply_gate(a::MPSTensor, b::MPSTensor, gate::NNGate, trunc::TruncationStrategy)
4138
V = space(b, 1)
4239
need_flip = isdual(V)
4340
if isdual(space(a, 2))
@@ -50,5 +47,6 @@ function _apply_gate(
5047
if need_flip
5148
a, s, b = flip(a, numind(a)), _fliptwist_s(s), flip(b, 1)
5249
end
50+
b = permute(b, ((1, 2), (3,)))
5351
return a, s, b, ϵ
5452
end

src/algorithms/time_evolution/ntupdate3site.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ function _bond_truncate(
5454
A, B = state2[row, col], state2[row, cp1]
5555

5656
# create bond environment
57-
X, a, b, Y = _qr_bond(A, B; trunc = trunctol(; rtol = 1.0e-12))
57+
X, a = bond_tensor_first(A; trunc = trunctol(; rtol = 1.0e-12))
58+
Y, b = bond_tensor_last(B; trunc = trunctol(; rtol = 1.0e-12))
5859
benv = bondenv_ntu(row, col, X, Y, state2, alg.bondenv_alg)
5960
@debug "cond(benv) before gauge fix: $(LinearAlgebra.cond(benv))"
6061
if alg.fixgauge
@@ -75,7 +76,8 @@ function _bond_truncate(
7576
end
7677

7778
a, s, b, info = bond_truncate(a, b, benv, alg.opt_alg)
78-
A, B = _qr_bond_undo(X, a, b, Y)
79+
A = undo_bond_tensor_first(X, a)
80+
B = undo_bond_tensor_last(Y, b)
7981
normalize!(A, Inf)
8082
normalize!(B, Inf)
8183
normalize!(s, Inf)

src/algorithms/time_evolution/simpleupdate.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,12 @@ function _su_iter!(
113113
ϵ, s = 0.0, nothing
114114
gate_axs = alg.purified ? (1:1) : (1:2)
115115
for gate_ax in gate_axs
116-
X, a, b, Y = _qr_bond(A, B; gate_ax, positive = true)
116+
X, a = bond_tensor_first(A; gate_ax, positive = true)
117+
Y, b = bond_tensor_last(B; gate_ax, positive = true)
117118
a, s, b, ϵ′ = _apply_gate(a, b, gate, trunc)
118119
ϵ = max(ϵ, ϵ′)
119-
A, B = _qr_bond_undo(X, a, b, Y)
120+
A = undo_bond_tensor_first(X, a; gate_ax)
121+
B = undo_bond_tensor_last(Y, b; gate_ax)
120122
end
121123
# rotate back
122124
A = _bond_rotation(A, bond[1], rev; inv = true)
Lines changed: 91 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,114 @@
11
"""
2-
$(SIGNATURES)
2+
Given the first tensor `A` in the cluster acted on by a gate,
3+
obtain reduced tensor on its next bond.
34
4-
Use QR decomposition on two tensors `A`, `B` connected by a bond to get the reduced tensors.
5-
When `A`, `B` are PEPSTensors,
5+
For PEPSTensor,
66
```
7-
2 1 1
8-
| | |
9-
5 -A/B- 3 ====> 4 - X ← 2 1 ← a - 3 1 - b → 3 4 → Y - 2
10-
| | ↘ ↘ |
11-
4 1 3 2 2 3
7+
1
8+
|
9+
4 - X ← 2 1 ← a - 3
10+
|
11+
3 2
1212
```
13-
When `A`, `B` are PEPOTensors,
14-
- If `gate_ax = 1`
13+
For PEPOTensor,
1514
```
16-
2 3 1 2 1 2
17-
↘ | ↘ | ↘ |
18-
6 -A/B- 4 ====> 5 - X ← 3 1 ← a - 3 1 - b → 3 5 → Y - 3
19-
| ↘ | ↘ ↘ |
20-
5 1 4 2 2 4
21-
```
22-
- If `gate_ax = 2`
23-
```
24-
2 3 2 2 2 2
25-
↘ | | ↘ ↘ |
26-
6 -A/B- 4 ====> 5 - X ← 3 1 ← a - 3 1 - b → 3 5 → Y - 3
27-
| ↘ | ↘ | ↘
28-
5 1 4 1 4 1
15+
gate_ax = 1 gate_ax = 2
16+
17+
1 2 2 2
18+
↘ | | ↘
19+
5 - X ← 3 1 ← a - 3 5 - X ← 3 1 ← a - 3
20+
| ↘ | ↘
21+
4 2 4 1
2922
```
3023
"""
31-
function _qr_bond(A::PT, B::PT; gate_ax::Int = 1, kwargs...) where {PT <: Union{PEPSTensor, PEPOTensor}}
32-
@assert 1 <= gate_ax <= numout(A)
33-
permA, permB, permX, permY = if A isa PEPSTensor
34-
((2, 4, 5), (1, 3)), ((2, 3, 4), (1, 5)), (1, 4, 2, 3), Tuple(1:4)
24+
function bond_tensor_first(A::PEPSTensor; gate_ax::Integer = 1, kwargs...)
25+
@assert gate_ax == 1
26+
X, a = left_orth!(permute(A, ((2, 4, 5), (1, 3)); copy = true); kwargs...)
27+
X = permute(X, (1, 4, 2, 3))
28+
a = permute(a, ((1, 2), (3,)))
29+
return X, a
30+
end
31+
function bond_tensor_first(A::PEPOTensor; gate_ax::Integer = 1, kwargs...)
32+
@assert 1 <= gate_ax <= 2
33+
X, a = if gate_ax == 1
34+
left_orth!(permute(A, ((2, 3, 5, 6), (1, 4)); copy = true); kwargs...)
3535
else
36-
if gate_ax == 1
37-
((2, 3, 5, 6), (1, 4)), ((2, 3, 4, 5), (1, 6)), (1, 2, 5, 3, 4), Tuple(1:5)
38-
else
39-
((1, 3, 5, 6), (2, 4)), ((1, 3, 4, 5), (2, 6)), (1, 2, 5, 3, 4), Tuple(1:5)
40-
end
36+
left_orth!(permute(A, ((1, 3, 5, 6), (2, 4)); copy = true); kwargs...)
4137
end
42-
X, a = left_orth!(permute(A, permA; copy = true); kwargs...)
43-
Y, b = left_orth!(permute(B, permB; copy = true); kwargs...)
44-
X, Y = permute(X, permX), permute(Y, permY)
45-
b = permute(b, ((3, 2), (1,)))
46-
return X, a, b, Y
38+
X = permute(X, (1, 2, 5, 3, 4))
39+
a = permute(a, ((1, 2), (3,)))
40+
return X, a
4741
end
4842

4943
"""
50-
$(SIGNATURES)
44+
Undo the decomposition in `bond_tensor_first`.
45+
"""
46+
function undo_bond_tensor_first(X::PEPSOrth, a::MPSTensor; gate_ax::Integer = 1)
47+
@assert gate_ax == 1
48+
return @tensor A[-1; -2 -3 -4 -5] := X[-2 1 -4 -5] * a[1 -1 -3]
49+
end
50+
function undo_bond_tensor_first(X::PEPOOrth, a::MPSTensor; gate_ax::Integer = 1)
51+
@assert 1 <= gate_ax <= 2
52+
if gate_ax == 1
53+
return @tensor A[-1 -2; -3 -4 -5 -6] := X[-2 -3 1 -5 -6] * a[1 -1 -4]
54+
else
55+
return @tensor A[-1 -2; -3 -4 -5 -6] := X[-1 -3 1 -5 -6] * a[1 -2 -4]
56+
end
57+
end
5158

52-
Reconstruct the tensors connected by a bond from their `_qr_bond` results.
53-
For PEPSTensors,
59+
"""
60+
Given the last tensor `A` in the cluster acted on by a gate,
61+
obtain reduced tensor on its previous bond.
62+
63+
For PEPSTensor,
5464
```
55-
-2 -2
56-
| |
57-
-5- X - 1 - a - -3 -5 - b - 1 - Y - -3
58-
| |
59-
-4 -1 -1 -4
65+
1
66+
|
67+
1 - b → 3 4 → Y - 2
68+
↘ |
69+
2 3
6070
```
61-
For PEPOTensors
71+
For PEPOTensor,
6272
```
63-
-2 -3 -2 -3
64-
↘ | ↘ |
65-
-6- X - 1 - a - -4 -6 - b - 1 - Y - -4
66-
| ↘ ↘ |
67-
-5 -1 -1 -5
73+
gate_ax = 1 gate_ax = 2
6874
69-
-3 -2 -2 -3
70-
| ↘ |
71-
-6- X - 1 - a - -4 -6 - b - 1 - Y - -4
72-
| ↘ | ↘
73-
-5 -1 -5 -1
75+
1 2 2 2
76+
↘ | |
77+
1 - b → 3 5 → Y - 3 1 - b → 3 5 → Y - 3
78+
| | ↘
79+
2 4 4 1
7480
```
7581
"""
76-
function _qr_bond_undo(X::PEPSOrth, a::AbstractTensorMap, b::AbstractTensorMap, Y::PEPSOrth)
77-
@tensor A[-1; -2 -3 -4 -5] := X[-2 1 -4 -5] * a[1 -1 -3]
78-
@tensor B[-1; -2 -3 -4 -5] := b[-5 -1 1] * Y[-2 -3 -4 1]
79-
return A, B
82+
function bond_tensor_last(A::PEPSTensor; gate_ax::Integer = 1, kwargs...)
83+
@assert gate_ax == 1
84+
Y, b = left_orth!(permute(A, ((2, 3, 4), (1, 5)); copy = true); kwargs...)
85+
Y = permute(Y, (1, 2, 3, 4))
86+
b = permute(b, ((3, 2), (1,)))
87+
return Y, b
88+
end
89+
function bond_tensor_last(A::PEPOTensor; gate_ax::Integer = 1, kwargs...)
90+
@assert 1 <= gate_ax <= 2
91+
Y, b = if gate_ax == 1
92+
left_orth!(permute(A, ((2, 3, 4, 5), (1, 6)); copy = true); kwargs...)
93+
else
94+
left_orth!(permute(A, ((1, 3, 4, 5), (2, 6)); copy = true); kwargs...)
95+
end
96+
Y = permute(Y, (1, 2, 3, 4, 5))
97+
b = permute(b, ((3, 2), (1,)))
98+
return Y, b
99+
end
100+
101+
"""
102+
Undo the decomposition in `bond_tensor_last`.
103+
"""
104+
function undo_bond_tensor_last(Y::PEPSOrth, b::MPSTensor)
105+
return @tensor A[-1; -2 -3 -4 -5] := b[-5 -1 1] * Y[-2 -3 -4 1]
80106
end
81-
function _qr_bond_undo(X::PEPOOrth, a::AbstractTensorMap, b::AbstractTensorMap, Y::PEPOOrth)
82-
if !isdual(space(a, 2))
83-
@tensor A[-1 -2; -3 -4 -5 -6] := X[-2 -3 1 -5 -6] * a[1 -1 -4]
84-
@tensor B[-1 -2; -3 -4 -5 -6] := b[-6 -1 1] * Y[-2 -3 -4 -5 1]
107+
function undo_bond_tensor_last(Y::PEPOOrth, b::MPSTensor; gate_ax::Integer = 1)
108+
@assert 1 <= gate_ax <= 2
109+
if gate_ax == 1
110+
return @tensor A[-1 -2; -3 -4 -5 -6] := b[-6 -1 1] * Y[-2 -3 -4 -5 1]
85111
else
86-
@tensor A[-1 -2; -3 -4 -5 -6] := X[-1 -3 1 -5 -6] * a[1 -2 -4]
87-
@tensor B[-1 -2; -3 -4 -5 -6] := b[-6 -2 1] * Y[-1 -3 -4 -5 1]
112+
return @tensor A[-1 -2; -3 -4 -5 -6] := b[-6 -2 1] * Y[-1 -3 -4 -5 1]
88113
end
89-
return A, B
90114
end

test/bondenv/benv_ctm.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ function test_benv_ctm(state::Union{InfinitePEPS, InfinitePEPO})
4242
for row in 1:Nr, col in 1:Nc
4343
cp1 = PEPSKit._next(col, Nc)
4444
A, B = state.A[row, col], state.A[row, cp1]
45-
X, a, b, Y = PEPSKit._qr_bond(A, B)
45+
X, a = PEPSKit.bond_tensor_first(A)
46+
Y, b = PEPSKit.bond_tensor_last(B)
4647
benv = PEPSKit.bondenv_ctm(row, col, X, Y, env)
4748
Z = PEPSKit.positive_approx(benv)
4849
# verify that gauge fixing can greatly reduce

test/bondenv/benv_ntu.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ function test_ntu_env(
1515
for row in 1:Nr, col in 1:Nc
1616
cp1 = PEPSKit._next(col, Nc)
1717
A, B = state.A[row, col], state.A[row, cp1]
18-
X, a, b, Y = PEPSKit._qr_bond(A, B)
18+
X, a = PEPSKit.bond_tensor_first(A)
19+
Y, b = PEPSKit.bond_tensor_last(B)
1920
@tensor ab[DX DY; da db] := a[DX da D] * b[D db DY]
2021
benv = PEPSKit.bondenv_ntu(row, col, X, Y, state, env_alg)
21-
# this is a result of `_qr_bond`
22+
# this is a result of `bond_tensor_...`
2223
@assert [isdual(space(benv, ax)) for ax in 1:numind(benv)] == [0, 0, 1, 1]
2324
# NTU bond environments are exact and should be positive definite
2425
@test benv' benv

0 commit comments

Comments
 (0)