Skip to content

Commit 4f03a99

Browse files
Simple update for PEPO (#250)
* Add simple update for PEPO (2-site) * Add gate_side for SU and ancilla utility functions * Remove `trivial_CTMRGEnv` * Add test with TF-Ising model * Fix formatting * Fix CTMRG convergence in test * Switch to sequential CTMRG * Optimizations * Change default gate_side * Using infinite_temperature_density_matrix and _fuse_ids * Change `gate_side` to `gate_bothsides::Bool` * Fix formatting * Clean up * Use new features on PEPO expectation value * Unexport infinite_temperature_density_matrix * Define scalartype for LocalOperator * Improve scalartype for LocalOperator Co-authored-by: Lukas Devos <[email protected]> --------- Co-authored-by: Lukas Devos <[email protected]>
1 parent 76344b9 commit 4f03a99

File tree

10 files changed

+299
-119
lines changed

10 files changed

+299
-119
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pkg> add PEPSKit
3333
- Contraction of infinite PEPS using the corner transfer matrix renormalization group (CTMRG) and boundary MPS methods
3434
- Native support for symmetric tensors through [TensorKit](https://github.com/Jutho/TensorKit.jl), including fermionic tensors
3535
- PEPS optimization using automatic differentiation (AD) provided through [Zygote](https://fluxml.ai/Zygote.jl/stable/)
36-
- Imaginary time evolution algorithms
36+
- Imaginary time evolution algorithms (including ground state and finite-temperature simulations)
3737
- Support for PEPS with generic unit cells
3838
- Support for classical 2D partition functions and projected entangled-pair operators (PEPOs)
3939
- Extensible system for custom states, operators and algorithms

src/PEPSKit.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ using LoggingExtras
1515

1616
using MPSKit
1717
using MPSKit: MPOTensor, GenericMPSTensor, MPSBondTensor, TransferMatrix
18-
import MPSKit: leading_boundary, loginit!, logiter!, logfinish!, logcancel!, physicalspace
18+
import MPSKit: tensorexpr, leading_boundary, loginit!, logiter!, logfinish!, logcancel!, physicalspace
19+
import MPSKit: infinite_temperature_density_matrix
1920

2021
using MPSKitModels
2122
using FiniteDifferences
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
const BondEnv{T, S} = AbstractTensorMap{T, S, 2, 2} where {T <: Number, S <: ElementarySpace}
22
const PEPSOrth{T, S} = AbstractTensor{T, S, 4} where {T <: Number, S <: ElementarySpace}
3+
const PEPOOrth{T, S} = AbstractTensor{T, S, 5} where {T <: Number, S <: ElementarySpace}

src/algorithms/contractions/localoperator.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# Contraction of local operators on arbitrary lattice locations
22
# -------------------------------------------------------------
3-
import MPSKit: tensorexpr
43

54
# currently need this because MPSKit restricts tensor names to symbols
65
_totuple(t) = t isa Tuple ? t : tuple(t)

src/algorithms/time_evolution/evoltools.jl

Lines changed: 91 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
const InfiniteState = Union{InfinitePEPS, InfinitePEPO}
2+
3+
function MPSKit.infinite_temperature_density_matrix(H::LocalOperator)
4+
T = scalartype(H)
5+
A = map(physicalspace(H)) do Vp
6+
ψ = permute(TensorKit.id(T, Vp), (1, 2))
7+
Vv = oneunit(Vp) # trivial (1D) virtual space
8+
virt = ones(T, domain(ψ) Vv Vv Vv' ⊗ Vv')
9+
return ψ * virt
10+
end
11+
return InfinitePEPO(cat(A; dims = 3))
12+
end
13+
114
"""
215
get_expham(H::LocalOperator, dt::Number)
316
@@ -71,75 +84,121 @@ end
7184
"""
7285
$(SIGNATURES)
7386
74-
Use QR decomposition on two tensors connected by a bond
75-
to get the reduced tensors
87+
Use QR decomposition on two tensors `A`, `B` connected by a bond to get the reduced tensors.
88+
When `A`, `B` are PEPSTensors,
7689
```
77-
2 1
78-
| |
79-
5 - A - 3 ====> 4 - X ← 2 1 ← a - 3
80-
| ↘ | ↘
81-
4 1 3 2
82-
83-
2 1
84-
| |
85-
5 - B - 3 ====> 1 - b → 3 4 → Y - 2
86-
| ↘ ↘ |
87-
4 1 2 3
90+
2 1 1
91+
| | |
92+
5 -A/B- 3 ====> 4 - X ← 2 1 ← a - 3 1 - b → 3 4 → Y - 2
93+
| ↘ | ↘ ↘ |
94+
4 1 3 2 2 3
95+
```
96+
When `A`, `B` are PEPOTensors,
97+
- If `gate_ax = 1`
98+
```
99+
2 3 1 2 1 2
100+
↘ | ↘ | ↘ |
101+
6 -A/B- 4 ====> 5 - X ← 3 1 ← a - 3 1 - b → 3 5 → Y - 3
102+
| ↘ | ↘ ↘ |
103+
5 1 4 2 2 4
104+
```
105+
- If `gate_ax = 2`
106+
```
107+
2 3 2 2 2 2
108+
↘ | | ↘ ↘ |
109+
6 -A/B- 4 ====> 5 - X ← 3 1 ← a - 3 1 - b → 3 5 → Y - 3
110+
| ↘ | ↘ | ↘
111+
5 1 4 1 4 1
88112
```
89113
"""
90-
function _qr_bond(A::PEPSTensor, B::PEPSTensor)
91-
X, a = leftorth(A, ((2, 4, 5), (1, 3)))
92-
Y, b = leftorth(B, ((2, 3, 4), (1, 5)))
114+
function _qr_bond(A::PT, B::PT; gate_ax::Int = 1) where {PT <: Union{PEPSTensor, PEPOTensor}}
115+
@assert 1 <= gate_ax <= numout(A)
116+
permA, permB, permX, permY = if A isa PEPSTensor
117+
((2, 4, 5), (1, 3)), ((2, 3, 4), (1, 5)), (1, 4, 2, 3), Tuple(1:4)
118+
else
119+
if gate_ax == 1
120+
((2, 3, 5, 6), (1, 4)), ((2, 3, 4, 5), (1, 6)), (1, 2, 5, 3, 4), Tuple(1:5)
121+
else
122+
((1, 3, 5, 6), (2, 4)), ((1, 3, 4, 5), (2, 6)), (1, 2, 5, 3, 4), Tuple(1:5)
123+
end
124+
end
125+
X, a = leftorth(A, permA)
126+
Y, b = leftorth(B, permB)
93127
@assert !isdual(space(a, 1))
94128
@assert !isdual(space(b, 1))
95-
X = permute(X, (1, 4, 2, 3))
96-
Y = permute(Y, (1, 2, 3, 4))
129+
X, Y = permute(X, permX), permute(Y, permY)
97130
b = permute(b, ((3, 2), (1,)))
98131
return X, a, b, Y
99132
end
100133

101134
"""
102135
$(SIGNATURES)
103136
104-
Reconstruct the tensors connected by a bond from their QR results
105-
obtained from `_qr_bond`
137+
Reconstruct the tensors connected by a bond from their `_qr_bond` results.
138+
For PEPSTensors,
106139
```
107140
-2 -2
108141
| |
109142
-5- X - 1 - a - -3 -5 - b - 1 - Y - -3
110143
| ↘ ↘ |
111144
-4 -1 -1 -4
112145
```
146+
For PEPOTensors
147+
```
148+
-2 -3 -2 -3
149+
↘ | ↘ |
150+
-6- X - 1 - a - -4 -6 - b - 1 - Y - -4
151+
| ↘ ↘ |
152+
-5 -1 -1 -5
153+
154+
-3 -2 -2 -3
155+
| ↘ ↘ |
156+
-6- X - 1 - a - -4 -6 - b - 1 - Y - -4
157+
| ↘ | ↘
158+
-5 -1 -5 -1
159+
```
113160
"""
114161
function _qr_bond_undo(X::PEPSOrth, a::AbstractTensorMap, b::AbstractTensorMap, Y::PEPSOrth)
115162
@tensor A[-1; -2 -3 -4 -5] := X[-2 1 -4 -5] * a[1 -1 -3]
116163
@tensor B[-1; -2 -3 -4 -5] := b[-5 -1 1] * Y[-2 -3 -4 1]
117164
return A, B
118165
end
166+
function _qr_bond_undo(X::PEPOOrth, a::AbstractTensorMap, b::AbstractTensorMap, Y::PEPOOrth)
167+
if !isdual(space(a, 2))
168+
@tensor A[-1 -2; -3 -4 -5 -6] := X[-2 -3 1 -5 -6] * a[1 -1 -4]
169+
@tensor B[-1 -2; -3 -4 -5 -6] := b[-6 -1 1] * Y[-2 -3 -4 -5 1]
170+
else
171+
@tensor A[-1 -2; -3 -4 -5 -6] := X[-1 -3 1 -5 -6] * a[1 -2 -4]
172+
@tensor B[-1 -2; -3 -4 -5 -6] := b[-6 -2 1] * Y[-1 -3 -4 -5 1]
173+
end
174+
return A, B
175+
end
119176

120177
"""
121178
$(SIGNATURES)
122179
123180
Apply 2-site `gate` on the reduced matrices `a`, `b`
124181
```
125-
-1← a --- 3 --- b ← -4
126-
↓ ↓
127-
1 2
128-
↓ ↓
129-
|----gate---|
130-
↓ ↓
131-
-2 -3
182+
-1← a --- 3 --- b ← -4 -2 -3
183+
↓ ↓ ↓ ↓
184+
1 2 |----gate---|
185+
↓ ↓ or ↓ ↓
186+
|----gate---| 1 2
187+
↓ ↓ ↓ ↓
188+
-2 -3 -1← a --- 3 --- b ← -4
132189
```
133190
"""
134191
function _apply_gate(
135-
a::AbstractTensorMap{T, S},
136-
b::AbstractTensorMap{T, S},
137-
gate::AbstractTensorMap{T, S, 2, 2},
138-
trscheme::TruncationScheme,
192+
a::AbstractTensorMap{T, S}, b::AbstractTensorMap{T, S},
193+
gate::AbstractTensorMap{T, S, 2, 2}, trscheme::TruncationScheme
139194
) where {T <: Number, S <: ElementarySpace}
140195
V = space(b, 1)
141196
need_flip = isdual(V)
142-
@tensor a2b2[-1 -2; -3 -4] := gate[-2 -3; 1 2] * a[-1 1 3] * b[3 2 -4]
197+
if isdual(space(a, 2))
198+
@tensor a2b2[-1 -2; -3 -4] := gate[1 2; -2 -3] * a[-1 1 3] * b[3 2 -4]
199+
else
200+
@tensor a2b2[-1 -2; -3 -4] := gate[-2 -3; 1 2] * a[-1 1 3] * b[3 2 -4]
201+
end
143202
trunc = (trscheme isa FixedSpaceTruncation) ? truncspace(V) : trscheme
144203
a, s, b, ϵ = tsvd!(a2b2; trunc, alg = TensorKit.SVD())
145204
a, b = absorb_s(a, s, b)

0 commit comments

Comments
 (0)