0 votes
asked by (450 points)

Hi all,

I am studying the ground state of a Heisenberg antiferromagnets on a 2D lattice (one periodic and one open), and I want to calculate the transfer matrix which is defined like this:

//got the ground state wave function psi through dmrg;
psi.position(N/2);
ITensor wf = psi(N/2 - Ny + 1);
for (int i = 2; i <= Ny; i++){
wf = wf * psi(N/2 - Ny + i);
}

then contract the wf with its own copy but keep the "Link" indices open,

wf *= prime(wf, "Link");

and I should get the transfer matrix where I want to calculate its largest eigenvalues and eigenvectors. However the second step throws an error of "std::bad_alloc" because the "Link" index dimension is too large ( around 3000), if I try 300 as "Link" index dimension it works well.

I have found a similar post http://itensor.org/support/1254/std-bad_alloc-in-spin-polarized-system where the solution is to avoid such large dimensions, but I can not think of a way to do that in my problem. Will it be better if I use a larger memory (like 512GB)? Any help would be much appreciated.

Best,

Yixuan

1 Answer

0 votes
answered by (36.3k points)

Hi Yixuan,
Yes, the reason for this error message is that your system has run out of memory / RAM. So one solution is definitely to try a system with more RAM if possible.

But another solution could be to write any large tensors you are not using at a particular step to disk. You can estimate the size of various tensors by multiplying the dimension of their indices together. Using this estimate, you might find that individual MPS tensors themselves aren't using a lot of memory, but tensors formed from the MPS can use a very large amount. (Or you might find that the MPS tensors alone are using a lot of memory; it depends on the details.)

We have some automatic facilities to write parts of an MPS to disk. But these may not work ideally for a transfer matrix calculation and are designed mostly to be used inside a DMRG calculation.

But you can even do writing to disk manually by just writing a tensor to a particular file with a good file name, then overwriting the tensor with an empty tensor to 'free' it from memory. Later, when you need the tensor again you can read it back in from the file and overwrite the read-in tensor onto your empty tensor to restore it.

If you decide to follow one of the three approaches above and run into issues, please post a comment below or a new question.

Best regards,
Miles

commented by (450 points)
edited by
Dear Miles,

Thanks for the suggestions, I have tested it using the delta function and tried to replace the indices but there is still the error saying "Diagonal elements of QDiag ITensor would have inconsistent divergence". I should have pointed out before that the error message only appears in the debug mode, but that is still a little bit concerning. Here is the printout of wf,

 ITensor ord=14:
(2|id=355|n=97,Site,S=1/2) <Out>
  1: 1 QN({"Sz",1})
  2: 1 QN({"Sz",-1})
(100|id=705|l=96,Link) <Out>
  1: 5 QN({"Sz",4})
  2: 26 QN({"Sz",2})
  3: 37 QN({"Sz",0})
  4: 26 QN({"Sz",-2})
  5: 6 QN({"Sz",-4})
(2|id=984|n=98,Site,S=1/2) <Out>
  1: 1 QN({"Sz",1})
  2: 1 QN({"Sz",-1})
(2|id=494|n=99,Site,S=1/2) <Out>
  1: 1 QN({"Sz",1})
  2: 1 QN({"Sz",-1})
(2|id=351|Site,n=100,S=1/2) <Out>
  1: 1 QN({"Sz",1})
  2: 1 QN({"Sz",-1})
(2|id=39|Site,n=101,S=1/2) <Out>
  1: 1 QN({"Sz",1})
  2: 1 QN({"Sz",-1})
(2|id=302|Site,S=1/2,n=102) <Out>
  1: 1 QN({"Sz",1})
  2: 1 QN({"Sz",-1})
(2|id=902|Site,S=1/2,n=103) <Out>
  1: 1 QN({"Sz",1})
  2: 1 QN({"Sz",-1})
(2|id=677|Site,S=1/2,n=104) <Out>
  1: 1 QN({"Sz",1})
  2: 1 QN({"Sz",-1})
(2|id=434|Site,S=1/2,n=105) <Out>
  1: 1 QN({"Sz",1})
  2: 1 QN({"Sz",-1})
(2|id=693|Site,S=1/2,n=106) <Out>
  1: 1 QN({"Sz",1})
  2: 1 QN({"Sz",-1})
(2|id=22|Site,S=1/2,n=107) <Out>
  1: 1 QN({"Sz",1})
  2: 1 QN({"Sz",-1})
(100|id=525|Link,l=108) <Out>
  1: 6 QN({"Sz",4})
  2: 26 QN({"Sz",2})
  3: 37 QN({"Sz",0})
  4: 25 QN({"Sz",-2})
  5: 6 QN({"Sz",-4})
(2|id=568|Site,S=1/2,n=108) <Out>
  1: 1 QN({"Sz",1})
  2: 1 QN({"Sz",-1})
{norm=1.00 (QDense Cplx)}


where lf is the Link index with l=96, and rt is the Index with l=108. I think the error is because that the bond dimensions of certain quantum number sector does not match with the one in the other index, if I do wf.replaceInds({rt}, {prime(rt)}); then there is no error.  I was wondering if there is any way to fix the bond dimensions of every quantum number sector for those two Indices the same during the DMRG process as a constrained sweeps.

Best,

Yixuan
commented by (36.3k points)
Hi Yixuan,
Is your transfer matrix from the unit cell of an infinite system calculation? Or is coming from a finite-size system? Thanks -

Miles
commented by (450 points)
It is from a finite-size 2D system.

Best,

Yixuan
commented by (36.3k points)
I see, so in general I'm not sure if this idea of taking the transfer matrix from a finite system is viable, especially when conserving quantum numbers. The issue is that while the index on the left-hand-side of the transfer matrix *might* be the same size as on the right-hand-side, there's no generic reason it has to be so it's kind of a brittle assumption. Even more brittle is assuming the quantum numbers will match on the left and right hand sides in terms of which sectors are present and which sizes they each have. It's hard to ensure that in general, unless one does special steps to try to ensure it (I'm not sure what these steps are, just saying they could exist maybe).

So I would mainly recommend using transfer matrix methods only for infinite systems, unless one has a way to ensure they will also work for finite systems.
commented by (450 points)
Hi Miles,

Thank you for the advice, now that I think more about it, it is hard to keep those two "Link" indices of the transfer matrix the same (differ by a prime) because they changed during the sweeps, and because I have an orthogonal center at a certain site, the transfer matrix I take from a finite system can not be considered as transnational invariant (even ignoring the finite size effect). I will try the infinite system for transfer matrix calculation.

Best,

Yixuan
Welcome to ITensor Support Q&A, where you can ask questions and receive answers from other members of the community.

Formatting Tips:
  • To format code, indent by four spaces
  • To format inline LaTeX, surround it by @@ on both sides
  • To format LaTeX on its own line, surround it by $$ above and below
  • For LaTeX, it may be necessary to backslash-escape underscore characters to obtain proper formatting. So for example writing \sum\_i to represent a sum over i.
If you cannot register due to firewall issues (e.g. you cannot see the capcha box) please email Miles Stoudenmire to ask for an account.

To report ITensor bugs, please use the issue tracker.

Categories

...