Skip to content

Commit 6852c0e

Browse files
authored
Optimize subspace expansion for long range interactions (#67)
1 parent db941c6 commit 6852c0e

File tree

4 files changed

+99
-21
lines changed

4 files changed

+99
-21
lines changed

examples/vumps/src/vumps_subspace_expansion.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@ using ITensorInfiniteMPS
66
function tdvp_subspace_expansion(
77
H, ψ; time_step, outer_iters, subspace_expansion_kwargs, vumps_kwargs
88
)
9-
@time for _ in 1:outer_iters
10-
println("\nIncrease bond dimension from $(maxlinkdim(ψ))")
9+
@time for outer_iter in 1:outer_iters
10+
println(
11+
"\nIncrease bond dimension $(outer_iter) out of $(outer_iters), starting from dimension $(maxlinkdim(ψ))",
12+
)
1113
println(
1214
"cutoff = $(subspace_expansion_kwargs[:cutoff]), maxdim = $(subspace_expansion_kwargs[:maxdim])",
1315
)
14-
ψ = subspace_expansion(ψ, H; subspace_expansion_kwargs...)
16+
ψ = @time subspace_expansion(ψ, H; subspace_expansion_kwargs...)
1517
println("\nRun VUMPS with new bond dimension $(maxlinkdim(ψ))")
16-
ψ = tdvp(H, ψ; time_step=time_step, vumps_kwargs...)
18+
ψ = @time tdvp(H, ψ; time_step=time_step, vumps_kwargs...)
1719
end
1820
return ψ
1921
end
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using ITensorInfiniteMPS
2+
using ITensors
3+
4+
include(
5+
joinpath(
6+
pkgdir(ITensorInfiniteMPS), "examples", "vumps", "src", "vumps_subspace_expansion.jl"
7+
),
8+
)
9+
10+
##############################################################################
11+
# VUMPS parameters
12+
#
13+
14+
maxdim = 256 # Maximum bond dimension
15+
cutoff = 1e-6 # Singular value cutoff when increasing the bond dimension
16+
max_vumps_iters = 100 # Maximum number of iterations of the VUMPS algorithm at each bond dimension
17+
vumps_tol = 1e-4
18+
conserve_qns = true
19+
solver_tol = (x -> x / 10)
20+
outer_iters = 10 # Number of times to increase the bond dimension
21+
width = 4
22+
23+
##############################################################################
24+
# CODE BELOW HERE DOES NOT NEED TO BE MODIFIED
25+
#
26+
27+
N = width # Number of sites in the unit cell
28+
29+
initstate(n) = isodd(n) ? "" : ""
30+
s = infsiteinds("S=1/2", N; conserve_qns, initstate)
31+
ψ = InfMPS(s, initstate)
32+
33+
function ITensorInfiniteMPS.unit_cell_terms(::Model"heisenberg2D"; width)
34+
opsum = OpSum()
35+
for i in 1:width
36+
# Vertical
37+
opsum += -0.5, "S+", i, "S-", mod(i + 1, width)
38+
opsum += -0.5, "S-", i, "S+", mod(i + 1, width)
39+
opsum += "Sz", i, "Sz", mod(i + 1, width)
40+
# Horizontal
41+
opsum += -0.5, "S+", i, "S-", i + width
42+
opsum += -0.5, "S-", i, "S+", i + width
43+
opsum += "Sz", i, "Sz", i + width
44+
end
45+
return opsum
46+
end
47+
model = Model("heisenberg2D")
48+
49+
# Form the Hamiltonian
50+
H = InfiniteSum{MPO}(model, s; width)
51+
52+
# Check translational invariance
53+
# println("\nCheck translation invariance of the initial VUMPS state")
54+
# @show norm(contract(ψ.AL[1:N]..., ψ.C[N]) - contract(ψ.C[0], ψ.AR[1:N]...))
55+
56+
vumps_kwargs = (tol=vumps_tol, maxiter=max_vumps_iters, solver_tol)
57+
subspace_expansion_kwargs = (cutoff=cutoff, maxdim=maxdim)
58+
59+
ψ = vumps_subspace_expansion(H, ψ; outer_iters, subspace_expansion_kwargs, vumps_kwargs)
60+
61+
# Check translational invariance
62+
# println()
63+
# println("==============================================================")
64+
# println()
65+
# println("\nCheck translation invariance of the final VUMPS state")
66+
# @show norm(contract(ψ.AL[1:N]..., ψ.C[N]) - contract(ψ.C[0], ψ.AR[1:N]...))
67+
68+
# Sz = [expect(ψ, "Sz", n) for n in 1:N]
69+
70+
energy_infinite = expect(ψ, H)
71+
@show energy_infinite
72+
73+
## using JLD2
74+
## jldsave("infmps.jld2"; ψ)

src/subspace_expansion.jl

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ function generate_twobody_nullspace(
2626
end
2727

2828
if range_H == 2
29-
ψH2 = noprime.AL[n1] * H[n1][1] * H[n1][2] * ψ.C[n1] * ψ.AR[n2])
29+
ψH2 =.AL[n1] * ψ.C[n1] * H[n1][1]) *.AR[n2] * H[n1][2])
30+
ψH2 = noprime(ψH2)
3031
else # Should be a better version now
3132
ψH2 =
32-
H[n1][end] *
33-
.AR[n2 + range_H - 2] * (ψ′.AR[n2 + range_H - 2] * δʳ(n2 + range_H - 2)))
33+
ψ.AR[n2 + range_H - 2] * H[n1][end] * (ψ′.AR[n2 + range_H - 2] * δʳ(n2 + range_H - 2))
3434
common_sites = findsites(ψ, H[(n1, n2)])
3535
idx = length(common_sites) - 1
3636
for j in reverse(1:(range_H - 3))
@@ -56,38 +56,40 @@ function generate_twobody_nullspace(
5656

5757
ψH2 = noprime(ψH2)
5858
for n in 1:(range_H - 2)
59-
temp_H2 = δʳ(n2 + range_H - 2 - n)
59+
temp_H2_right = δʳ(n2 + range_H - 2 - n)
6060
common_sites = findsites(ψ, H[n1 - n])
6161
idx = length(common_sites)
6262
for j in (n2 + range_H - 2 - n):-1:(n2 + 1)
6363
if j == common_sites[idx]
64-
temp_H2 = temp_H2 * ψ.AR[j] * H[n1 - n][idx] * ψ′.AR[j]
64+
temp_H2_right = temp_H2_right * ψ.AR[j] * H[n1 - n][idx] * ψ′.AR[j]
6565
idx -= 1
6666
else
67-
temp_H2 = temp_H2 * ψ.AR[j] * (δˢ(j) * ψ′.AR[j])
67+
temp_H2_right = temp_H2_right * ψ.AR[j] * (δˢ(j) * ψ′.AR[j])
6868
end
6969
end
7070
if common_sites[idx] == n2
71-
temp_H2 = temp_H2 * ψ.AR[n2] * H[n1 - n][idx]
71+
temp_H2_right = temp_H2_right * ψ.AR[n2] * H[n1 - n][idx]
7272
idx -= 1
7373
else
74-
temp_H2 = temp_H2 * ψ.AR[n2] * δˢ(n2)
74+
temp_H2_right = temp_H2_right * ψ.AR[n2] * δˢ(n2)
7575
end
7676
if common_sites[idx] == n1
77-
temp_H2 = temp_H2 *.AL[n1] * ψ.C[n1]) * H[n1 - n][idx]
77+
temp_H2_right = temp_H2_right *.AL[n1] * ψ.C[n1]) * H[n1 - n][idx]
7878
idx -= 1
7979
else
80-
temp_H2 = temp_H2 * ((ψ.AL[n1] * δˢ(n1)) * ψ.C[n1])
80+
temp_H2_right = temp_H2_right * ((ψ.AL[n1] * δˢ(n1)) * ψ.C[n1])
8181
end
82-
for j in 1:n
82+
idx = n - idx + 1
83+
temp_H2_left = δˡ(n1 - n - 1)
84+
for j in reverse(1:n)
8385
if n1 - j == common_sites[idx]
84-
temp_H2 = temp_H2 * ψ.AL[n1 - j] * H[n1 - n][idx] * ψ′.AL[n1 - j]
85-
idx -= 1
86+
temp_H2_left = temp_H2_left * ψ.AL[n1 - j] * H[n1 - n][idx] * ψ′.AL[n1 - j]
87+
idx += 1
8688
else
87-
temp_H2 = temp_H2 *.AL[n1 - j] * δˢ(n1 - j)) * ψ′.AL[n1 - j]
89+
temp_H2_left = temp_H2_left *.AL[n1 - j] * δˢ(n1 - j)) * ψ′.AL[n1 - j]
8890
end
8991
end
90-
ψH2 = ψH2 + noprime(temp_H2 * δˡ(n1 - n - 1))
92+
ψH2 = ψH2 + noprime(temp_H2_left * temp_H2_right)
9193
end
9294
end
9395
return ψH2

src/vumps_generic.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ function tdvp(
172172
flush(stderr)
173173
end
174174
for iter in 1:maxiter
175-
ψ, (eᴸ, eᴿ) = tdvp_iteration(
175+
iteration_time = @elapsed ψ, (eᴸ, eᴿ) = tdvp_iteration(
176176
solver,
177177
∑h,
178178
ψ;
@@ -187,7 +187,7 @@ function tdvp(
187187
maxdimψ = maxlinkdim(ψ[0:(N + 1)])
188188
if outputlevel > 0
189189
println(
190-
"VUMPS iteration $iter (out of maximum $maxiter). Bond dimension = $maxdimψ, energy = $((eᴸ, eᴿ)), ϵᵖʳᵉˢ = $ϵᵖʳᵉˢ, tol = $tol",
190+
"VUMPS iteration $iter (out of maximum $maxiter). Bond dimension = $maxdimψ, energy = $((eᴸ, eᴿ)), ϵᵖʳᵉˢ = $ϵᵖʳᵉˢ, tol = $tol, iteration time = $iteration_time seconds",
191191
)
192192
flush(stdout)
193193
flush(stderr)

0 commit comments

Comments
 (0)