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
movesite
to moves2
tos1+1
, and then calculate the correlation betweens1
ands1+1
. (one can further changes2
to 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