# Convergence issues for small system sizes for the transverse field Ising model

+1 vote

I am a bit puzzled by strange convergence behavior of DMRG for the transverse field Ising model.

Using the Julia version, I am running the transverse field Ising model example for various system sizes N and the coupling h

H = - \sum_{i} Z_i Z_{i+1} - h \sum_{i} X_i


My issue is that for certain values of h and N, the convergence seems to become very poor. I set energy tolerance of 1e-12 as a convergence criterion using a custom DMRGObserver, as shown in the documentation. For h>1.0, everything is good and DMRG converges very quickly. For example, even at critical h=1.0, I find it takes around ~10 sweeps.

However, for h=0.5, I notice that the convergence is very fast small N<10, but becomes quite poor for N~15, and then becomes very fast for N>24. For example, in a typical run, I find the following number of sweeps needed to reach an energy tolerance of 1e-12:

 Row │ N      sweeps  energy_tol
─────┼───────────────────────────
1 │     6       7  9.3e-13
2 │     8      14  7.2e-13
3 │    10      23  8.2e-13
4 │    12      55  4.3e-13
5 │    16     100  2.0e-09
6 │    24       4  1.4e-14
7 │    32       4  3.1e-14
8 │    48       4  3.2e-13


Note the rows for N=10,12,16. I am not sure what's happening at these intermediate values of N... why does the convergence suddenly become poor? This behavior depends on the coupling h. For example, in contrast to the above example, at h=1.0 (critical), there seems to be no problem and DMRG converges with very few sweeps (less than 10) within a tolerance of 1e-12 for N=6,..,48.

 Row │ N      sweeps  energy_tol
─────┼───────────────────────────
1 │     6       4  9.7e-16
2 │     8       6  1.4e-15
3 │    10       5  8.7e-14
4 │    12       6  9.5e-16
5 │    16       6  3.3e-13
6 │    24       8  9.6e-15
7 │    32      11  4.9e-13
8 │    48      12  4.7e-14


On the other hand, for h=0.2, I find that even L=6 has problem converging, but larger values of L become much better:

 Row │ N      sweeps  energy_tol
─────┼───────────────────────────
1 │     6     100  2.5e-09
2 │     8      36  6.9e-13
3 │    10       3  2.6e-13
4 │    12       4  1.1e-14
5 │    16       3  4.0e-13
6 │    24       4  5.5e-15
7 │    32       4  1.5e-15
8 │    48       4  5.4e-15


Larger h (greater than 1.0) seem to be all well behaved when I did a few spot checks. Does this behaviour make sense? My initial state is just a randomMPS. I tried playing with sweeps, both including noise and without. But that doesn't seem to matter very much. It's counter-intuitive to me that the problem is with small lattices, while larger ones do okay. Can you see what could be happening here? Thanks!

commented by (70.1k points)
Hi thanks for the question. What does your "sweep schedule" look like, in terms of how quickly you raise the maxdim from the first few sweeps to the final value, and similar with other DMRG accuracy parameters?

One suggestion I would have would be to always do a few initial sweeps with a rather low maxdim, of say 8 or 10, then start doubling it until you reach the final maxdim value you want (the final one could be very high if you have a modest size cutoff, which will then start to dominate the truncation).
commented by (130 points)
Hi Miles. Thanks for your response.

So, I tried playing with the sweep parameters, but somehow it didn't seem to make much difference. For example, for the above runs, I was using

sweeps = Sweeps(100, [
"maxdim" "mindim" "cutoff" "noise"
10       10       1e-12    1E-7
20       10       1e-12    1E-7
50       10       1e-12    1E-7
100      20       1e-12    1E-8
200      20       1e-12    1E-10
200      20       1e-12    0
])

I have tried the above schedule both with and without noise.  I also just tried with starting with even lower bond dimension of 5, but it does seem to alter the fact that L=16 just does not converge even for 100 sweeps.
commented by (70.1k points)
Hi, thanks for that info. So from the information provided, I can't easily guess what's going on. Could you please share a minimal code that can reproduce this issue? How are you defininig the energy tolerance? Is it through an observer object or just through your own comparison?

Thanks, Miles
commented by (130 points)
Thanks for your response. I define the energy tolerance through a custom observer object, pretty much following the documentation. Here's a MWE:

https://gist.github.com/hershsingh/e6bd6c1fab997530c1c0e31e0a1c87d5

Edit: for some reason, the code formatting didn't work in the comments for me, so putting a link to a gist instead.
commented by (130 points)
The code above will run DMRG for various lattice sizes and print a table of number of sweeps required for each N and the final energy tolerance achieved. When I run it for an energy tolerance of 1e-12, I find that N=16 saturates the maximum number of sweeps (100), and the  energy tolerance achieved is only 1e-9. Larger N seem to converge much faster.
commented by (70.1k points)
Hi Hersh,
Thanks for the code example. A bit separately from the issue you are seeing, I've found it's not usually a good idea to loop over many different DMRG runs. The reason is (like you are seeing), different systems and different parameters can require different treatment. Using the energy tolerance criterion seems like it automates things, but even then I think it's better to sort of get a 'feel' for each system by doing test runs yourself before committing to longer ones.

Do you think the issue might just be that you are using a random initial state (which is fine) but then sometimes it gets unlucky and starts out with a particularly high energy?

Did you try redoing some of the 'problem' systems a few times in a row (outside of the for loop) to see if the behavior happens every time even for different random 'draws' of the initial state?

Thanks,
Miles