Is that possible to use trotter gates to perform a square times of a on-site operator?

Hello everyone!

I’m doing some time-evoving problems with bose-hubbard model.

It’s hamiltonian is presented below which is constructed by nearest-neighbor operators, on-site operators and the square times of on-site operators.

\hat{H}=-j\sum_{i}(\hat{a}_i^{\dagger}\hat{a}_{i+1}+h.c.)+U/2\hat{N}_i^2-U/2\hat{N}_i
hterm = -j*op(sites,"Adag",b)*op(sites,"A",b+1);
hterm += -j*op(sites,"A",b)*op(sites,"Adag",b+1);
hterm += -U/2*op(sites,"N",b)*op(sites,"Id",b+1);

Nearest-neighbor operators and on-site operators are easy to construct, but how to construct the square times of on-site operators?
I have tried the following two ways, but all of them doesn’t work.

hterm += U/2*op(sites,"N",b)*op(sites,"N",b)*op(sites,"Id",b+1)*op(sites,"Id",b+1);

and

hterm += U/2*op(sites,"N",b)*op(sites,"Id",b+1)*op(sites,"N",b)*op(sites,"Id",b+1);

To better understand your question, are you trying to make your Hamiltonian as a single large tensor or as an MPO? If as an MPO, I could suggest a different approach to you that will work a lot better.

Either way, to implement the square of an on-site operator, you can use an operator string with a * in it like "N * N" where you should also put white space around the * symbol.

1 Like

Appreciate for your earlier reply.
Here comes another error, I`m sorry about that.
I did what you suggest.

hterm += U/2*op(sites,"N * N",b)*op(sites,"Id",b+1);

It says " what(): Operator " N" name not recognized"

What should I do when this happens?

Hm, that does seem like a subtle bug. Please try "N*N" to see if that resolves the issue. If not please let me know exactly how you are defining your sites object and I can give it a try. Thanks!

Well, it works. The error mentioned above didn’t occur.
But sadly, I didn’t get some data and there is definitely some mistakes in my codes.
It says “ITensoITensor::operator+=: different index structure”
Does that means the way I construct trotter gates is not correct?
Here is my code:

auto gates = vector<BondGate>();
auto hterm = -j*op(sites,"Adag",1)*op(sites,"A",2);
hterm += -j*op(sites,"A",1)*op(sites,"Adag",2);
hterm += -U/2*op(sites,"N",1)*op(sites,"Id",2);
hterm += U/2*op(sites,"N*N",1)*op(sites,"Id",2);
auto g = BondGate(sites,1,2,BondGate::tReal,tstep/2.,hterm);
gates.push_back(g);

for (int b = 2; b <= L-1; b++)
{
 hterm += U/2*op(sites,"N*N",b)*op(sites,"Id",b+1);
 hterm += -j*op(sites,"Adag",b)*op(sites,"A",b+1);
 hterm += -j*op(sites,"A",b)*op(sites,"Adag",b+1);
 hterm += -U/2*op(sites,"N",b)*op(sites,"Id",b+1);
//extra terms
 hterm += delta*op(sites,"N",b)*op(sites,"Id",b+1);
 if(b==L-1)
 {
 hterm += U/2*op(sites,"Id",b)*op(sites,"N*N",b+1);
 hterm += -U/2*op(sites,"Id",b)*op(sites,"N",b+1);
//extra terms
 hterm += delta*op(sites,"Id",b)*op(sites,"N",b+1);
 }
 g = BondGate(sites,b,b+1,BondGate::tReal,tstep/2.,hterm);
 gates.push_back(g);
}
hterm += U/2*op(sites,"Id",L-1)*op(sites,"N*N",L);
hterm += -U/2*op(sites,"Id",L-1)*op(sites,"N",L);
//extra terms
hterm += delta*op(sites,"Id",L-1)*op(sites,"N",L);
g = BondGate(sites,L-1,L,BondGate::tReal,tstep/2.,hterm);
gates.push_back(g);
for(int b = L-1; b >= 1; --b)
    {
    hterm += U/2*op(sites,"N*N",b)*op(sites,"Id",b+1);
    hterm = -j*op(sites,"Adag",b)*op(sites,"A",b+1);
    hterm += -j*op(sites,"A",b)*op(sites,"Adag",b+1);
    hterm += -U/2*op(sites,"N",b)*op(sites,"Id",b+1);
    //extra terms
if(b>1){
    hterm += delta*op(sites,"N",b)*op(sites,"Id",b+1);
    }
    g = BondGate(sites,b,b+1,BondGate::tReal,tstep/2.,hterm);
    gates.push_back(g);
    }
gateTEvol(gates,ttotal,tstep,psi,{"Cutoff=",cutoff,"Verbose=",true});

Yes that error message means that somewhere in your code two ITensors are being added which have different indices, which is not allowed.

Please print out the various ITensors that you are creating and adding to see if some of them have different indices than you thought, or than they should have.

Ok, I found it.
Errors occur in the last site term which is outside the loop.

c++
auto hterm = U/2*op(sites,"Id",L-1)*op(sites,"N*N",L);
hterm += -U/2*op(sites,"Id",L-1)*op(sites,"N",L);
hterm += delta*op(sites,"N",b)*op(sites,"Id",b+1);
auto g = BondGate(sites,L-1,L,BondGate::tReal,tstep/2.,hterm);
 gates.push_back(g);
//end
//Create the gates exp(-i*tstep/2*hterm) in reverse order
hterm += U/2*op(sites,"Id",L-1)*op(sites,"N*N",L);
hterm += -U/2*op(sites,"Id",L-1)*op(sites,"N",L);
hterm += delta*op(sites,"Id",L-1)*op(sites,"N",L);
g = BondGate(sites,L-1,L,BondGate::tReal,tstep/2.,hterm);
gates.push_back(g);

When I delete the last term outside the first loop and the first term above the second loop as posted above it works.
But how should I modificated it to make it complete.

Glad you found the error. I’m not sure I understand your last question, when you say how you should make it complete. Is it not complete? If not why?

(Note that I have not read your code in detail, as the purpose of this forum is not for us to read and debug other people’s codes but to answer specific questions about the usage of ITensor.)