Dear there,
I have a small confusion about bond index when measuring von Neumann entanglement entropy for a 4-leg cylinder. I find a piece of code measuring entropy for a 1D chain with N sites in an early post:
function entropyvonneumann(psi::MPS, N::Int)
s = siteinds(psi)
SvN = fill(0.0, N)
for b in 2:N-1
orthogonalize!(psi, b)
U,S,V = svd(psi[b], (linkind(psi, b-1), siteind(psi,b)))
for n in 1:dim(S, 1)
p = S[n,n]^2
SvN[b] -= p * log(p)
end
println("$(SvN[b])")
end
return SvN
end
I just wonder, for a cylinder system, say if I use the following site index, then does SvN[b] for b=2: (4*L)-1 corresponding to following cuts labelling? (by cuts I mean e.g. SvN[b=5] is the entropy between the left 1~4 sites and the remaining system, if I understand correctly)
Look forward to your reply! Thanks in advance!
Yes, your understanding is correct, if that is the numbering of the sites and how they map to the two-dimensional system.
If you are still wanting to be totally sure, you could try some tests like setting all of the interaction terms connecting sites 1-4 to the other sites to zero. Then the entanglement across bond 5 of the MPS should become zero. Or you could turn off all of the vertical Hamiltonian terms then the entropy should be the sum of the entropies of one-dimensional chains cutting each one on the first bond.
Dear Miles,
I’ve a quick related question about this topic. I’m also using this same piece of code to calculate entropy, and it works perfectly fine before, but recently when I run this piece of code again, it shows an error said:
ERROR: LoadError: MethodError: no method matching _indices(::Tuple{}, ::Nothing)
Closest candidates are:
_indices(::Tuple, ::Tuple) at ~/.julia/packages/ITensors/HjjU3/src/indexset.jl:43
_indices(::Tuple, ::Index) at ~/.julia/packages/ITensors/HjjU3/src/indexset.jl:45
_indices(::Vector, ::Any) at ~/.julia/packages/ITensors/HjjU3/src/indexset.jl:52
From the error message it seems the svd function in U,S,V=svd(...) line has new method structure for indices? May I ask how does it work now?
Thank you so much!!
Yes! Here is my code, basically just use a result.h5 and calculate its entropy:
using ITensors
using HDF5
using DataFrames
import XLSX
function entropy_von_neumann(psi::MPS, N::Int, filename)
SvN = fill(0.0, N)
open(filename,"a") do io
for b in 1:N-1
orthogonalize!(psi, b)
U,S,V = svd(psi[b], (linkind(psi, b-1), siteind(psi,b)))
for n=1:dim(S, 1)
p = S[n,n]^2
SvN[b] -= p * log(p)
end
println("$(SvN[b])")
println(io,"$(SvN[b])")
end
end
return SvN
end
L = 32
N = 4 * L
s = Vector{Index}(undef,4N)
for j=1:4N
s[j] = siteind("Electron";addtags="n=$j",conserve_qns=true)
end
filename="entropy.txt"
f = h5open("result.h5","r")
psi1 = read(f,"PGS",MPS)
close(f)
psi1 = replace_siteinds(psi1,s)
SvN1 = entropy_von_neumann(psi1, N, filename)
And the version of Itensors.jl is v0.3.57.
Thank you so much!
Do you get the error only when you load the MPS from an h5 file? Or do you also get it when you obtain the MPS directly from a brand new DMRG calculation?
I just tried a brand new DMRG calculation and directly measure the entropy, like:
# some simple H, then
energy, psi1 = dmrg(H, psi0, sweeps)
SvN1 = entropy_von_neumann(psi1, N, filename)
and I still got same error:
ERROR: LoadError: MethodError: no method matching _indices(::Tuple{}, ::Nothing)
Closest candidates are:
_indices(::Tuple, ::Tuple) at ~/.julia/packages/ITensors/WMeVS/src/indexset.jl:43
_indices(::Tuple, ::Index) at ~/.julia/packages/ITensors/WMeVS/src/indexset.jl:45
_indices(::Vector, ::Any) at ~/.julia/packages/ITensors/WMeVS/src/indexset.jl:52
although I notice the word “HjjU3” in previous error message changes to “WMeVS” which I don’t really know its meaning…
Oh! yes I miss that point in the original post, I just naively modify it to start from 1…I just change to 2:N-1 and it works! Sorry for my dumb mistake, so sorry. Thank you so much for all the help!!
May I ask why add “…” would make b==1 work? (I don’t see other thing change…)
And would b-1 with b==1, b-1=0 cause any problem? I thought linkindex start from 1 but maybe not?