finite open, finite periodic and infinite periodic chains

How do I use this algorithm? What does that parameter do?
Post Reply
Qottmann
Posts: 18
Joined: 27 Mar 2019, 09:11
Location: Barcelona

finite open, finite periodic and infinite periodic chains

Post by Qottmann »

Hello,

is there a way to have a finite periodic chain (so a ring) for the BoseHubbard model?
As far as I understand setting bc_MPS to "finite" gives a finite chain with open boundary conditions and "infinite" is basically performing iDMRG - or am I already getting this part wrong?

Thanks in advance!
Best regards,
Korbinian
User avatar
Johannes
Site Admin
Posts: 413
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: finite open, finite periodic and infinite periodic chains

Post by Johannes »

Qottmann wrote: 14 Oct 2019, 10:19 is there a way to have a finite periodic chain (so a ring) for the BoseHubbard model?
Kind of. We do not support finite MPS with periodic boundaries for the MPS itself i.e. writing
\[ | \Psi\rangle = \sum Tr(A^{\sigma_1} \cdots A^{\sigma_L}) | \sigma_1 \cdots \sigma_L\rangle \]
This is a form which is usefull analytically (e.g. if you write the ground state of the AKLT model on a finite ring), but not numerically, because it doesn't allow to define a canonical form.

However, you can define a bc_MPS="finite" and still have periodic couplings in your Hamiltonian. The price you pay for this is that the coupling over the "boundary" of the MPS is long range afterwards. Hence you can't use TEBD, and if you use DMRG, you should definitely use the mixer.
To do that, take a look at the parameters documented in init_lattice, i.e. use bc_MPS=True, bc_x="periodic".

Ian McCulloch once suggested that one can also use a different "enumeration" or "order" of the MPS compared to the physical sites in such a case to avoid having the terribly long range:
Instead of using
\[ | \Psi\rangle = \sum A^{\sigma_1} A^{\sigma_2} A^{\sigma_3} \cdots A^{\sigma_L}) | \sigma_1 \cdots \sigma_L\rangle \]
one could use
\[ | \Psi\rangle = \sum A^{\sigma_L} A^{\sigma_1} A^{\sigma_{L-1}} A^{\sigma_2} A^{\sigma_{L-2}} A^{\sigma_3} \cdots A^{\sigma_{L/2}} | \sigma_1 \cdots \sigma_L\rangle \]
In that way, a nearest neighbor coupling on the ring becomes a next-nearest neighbour coupling for the MPO.
I've never tried that out myself with TeNPy, but it is implemented already with the help of the order. I added a few lines in a git commit a few minutes ago such that you can now use order='folded' as model parameter for the tenpy.models.lattice.Chain.
Be aware the functions like the expectation_value, which return an array with the expectation value of a local operator on each site of an MPS will also be affected by that order. You can use the lattice method mps2lat_values to permute the values in the array such that it corresponds to the original/default order.
Qottmann
Posts: 18
Joined: 27 Mar 2019, 09:11
Location: Barcelona

Re: finite open, finite periodic and infinite periodic chains

Post by Qottmann »

Johannes wrote: 15 Oct 2019, 15:15
Qottmann wrote: 14 Oct 2019, 10:19 is there a way to have a finite periodic chain (so a ring) for the BoseHubbard model?
(..)
In that way, a nearest neighbor coupling on the ring becomes a next-nearest neighbour coupling for the MPO.
I've never tried that out myself with TeNPy, but it is implemented already with the help of the order. I added a few lines in a git commit a few minutes ago such that you can now use order='folded' as model parameter for the tenpy.models.lattice.Chain.
Be aware the functions like the expectation_value, which return an array with the expectation value of a local operator on each site of an MPS will also be affected by that order. You can use the lattice method mps2lat_values to permute the values in the array such that it corresponds to the original/default order.
First of all thanks for providing this feature!

