# Misunderstanding about C/A operators in electron model

+1 vote

Hi ITensor Support,

I am trying to construct and extended Hubbard model Hamiltonian with next-nearest-neighbour hopping but I am having some problems with the A/C operators while using the autoMPO functions.

As a minimal example, I have just considered the usual fermion hopping term

$$H = - t_0 \sum_{i, s} c_{i, s}^\dagger c_{i+1,s} + c_{i+1, s}^\dagger c_{i,s}$$

I have represented this three different ways using autoMPO:
-1st I just used the A operators without the Jordan-Wigner F operator (which I know should be wrong!)
-2nd I used the C operators as is standard
-3rd I used the A operators with the Jordan-Wigner F operators (this should be the same as above)

int L = 4;
double t0 = 5;

//Set arguments
auto args = Args("Cutoff=",1E-15,"MaxDim=",5000);

//Initialise System
auto sites = Electron(L, {"ConserveQNs=",false});

// Build Evolution Operators
auto ampo = AutoMPO(sites);
auto ampo2 = AutoMPO(sites);
auto ampo3 = AutoMPO(sites);

//Effective Hamiltonian
//NN Hopping
for(int j = 1; j < L; ++j)
{
int s1 = j;
int s2 = j + 1;
ampo += (-t0) , "Adagup", s1, "Aup", s2;
ampo += (-t0) , "Adagup", s2, "Aup", s1;

ampo2 += (-t0) , "Cdagup", s1, "Cup", s2;
ampo2 += (-t0) , "Cdagup", s2, "Cup", s1;

ampo2 += (-t0) , "Cdagdn", s1, "Cdn", s2;
ampo2 += (-t0) , "Cdagdn", s2, "Cdn", s1;

ampo3 += (-t0) , "Adagup", s1, "F", s1, "Aup", s2;
ampo3 += -(-t0) , "Aup", s1,"F", s1, "Adagup", s2;

}


I then compute the hopping amplitude between a state with a single spin down on the 2nd site and a single spin down on the 3rd site. By hand I get the following results:

$$|\psi_0 \rangle = c_{2, \downarrow}^\dagger |0\rangle, \ |\psi_1 \rangle = c_{3, \downarrow}^\dagger |0\rangle, \ \langle \psi_1 |H|\psi_0 \rangle = -t_0$$

However, performing the same thing in ITensor (with t_0 = 5) using

auto Ham1 = toMPO(ampo, {"ConserveQNs", false});
auto Ham2 = toMPO(ampo2, {"ConserveQNs", false});
auto Ham3 = toMPO(ampo3, {"ConserveQNs", false});
auto states0 = InitState(sites);
states0.set(2, "Dn");
auto psi0 = MPS(states0);
psi0.orthogonalize();
psi0.normalize();

auto states1 = InitState(sites);
states1.set(3, "Dn");

auto psi1 = MPS(states1);
psi1.orthogonalize();
psi1.normalize();

cout << "Initial State Built" << endl;

auto test1 = innerC(psi1, Ham1, psi0);
auto test2 = innerC(psi1, Ham2, psi0);
auto test3 = innerC(psi1, Ham3, psi0);

Print(test1);
Print(test2);
Print(test3);


I get:
test1 = (-5, 0)
test2 = (5, 0)
test3 = (5, 0)

Can you understand why these calculations are not agreeing with the theory? I have also tested these results against some exact diagonalisation calculations which agrees with the theory so I am rather confused. I'm sure I have just misunderstood something. I am hoping that by sorting out this bit I might be able to get my full model working.

Many thanks,
Cameron

commented by (70.1k points)
Thanks for your patience. So this is definitely a bug in the AutoMPO system, and I'm looking into it.

However, for now I can suggest a workaround: the bug above is only happening if you use a site set with all quantum numbers turned off, which we almost never do for fermions. So if it's possible for your problem (and it should be) to conserve at least fermion parity, or parity and spin, or even particle number and spin, then that will fix the problem for now.

Here are some ways of calling the Electron constructor to set different kinds of QN conservation:

// conserve particle number and total Sz
auto sites = Electron(L, {"ConserveQNs=",true});

//conserve just total Sz and fermion parity
auto sites = Electron(L, {"ConserveQNs=",true,"ConserveNf=",false});

//conserve just fermion parity
auto sites = Electron(L, {"ConserveQNs=",true,"ConserveNf=",false,"ConserveSz=",false});

We could definitely improve some of those named arguments and provide combinations which are more clear in the future but all three of those cases above should give correct results from AutoMPO.