Strange inconsistency in free fermion benchmark

+1 vote

Hi, I was trying to use a 4-site free fermion chain with PBC to do benchmark. From the tight-binding model, we know that for a single fermion, the GS energy is -2, and for 2 femrions, it's also -2, because the next unoccupied level is 0 in energy for this 4-site problem.

Firstly I tried directly using the "Fermion" site type provided at https://github.com/ITensor/ITensors.jl/blob/v0.1.41/src/physics/site_types/fermion.jl

Everything is consistent.

Then I tried defining my own site type, the only thing I changed is renaming "Fermion" to "CFermion" (copy paste and rename, that's all). It may sound weird, but the debugging process eventually led me to this trivial step. The one-fermion energy is still correct, but the two-fermion GS energy I got is -2.828..., which is even lower than the exact result.
Here is the structure of my code:

using ITensors

"the copy paste part, but with the renaming"

let
N = 4
numbsweeps = 10
sweeps = Sweeps(numb
sweeps)
maxdim!(sweeps,10,20,100)
cutoff!(sweeps,1e-10)

sites = siteinds("CFermion",N)

# two-particle
states = ["Occ","Occ","Emp","Emp"]

psi0 = productMPS(sites,states)

ampo = AutoMPO()
for j = 1:N-1
ampo += "C",j,"Cdag",j+1
ampo += "C",j+1,"Cdag",j
end
ampo += "C",N,"Cdag",1
ampo += "C",1,"Cdag",N
H = MPO(ampo,sites)

energy,psi = dmrg(H,psi0,sweeps)

return


end

Thanks a lot for your help.
-Mason

+1 vote
selected by

Hi Mason,
Thanks for the question. I tried your code and made a "CFermion" site type, but then I consistently got the answer -2.0 which I take it is the correct answer.

My steps to make the "CFermion" site type were:
1. copy-paste the entire src/physics/sitetypes/fermion.jl file into a file cfermion.jl
2. replace all instances of the string "Fermion" with the string "CFermion"
3. put the following at the top to make the code run outside the ITensors module:
using ITensors
import ITensors: space, op, op!, has
fermionstring, ValName, OpName, @ValNamestr, @OpNamestr, @SiteT
ype
str, state
(the better practice I think is to put ITensors. in front of each method, so like ITensors.space, ITensors.op etc. when it's outside of the module, so my approach above is sort of a lazy thing)

Then I did import("cfermion.jl") into your code, and it ran and gave the answer -2 each time.

Hope that helps you to see what may be different about your code. Also I am using the latest "main" branch of the library, so at least version 0.2.3 plus a few recent other changes (which shouldn't affect this code, ideally).

Best,
Miles

commented by (700 points)
Thanks a lot for your answer Miles. It turns out that it's the 3rd step that I was missing. Now everything works out fine. I guess for the default "Fermion" site type in ITensor, the 3rd step has been taken care of, so no need to add the 'ITensors.' part, but for my standalone new site type I need to add that explicitly.
commented by (64.7k points)
Correct - you know that’s good feedback about how the code in the included site types can’t just be copy-pasted outside the library. Maybe we should write it there in a way that is identical to what users would need to write in order to make that code more useful as an example or as a starting point. I’ll think about maybe doing that!
commented by (700 points)
That would be awesome! Thanks!
commented by (64.7k points)
We filed an issue to discuss the best way to make this change:
https://github.com/ITensor/ITensors.jl/issues/703