I am trying now to use this folding method. What @Johannes wrote here sounds like I can just give a Chain with order="folded" as the lattice in model_params, but is this really the case? Don't i need to have 2 single n-n coupling at initial and last bond and n-n-n-coupling in the bulk, in order to get the periodic circle?
Screenshot from 2020-09-02 17-21-44.png
Screenshot from 2020-09-02 17-21-44.png (11.32 KiB) Viewed 7897 times
I am talking about n-n models that are inititated like

Code: Select all

def init_terms(self, model_params):
        # 0) Read and set parameters.
        t = get_parameter(model_params, 't', 1., self.name, True)
        U = get_parameter(model_params, 'U', 0., self.name, True)
        for u in range(len(self.lat.unit_cell)):
            self.add_onsite(U / 2., u, 'NN')
        for u1, u2, dx in self.lat.pairs['nearest_neighbors']:
            self.add_coupling(-t, u1, 'Bd', u2, 'B', dx, plus_hc=True)
I am asking because the lattice.pairs entries are the same for a default and folded Chain. Or am I missing something in how CouplingMPOModels are created?

edit: I guess I am asking how I would implement it in the end. I am bit puzzled by the add_coupling routine and the fact that u1, and u2 are both 0 in the n-n case (general confusion, no specific to this post/model).

Maybe something like this could work:

Code: Select all

for u1, u2, dx in self.lat.pairs['nearest_neighbors']:
    self.add_coupling(t * np.array([1,0,...0,1]), u1, 'Bd', u2, 'B', dx, plus_hc=True)
for u1, u2, dx in self.lat.pairs['next_nearest_neighbors']:
    self.add_coupling(t * np.array([0,1,1,....,1,1,0]), u1, 'Bd', u2, 'B', dx, plus_hc=True)
so like "masking" the interactions as add_coupling can take numpy arrays of different strength,
User avatar
Johannes
Site Admin
Posts: 413
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: finite open, finite periodic and infinite periodic chains

Post by Johannes »

Oops!
There was a bug in init_lattice that the 'order' parameter was read out, but not used for 1D lattices (i.e. the Chain and Ladder).
I've quickly fixed this in 9e020640e180d6fb9d09f534a9c91fa047cf6bab.

After this fix, using order='folded' is really "enough", apart from making sure that you understand how to read expectation values etc.
Example:

Code: Select all

import tenpy
from tenpy.models.spins import SpinModel

M = SpinModel({'L': 10,
               'Jx': 0., 'Jy': 0., 'Jz': 1.,
               'bc_MPS': 'finite', 'bc_x': 'periodic',
               'order': 'folded'})
print("order:")
print(M.lat.order)
print("coupling terms:")
print(M.all_coupling_terms().to_TermList())

