# Making Initial Product States in 2D

Dear all,

First, the background is that I am currently trying performing some DMRG calculation for the 2-Dimensional Spin-1 BBH model "on a cylinder" (periodic in y direction) with only nearest neighbor interaction, which goes as follows.

$$\hat{H} = \sum_{i, j} \cos\theta \vec{S}_i\cdot \vec{S}_j + \sin\theta (\vec{S}_i\cdot \vec{S}_j)^2$$

Now, I want to start with different types of initial states, such as Neel-like state, dimer(spin-singlet) state, or other initial states of interests. There are already a number of great discussions about how to set a product initial state in 1D, as shown in the following links,

http://itensor.org/support/1357/setting-random-initial-product-state

http://itensor.org/support/1359/how-to-create-a-particular-initial-state-as-a-mps

Also, as previously pointed by Miles, there is a very good example in the "finiteT/ancilla.cc". https://github.com/ITensor/ITensor/blob/v3/tutorial/finiteT/ancilla.cc

But after reading these answers, now I want to construct a dimer state as follow.

$$\left| Initial\right>=\otimes_{1\leq n\leq N_x, 1\leq m\leq N_y} (2n-1, 2n; m)$$

here my notation is that I use @@(2n-1, 2n; m)@@ to indicate a spin-singlet (dimer) state between site (x=2n-1, y=m) and site (x=2n, y=m). A spin-singlet state is like @@1/\sqrt{3} (\left|+1\right>_i\otimes\left|-1\right>_j+\left|-1\right>_i\otimes\left|+1\right>_j-\left|0\right>_i\otimes\left|0\right>_j)@@, if you wish.

And a naive thought of mine is just to do something similar in 1D case that I product all the pairs of site and make a product state. Here're my codes in c++ v3.

auto psi0 = MPS(sites);
for (int n = 1; n < N; n += 2 * Ny)
{
for (int m = 0; m < Ny; m++)
{
auto s1 = sites(n + m);
auto s2 = sites(n + m + Ny);
auto wf = ITensor(s1, s2);
wf.set(s1(1), s2(3), ISqrt3); // 1- Up; 2- Z0; 3 - Dn; ISqrt=1/\sqrt{3}
wf.set(s1(3), s2(1), ISqrt3);
wf.set(s1(2), s2(2), -ISqrt3);
ITensor D;
psi0.ref(n + m) = ITensor(s1);
psi0.ref(n + m + Ny) = ITensor(s2);
svd(wf, psi0.ref(n + m), D, psi0.ref(n + m + Ny));
psi0.ref(n + m) *= D;
}
}


But it returns some error as follow.

davidson: size of initial vector should match linear matrix size


I guess that since in ITensor, a 2D model is simply mapped into a snake-like 1D chain, I should have not made such naive generalization from 1D to 2D. So, I hope someone can help me figure out why this does not work from the perspective of building a product state in ITensor, as well as how to realize the setup of a product state in 2D. Btw, I think this question can also be generalized to how to set an general initial product state in the case of 2D models.

Thank you very much!

Best,
Yi

+1 vote
selected by

Hi Yi,
So if I understand the code correctly, the problem (not the error but the conceptual problem) is coming from the lines:

psi0.ref(n + m) = ITensor(s1);
psi0.ref(n + m + Ny) = ITensor(s2);


It seems you are planning to split the two-site singlet tensor "wf" into two pieces and then assign these two pieces, which share a common bond index, to two MPS tensors which are not neighbors of each other, in the sense of the 1D MPS ordering.

In short, the resulting setting of psi0 will not be a valid MPS. The tensors will not have an MPS structure.

I hope that's clear, but a good way to see it is to draw the tensor diagram for your MPS psi0 (putting the tensors along a 1D line, since the DMRG code doesn't know anything about 2D) and then you will see that the common bond between sitees n+m and n+m+Ny is a "long bond" that is connecting across many 1D sites, which is not the form an MPS has by definition.

Ok please let me know if that helps & we can discuss more.

Finally, we had previously discussed an idea of moving the dimers around using swap operators. The reason for the swaps is precisely because the dimers cannot be initially created in the way above: they would have to be placed along the MPS path initially then moved with nearest-neighbor moves.

Also what did you think about the idea of just using a Hamiltonian whose ground state is exactly the desired dimer state? That idea would be the simplest one to try first, assuming it works.

Miles

commented by (400 points)
Thanks for the answer. And first, I know the bond between sites n+m and n+m+Ny is actually a bond corresponding to long range interaction when being mapped into 1D. I know I was doing something wrong, but just don't know the right way to do it.

Second, could you give a bit more details on how to use swap operation in ITensor for this case?

And finally, yes, I think that's a good idea. But for now I don't know what the hamiltonian  looks like in 2D. Then there comes the difficulty that the desired dimer state is actually a ground state in 1D model. What I am tring to do is basically more like to "lay" such 1d ground states one on top of another to form a 2D initial guess.
commented by (70.1k points)
Hi Yi, so I would strongly encourage you to try the Hamiltonian approach first since it will be *much* easier. It might not work but you'd know after a short time.

All that approach requires is figuring out a two-site Hamiltonian (probably just a antiferromagnetic Heisenberg coupling) which has as its ground state the dimer state of two spins that you want. Then you just use our AutoMPO system to make a Hamiltonian where sites 1 and Ny+1 have your dimer Hamiltonian, then sites 2 and Ny+2, etc. It is easy to do this with AutoMPO because you just add in all of the terms which make up the Hamiltonian. Please let me know if you have more questions about this.

We could discuss the swap idea after that, but it would take a lot of time for you to develop and code so I just think you'll have a much better time trying the Hamiltonian idea first.

Best,
Miles
commented by (70.1k points)
It also occurs to me that we do have the swapping logic fully automated, but only in our Julia version since most of our very newest features are going in there first. So if you are interested or willing to work with Julia it could offer an easy way to prepare these states.

We are working also on a system to allow things like MPS to be written to HDF5 files and read into the other language (C++ to Julia or the other way). But it's not quite finished: almost there.
commented by (400 points)
Thanks a lot. That's super helpful.
commented by (310 points)
Thanks a lot for above discussion, it certainly help great deal on a problem I was stuck at past few months :P .