# possible error of last site MPO in iqdmrg

+1 vote

Hello, Miles,

When I was using iqdmrg, I found there probably is an error in last site MPO in one dimensional spin model, when include external magnetic field as
$$H = \sum h S^z$$

It seems the magnetic term is missing for last site. Is it because of your way of constructing MPO? Thanks very much.

Best Regards
Wangwei

Hi Wangwei,
Are you referring to a particular sample code included with ITensor? The iqdmrg.cc code doesn't have a field term in it, so you must add it yourself the correct way, making sure that the loop index "j" runs over all sites and includes the last site.

If you can attach some sample code I can respond with more details.

Miles

commented by (280 points)
Hello, Miles,

You are right, I did make a mistake by excluding the last site. I can't believe I made such a stupid mistake.

Please allow me to ask another trivial question though. In the construction of IQMPO, I notice that the quantum number for the link index is QN(), QN(2) and QN(-2), and the size of the Index is 3,1,1. However, is there a specific reason why the quantum number should be these numbers, and the degeneracy is 3, 1,1? Because the link index is going to be contracted finally, thus, my expectation would be that they are not from physics. Is that right?

Thanks very much for your patience.

Best Regards
Wangwei
commented by (56.3k points)
Hi Wangwei,
The quantum numbers of the link indices comes from the convention we use for Hamiltonian (IQ)MPOs, which is that each IQMPO tensor must have a total QN flux of zero (see http://itensor.org/docs.cgi?page=book/block_sparse for an introductory explanation of what I mean by QN flux). So the pattern of IQIndex arrows and QN values (QNs associated with each sector of an IQIndex) are designed such that the non-zero blocks of each IQTensor making up the IQMPO has flux zero. This makes sense physically, because by definition an IQMPO conserves a particular set of quantum numbers, and the flux of an IQTensor is a measure of how much it will change the quantum number of another tensor when contracting with that tensor.

Miles
commented by (680 points)
Hi Miles,

The explanation on http://itensor.org/docs.cgi?page=book/block_sparse is very clear and helpful, and I've learned a lot from it, thanks!

I have now another question about QN system. In the siteset file, e.g. itensor/mps/sites/spinhalf.h, a QN is defined for the operators. On the other hand, when defining IQMPO by hand, a QN is defined again for each "QN block", as in sample/Heisenbberg.h, line 73-81. Do these QN have to be consistent, or they are different stories?

Best,
Chengshu
commented by (56.3k points)
Hi Chengshu,
Good question. I am hoping to cover this in future chapters to be added to the ITensor book.

The key thing to know about IQMPOs for Hamiltonians is that we use the convention that each IQMPO tensor has a flux of zero. This is a very sensible convention when you consider that Hamiltonians always have a flux of zero (otherwise acting them wouldn't conserve the quantity that they are supposed to conserve). Now, one could allow the individual tensors of a Hamiltonian IQMPO to not have flux zero as long as the overall Hamiltonian still has total flux zero, but its easier and more natural to just make every tensor individually have flux zero.

So if you study each non-zero block defined for the IQMPO examples (such as for the idmrg.cc sample code) you'll see that they all have flux zero. The QNs carried by the virtual indices are designed to balance the net QN flux of the site indices for each non-zero block. Even with this choice, there is still a lot of freedom in how to arrange the blocks. Here there is no right or wrong convention and I even use different one sometimes as seems most convenient to me.

If you want to study a particular IQMPO example, I would recommend thinking of each IQMPO tensor as a matrix of site operators (an operator-valued matrix) then writing out each IQMPO "matrix" and labeling the QN sectors along the rows and columns to compute the flux of each non-zero block, checking that it is always zero the way I have defined things.

- Miles
commented by (680 points)
Hi Miles,

Thanks for the detailed explanation, which I believe is very helpful to whoever tries to construct IQMPO by hand. To make sure I do understand what's going on, take the Heisenberg.h as an example (again), where the virtual indices QN is defined as

for(int l = 0; l <= N_; ++l)
{
q0.at(l) = Index(nameint("q0_",l),3);
qP.at(l) = Index(nameint("qP_",l),1);
qM.at(l) = Index(nameint("qM_",l),1);

q0[l],QN( 0),
qP[l],QN(-2),
qM[l],QN(+2),
Out);
}

Then the QN at (row(2), col(4)) is 0+(-2)=-2.
On the other hand, one term in the Hamiltonian is

W += sites_.op("Sp",n) * row(2) * col(4) * J_/2;

where "Sp" has QN +2 as it raises the spin by 1. And -2 and 2 add to be 0. Is this the correct understanding? Thanks!

Best,
Chengshu
commented by (56.3k points)
Hi Chengshu,
Yes that is the correct understanding. You can think of the "S+" (or "Sp") operator as being a block of the IQMPO that would have a flux of +2, so we balance this flux by having the outgoing (right) index carry a QN of -2. Later on (i.e. spatially to the right on another site) there must be an "S-" operator with a flux of -2 that balances out the incoming QN of -2 (because remember that an In arrow carries the opposite sign of QN). So you can almost envision the -2 QN on the link picturesquely as a "flux tube" or a "string" that enforces a contract saying that if a "S+" appears somewhere, a "S-" must appear later to balance it out.

Miles
commented by (680 points)
Thanks very much for the explanations!