Translationally Invariant MPS from Single Site DMRG

How do I use this algorithm? What does that parameter do?
Post Reply
Bernhard
Posts: 2
Joined: 04 May 2020, 12:13

Translationally Invariant MPS from Single Site DMRG

Post by Bernhard »

Hi, I want to find a translationally invariant iMPS representation of the following model
\[H = \sum_i t_0 Z_i + t_1 X_i X_{i+1} + t_2 Z_i X_{i+1} Z_{i+2}, \quad t_0,t_1,t_2 \in\mathbb{R}.\]
As the usual iDMRG algorithm uses two sites and gives back two different MPS tensors for the two different sites, so I tried to use the Single Site DMRG Engine to only optimize one site at a time, but I still get two different MPS tensors for the two different sites. I use the following code:

Code: Select all

# Implementing the model from the Hamiltonian above

class GenCluster(MultiCouplingModel):
    def __init__(self, model_params):
        # Read out/set default parameters
        name = "Generalized Cluster Models"
        L = get_parameter(model_params, 'L', 2, name)
        t0 = get_parameter(model_params, 't0', 1., name, True)
        t1 = get_parameter(model_params, 't1', 0., name, True)
        t2 = get_parameter(model_params, 't2', 0., name, True)
        bc_MPS = get_parameter(model_params, 'bc_MPS', 'infinite', name)
        unused_parameters(model_params, name) # checks for mistyped parameters
        
        # sites
        site = SpinHalfSite(conserve=None)

        # lattice
        bc = 'periodic'
        lat = Chain(L, site, bc=bc, bc_MPS=bc_MPS)

        # initialize CouplingModel
        MultiCouplingModel.__init__(self, lat)

        # add terms of the Hamiltonian
        self.add_onsite(t0/2, 0, 'Sigmaz')
        self.add_coupling(-t1/2, 0, 'Sigmax', 0, 'Sigmax', 1)
        self.add_multi_coupling(-t2/2, 0, 'Sigmax', [(0, 'Sigmaz', 1), (0, 'Sigmax', 2)])

        # initialize H_MPO
        MPOModel.__init__(self, lat, self.calc_H_MPO())

Code: Select all

N = 2    # The length of the chain
param = {"t0": 0., "t1": 0., "t2": 0., "L": N, "bc_MPS": "infinite"}    # Set infinite system

g_list = np.linspace(-1.,1.,11)    # Set parameters

for g in g_list:
    # Set parameters for the model
    param["t0"] = 2*(1-g)**2
    param["t1"] = 4*(1-g**2)
    param["t2"] = 2*(1+g)**2

    # Implement the model from above with the parameters t0, t1, and t2
    model = GenCluster(param)
    sites = model.lat.mps_sites()

    # The initial state is a randomly time evolved state:
    product_state = (["up", "down"] * (model.lat.N_sites))[:model.lat.N_sites]
    psi = MPS.from_product_state(model.lat.mps_sites(), product_state, bc=model.lat.bc_MPS)
    TEBD_params = {'N_steps':10, 'trunc_params':{'chi_max':4},'verbose':0}
    eng = tebd.RandomUnitaryEvolution(psi, TEBD_params)
    eng.run()
    psi.canonical_form()

    # The parameters for DMRG
    dmrg_params = {"trunc_params": {"chi_max": 4, "chi_min": 2, "svd_min": 1.e-10},
                   "min_sweeps":100, "max_sweeps":200, "mixer": True, "combine":False, 'decay':2,
                   'amplitude':10e-1, 'disable_after':60, 'update_env':0}

    # Use the Single Site DMRG Engine
    eng = dmrg.SingleSiteDMRGEngine(psi, model, dmrg_params)
    e, psi = eng.run()
    print(psi.get_B(0))
    print(psi.get_B(1))
Using this code I would expect the last two print statements to print out the same tensors, but they are different.
Why is the resulting MPS not translationally invariant and how can I get an MPS that is translationally invariant, i.e. the same on both sites? Thanks in advance :)

User avatar
Johannes
Site Admin
Posts: 159
Joined: 21 Jul 2018, 12:52
Location: UC Berkeley

Re: Translationally Invariant MPS from Single Site DMRG

Post by Johannes »

As long as you have more than one tensor in you MPS, they will be different, even with single site DMRG.
DMRG optimizes the tensors one after another (in the "sweep"), which immediately breaks the translation invariance in the beginning.

