finite open, finite periodic and infinite periodic chains
finite open, finite periodic and infinite periodic chains
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
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
Re: finite open, finite periodic and infinite periodic chains
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.
Re: finite open, finite periodic and infinite periodic chains
First of all thanks for providing this feature!Johannes wrote: ↑15 Oct 2019, 15:15(..)
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 useorder='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.
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?
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)
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)
Re: finite open, finite periodic and infinite periodic chains
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
Example:
The output:
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.
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)
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 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.
Re: finite open, finite periodic and infinite periodic chains
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?
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?
Re: finite open, finite periodic and infinite periodic chains
Yes, the MPS is still finite and OBC-style
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!
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!
Re: finite open, finite periodic and infinite periodic chains
Newbie in TeNPy, thanks for this great py-package.
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.
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) ?
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())
as mentioned in above discussion, is tebd not worked and need dmrg especiall the [mixer](https://tenpy.readthedocs.io/en/latest/ ... Mixer.html) ?
Re: finite open, finite periodic and infinite periodic chains
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.
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.
Re: finite open, finite periodic and infinite periodic chains
thx for the reply, I use TDVPEngine for real time evolution, but the warnings are always like this.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.
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)
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 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')
Re: finite open, finite periodic and infinite periodic chains
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...
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...
Re: finite open, finite periodic and infinite periodic chains
Well, finally I want to soloving open system real time evolution with both open and periodic boundary condition.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...
- 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.