About measuring entropy

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.

3 Likes

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!!

Could you share a minimal runnable example that reproduces that error, along with the version of ITensors.jl you are using when you get that error?

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?

1 Like

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…

You seem to be looping over 1:N-1 in the more recent post but you were looping over 2:N-1 in the first post.

1 Like

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!!

Probably we should have a better error message for that issue.

Also it may work for b == 1 if you write it as:

        U,S,V = svd(psi[b], (linkinds(psi, b-1)..., siteinds(psi,b)...))

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?