Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Start simplifying the necessary OpSum definitions for Models #63

Merged
merged 35 commits into from
Aug 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
fbf3e22
Start simplifying the necessary OpSum definitions for Models
mtfishman Jun 15, 2022
3df8da3
Merge main, fix conflicts
mtfishman Jun 21, 2022
712c9fb
Format
mtfishman Jun 21, 2022
469b8e1
Fix finite to infinite MPS conversion
mtfishman Jun 21, 2022
b2b43ba
New interface for models in terms of unit_cell_terms, defining the te…
mtfishman Jun 22, 2022
b89c072
Rewrite models in terms of new interface
mtfishman Jun 22, 2022
5551250
Replace broken subtraction in OpSum with addition
mtfishman Jun 22, 2022
0e409bf
Start testing examples
mtfishman Jun 23, 2022
e111000
Update examples/vumps/transfer_matrix_spectrum.jl
mtfishman Jun 23, 2022
73ea449
Update src/abstractinfinitemps.jl
mtfishman Jun 23, 2022
f80abc2
Fix path in examples
mtfishman Jun 23, 2022
e1ec11a
Move some old examples to development directory
mtfishman Jun 23, 2022
0637def
Start simplifying interface for defining site indices
mtfishman Jun 23, 2022
a974f02
Update examples for simpler interface
mtfishman Jun 23, 2022
6ae2e23
Continue updating tests for new interface
mtfishman Jun 23, 2022
1186278
Format
mtfishman Jun 23, 2022
82b23c4
Fix more tests
mtfishman Jun 23, 2022
3f98fbc
Clean up tests
mtfishman Jun 23, 2022
a145680
Small test fix
mtfishman Jun 23, 2022
847ac33
Fix Hubbard example, fix more tests
mtfishman Jun 23, 2022
9cfd0d3
Update FQHE example for new interface
mtfishman Jun 23, 2022
f4451e7
Update test/test_vumpsmpo_fqhe.jl
mtfishman Jun 23, 2022
24663c3
Format and clean up code
mtfishman Jun 23, 2022
e4cbe22
Merge branch 'simplify_models' of github.com:mtfishman/ITensorsInfini…
mtfishman Jun 23, 2022
d30675d
Default to V=0 for Hubbard model
mtfishman Jun 24, 2022
baea006
Start updating development examples
mtfishman Jun 27, 2022
742a5aa
Update directsum for latest ITensors interface
mtfishman Jul 15, 2022
275ea00
Update examples/vumps/transfer_matrix_spectrum.jl
mtfishman Jul 15, 2022
1ae9ed4
Update examples/vumps/vumps_heisenberg.jl
mtfishman Jul 15, 2022
b03215c
Format
mtfishman Jul 15, 2022
6221209
Merge branch 'simplify_models' of github.com:mtfishman/ITensorsInfini…
mtfishman Jul 15, 2022
ab7f0cd
Fix examples. Simplify overload requirements for new models
mtfishman Aug 16, 2022
6fa08e1
Format
mtfishman Aug 16, 2022
a6b7279
Fix test
mtfishman Aug 16, 2022
11ce0f8
Clean up code a bit with SplitApplyCombine
mtfishman Aug 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,19 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66"

[compat]
Compat = "3, 4"
HDF5 = "0.15, 0.16"
ITensors = "0.3"
ITensors = "0.3.18"
Infinities = "0.1"
IterTools = "1"
KrylovKit = "0.5"
OffsetArrays = "1"
QuadGK = "2"
Requires = "1"
SplitApplyCombine = "1.2.2"
julia = "1.6"

[extras]
Expand Down
63 changes: 63 additions & 0 deletions examples/development/finite_mps_to_infinite_mps.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using ITensors
using ITensorInfiniteMPS

# H = -J Σⱼ XⱼXⱼ₊₁ - h Σⱼ Zⱼ
function ising_opsum_infinite(N; J, h)
os = OpSum()
for n in 1:N
os -= J, "X", n, "X", n + 1
end
for n in 1:N
os -= h, "Z", n
end
return os
end

function ising_opsum_finite(N; J, h)
return ising_opsum_infinite(N - 1; J, h) + (-h, "Z", N)
end

function main(; N, J, h, nsites)
s = siteinds("S=1/2", N)

H = MPO(ising_opsum_finite(N; J=J, h=h), s)
ψ0 = randomMPS(s)

energy, ψ = dmrg(H, ψ0; nsweeps=10, cutoff=1e-10)
@show energy / N

n1 = N ÷ 2
n2 = n1 + 1

ψ = orthogonalize(ψ, n1)

println("\nFinite MPS energy on bond (n1, n2) = $((n1, n2))")

