Skip to content

Commit 2a7856c

Browse files
authored
IDMRG updates (#294)
Improvements and changes to more easily extend IDMRG methods for `approximate`, `leading_boundary` and `find_groundstate`, with arbitrary number of physical legs.
1 parent 7e0ecfe commit 2a7856c

File tree

11 files changed

+306
-49
lines changed

11 files changed

+306
-49
lines changed

src/MPSKit.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ include("algorithms/statmech/leading_boundary.jl")
173173
include("algorithms/statmech/vumps.jl")
174174
include("algorithms/statmech/vomps.jl")
175175
include("algorithms/statmech/gradient_grassmann.jl")
176+
include("algorithms/statmech/idmrg.jl")
176177

177178
include("algorithms/fidelity_susceptibility.jl")
178179

src/algorithms/approximate/idmrg.jl

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function approximate!(ψ::MultilineMPS, toapprox::Tuple{<:MultilineMPO,<:Multili
2121
end
2222

2323
# right to left sweep
24-
for col in size(ψ, 2):-1:1
24+
for col in reverse(1:size(ψ, 2))
2525
for row in 1:size(ψ, 1)
2626
ψ.AC[row + 1, col] = AC_projection(CartesianIndex(row, col),
2727
ψ, toapprox, envs)
@@ -71,38 +71,42 @@ function approximate!(ψ::MultilineMPS, toapprox::Tuple{<:MultilineMPO,<:Multili
7171
C_current = ψ.C[:, 0]
7272

7373
# sweep from left to right
74-
for col in 1:size(ψ, 2)
74+
for site in 1:size(ψ, 2)
7575
for row in 1:size(ψ, 1)
76-
AC2′ = AC2_projection(CartesianIndex(row, col), ψ, toapprox, envs)
76+
AC2′ = AC2_projection(CartesianIndex(row, site), ψ, toapprox, envs;
77+
kind=:ACAR)
7778
al, c, ar, = tsvd!(AC2′; trunc=alg.trscheme, alg=alg.alg_svd)
7879
normalize!(c)
7980

80-
ψ.AL[row + 1, col] = al
81-
ψ.C[row + 1, col] = complex(c)
82-
ψ.AR[row + 1, col + 1] = _transpose_front(ar)
83-
ψ.AC[row + 1, col + 1] = _transpose_front(c * ar)
81+
ψ.AL[row + 1, site] = al
82+
ψ.C[row + 1, site] = complex(c)
83+
ψ.AR[row + 1, site + 1] = _transpose_front(ar)
84+
ψ.AC[row + 1, site + 1] = _transpose_front(c * ar)
8485
end
85-
transfer_leftenv!(envs, ψ, toapprox, col + 1)
86-
transfer_rightenv!(envs, ψ, toapprox, col)
86+
87+
transfer_leftenv!(envs, ψ, toapprox, site + 1)
88+
transfer_rightenv!(envs, ψ, toapprox, site)
8789
end
90+
8891
normalize!(envs, ψ, toapprox)
8992

9093
# sweep from right to left
91-
for col in (size(ψ, 2) - 1):-1:0
94+
for site in reverse(0:(size(ψ, 2) - 1))
9295
for row in 1:size(ψ, 1)
93-
# TODO: also write this as AC2_projection?
94-
AC2 = ϕ.AL[row, col] * _transpose_tail.AC[row, col + 1])
95-
AC2′ = AC2_hamiltonian(CartesianIndex(row, col), ψ, O, ϕ, envs) * AC2
96+
AC2′ = AC2_projection(CartesianIndex(row, site), ψ, toapprox, envs;
97+
kind=:ALAC)
9698
al, c, ar, = tsvd!(AC2′; trunc=alg.trscheme, alg=alg.alg_svd)
9799
normalize!(c)
98100

99-
ψ.AL[row + 1, col] = al
100-
ψ.C[row + 1, col] = complex(c)
101-
ψ.AR[row + 1, col + 1] = _transpose_front(ar)
101+
ψ.AL[row + 1, site] = al
102+
ψ.C[row + 1, site] = complex(c)
103+
ψ.AR[row + 1, site + 1] = _transpose_front(ar)
102104
end
103-
transfer_leftenv!(envs, ψ, toapprox, col + 1)
104-
transfer_rightenv!(envs, ψ, toapprox, col)
105+
106+
transfer_leftenv!(envs, ψ, toapprox, site + 1)
107+
transfer_rightenv!(envs, ψ, toapprox, site)
105108
end
109+
106110
normalize!(envs, ψ, toapprox)
107111

108112
# update error
@@ -127,7 +131,7 @@ function approximate!(ψ::MultilineMPS, toapprox::Tuple{<:MultilineMPO,<:Multili
127131

128132
# TODO: immediately compute in-place
129133
alg_gauge = updatetol(alg.alg_gauge, iter, ϵ)
130-
ψ′ = MultilineMPS(map(x -> x, ψ.AR); alg_gauge.tol, alg_gauge.maxiter)
134+
ψ′ = MultilineMPS(map(identity, ψ.AR); alg_gauge.tol, alg_gauge.maxiter)
131135
copy!(ψ, ψ′) # ensure output destination is unchanged
132136

133137
recalculate!(envs, ψ, toapprox)

src/algorithms/derivatives/derivatives.jl

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -164,20 +164,21 @@ for kind in (:C, :AC, :AC2)
164164
projection = Symbol(kind, "_projection")
165165
hamiltonian = Symbol(kind, "_hamiltonian")
166166

167-
@eval function $projection(site, below, above::Tuple, envs)
168-
return $projection(site, below, above..., envs)
167+
@eval function $projection(site, below, above::Tuple, envs; kwargs...)
168+
return $projection(site, below, above..., envs; kwargs...)
169169
end
170-
@eval function $projection(site, below, above::AbstractMPS, envs)
171-
return $projection(site, below, nothing, above, envs)
170+
@eval function $projection(site, below, above::AbstractMPS, envs; kwargs...)
171+
return $projection(site, below, nothing, above, envs; kwargs...)
172172
end
173173
@eval function $projection(site::CartesianIndex{2}, below::MultilineMPS, operator,
174-
above::MultilineMPS, envs)
174+
above::MultilineMPS, envs; kwargs...)
175175
row, col = Tuple(site)
176-
return $projection(col, below[row + 1], operator[row], above[row], envs[row])
176+
return $projection(col, below[row + 1], operator[row], above[row], envs[row];
177+
kwargs...)
177178
end
178-
@eval function $projection(site, below, above::LazySum, envs)
179+
@eval function $projection(site, below, above::LazySum, envs; kwargs...)
179180
return sum(zip(above.ops, envs.envs)) do x
180-
return $projection(site, below, x...)
181+
return $projection(site, below, x...; kwargs...)
181182
end
182183
end
183184
end
@@ -187,9 +188,8 @@ end
187188
function AC_projection(site, below, operator, above, envs)
188189
return AC_hamiltonian(site, below, operator, above, envs) * above.AC[site]
189190
end
190-
function AC2_projection(site::Int, below, operator, above, envs)
191-
AC2 = above.AC[site] * _transpose_tail(above.AR[site + 1])
192-
return AC2_hamiltonian(site, below, operator, above, envs) * AC2
191+
function AC2_projection(site::Int, below, operator, above, envs; kwargs...)
192+
return AC2_hamiltonian(site, below, operator, above, envs) * AC2(above, site; kwargs...)
193193
end
194194

195195
# Multiline

src/algorithms/groundstate/idmrg.jl

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@ function find_groundstate(ost::InfiniteMPS, H, alg::IDMRG, envs=environments(ost
4040
for pos in 1:length(ψ)
4141
h = AC_hamiltonian(pos, ψ, H, ψ, envs)
4242
_, ψ.AC[pos] = fixedpoint(h, ψ.AC[pos], :SR, alg_eigsolve)
43-
ψ.AL[pos], ψ.C[pos] = leftorth!.AC[pos])
43+
if pos == length(ψ)
44+
# AC needed in next sweep
45+
ψ.AL[pos], ψ.C[pos] = leftorth.AC[pos])
46+
else
47+
ψ.AL[pos], ψ.C[pos] = leftorth!.AC[pos])
48+
end
4449
transfer_leftenv!(envs, ψ, H, ψ, pos + 1)
4550
end
4651

@@ -124,7 +129,7 @@ function find_groundstate(ost::InfiniteMPS, H, alg::IDMRG2, envs=environments(os
124129

125130
# sweep from left to right
126131
for pos in 1:(length(ψ) - 1)
127-
ac2 = ψ.AC[pos] * _transpose_tail.AR[pos + 1])
132+
ac2 = AC2(ψ, pos; kind=:ACAR)
128133
h_ac2 = AC2_hamiltonian(pos, ψ, H, ψ, envs)
129134
_, ac2′ = fixedpoint(h_ac2, ac2, :SR, alg_eigsolve)
130135

@@ -141,20 +146,22 @@ function find_groundstate(ost::InfiniteMPS, H, alg::IDMRG2, envs=environments(os
141146
end
142147

143148
# update the edge
144-
@plansor ac2[-1 -2; -3 -4] := ψ.AC[end][-1 -2; 1] * inv.C[0])[1; 2] *
145-
ψ.AL[1][2 -4; 3] * ψ.C[1][3; -3]
149+
ψ.AL[end] = ψ.AC[end] / ψ.C[end]
150+
ψ.AC[1] = _mul_tail.AL[1], ψ.C[1])
151+
ac2 = AC2(ψ, 0; kind=:ALAC)
146152
h_ac2 = AC2_hamiltonian(0, ψ, H, ψ, envs)
147153
_, ac2′ = fixedpoint(h_ac2, ac2, :SR, alg_eigsolve)
148154

149155
al, c, ar, = tsvd!(ac2′; trunc=alg.trscheme, alg=alg.alg_svd)
150156
normalize!(c)
151157

152-
ψ.AC[end] = al * c
153158
ψ.AL[end] = al
154159
ψ.C[end] = complex(c)
155160
ψ.AR[1] = _transpose_front(ar)
161+
162+
ψ.AC[end] = _mul_tail(al, c)
156163
ψ.AC[1] = _transpose_front(c * ar)
157-
ψ.AL[1] = ψ.AC[1] * inv(ψ.C[1])
164+
ψ.AL[1] = ψ.AC[1] / ψ.C[1]
158165

159166
C_current = complex(c)
160167

@@ -164,15 +171,15 @@ function find_groundstate(ost::InfiniteMPS, H, alg::IDMRG2, envs=environments(os
164171

165172
# sweep from right to left
166173
for pos in (length(ψ) - 1):-1:1
167-
ac2 = ψ.AL[pos] * _transpose_tail.AC[pos + 1])
174+
ac2 = AC2(ψ, pos; kind=:ALAC)
168175
h_ac2 = AC2_hamiltonian(pos, ψ, H, ψ, envs)
169176
_, ac2′ = fixedpoint(h_ac2, ac2, :SR, alg_eigsolve)
170177

171178
al, c, ar, = tsvd!(ac2′; trunc=alg.trscheme, alg=alg.alg_svd)
172179
normalize!(c)
173180

174181
ψ.AL[pos] = al
175-
ψ.AC[pos] = al * c
182+
ψ.AC[pos] = _mul_tail(al, c)
176183
ψ.C[pos] = complex(c)
177184
ψ.AR[pos + 1] = _transpose_front(ar)
178185
ψ.AC[pos + 1] = _transpose_front(c * ar)
@@ -182,17 +189,19 @@ function find_groundstate(ost::InfiniteMPS, H, alg::IDMRG2, envs=environments(os
182189
end
183190

184191
# update the edge
185-
@plansor ac2[-1 -2; -3 -4] := ψ.C[end - 1][-1; 1] * ψ.AR[end][1 -2; 2] *
186-
inv.C[end])[2; 3] * ψ.AC[1][3 -4; -3]
192+
ψ.AC[end] = _mul_front.C[end - 1], ψ.AR[end])
193+
ψ.AR[1] = _transpose_front.C[end] \ _transpose_tail.AC[1]))
194+
ac2 = AC2(ψ, 0; kind=:ACAR)
187195
h_ac2 = AC2_hamiltonian(0, ψ, H, ψ, envs)
188196
_, ac2′ = fixedpoint(h_ac2, ac2, :SR, alg_eigsolve)
189197
al, c, ar, = tsvd!(ac2′; trunc=alg.trscheme, alg=alg.alg_svd)
190198
normalize!(c)
191199

192-
ψ.AR[end] = _transpose_front(inv.C[end - 1]) * _transpose_tail(al * c))
193200
ψ.AL[end] = al
194201
ψ.C[end] = complex(c)
195202
ψ.AR[1] = _transpose_front(ar)
203+
204+
ψ.AR[end] = _transpose_front.C[end - 1] \ _transpose_tail(al * c))
196205
ψ.AC[1] = _transpose_front(c * ar)
197206

198207
transfer_leftenv!(envs, ψ, H, ψ, 1)

0 commit comments

Comments
 (0)