def __init__(self, N_v, N_h, beta, couplings): # The size of hilbert space associated with the hidden units self.hidden_dim = 2**N_h # Spind numbers self.N_spins = N_v + N_h self.N_h = N_h # Fields are stored as bonds acting over a single site self.bonds = [[e] for e in (range(self.N_spins) + range(self.N_spins))] # Add a set of semi-restricted couplings semi_rest, self.fully_connected_offset = Hbuilder.semiRBM_Connected(N_v, N_h) self.bonds = self.bonds + semi_rest self.couplings = couplings self.N_couplings = len(self.bonds) # Introduce the matrix form of local elements in the Hamiltonian I = np.eye(2) X = np.array([[0, 1], [1, 0]]) Z = np.array([[1, 0], [0, -1]]) # The Hamiltonian self.H = np.zeros((2**self.N_spins, 2**self.N_spins)) # The list of local operators we are interested in. # The elements of the list are tuples (operator_representation, is_diagonal_flag) self.oper_list = [] # Build and store those objects at the same time for index, (coupling, bond) in enumerate(zip(couplings, self.bonds[:])): # The operator type can be determined by its index if index in range(self.N_spins, self.N_spins*2): oper = Hbuilder.EmbedOper(X, self.N_spins, bond+[1.0]) # for the off-diagonal operators, store both row and column indices of non-zero elements self.oper_list += [(oper.nonzero(), False)] else: oper = Hbuilder.EmbedOper(Z, self.N_spins, bond+[1.0]) # keep track only of the diagonal (non-zero) elements for the diagonal operators self.oper_list += [(oper.diagonal(), True)] self.H = self.H + oper*coupling # Compute the full unnormalized density matrix self.beta = beta self.rho = np.matrix(mexp.expm(-self.H*beta), copy=False) # Store separately its diagonal elements and normalize them self.norm_rho_diag = np.diagonal(self.rho).copy() self.normalization = np.sum(self.norm_rho_diag) self.norm_rho_diag /= self.normalization
def __init__(self, N, beta, **kwargs): self.Ns = N self.Nb = len(kwargs['Z2']) I = np.eye(2) X = np.array([[0, 1], [1, 0]]) Z = np.array([[1, 0], [0, -1]]) self.H = np.zeros((2**N, 2**N)) #I = sparse.eye(2, format="csc") #X = sparse.csc_matrix(np.array([[0, 1], [1, 0]])) #Z = sparse.csc_matrix(np.array([[1, 0], [0, -1]])) #self.H = sparse.csc_matrix((2**N, 2**N)) for itype, bonds in kwargs.iteritems(): if itype == 'X': oper = X else: oper = Z for bond in bonds: self.H = self.H + Hbuilder.EmbedOper(oper, N, bond) self.beta = beta #self.rho = np.matrix(slin.expm(-self.H*beta), copy=False) #self.H = np.matrix(self.H) #self.rho = mexp.expm(-self.H*beta) self.rho = np.matrix(mexp.expm(-self.H*beta), copy=False) #self.rhoN = self.rho/np.sum(self.rho.diagonal()) self.rhoN = np.diagonal(self.rho).copy() self.rhoN /= np.sum(self.rhoN) #print 'X1: ', kwargs['X'][:,-1] #print 'Z1: ', kwargs['Z1'][:,-1] #print 'Z2: ', kwargs['Z2'][:,-1] #print "max H: ", np.amax(np.abs(np.array([self.H.max(), self.H.min()]))),\ # "max rho: ", np.amax(np.abs(np.array([self.rho.max(), self.rho.min()]))),\ # "Z: ", np.sum(self.rho.diagonal()) self.oper1Zs = [] self.operXs = [] for site in range(N): self.oper1Zs += [Hbuilder.EmbedOper(Z, N, [site, 1.0], True).diagonal()] self.operXs += [sparse.csr_matrix( Hbuilder.EmbedOper(X, N, [site, 1.0], True) ).nonzero()[1]] #self.oper1Zs += [Hbuilder.EmbedOper(Z, N, [site, 1.0], True)] #self.operXs += [Hbuilder.EmbedOper(X, N, [site, 1.0], True)] self.oper2Zs = [] for bond in kwargs['Z2'].copy(): bond[-1] = 1.0 self.oper2Zs += [Hbuilder.EmbedOper(Z, N, bond, True).diagonal()] #self.oper2Zs += [Hbuilder.EmbedOper(Z, N, bond, True)] self.oper3Zs = [] if 'tribody' in kwargs.keys(): for bond in kwargs['tribody'].copy(): bond[-1] = 1.0 self.oper3Zs += [Hbuilder.EmbedOper(Z, N, bond, True).diagonal()] self.N3b = len(self.oper3Zs)
def comp_local_averages_clamped(self): # Define the imaginary-time propagation operator U = np.matrix(np.zeros((2**self.N_spins, 2**self.N_spins)), copy=False) # Apply the projector operator from the right U[:, self.proj_index : self.proj_index + self.hidden_dim] = self.rho[:, self.proj_index : self.proj_index + self.hidden_dim ] # Normalize U by Tr_{h} <projector, h| e^{-H \beta} |projector, h> clamped_norm = np.sum( np.diagonal(self.rho)[self.proj_index : self.proj_index + self.hidden_dim ]) U /= clamped_norm # Define discrete imaginary-time step propagators N_grid = 12 tau = 1.0*self.beta/(2.0*N_grid) Ub0 = np.matrix( mexp.expm( self.H*tau), copy=False) Uf0 = np.matrix( mexp.expm(-self.H*tau), copy=False) # Evaluate time-evolved operators on a discrete grid grid_aves = np.zeros((N_grid+1, self.N_couplings)) for step in range(N_grid+1): # At tau = 0, both propagators are just identities if step>0: U = Ub0 * U * Uf0 # compute all the local expectation values for index, oper_repr in enumerate(self.oper_list): grid_aves[step][index] = self.comp_local_operator(oper_repr, U) # Numerically integrate aves = np.zeros(self.N_couplings) xs = np.linspace(0.0, N_grid+1-1, N_grid+1)*tau for index in range(self.N_couplings): aves[index] = trapz(grid_aves[:, index], xs)*2.0 return aves
def computeLocalAverages(self, test = False): #U = self.rho*self.P #U /= np.sum(U.diagonal()) if ((not self.clamped) or (test)): U = self.rho/np.sum(self.rho.diagonal()) aves = np.zeros(self.Ns + self.Ns + self.Nb + self.N3b + self.N4b) # Z1 operator for site in range(self.Ns): aves[site] = np.sum(self.oper1Zs[site]*U.diagonal().T) #aves[site] = np.real(np.sum((U*self.oper1Zs[site]).diagonal())) # X1 operator shift = self.Ns for site in range(self.Ns): for r,c in enumerate(self.operXs[site]): aves[shift+site] += U[c, r] #aves[self.Ns+site] += np.real(np.sum((U*self.operXs[site]).diagonal())) # Z2 operator shift += self.Ns for i in range(self.Nb): aves[shift+i] = np.sum(self.oper2Zs[i]*U.diagonal().T) #aves[2*self.Ns+i] += np.real(np.sum((U*self.oper2Zs[i]).diagonal())) # Z3 operator shift += self.Nb for i in range(self.N3b): aves[shift+i] = np.sum(self.oper3Zs[i]*U.diagonal().T) # Z4 operator shift +=self.N3b for i in range(self.N4b): aves[shift+i] = np.sum(self.oper4Zs[i]*U.diagonal().T) return aves else: U = np.matrix(np.zeros((2**self.Ns, 2**self.Ns)), copy=False) Prob = self.rho[self.bindex, self.bindex] U[:, self.bindex] = self.rho[:, self.bindex]/Prob Nsamples = 12 eO = np.zeros((Nsamples+1, self.Ns + self.Ns + self.Nb + self.N3b + self.N4b)) # Evaluate time-evolved operators on a discrete grid tau = 1.0*self.beta/(2.0*Nsamples) #Ub0 = np.matrix(slin.expm( self.H*tau), copy=False) #Uf0 = np.matrix(slin.expm(-self.H*tau), copy=False) Ub0 = np.matrix(mexp.expm( self.H*tau), copy=False) Uf0 = np.matrix(mexp.expm(-self.H*tau), copy=False) for step in range(Nsamples+1): if step>0: U = Ub0*U*Uf0 shift = 0 for site in range(self.Ns): eO[step][site] = np.sum(self.oper1Zs[site]*U.diagonal().T) #eZ[step][site] = np.real(np.sum((self.oper1Zs[site]*U).diagonal())) shift += self.Ns for site in range(self.Ns): for r,c in enumerate(self.operXs[site]): eO[step][shift+site] += U[c, r] #eX[step][site] = np.real(np.sum((self.operXs[site]*U).diagonal())) shift += self.Ns for i in range(self.Nb): eO[step][shift+i] = np.sum(self.oper2Zs[i]*U.diagonal().T) shift += self.Nb for i in range(self.N3b): eO[step][shift+i] = np.sum(self.oper3Zs[i]*U.diagonal().T) shift += self.N3b for i in range(self.N4b): eO[step][shift+i] = np.sum(self.oper4Zs[i]*U.diagonal().T) # Numerically integrate UE = np.zeros(self.Ns + self.Ns + self.Nb + self.N3b + self.N4b) xs = np.linspace(0.0, Nsamples+1-1, Nsamples+1)*tau shift = self.Ns for site in range(self.Ns): UE[site] = trapz(eO[:,site], xs)*2.0 UE[shift+site] = trapz(eO[:,shift+site], xs)*2.0 shift += self.Ns for bond in range(self.Nb): UE[shift+bond] = trapz(eO[:,shift+bond], xs)*2.0 shift += self.Nb for bond in range(self.N3b): UE[shift+bond] = trapz(eO[:,shift+bond], xs)*2.0 shift += self.N3b for bond in range(self.N4b): UE[shift+bond] = trapz(eO[:,shift+bond], xs)*2.0 return UE
#Js = np.hstack((np.array(bonds), Js )) # #kwargs['X'] = Ds #kwargs['Z1'] = Hs #kwargs['Z2'] = Js #for itype, bonds in kwargs.iteritems(): # if itype == 'X': oper = X # else: oper = Z # for bond in bonds: # H = H + Hbuilder.EmbedOper(oper, Ns, bond) #H = H.todense() t0 = time.time() rho1 = m.expm(H) times1[i] = time.time() - t0 print 'new : %0.4f ' %times1[i] t0 = time.time() rho2 = sl.expm(H) times2[i] = time.time() - t0 print 'old: %0.4f ' %times2[i] #print rho1.todense() #print #print rho2.todense() #rho2 = rho2.todense() #rho1 = rho1.todense() print rho2 print rho1