ϕ12 = ψ[n1] * ψ[n2]
ham12 = contract(MPO(ising_opsum_infinite(1; J=J, h=h), [s[n1], s[n2]]))
@show inner(ϕ12, apply(ham12, ϕ12))

# Get an infinite MPS that approximates
# the finite MPS in the bulk.
# `nsites` sets the number of sites in the unit
# cell of the infinite MPS.
ψ∞ = infinitemps_approx(ψ; nsites=nsites, nsweeps=10)

println("\nInfinite MPS energy on a few different bonds")
println("Infinite MPS has unit cell of size $nsites")

# Compute a few energies
for n1 in 1:3
n2 = n1 + 1
@show n1, n2
ϕ12 = ψ∞.AL[n1] * ψ∞.AL[n2] * ψ∞.C[n2]
s1 = siteind(ψ∞, n1)
s2 = siteind(ψ∞, n2)
ham12 = contract(MPO(ising_opsum_infinite(1; J=J, h=h), [s1, s2]))
@show inner(ϕ12, apply(ham12, ϕ12)) / norm(ϕ12)
end

return nothing
end

main(; N=100, J=1.0, h=1.5, nsites=1)
19 changes: 19 additions & 0 deletions examples/development/orthogonalize_infinitemps.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using ITensors
using ITensorInfiniteMPS
using Random

Random.seed!(1234)

# n-site unit cell
nsites = 4
s = siteinds("S=1/2", nsites; conserve_szparity=true)
χ = 10
@assert iseven(χ)
space = (("SzParity", 1, 2) => χ ÷ 2) ⊕ (("SzParity", 0, 2) => χ ÷ 2)
ψ = InfiniteMPS(ComplexF64, s; space=space)
for n in 1:nsites
ψ[n] = randomITensor(inds(ψ[n]))
end

ψ = orthogonalize(ψ, :)
@show norm(contract(ψ.AL[1:nsites]) * ψ.C[nsites] - ψ.C[0] * contract(ψ.AR[1:nsites]))
193 changes: 193 additions & 0 deletions examples/development/vumps/transfer_matrix_spectrum_arpack.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
using ITensors
using ITensorInfiniteMPS

##############################################################################
# VUMPS parameters
#

maxdim = 10 # Maximum bond dimension
cutoff = 1e-6 # Singular value cutoff when increasing the bond dimension
max_vumps_iters = 20 # Maximum number of iterations of the VUMPS algorithm at a fixed bond dimension
tol = 1e-5 # Precision error tolerance for outer loop of VUMPS or TDVP
outer_iters = 5 # Number of times to increase the bond dimension
time_step = -Inf # -Inf corresponds to VUMPS
solver_tol = (x -> x / 100) # Tolerance for the local solver (eigsolve in VUMPS and exponentiate in TDVP)
multisite_update_alg = "parallel" # Choose between ["sequential", "parallel"]
conserve_qns = false
N = 2 # Number of sites in the unit cell (1 site unit cell is currently broken)

# Parameters of the transverse field Ising model
model_params = (J=1.0, h=0.9)

##############################################################################
# CODE BELOW HERE DOES NOT NEED TO BE MODIFIED
#

model = Model("ising")

initstate(n) = "↑"
s = infsiteinds("S=1/2", N; initstate, conserve_szparity=conserve_qns)
ψ = InfMPS(s, initstate)

# Form the Hamiltonian
H = InfiniteSum{MPO}(model, s; model_params...)

# Check translational invariance
@show norm(contract(ψ.AL[1:N]..., ψ.C[N]) - contract(ψ.C[0], ψ.AR[1:N]...))

vumps_kwargs = (
tol=tol,
maxiter=max_vumps_iters,
solver_tol=solver_tol,
multisite_update_alg=multisite_update_alg,
)
subspace_expansion_kwargs = (cutoff=cutoff, maxdim=maxdim)
#ψ = tdvp(H, ψ; time_step=time_step, vumps_kwargs...)

# Alternate steps of running VUMPS and increasing the bond dimension
@time for _ in 1:outer_iters
println("\nIncrease bond dimension")
global ψ = subspace_expansion(ψ, H; subspace_expansion_kwargs...)
println("Run VUMPS with new bond dimension")
global ψ = tdvp(H, ψ; time_step=time_step, vumps_kwargs...)
end

# Check translational invariance
@show norm(contract(ψ.AL[1:N]..., ψ.C[N]) - contract(ψ.C[0], ψ.AR[1:N]...))

#
# Compare to DMRG
#

Nfinite = 100
sfinite = siteinds("S=1/2", Nfinite; conserve_szparity=true)
Hfinite = MPO(model, sfinite; model_params...)
ψfinite = randomMPS(sfinite, initstate)
@show flux(ψfinite)
sweeps = Sweeps(10)
setmaxdim!(sweeps, maxdim)
setcutoff!(sweeps, cutoff)
energy_finite_total, ψfinite = @time dmrg(Hfinite, ψfinite, sweeps)
@show energy_finite_total / Nfinite

function energy_local(ψ1, ψ2, h)
ϕ = ψ1 * ψ2
return (noprime(ϕ * h) * dag(ϕ))[]
end

function ITensors.expect(ψ, o)
return (noprime(ψ * op(o, filterinds(ψ, "Site")...)) * dag(ψ))[]
end

# Exact energy at criticality: 4/pi = 1.2732395447351628

nfinite = Nfinite ÷ 2
orthogonalize!(ψfinite, nfinite)
hnfinite = ITensor(model, sfinite[nfinite], sfinite[nfinite + 1]; model_params...)
energy_finite = energy_local(ψfinite[nfinite], ψfinite[nfinite + 1], hnfinite)
energy_infinite = energy_local(ψ.AL[1], ψ.AL[2] * ψ.C[2], contract(H[(1, 2)]))
@show energy_finite, energy_infinite
@show abs(energy_finite - energy_infinite)

energy_exact = reference(model, Observable("energy"); model_params...)
@show energy_exact

Sz1_finite = expect(ψfinite[nfinite], "Sz")
orthogonalize!(ψfinite, nfinite + 1)
Sz2_finite = expect(ψfinite[nfinite + 1], "Sz")
Sz1_infinite = expect(ψ.AL[1] * ψ.C[1], "Sz")
Sz2_infinite = expect(ψ.AL[2] * ψ.C[2], "Sz")

@show Sz1_finite, Sz2_finite
@show Sz1_infinite, Sz2_infinite

##############################################################################
# Compute eigenspace of the transfer matrix
#

using Arpack
using KrylovKit: eigsolve
using LinearAlgebra

T = TransferMatrix(ψ.AL)
Tᵀ = transpose(T)
vⁱᴿ = randomITensor(dag(input_inds(T)))
vⁱᴸ = randomITensor(dag(input_inds(Tᵀ)))

neigs = 10
tol = 1e-10
λ⃗ᴿ, v⃗ᴿ, right_info = eigsolve(T, vⁱᴿ, neigs, :LM; tol=tol)
λ⃗ᴸ, v⃗ᴸ, left_info = eigsolve(Tᵀ, vⁱᴸ, neigs, :LM; tol=tol)

@show norm(T(v⃗ᴿ[1]) - λ⃗ᴿ[1] * v⃗ᴿ[1])
@show norm(Tᵀ(v⃗ᴸ[1]) - λ⃗ᴸ[1] * v⃗ᴸ[1])

@show λ⃗ᴿ
@show λ⃗ᴸ
@show flux.(v⃗ᴿ)

neigs = min(length(v⃗ᴸ), length(v⃗ᴿ))
v⃗ᴸ = v⃗ᴸ[1:neigs]
v⃗ᴿ = v⃗ᴿ[1:neigs]

# Normalize the vectors
N⃗ = [(translatecelltags(v⃗ᴸ[n], 1) * v⃗ᴿ[n])[] for n in 1:neigs]

v⃗ᴿ ./= sqrt.(N⃗)
v⃗ᴸ ./= sqrt.(N⃗)

# Form a second starting vector orthogonal to v⃗ᴿ[1]
# This doesn't work. TODO: project out v⃗ᴿ[1], v⃗ᴸ[1] from T
#λ⃗ᴿ², v⃗ᴿ², right_info_2 = eigsolve(T, vⁱᴿ², neigs, :LM; tol=tol)

# Projector onto the n-th eigenstate
function proj(v⃗ᴸ, v⃗ᴿ, n)
Lⁿ = v⃗ᴸ[n]
Rⁿ = v⃗ᴿ[n]
return ITensorMap(
[translatecelltags(Lⁿ, 1), translatecelltags(Rⁿ, -1)];
input_inds=inds(Rⁿ),
output_inds=inds(Lⁿ),
)
end

P⃗ = [proj(v⃗ᴸ, v⃗ᴿ, n) for n in 1:neigs]
T⁻P = T - sum(P⃗)

#vⁱᴿ² = vⁱᴿ - (translatecelltags(v⃗ᴸ[1], 1) * vⁱᴿ)[] / norm(v⃗ᴿ[1]) * v⃗ᴿ[1]
#@show norm(dag(vⁱᴿ²) * v⃗ᴿ[1])

