term_correlation_function_left for MPSEnvironment

How do I use this algorithm? What does that parameter do?
Post Reply
dorf
Posts: 22
Joined: 16 Feb 2021, 16:34

term_correlation_function_left for MPSEnvironment

Post by dorf »

Hi,
I want to calculate the expectation value \(\langle \psi| S_i^z S_{i+1}^z |\phi \rangle\).

Because the two MPS are different, I create a tenpy.networks.mps.MPSEnvironment. What is the best way to compute the above correlation function? For tenpy.networks.mps.MPS there is tenpy.networks.mps.MPS.term_correlation_function_left() which I can use to define a left and right operator, but it seems that MPSEnvironment does not have this functionality. In that case, should I loop over \(i\), apply the local operators and then calculate the overlap via tenpy.networks.mps.MPSEnvironment.full_contraction()?

Thank you
User avatar
Johannes
Site Admin
Posts: 337
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: term_correlation_function_left for MPSEnvironment

Post by Johannes »

Really, the proper functions is to adjust the *correlation_function methods of the MPS to the MPSEnvironment, see the new Issue #173.

If you really just need the nearest-neighbor correlations, the expectation_value actually supports this:

Code: Select all

import tenpy

s = tenpy.networks.site.SpinHalfSite()
psi = tenpy.networks.mps.MPS.from_singlets(s, 10, [(i,i+1) for i in range(0, 10, 2)])
print(psi.correlation_function('Sp', 'Sm'))
SpSm = tenpy.networks.site.kron(s.Sp, s.Sm, group=False)
print(psi.expectation_value(SpSm))
assert np.allclose(psi.expectation_value(SpSm), np.diag(psi.correlation_function('Sp', 'Sm'), k=1))
print(tenpy.networks.mps.MPSEnvironment(psi, psi).expectation_value(SpSm)/psi.norm/psi.norm)
I assume you're working with finite MPS here? For Finite MPS, applying local operator is fine, even though it's definitely not efficient...
For infinite MPS, using the strategy with `apply_local_op` and a subsequent `overlap` is "wrong" because it would apply the operator in each MPS unit cell, i.e. calculate something like \( \langle \psi | \left(\prod_{n \in \mathbb{Z}} S^z_{i+n*L}\right) S^z_{i+1}|\phi \rangle \) (or similar, depending on how you set it up exactly).

Edit: correctly normalize MPSEnvironment expectation values
dorf
Posts: 22
Joined: 16 Feb 2021, 16:34

Re: term_correlation_function_left for MPSEnvironment

Post by dorf »

Dear Johannes,
yes, I am using finite MPS.
Thank you very much for opening up the issue on github.
In my case it's actually not i+1, but actually i+2, because I am working on a ladder.

I am actually not sure whether I understand why the example that you kindly provided works. So is it because you set group=False in 'kron' that 'Sm' is evaluated on the neighboring site?
Thanks!

Edit: Oh and shouldn't one also divide by some norm in the case of using an MPSEnvironment for an expectation value?
User avatar
Johannes
Site Admin
Posts: 337
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: term_correlation_function_left for MPSEnvironment

Post by Johannes »

You can also do

Code: Select all

SpIdSm = tenpy.networks.site.kron(s.Sp, s.Id, S.Sm, group=False)
The tenpy.networks.site.kron function with n input onsite operators generates an operator acting on n consecutive sites at once, with n input and n output legs, e.g for n=3, p0*, p1*, p2*, p0, p1, p2.

The expectation_value functions can handle such generic n-site operators. You can even add them before if you want, e.g.

Code: Select all

SmIdSp = tenpy.networks.site.kron(s.Sm, s.Id, S.Sp, group=False)
sigma_x_NNN = SmIdSp + SpIdSm
psi.expectation_value(sigma_x_NNN)
While this is a good trick for (next) nearest neighbors, this becomes expenonentially expensive with the number of sites n involved, so don't concatenate too many of them...

Oh, and yes, you should in general divide by the norm, even though it's guaranteed to be 1 in this example. Edit above.
Post Reply