from __future__ import division import numpy as np import scipy as sp, scipy.linalg import matplotlib.pyplot as plt import sys # Import pure state MPS import iMPS import iTEBD # Set system size L = 10 # Set local Hilbert space dimension (i.e. how many particles per site = d - 1) d = 2 # Create a new MPS qwMPS = iMPS.iMPS(L, d, 10) # Create an array of zeros... sites = [1,0]*int(L/2) # Use this array as a configuration of how many particles are on each site qwMPS.set_product_state(sites) print qwMPS.Q # Define operators b = np.diag(np.sqrt(range(d-1)+np.ones(d-1)),1) # Annihilation bdag = np.diag(np.sqrt(range(d-1)+np.ones(d-1)),-1) # Creation dens = np.dot(bdag, b) # Density operator occ = [np.real(qwMPS.measure([dens], [s])) for s in range(L)]
densup = np.dot(cdagup, cup) densdown = np.dot(cdagdown, cdown) # Heisenberg model for spin-1/2 t = 1 H = t * (np.kron(cdagup, cup) + np.kron(cup, cdagup) + np.kron(cdagdown, cdown) + np.kron(cdown, cdagdown)) + np.kron( np.dot(cdagup, cdagup), identity) # Imaginary time propagator dt = 0.01 U = np.reshape(sp.linalg.expm(-dt * 1j * H), (d, d, d, d)) H = np.reshape(H, (d, d, d, d)) L = 20 testMPS = iMPS.iMPS(L, d, 10) sites = 3 * np.ones(L) sites[4] = 2 sites[16] = 1 testMPS.set_product_state(sites) # Perform 5000 time steps total_dens_up = [] total_dens_down = [] updowncorr = [] for n in xrange(500): # Update both bonds for i in xrange(0, L - 1, 2):
Sy = 1 / 2 * np.array([[0, -1j], [1j, 0]], dtype=np.complex128) Sz = 1 / 2 * np.array([[1, 0], [0, -1]], dtype=np.complex128) # Create a new MPS instance. # For the infinite case, a single site unit cell (L=1) would really suffice. # However, the iTEBD algorithm needs to act on bonds, and so the minimum number # of sites we need is 2. L = 2 # The local Hilbert space is that of a spin-1/2, so 2-dimensional d = 2 # The bond-dimension is the most important parameter of the MPS, it sets the 'complexity' # of the wavefunction. The larger the better, but at a price of MUCH slower numerics. # Best is to start with a small value (~10) and slowly increase. If the final result # of the numerics no longer changes drastically with increasing D, we are safe. D = 30 testMPS = iMPS.iMPS(L, d, D) # We will be performing imaginary time evolution, so we want to have some overlap # with the actual groundstate. Using a random initial state, we will most likely # have such overlap. testMPS.set_random_state() # Heisenberg model for spin-1/2 # Since we are considering the infinite system, we consider only a single # type of bond. Hence all we need to define is the Hamiltonian for this bond. H = np.kron(Sx, Sx) + np.kron(Sy, Sy) + np.kron(Sz, Sz) # Imaginary time propagator # The trotter step-size dt is an important parameter. If it is too large, # we will not converge to the groundstate (and/or build up large errors). dt = 0.01
splus = np.array([[0, 1], [0, 0]], dtype=np.complex128) # Define separate superoperators for the spins, so that we may use them # in measurements ssx = superOperator(sx, d) ssy = superOperator(sy, d) ssz = superOperator(sz, d) # Drive gammaLplus = 1 #0.3 gammaLminus = 0 #0.5 gammaRplus = 0 #0.1 gammaRminus = 1 #0.5 # The initial state is a simple product state MPS = iMPS.iMPS(4, 2, D, pure=False) MPS.set_product_state([1, 0] * 2) # Function to compute H and the time evolution operator U for the various values of parameters def compute_H_and_U(Jx, Jy, mu, dt): """Compute Hamiltonian and time evolution operators""" u = np.zeros((L, d**2, d**2, d**2, d**2), dtype=np.complex128) u2 = np.zeros((L, d**2, d**2, d**2, d**2), dtype=np.complex128) for site in range(L): # Define Hamiltonian h = -Jx * np.kron(sx, sx) - Jy * np.kron( sy, sy) - mu * 0.5 * (np.kron(sz, s0) + np.kron(s0, sz)) if site == 0: