Hi everyone,
I am quite curious about a fact about the function ITensors.ITensorMPS.movesite. I’d like to calculate two-point correlation function between site s1 and s2 in two ways:
- just calculate using
inner - first use
movesiteto moves2tos1+1, and then calculate the correlation betweens1ands1+1. (one can further changes2to arbitrary sites3)
Should the two approaches be equivalent?
Based on my test, for spin system (transversed-field Ising model), the correlations between spin operators are unchanged.
using ITensors, ITensorMPS
function TFIM_MPO(L::Int64, J::Float64, h::Float64)
sites = siteinds("S=1/2",L)
os = OpSum()
for jc ∈ 1:L
# transverse field
os += -2.0*h,"Sz",jc
# Ising interaction
os += -4.0*J,"Sx",jc,"Sx",mod1(jc+1,L)
end
H = MPO(os,sites)
# initialize the MPS
state = [isodd(i) ? "Up" : "Up" for i in 1:L]
psi0 = productMPS(sites, state)
return sites, H, psi0
end
L = 8
J = 1.0
h = 0.5
sites, H, psi0 = TFIM_MPO(L, J, h)
nsweeps = 20
maxdims = [2,2,8,8,20,20,50,50,100,100,200,200,400]
cutoff1 = [1E-13]
noise = [1E-4, 1E-4, 1E-5, 1E-6, 1E-7, 1E-8, 0.0]
energy, psi = dmrg(H,psi0;nsweeps,maxdim=maxdims,cutoff=cutoff1, noise)
## correlation functions under movesite
s1 = 1
s2 = 4
SS = zeros(3)
sites = siteinds(psi)
for (i,comp) in enumerate(["Sx","Sy","Sz"])
SS_os = OpSum()
SS_os += 1,comp,s1,comp,s2
SS_mpo = MPO(SS_os, sites)
SS[i] = inner(psi',SS_mpo,psi)
end
@show SS
psi2 = movesite(psi, s2=>2)
s2 = 2
SS2 = zeros(3)
sites = siteinds(psi2)
for (i,comp) in enumerate(["Sx","Sy","Sz"])
SS_os = OpSum()
SS_os += 1,comp,s1,comp,s2
SS_mpo = MPO(SS_os, sites)
SS2[i] = inner(psi2',SS_mpo,psi2)
end
@show SS2
However, for fermionic system (free fermion), the Green’s functions obtained through the two approaches are different.
using ITensors, ITensorMPS
function free_fermion_MPO(L::Int64, t::Float64, μ::Float64)
sites = siteinds("Fermion",L)
os = OpSum()
for jc ∈ 1:L
# chemical potential
os += -μ, "n", jc
# hopping
os += -t, "c†", jc, "c", mod1(jc+1,L)
os += -t, "c†", mod1(jc+1,L), "c", jc
end
H = MPO(os,sites)
# initialize the MPS
psi0 = random_mps(sites;linkdims=10)
return sites, H, psi0
end
L = 8
t = 1.0
μ = 0.5
sites, H, psi0 = free_fermion_MPO(L, t, μ)
nsweeps = 10
maxdims = [2,2,8,8,20,20,50,50,100,100,200,200,400]
cutoff1 = [1E-10]
noise = [1E-4, 1E-4, 1E-5, 1E-6, 1E-7, 1E-8, 0.0]
energy, psi = dmrg(H,psi0;nsweeps,maxdim=maxdims,cutoff=cutoff1, noise)
## correlation functions under movesite
s1 = 1
s2 = 3
sites = siteinds(psi)
gr_os = OpSum()
gr_os += 1, "c†", s1, "c", s2
gr_mpo = MPO(gr_os, sites)
gr = inner(psi', gr_mpo, psi)
@show gr # -0.125
psi2 = movesite(psi, s2=>2)
s2 = 2
sites = siteinds(psi2)
gr_os = OpSum()
gr_os += 1, "c†", s1, "c", s2
gr_mpo = MPO(gr_os, sites)
gr2 = inner(psi2', gr_mpo, psi2)
@show gr2 # 0.21338834764831804
From my naive perspective and intuition, this does not make sense. So my question is how to understand this behavior. I’m not very familiar with the language of MPS. Any idea would be appreciated!
Fo-Hong