Page 1 of 1

Constructing a product state of rotated spins

Posted: 03 Dec 2019, 14:02
by SJThomson
Hi there,

This is just a quick request for clarification about a particular bit of TenPy syntax. I'm trying to initialise a product state in TenPy's spin chain class which allows me to rotate individual spins by some specified angle, before doing TDVP and computing the quench dynamics starting from this state. I see how to initialise spins in "up" or "down" states using the keywords, and that in the documentation it is written that "For Spin S=1/2, you could get a state with all sites pointing in negative x-direction with: neg_x_state = np.array([1., -1.])...". This is probably a very basic question, but I'm looking for clarification as to what the two numbers in the array actually refer to? I can't find it clearly stated in the documentation in the case of spins.

I'm asking because if I set the the spin state equal to np.array([np.sin(theta/2), np.cos(theta/2)]), where theta is my angle of rotation, I seem to get the desired result, but before I get too far with this calculation, I want to clarify that the syntax does indeed mean what I think it means. The following code snippet should hopefully illustrate what I'm trying to do, here for the case of a single rotated spin in the centre of a chain of up spins:

Code: Select all

model_params = dict(L=L, Jx=J, Jy=J, Jz=J, bc_MPS='finite', conserve=None, verbose=0)
M = SpinChain(model_params)
theta_state = np.array([np.sin(theta/2), np.cos(theta/2)])
product_state = ["up"]*L
product_state[L//2] = theta_state/np.linalg.norm(theta_state)
psi = MPS.from_product_state(M.lat.mps_sites(), product_state, bc=M.lat.bc_MPS)

Re: Constructing a product state of rotated spins

Posted: 03 Dec 2019, 21:31
by Johannes
Yes, that is indeed what you want.
Just for reference, here is the documentation: from_product_state.
If you look at the example, one line below the state is normalized, such that it gets np.array([1/sqrt(2), -1/sqrt(2)]).
This is the negative-x state of a spin-1/2 and equivalent to the np.array([np.sin(theta/2), np.cos(theta/2)]) you wrote down for theta = 1.5* np.pi .

Do you have a suggestions how to document it more clearly? ;)

Re: Constructing a product state of rotated spins

Posted: 04 Dec 2019, 14:19
by SJThomson
Hi Johannes,

Thanks for the reply! That makes sense, and as you point out, my definition of the rotated spin gives the correct normalised value for the negative-x state.

So far, so good. My confusion comes from the way that two different spin chains (in this case, TFIChain and SpinChain with S=1/2) seem to interpret the arrays differently. The following bit of code should illustrate: it runs over four arrays, [[1,0],[0,1],[1,1],[1,-1]], initialises the TFI and XXZ models (in this case, XXX since all couplings are the same), then computes the Sz and Sx expectation values on the central site for each.

Code: Select all

from tenpy.networks.mps import MPS
from tenpy.models.tf_ising import TFIChain
from tenpy.models.spins import SpinChain
import numpy as np

L = 5

for state in [[1,0],[0,1],[1,1],[1,-1]]:
    print('Array: ', state)
    
    # Transverse Ising
    model_params = dict(L=L, J=1, g=1, bc_MPS='finite', conserve=None, verbose=False)
    M = TFIChain(model_params)
    theta_state = np.array(state)
    product_state = ["up"]*L 
    product_state[L//2] = theta_state/np.linalg.norm(theta_state)
    print(M.lat.mps_sites())
    psi = MPS.from_product_state(M.lat.mps_sites(), product_state, bc=M.lat.bc_MPS)
    print('Ising <S_z>', psi.expectation_value('Sz')[L//2])
    print('Ising <S_x>', psi.expectation_value('Sx')[L//2])
            
    # XXZ        
    model_params = dict(S=0.5,L=L,Jx=1,Jy=1,Jz=1, bc_MPS='finite', conserve=None, verbose=0)
    M = SpinChain(model_params)
    theta_state = np.array(state)
    product_state = ["up"]*L 
    product_state[L//2] = theta_state/np.linalg.norm(theta_state)
    print(M.lat.mps_sites())
    psi = MPS.from_product_state(M.lat.mps_sites(), product_state, bc=M.lat.bc_MPS)
    print('XXZ <S_z>', psi.expectation_value('Sz')[L//2])
    print('XXZ <S_x>', psi.expectation_value('Sx')[L//2])
The output given is:

Code: Select all

Array:  [1, 0]
Ising <S_z> 0.5
Ising <S_x> 0.0
XXZ <S_z> -0.5
XXZ <S_x> 0.0

Array:  [0, 1]
Ising <S_z> -0.5
Ising <S_x> 0.0
XXZ <S_z> 0.5
XXZ <S_x> 0.0

Array:  [1, 1]
Ising <S_z> 0.0
Ising <S_x> 0.4999999999999999
XXZ <S_z> 0.0
XXZ <S_x> 0.4999999999999999

Array:  [1, -1]
Ising <S_z> 0.0
Ising <S_x> -0.4999999999999999
XXZ <S_z> 0.0
XXZ <S_x> -0.4999999999999999
So it seems that there's a relative minus sign between the z-components of the Ising and XXZ models. This is the reason I'm asking for what the elements of the arrays refer to, and for this to be clearly signposted in the documentation. Is there some difference in definition between Ising and XXZ models, or am I missing something?

Re: Constructing a product state of rotated spins

Posted: 04 Dec 2019, 14:30
by SJThomson
Actually, I think I've found my answer. The only place I could see the model making a difference to the MPS.from_product_state command was in the term 'M.lat.nps_sites()'. Checking this, it turns out that the TFIChain uses SpinHalfSite and the SpinChain uses SpinSite. Digging through the source code for these reveals the following comment (lines 780-785 in SpinSite):

Code: Select all

        # Note: For S=1/2, Sy might look wrong compared to the Pauli matrix or SpinHalfSite.
        # Don't worry, I'm 99.99% sure it's correct (J. Hauschild)
        # The reason it looks wrong is simply that this class orders the states as ['down', 'up'],
        # while the usual spin-1/2 convention is ['up', 'down'], as you can also see if you look
        # at the Sz entries...
        # (The commutation relations are checked explicitly in `tests/test_site.py`)
So I guess that answers my question - the definition is slightly different for both models. I think that clears things up!

Re: Constructing a product state of rotated spins

Posted: 05 Dec 2019, 23:09
by Johannes
You're absolutely right, the different type of "Site" makes the difference here.
That's certainly a thing to keep in mind, so I actually added your example (slightly extended) to the documentation of from_product_state.
Do you agree that it is more clear now?

Re: Constructing a product state of rotated spins

Posted: 09 Dec 2019, 10:59
by SJThomson
Yeah, that's perfect. Thanks!