# How to Turn an Operator into an MPO to apply to MPS

Hi, I am new to itensor and MPS/MPO in general and I have the following question:
I have a chain of spin-1/2 and a 4x4 matrix U that couples two adjacent spins i and i+1. How can I form the MPO in itensor:
U1,2 + U3,4 + U_5,6 + ...
If all of the Us are the same but just operate on different sites and similarly if all of the Us are different.

I hope my question is clear. Thank you in advance.

commented by (32.1k points)
Hi, one question back to you is: what is the next step you are planning to do with this MPO? If you are planning to use it as a Hamiltonian for a DMRG calculation then, yes, you'll probably need an MPO. If you are just planning to multiply this MPO by your MPS, then there is a more efficient algorithm you can use starting directly from the U matrices.
commented by (180 points)
Hi, thank you for the help and quick reply. The idea is to time evolve the MPS with a series of unitaries:
In the first time step I will apply the unitaries to all odd bonds (1:2, 3:4, 5:6...) and in the next time step I will apply it to all even bonds (2:3, 4:5, 6:7....).
I would then like to calculate (for example entanglement entropies) at each time step and see how they evolve over time.

Hi, so thanks for the question. We didn't have anything in the documentation that covers precisely this, which is an important operation for MPS.

So I just added a new 'Code Formula' that shows you how to apply a gate to an MPS efficiently:
http://itensor.org/docs.cgi?page=formulas/gate

To apply each of your gates, just iterate the above formula for each gate you want to apply and for each bond you want to apply it to.

Please let me know if anything is unclear about the code in the formula or if you have more questions -

Best regards,
Miles

commented by (180 points)
Hi, thanks again for the reply. This is really helpful. For the Gates, a for loop (pseudocode) like below would generate all the gates?
for(i,j){
auto si = Index(nameint("s", i),2,Site);
auto sj = Index(nameint("s",j),2,Site);
auto Gate(i,j) = ITensor(si,sj,prime(si),prime(sj))
}
commented by (32.1k points)
Hi, glad it helps. That's almost right but not quite. The thing that you'll need to change is that you can't just make new site indices, but rather you have to obtain the site indices which match those of the MPS. As discussed here: http://itensor.org/docs.cgi?page=book/index, Index objects contract if they have the same internal id (and prime level). So if you make new indices they will have a different id number from the ones the MPS uses.

If you used a site set such as SpinHalf to make your MPS, then a good way to get the site indices is just to do:

SpinHalf sites(N);
...
Index si = sites(i);

Or if you don't have a site set, and just an MPS, you can get the site index of site i like this:

MPS psi;
...
auto si = findtype(psi.A(i),Site);

-Miles