If you model is translation invariant and the ground state does not sponanteously break the symmetry (e.g. because it forms a charge density wave, or a Neel state for an antiferromagnet), you can expect the translation invariance to be recovered (approximately) after DMRG convergence.
Even then, however, the tensors don't need to be the same; you need to impose further conditions to fix the gauge freedom of the MPS under \(B_0 B_1 \rightarrow (B_0 X) (X^{-1} B_1)\).
The canonical form is only sufficient for fixing this gauge if there are no degenerate singular values.

The only way around it would be to use single site DMRG and to really just have a single tensor in the unit cell.
The current code of TeNPy does not allow it. It starts to fail at the assert L >= 2 in get_sweep_schedule, which is there because other parts are written assuming that.
In general, it should be possible to adjust the existing code to not assume L>= 2.

I just tried updating the code quickly, but I failed. It's a bit more effort than I thought...
The "update_LP" and "update_RP" can be quite easily fixed.
However, the mixer interface would need to be rewritten, since right now it gets
two tensors and updates the leg in between, this does no longer work for L = 1. :(

Bernhard
Posts: 2
Joined: 04 May 2020, 12:13

Re: Translationally Invariant MPS from Single Site DMRG

Post by Bernhard »

Thank you very much for your answer, that makes sense.
Too bad that TeNPy does not allow for the use of just a single tensor. Instead of trying to rewrite all that code I found another way to work around that and I'll put it here in case anyone else has a similar problem.

If we know that there is a translationally invariant, canonical MPS, let's call it \(C^i_{ab}\), then it is related to the MPS tensors found by DMRG via a unitary matrix \(U\):
\[B_0^i = U C^i \quad\text{and}\quad B_1^i = C^i U^{\dagger}.\]
We can then calculate the mixed transfer matrix of the state we get from DMRG and the state translated by one site:
\[T_{ab;a'b'} = \sum_{i,j} (B_1^iB_0^j)_{aa'}\otimes(B_0^iB_1^j)^*_{bb'} = \sum_{i,j} (C^iC^j)_{aa'}\otimes(U C^i C^j U^{\dagger})^*_{bb'}.\]
If the state is invariant under translation by one site, this transfer matrix should have one eigenvalue with magnitude one. This eigenvalue is the unitary matrix \(U^{\dagger}\):
\[\sum_{a'b'} T_{ab;a'b'} (U^{\dagger})_{a'b'} = \sum_{i,j} (C^iC^j)_{aa'}\otimes(U C^i C^j U^{\dagger})^*_{bb'} U^*_{b'a'} = \sum_{i,j} (C^iC^j)_{aa'}\otimes(U C^i C^j)^*_{bb'} \delta_{b'a'} = U^*_{ba} = (U^{\dagger})_{ab}. \]
So we can find the matrix \(U\) as an eigenvector of the mixed transfer matrix, which we can calculate from the DMRG result, and get the translationally invariant tensors as
\[C^i = U^{\dagger} B_0^i = B_1^i U.\]

User avatar
Johannes
Site Admin
Posts: 159
Joined: 21 Jul 2018, 12:52
Location: UC Berkeley

Re: Translationally Invariant MPS from Single Site DMRG

Post by Johannes »

Nice workaround!

I'd formulate it slightly differnt, though.
Bernhard wrote:
06 May 2020, 23:39
If we know that there is a translationally invariant, canonical MPS, let's call it \(C^i_{ab}\), then it is related to the MPS tensors found by DMRG via a unitary matrix \(U\):
\[B_0^i = U C^i \quad\text{and}\quad B_1^i = C^i U^{\dagger}.\]
In general, I'd expect that (assuming canonical form) there can be two unitaries
\(U_0, U_1\) with
\[B_0^i = U_0 C^i U_1^{\dagger} \quad\text{and}\quad B_1^i = U_1 C^i U_0^{\dagger}.\]
The overlap of the shifted transfer matrix as you wrote it down should give you a right eigenvector of \( U^\dagger = U_1 U_0^\dagger\), which you can use as you proposed to calculate
\[ U_1 C^i U_1^\dagger = U^\dagger B_0^i = B_1^i U \]
Of course, \( U_1 C^i U_1^\dagger\) is as much a valid, translation invariant MPS, as is \(C^i\).

So the procedure I'd do is the very same, I just wrote down slightly different formulas to understand why it works.

Post Reply