Great question. So the situation with fermions is indeed a bit confusing in ITensor right now. It would be simpler (though harder to use) if you had to do everything by hand, but the current setup is that some things are done automatically for you and others aren’t. The handling of Jordan-Wigner string in particular as well as fermionic swaps is only done automatically for you in three places in the code:
- the AutoMPO / OpSum system
- the
apply
function - the
correlation_matrix
function
In any other place you have to account for minus signs and Jordan-Wigner string yourself. So in your code you need two changes:
- you need to add J-W string to the second terms in your o24_naive and o31_naive operators and also possibly flip some minus signs there
- you need to use the
apply
function when applying these operators (may not strictly be necessary for this case but better to be safe)
So some code that almost gets this right is this:
o24_naive = op("Id", s[2])*op("Id",s[3])*op("Id", s[4]) + op("c†", s[2])*op("F",s[3])*op("c†", s[4]);
o31_naive = op("Id", s[1])*op("Id",s[2])*op("Id", s[3]) + op("c†", s[3])*op("F",s[2])*op("c†", s[1])
ψ_naive = apply([o31_naive, o24_naive], ψ0)
I say almost because I’m getting some sign flips from the correct correlation matrix, so I think there may be an extra minus sign needed in one or both definitions of o24_naive and o31_naive, when you go through the Jordan-Wigner mapping correctly.
Finally, the auto fermion system isn’t ready to use yet, and is only in the code right now as a developer-level feature for us to keep testing it out. I wish it was ready sooner but there are some conceptual issues I’m still working through!