def SziOp(N,S,index, Jcurr=0, full='False'): Slist = to.Statelist(N,S,Jcurr=Jcurr,full=full) Szidiag = [] for state in Slist: if state[index-1] == 1: sign = 1 elif state[index-1]== 0: sign = -1 Szidiag.append(sign*0.5) Szi = sp.sparse.diags(Szidiag) return(Szi)
def blockH(N, S, nlegs, c, TotalSz=0, Js=[1, 1], gamma=[0, 0], phi=[0, 0], full='False'): #inistate=t.initialState(N,S,TotalSz) #Generating the StateAltlist is faster, but accessing it is slower Slist = t.Statelist(N, S, Jcurr=TotalSz, full=full) Sdict = t.Statedict(Slist) Ipairs = t.Intpairs(N, nlegs) #Intpairs(N,nlegs) Nint = int(N / nlegs) H = [] #print(Slist) ###Here we generate the site Hamiltonian for the ith spin for site in range(0, N): start = time.time() siteindex = int(site) Siteint = [] #Pulls interaction pairs for the ith site e.g. site=1: S1*S2, S1*S3,...,S1*Sn for pair in Ipairs: if pair[1] == siteindex: Siteint.append(pair) else: Siteint = Siteint #prepare information to generate sparse site-Hamiltonian rows = [] cols = [] data = [] for exchange in Siteint: #The interaction constants are determined by direction, which is referenced in Intpairs(). if exchange[0] == 1: J = Js[0] elif exchange[0] == 2: J = Js[1] m = exchange[1] #site1 index n = exchange[2] #site2 index #### def interaction(interinfo): i = interinfo[0] def getrowcol(iter1): j = Sdict[''.join(map(str, iter1[1]))] return (i, j, J * iter1[0]) A = t.ExOp(m, n, interinfo[1]) #list of tuples: info for row and col indicies with corresponding matrix coefficient:(row,col,coeff) #for a corresponding state(row) row_col_data = map(getrowcol, A) return (row_col_data) row_col_info = list(map(interaction, enumerate(Slist))) for item in row_col_info: print(list(item)) #### ''' for i,state in enumerate(Slist): interact = t.ExOp(m,n,state)#Performs interaction between site1 and site2: returns [(coeff1,state),(coeff2,copuledstate)] Where the magic happens. Here we reference the dictionary to see which states couple with 'state', and we record the coordinates and coefficients. k is a tuple (coeff,state), k[1] gives the state which is used as a key to find the column index. Together with the index i, we have the coordinate for the coefficient given by k[0]. for k in interact: # j = Sdict[''.join(map(str,k[1]))] rows.append(i) cols.append(j) data.append(J*k[0]) ''' #generate disorder terms, which only lie on the diagonal, along direction 1 gamma1 = gamma[0] gamma2 = gamma[1] phi1 = phi[0] phi2 = phi[1] disorder1 = [] disorder2 = [] rowindex = rowfunc(N, nlegs, siteindex) colindex = siteindex % Nint sitephase1 = colindex + 1 sitephase2 = rowindex + 1 g1 = gamma1 * np.cos( 2 * np.pi * c * sitephase1 + phi1) #gives disorder only along x-direction(or direction 1) g2 = gamma2 * np.cos(2 * np.pi * c * sitephase2 + phi2) for state in Slist: if state[siteindex] == 0: ms = -0.5 elif state[siteindex] == 1: ms = 0.5 disorder1.append(ms * g1) disorder2.append(ms * g2) dim = int(len(Slist)) disorderH1 = sp.sparse.diags(disorder1) disorderH2 = sp.sparse.diags(disorder2) interactionH = sp.sparse.coo_matrix((data, (rows, cols)), shape=(dim, dim)) siteH = interactionH + disorderH1 + disorderH2 H.append(siteH) end = time.time() #print(end-start) return (H)
def reducedDM(energystate, NAsites, NBsites, N, S, Jcurr=0, full='False'): ''' energystate: eigen energy state in decreasing binary basis NAsites/NBsites: arrays with corresponding site indecies for system A/B N: total number of sites S: total spin of each site ''' ''' Generate coefficients ''' coeffs1 = [(i, coeff) for i, coeff in enumerate(energystate)] coeffdict1 = dict(coeffs1) ###Generate list and dictionary of full binary basis with total spin Jcurr Slist = to.Statelist(N, S, Jcurr=Jcurr, full=full) Sdict = to.Statedict(Slist) ####Generate system-basis based off size of system A/B Na = len(NAsites) Nb = len(NBsites) basiskeyA = list(itertools.product([0, 1], repeat=Na)) statesA = [] for i, basis in enumerate(basiskeyA): basis_state = [basis[i] for i in range(len(basis))] statesA.append(basis_state) basiskeyB = list(itertools.product([0, 1], repeat=Nb)) SAdict = to.Statedict(statesA) statesB = [] for i, basis in enumerate(basiskeyB): basis_state = [basis[i] for i in range(len(basis))] statesB.append((i, basis_state)) ####Figure out which states in basis B are connected to A via full binary state Bconnect = [] for stateB in statesB: connected = [stateB[0], []] ###array used to form dictionary for states in Slist: B = [states[i2] for i2 in NBsites] #used to compare overall state with stateB if stateB[1] == B: #if stateB and overall state are compatible A = [states[i1] for i1 in NAsites] ###finds connected A state stateindex = Sdict[''.join(map( str, states))] ###finds stateindex to look up coefficient stateindexA = SAdict[''.join(map( str, A))] ###finds index of connected A state ###stores index of state A, and corresponding coefficient for a given State B connected[1].append((stateindexA, coeffdict1[stateindex])) else: connected = connected Bconnect.append(connected) ###connectD stores all necessary information to find out which states are entangled, ###and what the coefficient is connectD = dict(Bconnect) dim = int(len(statesA)) #rhoA is based on dimensions of system A rho = [] for i in range(len(statesB)): trace = connectD[i] #pulls up specific info for a given B state row = [] col = [] data = [] ''' Essentially all state indicies for the given A states are iterated over, the corresponding coefficients are connected to state A given a specific state B. ''' for info1 in trace: for info2 in trace: row.append(info1[0]) col.append(info2[0]) data.append(info1[1] * info2[1].conjugate()) rhoAB = sp.sparse.coo_matrix((data, (row, col)), shape=(dim, dim)) rho.append(rhoAB) rhoA = sum(rho) return (rhoA)
import itertools as it import Hamiltonians as H import numpy as np from matplotlib import pyplot as plt ''' Find variance function <Sz^2>- <Sz>^2 where Sz is the total Sz operator for system A . ''' N = 6 S = 0.5 Nstates = 10 nlegs = 3 c = np.sqrt(2) Na = 3 Slist = to.Statelist(N, S) ms = [] for i, state in enumerate(Slist): mstate = 0 for spin in it.islice(state, Na): if spin == 0: m = -1 elif spin == 1: m = 1 mstate = mstate + m ms.append((i, mstate)) mdict = dict(ms)
nlegs, c, Js=[1, 1], gamma=[0.0, 4.0], full='True') Hfull = sum(Htot).todense() eigs, vecs = np.linalg.eigh(Hfull) Eigvecs = np.asarray(vecs.T) print(list(eigs)) Envecs = [] for vc in Eigvecs: A = ex.Expand(vc, S, N, Jcurr) Envecs.append(A) statelist = t.Statelist(N, S) Statevecs = [] for state in statelist: vec = [] up = [1, 0] down = [0, 1] for i in state: if i == 0: vec.append(down) elif i == 1: vec.append(up) Basestate = ''.join(map(str, state)) B = [Basestate,
def blockH(N, nlegs, c, S=0.5, TotalSz=0, Js=[1, 1], gamma=[0, 0], phi=[0, 0], modex1='open', modey1='open', full='False', uniform='False'): #We often only look at state with some total Sz, the default is Sz=0. If we wish to look #at the Full, block-diagonalized Hamiltonian simply set full='True' #be warned that the Hilbert dimensions for the Full Hamiltonian goes as 2**N where N is the number of spins. #Exploring the Full Hamiltonian is incredibly resource intensive for the average computer. #nlegs is along x-direction i.e. it gives the number or columns or legs of the ladder #N/nlegs gives the number of rows #Generating the StateAltlist is faster, but accessing it is slower Slist = t.Statelist(N, S, Jcurr=TotalSz, full=full) Sdict = t.Statedict( Slist ) #generates a dictionary where each state has an index, and so we have an ordered basis Ipairs = t.Intpairs(N, nlegs, modex=modex1, modey=modey1) #generates interaction pairs as tuples Nint = int(N / nlegs) H = [] #our list of site Hamiltonians ###Here we generate the site Hamiltonian for the ith spin for site in range(0, N): siteindex = int(site) Siteint = [] #Pulls interaction pairs for the ith site e.g. site=1: S1*S2, S1*S3,...,S1*Sn for pair in Ipairs: if pair[1] == siteindex: Siteint.append(pair) else: Siteint = Siteint #prepare information to generate sparse site-Hamiltonian rows = [] cols = [] data = [] for i, state in enumerate(Slist): for exchange in Siteint: #The interaction constants are determined by direction, which is referenced in Intpairs(). if exchange[0] == 1: J = Js[0] elif exchange[0] == 2: J = Js[1] m = exchange[1] n = exchange[2] interact = t.ExOp( m, n, state) #returns [(coeff1,state),(coeff2,copuledstate)] ''' Where the magic happens. Here we reference the dictionary to see which states couple with 'state', and we record the coordinates and coefficients. k is a tuple (coeff,state), k[1] gives the state which is used as a key to find the column index. Together with the index i, we have the coordinate for the coefficient given by k[0]. ''' for k in interact: j = Sdict[''.join( map(str, k[1]) )] #here we reference the dictionary to determine j rows.append(i) cols.append(j) data.append(J * k[0]) #generate disorder terms, which only lie on the diagonal, along a direction or combination thereof gamma1 = gamma[0] gamma2 = gamma[1] phi1 = phi[0] phi2 = phi[1] disorder1 = [] disorder2 = [] rowindex = rowfunc(N, nlegs, siteindex) #gets row index colindex = siteindex % Nint sitephase1 = colindex + 1 sitephase2 = rowindex + 1 ##Here we account for the regime where we only want to look at uniform randomness for our disorder term. if uniform == 'True': g1 = random.uniform(-gamma1, gamma1) g2 = 0 elif uniform == 'False': phi1 = phi[0] phi2 = phi[1] #technically these are just two disorder terms that are added to the hamiltonian. Their dependence on the x(y)-direction is simply due to the model; they can be anything really. g1 = gamma1 * np.cos(2 * np.pi * c * sitephase1 + phi1) #gives disorder along x-direction g2 = gamma2 * np.cos(2 * np.pi * c * sitephase2 + phi2) #gives disorder along y-direction #this determines if the ith-spin is spin up or down and gives the appropriate spin value to be multiplied to our disorder terms for state in Slist: if state[siteindex] == 0: ms = -0.5 elif state[siteindex] == 1: ms = 0.5 disorder1.append(ms * g1) disorder2.append(ms * g2) #generates sparese, disorder matrices for the ith spin dim = int(len(Slist)) disorderH1 = sp.sparse.diags(disorder1) disorderH2 = sp.sparse.diags(disorder2) # each site Hamiltonian is simply the Heisenberg interaction, plus any disorder. interactionH = sp.sparse.coo_matrix((data, (rows, cols)), shape=(dim, dim)) siteH = interactionH + disorderH1 + disorderH2 H.append(siteH) return (H)