# XXX: Error with mismatched QN index arrows
# λ⃗ᴾᴿ, v⃗ᴾᴿ, right_info = eigsolve(T⁻P, vⁱᴿ, neigs, :LM; tol=tol)
# @show λ⃗ᴾᴿ

vⁱᴿ⁻ᵈᵃᵗᵃ = vec(array(vⁱᴿ))
λ⃗ᴿᴬ, v⃗ᴿ⁻ᵈᵃᵗᵃ = Arpack.eigs(T; v0=vⁱᴿ⁻ᵈᵃᵗᵃ, nev=neigs)

## XXX: this is giving an error about trying to set the element of the wrong QN block for:
## maxdim = 5
## cutoff = 1e-12
## max_vumps_iters = 10
## outer_iters = 10
## model_params = (J=1.0, h=0.8)
##
## v⃗ᴿᴬ = [itensor(v⃗ᴿ⁻ᵈᵃᵗᵃ[:, n], input_inds(T); tol=1e-4) for n in 1:length(λ⃗ᴿᴬ)]
## @show flux.(v⃗ᴿᴬ)

@show λ⃗ᴿᴬ

# Full eigendecomposition

Tfull = prod(T)
DV = eigen(Tfull, input_inds(T), output_inds(T))

@show norm(Tfull * DV.V - DV.Vt * DV.D)

d = diag(array(DV.D))

p = sortperm(d; by=abs, rev=true)
@show p[1:neigs]
@show d[p[1:neigs]]

println("Error if ED with Arpack")
@show d[p[1:neigs]] - λ⃗ᴿᴬ
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,8 @@ N = 2# Number of sites in the unit cell
J = 1.0
h = 1.0;

function space_shifted(q̃sz)
return [QN("SzParity", 1 - q̃sz, 2) => 1, QN("SzParity", 0 - q̃sz, 2) => 1]
end

space_ = fill(space_shifted(1), N);
s = infsiteinds("S=1/2", N; space=space_)
initstate(n) = "↑"
s = infsiteinds("S=1/2", N; initstate)
ψ = InfMPS(s, initstate);

model = Model("ising");
Expand Down Expand Up @@ -70,7 +65,7 @@ Sz_finite = expect(ψfinite, "Sz")[nfinite:(nfinite + N - 1)]
@show (
energy_infinite,
energy_finite_total / Nfinite,
reference(model, Observable("energy"); J=J, h=h, J₂=J₂),
reference(model, Observable("energy"); J=J, h=h),
)

@show (Sz, Sz_finite)
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ using Random

Random.seed!(1234)

include("models.jl")

function _siteind(site_tag, n::Int; space)
return addtags(Index(space, "Site,n=$n"), site_tag)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,30 @@ maxiter = 20
outer_iters = 3

N = 2
model = Model"ising"()
model = Model("ising")

function space_shifted(::Model"ising", q̃sz)
return [QN("SzParity", 1 - q̃sz, 2) => 1, QN("SzParity", 0 - q̃sz, 2) => 1]
end

space_ = fill(space_shifted(model, 1), N)
s = infsiteinds("S=1/2", N; space=space_)
initstate(n) = "↑"
s = infsiteinds("S=1/2", N; initstate)
ψ = InfMPS(s, initstate)

model_params = (J=-1.0, h=0.9)
vumps_kwargs = (multisite_update_alg="sequential", tol=tol, maxiter=maxiter)
subspace_expansion_kwargs = (cutoff=cutoff, maxdim=maxdim)

H = InfiniteITensorSum(model, s; model_params...)
H = InfiniteSum{ITensor}(model, s; model_params...)
# Alternate steps of running VUMPS and increasing the bond dimension
ψ1 = vumps(H, ψ; vumps_kwargs...)
for _ in 1:outer_iters
ψ1 = subspace_expansion(ψ1, H; subspace_expansion_kwargs...)
ψ1 = vumps(H, ψ1; vumps_kwargs...)
global ψ1 = subspace_expansion(ψ1, H; subspace_expansion_kwargs...)
global ψ1 = vumps(H, ψ1; vumps_kwargs...)
end

Hmpo = InfiniteMPOMatrix(model, s; model_params...)
# Alternate steps of running VUMPS and increasing the bond dimension
ψ2 = vumps(Hmpo, ψ; vumps_kwargs...)
for _ in 1:outer_iters
ψ2 = subspace_expansion(ψ2, Hmpo; subspace_expansion_kwargs...)
ψ2 = vumps(Hmpo, ψ2; vumps_kwargs...)
global ψ2 = subspace_expansion(ψ2, Hmpo; subspace_expansion_kwargs...)
global ψ2 = vumps(Hmpo, ψ2; vumps_kwargs...)
end

SzSz = prod(op("Sz", s[1]) * op("Sz", s[2]))
Loading