ps = [['up'], ['down']] * (M.options['L']//2)  # Neel state in lattice order
psi = tenpy.networks.mps.MPS.from_lat_product_state(M.lat, ps)
Sz_mps = psi.expectation_value("Sz")
print("Sz_mps = ", Sz_mps)
Sz_lat = M.lat.mps2lat_values(Sz_mps)
print("Sz_lat = ", Sz_lat)
The output:

Code: Select all

Reading 'bc_MPS'='finite' for config SpinModel
Reading 'order'='folded' for config SpinModel
SpinModel: set conserve to Sz
Reading 'bc_x'='periodic' for config SpinModel
Reading 'L'=10 for config SpinModel
Reading 'Jx'=0.0 for config SpinModel
Reading 'Jy'=0.0 for config SpinModel
Reading 'Jz'=1.0 for config SpinModel
order:
[[0 0]
 [9 0]
 [1 0]
 [8 0]
 [2 0]
 [7 0]
 [3 0]
 [6 0]
 [4 0]
 [5 0]]
coupling terms:
1.00000 * Sz_0 Sz_1 +
1.00000 * Sz_0 Sz_2 +
1.00000 * Sz_1 Sz_3 +
1.00000 * Sz_2 Sz_4 +
1.00000 * Sz_3 Sz_5 +
1.00000 * Sz_4 Sz_6 +
1.00000 * Sz_5 Sz_7 +
1.00000 * Sz_6 Sz_8 +
1.00000 * Sz_7 Sz_9 +
1.00000 * Sz_8 Sz_9
Sz_mps =  [ 0.5 -0.5 -0.5  0.5  0.5 -0.5 -0.5  0.5  0.5 -0.5]
Sz_lat =  [ 0.5 -0.5  0.5 -0.5  0.5 -0.5  0.5 -0.5  0.5 -0.5]
The entries of order define in which order the MPS winds, and indeed you get the same order as in the bottom of your figure (apart from the fact that python starts counting with 0, so you have to subtract 1).
The second print shows that the "long range" couplings appear correctly: 0-9 now label the sites inside the MPS (left to right in your figure), so we have coupling pairs (0,1), (i, i+2) for 0 < i < 8, and (8,9), as we expect from your figure.

The product state you define for from_lat_product_state is independent of the order, i.e. as you would write it down with "default" order. (The extra brackets are for the unit cell index, for example for the ladder you need two entries each.)

Finally, the function mps2lat_values can be used to convert an array of expectation values back into the canonical form again.
Qottmann
Posts: 18
Joined: 27 Mar 2019, 09:11
Location: Barcelona

Re: finite open, finite periodic and infinite periodic chains

Post by Qottmann »

This was perfect and super helpful! Thank you so much for the help Johannes, it really is much appreciated!

I have one follow-up question. So far it seems to work fine, there is just one thing I am unsure about. With this method the resulting MPS is still finite (obc-style finite), right? I.e. the left-most and right-most matrices are actually vectors and there is no connection between them. Would going to the non-folded PBC picture change this? (I guess not.)

I am asking about this because we were comparing results with "traditional" DMRG (by White w/o MPS), and for PBC there are significant differences for phases where translational symmetry is broken. "Traditional" DMRG actually manifests a translational invariance, while this (i.e. the MPS) approach still breaks it somehow by default due to the finite obc-style MPS (or is that a misconception of mine?).

To put the actual question more explicitly: Does it make sense that with this approach the translational invariance is still broken and results may differ for phases with broken transl. symmetry with respect to traditional DMRG?
User avatar
Johannes
Site Admin
Posts: 413
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: finite open, finite periodic and infinite periodic chains

Post by Johannes »

Yes, the MPS is still finite and OBC-style bc_MPS='finite', with vectors at the boundary. It's just that the couplings in the MPO are topolically equivalent to a ring, as you drew it in your picture. Using the "default" order wouldn't change this, you would still need to define the MPS to have bc_MPS='finite' with vectors at the boundary, at least in TeNPy.


Of course, this setup of OBC-style MPS explicitly breaks translation invariance (=rotation of the ring), so I wouldn't be surprised if translation invariance is not given in systems which spontaneously break translation invariance.
For example, you have (spinless) fermions with very strong nearest neighbor interactions forming a charge-density wave, such that the states with N= [0, 1, 0, 1,...] and N= [1, 0, 1, 0, ...] are (nearly) degenerate for large L (along the ring; in the folded order something like [0 1 1 0 0 1 1 0 0 1 1 ...] or [1 0 0 1 1 0 0 1 1 0 0 ...] ), I wouldn't be surprised to see only one of them, at least for large enough L where the degeneracy is smaller than the DMRG precision; the "true" groundstate for finite L will always be a superposition of them, I believe.

That being said I'm not sure what "traditional" DMRG you're referring to, and what implementation you're using for that?
As far as I understood the "traditional" DMRG it's basically the same algorithm just described in a different language.

I should have warned you that the extra long-range coupling of the PBC implies that you need a much larger MPS bond dimension; formally up to the square of the chi for OBC (a bit less, actually, depending on the decay of singular values, but the scaling is square!).
You can easily see this if you take the AKLT of the PBC MPS model and force it into the OBC MPS.
You need 2x2 matrices for the PBC MPS ring (when you write psi = sum tr(A ....)).
Writing it as an OBC MPS, you need one 1x4 "vector" (just reshaping one A, followed by block-diagonal 4x4 matrices with the original A and 2x2 identities as contents.

Did you account for that? I.e. did you allow for much larger bond dimensions?
Did you try a small system (L<=14), where you don't need to truncate at all? There you should get the ED results and definitely still get translation invariance!
minger
Posts: 3
Joined: 09 Jan 2021, 06:42

Re: finite open, finite periodic and infinite periodic chains

Post by minger »

Newbie in TeNPy, thanks for this great py-package. :D

Following above discussion, by setting "bc_x=periodic" and "order="folded"",
I have tried sucessfully building a CouplingMPOModel and checking the coupling terms by the code snippet Johanes given.

Code: Select all

print("order:")
print(M.lat.order)
print("coupling terms:")
print(M.all_coupling_terms().to_TermList())
But when I use TEBD-Engine to do real time evolution, the code thrrow errors for no "H_bond"?
as mentioned in above discussion, is tebd not worked and need dmrg especiall the [mixer](https://tenpy.readthedocs.io/en/latest/ ... Mixer.html) ?
User avatar
Johannes
Site Admin
Posts: 413
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: finite open, finite periodic and infinite periodic chains

Post by Johannes »

Even though the model is originially nearest-neighbor on the periodic chain, it will have longer-range interactions in the (open-boundary) MPS - with default ordering, there is one interaction going from site 0 to site L-1, or if you use the "folded" order, most of the originally nearest-neighbor interactions will become next-nearest neighbor.
TEBD throws the "no H_bond" error because it only works if there is a representation of H in terms of nearest-neighbor bonds.
You can either try grouping sites before appying the TEBD.
However, I'd rather recommend to use an alternative time evolution method instead, e.g. the tenpy.algorithms.mpo_evolution.ExpMPOEvolution or tenpy.algorithms.tdvp.TDVPEngine.
minger
Posts: 3
Joined: 09 Jan 2021, 06:42

Re: finite open, finite periodic and infinite periodic chains

Post by minger »

Johannes wrote: 04 Feb 2021, 19:37 Even though the model is originially nearest-neighbor on the periodic chain, it will have longer-range interactions in the (open-boundary) MPS - with default ordering, there is one interaction going from site 0 to site L-1, or if you use the "folded" order, most of the originally nearest-neighbor interactions will become next-nearest neighbor.
TEBD throws the "no H_bond" error because it only works if there is a representation of H in terms of nearest-neighbor bonds.
You can either try grouping sites before appying the TEBD.
However, I'd rather recommend to use an alternative time evolution method instead, e.g. the tenpy.algorithms.mpo_evolution.ExpMPOEvolution or tenpy.algorithms.tdvp.TDVPEngine.
thx for the reply, I use TDVPEngine for real time evolution, but the warnings are always like this.

Code: Select all

    for n in range(int(tmax / dt_measure + 0.5)):
        # each step of n means a dt_meausre time elapsed.
        # run dt every step for norm test!!!!
        for n_ in range(N_steps):
            tdvp_engine.run()
            psi.canonical_form(renormalize=True)

        # measure obsevables
        num_exp = list(map(lambda k: cal_expectation(k,psi.copy(), range(L)))
        num_exp_lat = M.lat.mps2lat_values(num_exp)
        num_dist.append(num_exp_lat)
        times.append(tdvp_engine.evolved_time)

with TDVP parameters:

Code: Select all

    tdvp_params = {'start_time': 0,
                    'dt': args.dt,
                    'active_sites':2,
                    'N_steps':1,
                    'trunc_params' : {'chi_max': args.chi_max,
                    'svd_min': args.svd_min,
                    'trunc_cut': args.trunc_cut
                    },
                    
                     lanczos_options : {'reortho': True}
                    }

Code: Select all


poorly conditioned Lanczos! |psi_0| = 0.998860
poorly conditioned Lanczos! |psi_0| = 1.001141
poorly conditioned Lanczos! |psi_0| = 0.998860
poorly conditioned Lanczos! |psi_0| = 1.001141
poorly conditioned Lanczos! |psi_0| = 0.998859
poorly conditioned Lanczos! |psi_0| = 1.001142
poorly conditioned Lanczos! |psi_0| = 0.998860
poorly conditioned Lanczos! |psi_0| = 0.998861
poorly conditioned Lanczos! |psi_0| = 1.001140
poorly conditioned Lanczos! |psi_0| = 0.998861
poorly conditioned Lanczos! |psi_0| = 1.001140
...
The Hamiltonian is non-hermitian $H=h1+1.0j*h2$, the expectation value of obervables alway have a small imaginary part, this may caused by the non-hermitian, I guess!



the model I am working with pbc is as follows,

Code: Select all

class DissChain(CouplingMPOModel):
    def __init__(self, model_params):
        model_params = asConfig(model_params, self.__class__.__name__)
        model_params.setdefault('lattice', "Chain")
        CouplingMPOModel.__init__(self, model_params)

    def init_sites(self, model_params):
        conserve = model_params.get('conserve', None)
        site = MYSpinHalfSite(conserve=conserve)
        return site

    def init_terms(self, model_params):
        Omega = np.asarray(model_params.get('Omega', 1.))
        kappa = np.asarray(model_params.get('kappa', 0.))
        gamma = np.asarray(model_params.get('gamma', 1.))
        L = model_params.get('L',None)

        bc_lat_order = model_params.get('order', 'default')

	# **********  add coupling for pbc here. *********
        if bc_lat_order=='folded':
            # only for i=0 and L-1
            self.add_coupling(Omega, 0, 'Xl1', 0, 'Numl1', L-1)

        for u1, u2, dx in self.lat.pairs['nearest_neighbors']:
            # Two-site H_{i,i+1}
            self.add_coupling(Omega, u1, 'Xl1', u2, 'Numl1', dx)

        for u in range(len(self.lat.unit_cell)):
            self.add_onsite(1.0j*gamma, u, 'SmSm')
            
Any other techniques can be used to renormalize the `psi` more efficiently, or I am on the wrong direction for solving real-time evolution with periodic boundary condition ? Thanks in advance.
User avatar
Johannes
Site Admin
Posts: 413
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: finite open, finite periodic and infinite periodic chains

Post by Johannes »

Whoa, I wasn't aware that you want to run it for non-hermitian H. Lancos implicitly assumes that H is hermitian! For that reason at least TeNPy's implementation of TDVP (which uses Lancos to do the local time evolution) does not work for that case!

Dropping the hermiticity of H is in general very dangerous terrain. I believe TEBD should work if you use left-right sweeps instead of the Brick-wall fashion, TDVP definitely fails. Not sure about the ExpMPOEvolution right now...
minger
Posts: 3
Joined: 09 Jan 2021, 06:42

Re: finite open, finite periodic and infinite periodic chains

Post by minger »

Johannes wrote: 13 Apr 2021, 23:58 Whoa, I wasn't aware that you want to run it for non-hermitian H. Lancos implicitly assumes that H is hermitian! For that reason at least TeNPy's implementation of TDVP (which uses Lancos to do the local time evolution) does not work for that case!

Dropping the hermiticity of H is in general very dangerous terrain. I believe TEBD should work if you use left-right sweeps instead of the Brick-wall fashion, TDVP definitely fails. Not sure about the ExpMPOEvolution right now...
Well, finally I want to soloving open system real time evolution with both open and periodic boundary condition.
- for OBC case, I use TEBD and get exactly the same long-time evolution results(L=12) with master equation solving by using QuTip.
- for PBC case, with "folded" trick and TDVPEngine, I still failed to get nice coincidence with master eq.

thank you Jahannes, I will try the`ExpMPOEvolution`, and I would be grateful if you have any suggestions. :D
Post Reply