the truncation in dmrg

How do I use this algorithm? What does that parameter do?
Post Reply
QichengTang
Posts: 32
Joined: 08 Jan 2019, 03:03

the truncation in dmrg

Post by QichengTang »

I think the following finding should be noticed by everyone who uses tenpy.
When I run dmrg for xxz chian, I found that the result will be strongly dependents on the parameter "svd_min", and this doesn't make sense.
I have run the following test to show the problem.
I'm confused, what may cause this problem?

Thanks,
Qicheng

Code: Select all

def DMRG_XXZ(D0, svd_min, L=48, S=0.5, bc_MPS='finite'):
    print("finite dmrg, XXZ chain")
    model_params = dict(L=L, Jx=1, Jy=1, Jz=D0, conserve='best',
                        S=S, bc_MPS=bc_MPS, verbose=0)
    M = SpinChain(model_params)
    psi = MPS.from_product_state(M.lat.mps_sites(), ([1, 0] * L)[:L], bc=bc_MPS)
    dmrg_params = {
        'mixer': None,
        'trunc_params': {
            'chi_max': 512,
            'svd_min': svd_min
        },
        'max_E_err': 1.e-10,
        'verbose': 1
    }
    dmrg.run(psi, M, dmrg_params)
    E = np.sum(psi.expectation_value(M.H_bond[1:]))
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    return E, psi

def test_dmrg_xxz():
    svd_mins = []
    psis = []
    Ss = []
    S_half = []
    for n in range(20):
        svd_min = (0.5*(n+1)+1.5)*1.e-12
        svd_mins += [svd_min]
        a = DMRG_XXZ(4, svd_min)
        psis += [a[1]]
        Ss.append(a[1].entanglement_entropy())
        S_half += [Ss[n][23]]

    pl.figure()
    pl.plot(svd_mins, S_half, 'ob-')
    pl.xlabel('svd_min$')
    pl.ylabel('entanglement entropy')
    pl.savefig('test_svd_min.pdf')

    return svd_mins, psis, Ss, S_half
download.png
download.png (13.95 KiB) Viewed 5568 times
User avatar
Johannes
Site Admin
Posts: 413
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: the truncation in dmrg

Post by Johannes »

What's even more worrying is that the expectation values of say "Sz" are also changing :!:
However, it's not a bug of TenPy, but there is a simple explanation for this behaviour :roll:
The problem is that the ground state is degenerate (up to a finite size gap below the precision).

You chose the limit Jz=4, which corresponds to the strong Ising anisotropy, so the exact ground state is the Neel state with some very minor fluctuations.
But there are two Neel states |N1> = |ududud> and |N2> = |dududu>, relatet by the symmetry of flipping all spins.
For a finite system, only a superposition of the both states (+ fluctuations) is the exact ground states (consider the extreme case L=2, where you get the singlet |psi_0> = 1/\sqrt{2}(|N1> - |N2>) as exact ground state, and the triplet |psi_1> = 1/\sqrt{2}(|N1> + |N2>) has a higher energy.
However, the gap between the different superpositions of N1 and N2 goes down exponentially with system size, such that at some point the energy gap is below machine precision. Hence, DMRG can give you *any* superposition of the two Neel states as a "correct" answer.

The two superpositions have clearly different expectation values for "Sz", and also different entropies - you can add an arbitrary value between 0 and log(2) to the entropy by forming an appropriate superposition.
(If you have larger degeneracy, you can even add log(omega), where omega is the degeneracy of the ground state.)

One way to avoid these superpositions is to limit chi stronger.
In your case, you allowed a chi=512, which is much larger than necessary; the limititation of chi didn't contribute to the truncation at all.
If you limit e.g. chi=50, you get a single one of the two superposition states only. Let's say you need a bond dimension chi=M to represent (|N1>+fluctuations) being a ground state, and the same chi=M to represent (|N2>+fluctuations), then the superposition 1/sqrt(2)(|N1>+fluctuations + |N2>+fluctuations) requires a bond dimension chi=M*M = M^2.
In that way, the superpositions are suppressed by the truncation, and you end up with a single state.

The DMRG parameter chi_list allows to increase chi gradually during the DMRG simulation, to initially truncate strongly (suppressing superpositions), and later increase chi to reduce the truncation error (with an already symmetry broken state).
In particular for infinite DMRG calculations, this is a very good technique because the "environments" give a symmetry-broken boundary and hence a superposition is no longer possible. In the finite DMRG, this might not work so well, because the complete "environment" can be changed from one sweep to the other.

Alternatively, you can add a small term to the Hamiltonian to explicitly break the symmetry; e.g. in this case a staggered magnetic field. Playing around, I found that in this case a field hz = np.array([1.e-6, -1.e-6]* (L//2)) was enough to fix the direction of the Neel state.
Of course, this requires to know the symmetry leading to the degeneracy. It might also change the physics, so be careful whether your "perturbation" still describes the same physical system ;-)
QichengTang
Posts: 32
Joined: 08 Jan 2019, 03:03

Re: the truncation in dmrg

Post by QichengTang »

Thanks for your reply, I know that the problem maybe the degeneracy of the ground state, but that's not my point.
My point is, I thought only one of these parameters "svd_min", "trunc_err", "max_bond" for truncation works. I mean I thought there is a protocol to choose the minimal requirement of these parameters, lke if "svd_min" will save less states, so it'll choose this "svd_min" to do the truncation.
But tenpy is another way to do the truncation, it uses the "max_bond" to do the first truncation, and then ues "svd_min" to do the second, and this leads to the problem which I have meet.
User avatar
Johannes
Site Admin
Posts: 413
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: the truncation in dmrg

Post by Johannes »

The problem you have met comes from the degeneracy of the states - you have a bunch of correct, possible solutions, and which one is returned depends on numerical round off errors.

I don't get the comment on truncation. Let me clarify:
The truncation respects all the parameters chi_max, svd_min and trunc_err (and furthers, e.g., chi_min) at the same time.
All of the parameters correspond to certain conditions which singular values can be kept, and it just chooses a truncation compatible with all the conditions (if possible). chi_max puts an upper limit (in your case 500) on the bond dimension, but if you also specify svd_min, it will truncate to a lower chi if the remaining singular values are below this threshold - this might (and does in your case) result in bond dimensions smaller than chi_max.
However, chi_max has higher priority, so if there are 800 states with singular values larger than svd_min, it still keeps only the 500 largest ones.
QichengTang
Posts: 32
Joined: 08 Jan 2019, 03:03

Re: the truncation in dmrg

Post by QichengTang »

Okay, I see. I'm wrong about the truncation protocol in tenpy.
But, it's still kind of weird for me, I mean, the value of 1.e-10 ("svd_min") is a very small number, it should not influence the result, or I'm wrong with some very trivial things?
User avatar
Johannes
Site Admin
Posts: 413
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: the truncation in dmrg

Post by Johannes »

That's the point: if your result is not unique (due to the degeneracy), any (small) change of the setup can change the result - it's basically random, what you get. Your results should usually still be reproducable, when you run the same code on the same machine with the same python version, but changing the slightest thing might change it.
However, when you have a "unique" solution for what the ground state should be, you should of course get it, independent of what machine/python version/OS/... you use, and then a change of the `svd_min` parameter will not (dramatically) influence the result.
Post Reply