def compute_psi2(self): merg_psi, idx = contra(self.tensors[self.current_site], self.order_left[self.current_site], self.tensors[self.current_site + 1], self.order_left[self.current_site + 1]) merg_psi_r, idx_r = contra(self.image_tensors[self.current_site], self.order_right[self.current_site], self.image_tensors[self.current_site + 1], self.order_right[self.current_site + 1]) merg, idx = contra(merg_psi, idx, merg_psi_r, idx_r) if self.current_site == 0: psi, idx_psi = contra(merg, idx, self.contraction_psi2[2][0], self.contraction_psi2[2][1]) else: if self.current_site == self.n - 2: psi, idx_psi = contra( merg, idx, self.contraction_psi2[self.current_site - 1][0], self.contraction_psi2[self.current_site - 1][1]) # Z, idz = contra(Z, idz, merg_l, idm_l) else: psi_r, idx_r = contra( merg, idx, self.contraction_psi2[self.current_site - 1][0], self.contraction_psi2[self.current_site - 1][1]) psi, idx_psi = contra( psi_r, idx_r, self.contraction_psi2[self.current_site + 2][0], self.contraction_psi2[self.current_site + 2][1]) # Z, idz = contra(Z, idz, merg_l, idm_l) return psi
def compute_Z(self): merg, idm = contra(self.tensors[self.current_site], self.order[self.current_site], self.tensors[self.current_site + 1], self.order[self.current_site + 1]) merg_l, idm_l = contra(self.tensors[self.current_site], self.order_left[self.current_site], self.tensors[self.current_site + 1], self.order_left[self.current_site + 1]) merg_m, idm_m = contra(merg, idm, merg_l, idm_l) if self.current_site == 0: Z, idz = contra(merg_m, idm_m, self.contraction_z[self.current_site + 2][0], self.contraction_z[self.current_site + 2][1]) # Z, idz = contra(Z, idz, merg_l,idm_l) else: if self.current_site == self.n - 2: Z, idz = contra(merg_m, idm_m, self.contraction_z[self.current_site - 1][0], self.contraction_z[self.current_site - 1][1]) # Z, idz = contra(Z, idz, merg_l, idm_l) else: Z_l, idz_l = contra( merg_m, idm_m, self.contraction_z[self.current_site - 1][0], self.contraction_z[self.current_site - 1][1]) Z, idz = contra(Z_l, idz_l, self.contraction_z[self.current_site + 2][0], self.contraction_z[self.current_site + 2][1]) # Z, idz = contra(Z, idz, merg_l, idm_l) return Z
def contraction_update_all_left2(self): # v1=torch.Tensor([0,1]) # v2=torch.Tensor([1,0]) self.going_righ = 0 merg, idm = contra(self.tensors[0], self.order_left[0], self.tensors[0], self.order[0]) self.contraction_z[0] = ([merg, idm]) merg_psi, merg_psi_idx = contra(self.tensors[0], self.order_left[0], self.image_tensors[0], self.order_right[0]) self.contraction_psi2[0] = ([merg_psi, merg_psi_idx]) for i in range(1, self.n - 2): merg, idm = contra(merg, idm, self.tensors[i], self.order_left[i]) merg, idm = contra(merg, idm, self.tensors[i], self.order[i]) self.contraction_z[i] = ([merg, idm]) merg_psi, merg_psi_idx = contra(merg_psi, merg_psi_idx, self.tensors[i], self.order_left[i]) merg_psi, merg_psi_idx = contra(merg_psi, merg_psi_idx, self.image_tensors[i], self.order_right[i]) self.contraction_psi2[i] = ([merg_psi, merg_psi_idx])
def contraction_update_all_left(self): v1 = torch.Tensor([0, 1]).cuda() v2 = torch.Tensor([1, 0]).cuda() self.going_righ = 0 merg, idm = contra(self.tensors[0], self.order_left[0], self.tensors[0], self.order[0]) self.contraction_z[0] = ([merg, idm]) merg_psi = [] for j in range(self.m): if self.image[0, j] == 1: #n*m mergv, idv = contra(self.tensors[0], self.order_left[0], v1, [0]) else: mergv, idv = contra(self.tensors[0], self.order_left[0], v2, [0]) merg_psi.append(mergv) self.contraction_psi[0] = ([merg_psi, idv]) for i in range(1, self.n - 2): merg, idm = contra(merg, idm, self.tensors[i], self.order_left[i]) merg, idm = contra(merg, idm, self.tensors[i], self.order[i]) self.contraction_z[i] = ([merg, idm]) merg_psi = [] for j in range(0, self.m): if self.image[i, j] == 1: # n*m mergv, idvm = contra(self.contraction_psi[i - 1][0][j], idv, self.tensors[i], self.order_left[i]) mergv, idvm = contra(mergv, idvm, v1, [2 * i]) else: mergv, idvm = contra(self.contraction_psi[i - 1][0][j], idv, self.tensors[i], self.order_left[i]) mergv, idvm = contra(mergv, idvm, v2, [2 * i]) merg_psi.append(mergv) idv = idvm self.contraction_psi[i] = ([merg_psi, idvm])
import os os.environ["CUDA_VISIBLE_DEVICES"] = "2" d1 = 30 d2 = 30 r = 10 learning_rate = 0.1 loops = 30 his_loss = torch.zeros(1, loops) A = torch.rand(d1, d2).cuda() E = torch.rand(d1, d2).cuda() M = torch.rand(d1, r).cuda() N = torch.rand(r, d2).cuda() A = A / A.norm() E = E / E.norm() M = M / M.norm() N = N / N.norm() t1 = time.time() for loop in range(loops): A0 = (contra(M, [1, 2], N, [2, 3]))[0] loss = (contra((A - A0), [1, 2], E, [1, 2]))[0] grad_M = 2 * loss * contra(E, [0, 2], N, [1, 2])[0] grad_N = 2 * loss * contra(M, [1, 2], E, [1, 3])[0] M = M + learning_rate * grad_M N = N + learning_rate * grad_N his_loss[0, loop] = loss**2 t2 = time.time() print(his_loss, t2 - t1)
def train(self, loops): for loop in range(loops): self.going_righ = 0 for i in np.arange(self.n - 2, 0, -1): self.current_site = i self.merged_tensor, self.merged_idx = contra( self.tensors[self.current_site], self.order_left[self.current_site], self.tensors[self.current_site + 1], self.order_left[self.current_site + 1]) self.Z = self.compute_Z() self.psi = self.compute_psi() dmerge = self.gradient_descent # nll=0 # for k in range(self.m): # nll=nll+(torch.log(self.psi[k] *self.psi[k] /self.Z)) # nll=nll/self.m # print nll,i self.tensors[self.current_site], self.tensors[ self.current_site + 1] = svd_update( self.tensors[self.current_site], self.order[self.current_site], self.tensors[self.current_site + 1], self.order[self.current_site + 1], dmerge, self.going_righ, 0.0002, self.max_bond) self.contraction_updat_twosite() self.going_righ = 1 for i in range(self.n - 2): self.current_site = i self.merged_tensor, self.merged_idx = contra( self.tensors[self.current_site], self.order_left[self.current_site], self.tensors[self.current_site + 1], self.order_left[self.current_site + 1]) self.Z = self.compute_Z() self.psi = self.compute_psi() # nll = 0 # for k in range(self.m): # nll = nll + ( torch.log(self.psi[k] *self.psi[k] / self.Z)) # nll=nll/self.m # print nll,i dmerge = self.gradient_descent self.tensors[self.current_site], self.tensors[ self.current_site + 1] = svd_update( self.tensors[self.current_site], self.order[self.current_site], self.tensors[self.current_site + 1], self.order[self.current_site + 1], dmerge, self.going_righ, 0.0002, self.max_bond) self.contraction_updat_twosite() for j in range(len(self.links)): self.Z = self.compute_Z() self.psi = self.compute_psi() k0 = self.links[j][0] k1 = self.links[j][1] dmerge = self.gradient_descent5(k0, k1) self.tensors[k0], self.tensors[k1] = svd_update( self.tensors[k0], self.order[k0], self.tensors[k1], self.order[k1], dmerge, self.going_righ, 0.0002, self.max_bond) self.contraction_update_all_left() nll = 0 for k in range(self.m): nll = nll + (torch.log(self.psi[k] * self.psi[k] / self.Z)) nll = nll / self.m print nll if nll > self.nll_history[-1] + 0.002: self.nll_history.append(nll) else: break
def gradient_descent5(self, j, k): self.current_site = j self.merged_tensor, self.merged_idx = contra(self.tensors[j], self.order_left[j], self.tensors[k], self.order_left[k]) merged_idx2 = self.merged_idx[:] for l in range(len(self.merged_idx)): if self.merged_idx[l] % 2 == 1: merged_idx2[l] = merged_idx2[l] - 8 * self.n mer_l, mer_l_idx = contra(self.tensors[0], self.order_left[0], self.tensors[0], self.order[0]) for i in range(1, j): mer_l, mer_l_idx = contra(mer_l, mer_l_idx, self.tensors[i], self.order_left[i]) mer_l, mer_l_idx = contra(mer_l, mer_l_idx, self.tensors[i], self.order[i]) mer_r, mer_r_idx = contra(self.tensors[self.n - 1], self.order_left[self.n - 1], self.tensors[self.n - 1], self.order[self.n - 1]) for i in np.arange(self.n - 2, k, -1): mer_r, mer_r_idx = contra(mer_r, mer_r_idx, self.tensors[i], self.order_left[i]) mer_r, mer_r_idx = contra(mer_r, mer_r_idx, self.tensors[i], self.order[i]) mer_m, mer_m_idx = contra(self.tensors[j + 1], self.order_left[j + 1], self.tensors[j + 1], self.order[j + 1]) for i in range(j + 2, k): mer_m, mer_m_idx = contra(mer_m, mer_m_idx, self.tensors[i], self.order_left[i]) mer_m, mer_m_idx = contra(mer_m, mer_m_idx, self.tensors[i], self.order[i]) dZ, dZ_idx = contra(mer_l, mer_l_idx, self.merged_tensor, merged_idx2) dZ, dZ_idx = contra(dZ, dZ_idx, mer_r, mer_r_idx) dZ, dZ_idx = contra(dZ, dZ_idx, mer_m, mer_m_idx) dpsi = [] dPsi = [] v1 = torch.Tensor([0, 1]).cuda() v2 = torch.Tensor([1, 0]).cuda() for jl in range(self.m): if self.image[0, jl] == 1: psi_l, psi_l_idx = contra(self.tensors[0], self.order_left[0], v1, [0]) else: psi_l, psi_l_idx = contra(self.tensors[0], self.order_left[0], v2, [0]) dpsi.append(psi_l) for i in range(1, j): for jl in range(self.m): dpsi[jl], psi_l_idx2 = contra(dpsi[jl], psi_l_idx, self.tensors[i], self.order_left[i]) if self.image[j, jl] == 1: psi_l, psi_l_idx2 = contra(dpsi[jl], psi_l_idx2, v1, [2 * i]) else: psi_l, psi_l_idx2 = contra(dpsi[jl], psi_l_idx2, v2, [2 * i]) dpsi[jl] = psi_l psi_l_idx = psi_l_idx2[:] for i in range(j + 1, k): for jl in range(self.m): dpsi[jl], psi_l_idx2 = contra(dpsi[jl], psi_l_idx, self.tensors[i], self.order_left[i]) if self.image[j, jl] == 1: psi_l, psi_l_idx2 = contra(dpsi[jl], psi_l_idx2, v1, [2 * i]) else: psi_l, psi_l_idx2 = contra(dpsi[jl], psi_l_idx2, v2, [2 * i]) dpsi[jl] = psi_l psi_l_idx = psi_l_idx2[:] for i in range(k + 1, self.n): for jl in range(self.m): dpsi[jl], psi_l_idx2 = contra(dpsi[jl], psi_l_idx, self.tensors[i], self.order_left[i]) if self.image[j, jl] == 1: psi_l, psi_l_idx2 = contra(dpsi[jl], psi_l_idx2, v1, [2 * i]) else: psi_l, psi_l_idx2 = contra(dpsi[jl], psi_l_idx2, v2, [2 * i]) dpsi[jl] = psi_l psi_l_idx = psi_l_idx2[:] dPsi.append(dpsi + [psi_l_idx]) dmerge = torch.zeros((self.merged_tensor).size()).cuda() for im1 in [1, 2]: for im2 in [1, 2]: dpsi = torch.zeros((dPsi[0][0]).size()).cuda() im = (self.image[self.current_site, :] == im1) * (self.image[self.current_site + 1, :] == im2) for jl in range(self.m): if im[jl] == 1: dpsi = 2 * dPsi[0][jl] / self.psi[jl] + dpsi dmerge = tensor_slide(dmerge, self.merged_idx, [2 - im1, 2 - im2], [j * 2, k * 2], dpsi, (dPsi[0][-1])) dmerge = tensor_add(dmerge / self.n, self.merged_idx, -2 * dZ / self.Z, dZ_idx) gnorm = torch.norm(dmerge) / 20 if (gnorm < 1.0): # % & & self.bond_dims(self.current_bond) <= 50; dmerge = dmerge / gnorm dmerge = self.merged_tensor + self.learning_rate * dmerge return dmerge
def gradient_descent(self): dpsi = [] dPsi = [] merged_idx2 = self.merged_idx[:] for k in range(len(self.merged_idx)): if self.merged_idx[k] % 2 == 1: merged_idx2[k] = merged_idx2[k] - 8 * self.n if self.current_site == 0: dZ, dZ_idx = contra(self.merged_tensor, merged_idx2, self.contraction_z[self.current_site + 2][0], self.contraction_z[self.current_site + 2][1]) for j in range(self.m): dpsi.append(self.contraction_psi[self.current_site + 2][0][j]) dpsi_idx = self.contraction_psi[self.current_site + 2][1] dPsi.append(dpsi + [dpsi_idx]) else: if self.current_site == self.n - 2: dZ, dZ_idx = contra( self.merged_tensor, merged_idx2, self.contraction_z[self.current_site - 1][0], self.contraction_z[self.current_site - 1][1]) for j in range(self.m): dpsi.append(self.contraction_psi[self.current_site - 1][0][j]) dpsi_idx = self.contraction_psi[self.current_site - 1][1] dPsi.append(dpsi + [dpsi_idx]) else: merg_Z, idz = contra( self.merged_tensor, merged_idx2, self.contraction_z[self.current_site - 1][0], self.contraction_z[self.current_site - 1][1]) dZ, dZ_idx = contra( merg_Z, idz, self.contraction_z[self.current_site + 2][0], self.contraction_z[self.current_site + 2][1]) for j in range(self.m): merg_psi, dpsi_idx = contra( self.contraction_psi[self.current_site - 1][0][j], self.contraction_psi[self.current_site - 1][1], self.contraction_psi[self.current_site + 2][0][j], self.contraction_psi[self.current_site + 2][1]) dpsi.append(merg_psi) dPsi.append(dpsi + [dpsi_idx]) dmerge = torch.zeros((self.merged_tensor).size()).cuda() for im1 in [1, 2]: for im2 in [1, 2]: dpsi = torch.zeros((dPsi[0][0]).size()).cuda() im = (self.image[self.current_site, :] == im1) * (self.image[self.current_site + 1, :] == im2) for j in range(self.m): if im[j] == 1: dpsi = 2 * dPsi[0][j] / self.psi[j] + dpsi dmerge = tensor_slide( dmerge, self.merged_idx, [2 - im1, 2 - im2], [self.current_site * 2, self.current_site * 2 + 2], dpsi, (dPsi[0][-1])) dmerge = tensor_add(dmerge / self.n, self.merged_idx, -2 * dZ / self.Z, dZ_idx) gnorm = torch.norm(dmerge) / 20 if (gnorm < 1.0): #% & & self.bond_dims(self.current_bond) <= 50; dmerge = dmerge / gnorm dmerge = self.merged_tensor + self.learning_rate * dmerge return dmerge
def compute_psi(self): Psi = [] v1 = torch.Tensor([0, 1]).cuda() v2 = torch.Tensor([1, 0]).cuda() if self.current_site == 0: for j in range(self.m): if self.image[0, j] == 1: # n*m mergv, idvm = contra(self.tensors[0], self.order_left[0], v1, [0]) mergv, idvm = contra(mergv, idvm, self.tensors[1], self.order_left[1]) if self.image[1, j] == 1: mergv, idvm = contra(mergv, idvm, v1, [2]) else: mergv, idvm = contra(mergv, idvm, v2, [2]) else: mergv, idvm = contra(self.tensors[0], self.order_left[0], v2, [0]) mergv, idvm = contra(mergv, idvm, self.tensors[1], self.order_left[1]) if self.image[1, j] == 1: mergv, idvm = contra(mergv, idvm, v1, [2]) else: mergv, idvm = contra(mergv, idvm, v2, [2]) psi, id = contra(mergv, idvm, self.contraction_psi[2][0][j], self.contraction_psi[2][1]) Psi.append(psi) else: if self.current_site == self.n - 2: for j in range(self.m): if self.image[self.n - 2, j] == 1: # n*m mergv, idvm = contra(self.tensors[self.n - 2], self.order_left[self.n - 2], v1, [2 * self.n - 4]) mergv, idvm = contra(mergv, idvm, self.tensors[self.n - 1], self.order_left[self.n - 1]) if self.image[self.n - 1, j] == 1: mergv, idvm = contra(mergv, idvm, v1, [2 * self.n - 2]) else: mergv, idvm = contra(mergv, idvm, v2, [2 * self.n - 2]) else: mergv, idvm = contra(self.tensors[self.n - 2], self.order_left[self.n - 2], v2, [2 * self.n - 4]) mergv, idvm = contra(mergv, idvm, self.tensors[self.n - 1], self.order_left[self.n - 1]) if self.image[self.n - 1, j] == 1: mergv, idvm = contra(mergv, idvm, v1, [2 * self.n - 2]) else: mergv, idvm = contra(mergv, idvm, v2, [2 * self.n - 2]) psi, id = contra(mergv, idvm, self.contraction_psi[self.n - 3][0][j], self.contraction_psi[self.n - 3][1]) Psi.append(psi) else: for j in range(self.m): if self.image[self.current_site, j] == 1: # n*m mergv, idvm = contra( self.tensors[self.current_site], self.order_left[self.current_site], v1, [2 * self.current_site]) mergv, idvm = contra( mergv, idvm, self.tensors[self.current_site + 1], self.order_left[self.current_site + 1]) if self.image[self.current_site + 1, j] == 1: mergv, idvm = contra(mergv, idvm, v1, [2 * self.current_site + 2]) else: mergv, idvm = contra(mergv, idvm, v2, [2 * self.current_site + 2]) else: mergv, idvm = contra( self.tensors[self.current_site], self.order_left[self.current_site], v2, [2 * self.current_site]) mergv, idvm = contra( mergv, idvm, self.tensors[self.current_site + 1], self.order_left[self.current_site + 1]) if self.image[self.current_site + 1, j] == 1: mergv, idvm = contra(mergv, idvm, v1, [2 * self.current_site + 2]) else: mergv, idvm = contra(mergv, idvm, v2, [2 * self.current_site + 2]) mergv, idvm = contra( mergv, idvm, self.contraction_psi[self.current_site - 1][0][j], self.contraction_psi[self.current_site - 1][1]) psi, id = contra( mergv, idvm, self.contraction_psi[self.current_site + 2][0][j], self.contraction_psi[self.current_site + 2][1]) Psi.append(psi) return Psi
def contraction_updat_twosite(self): v1 = torch.Tensor([0, 1]).cuda() v2 = torch.Tensor([1, 0]).cuda() if self.going_righ == 0: if self.current_site == self.n - 2: merg, idm = contra(self.tensors[self.n - 1], self.order[self.n - 1], self.tensors[self.n - 1], self.order_left[self.n - 1]) # self.contraction_z[self.current_site+1]=merg merg_psi = [] for j in range(self.m): if self.image[self.n - 1, j] == 1: # n*m mergv, idvm = contra(self.tensors[self.n - 1], self.order_left[self.n - 1], v1, [self.n * 2 - 2]) else: mergv, idvm = contra(self.tensors[self.n - 1], self.order_left[self.n - 1], v2, [self.n * 2 - 2]) merg_psi.append(mergv) else: merg, idm = contra( self.tensors[self.current_site + 1], self.order_left[self.current_site + 1], self.contraction_z[self.current_site + 2][0], self.contraction_z[self.current_site + 2][1]) merg, idm = contra(merg, idm, self.tensors[self.current_site + 1], self.order[self.current_site + 1]) merg_psi = [] for j in range(0, self.m): if self.image[self.current_site + 1, j] == 1: # n*m mergv, idvm = contra( self.tensors[self.current_site + 1], self.order_left[self.current_site + 1], self.contraction_psi[self.current_site + 2][0][j], self.contraction_psi[self.current_site + 2][1]) mergv, idvm = contra(mergv, idvm, v1, [2 * self.current_site + 2]) else: mergv, idvm = contra( self.tensors[self.current_site + 1], self.order_left[self.current_site + 1], self.contraction_psi[self.current_site + 2][0][j], self.contraction_psi[self.current_site + 2][1]) mergv, idvm = contra(mergv, idvm, v2, [2 * self.current_site + 2]) merg_psi.append(mergv) self.contraction_psi[self.current_site + 1] = ([merg_psi, idvm]) self.contraction_z[self.current_site + 1] = ([merg, idm]) if self.going_righ == 1: if self.current_site == 0: merg, idm = contra(self.tensors[0], self.order[0], self.tensors[0], self.order_left[0]) # self.contraction_z[self.current_site+1]=merg merg_psi = [] for j in range(self.m): if self.image[0, j] == 1: # n*m mergv, idvm = contra(self.tensors[0], self.order_left[0], v1, [0]) else: mergv, idvm = contra(self.tensors[0], self.order_left[0], v2, [0]) merg_psi.append(mergv) else: merg, idm = contra( self.tensors[self.current_site], self.order_left[self.current_site], self.contraction_z[self.current_site - 1][0], self.contraction_z[self.current_site - 1][1]) merg, idm = contra(merg, idm, self.tensors[self.current_site], self.order[self.current_site]) merg_psi = [] for j in range(0, self.m): if self.image[self.current_site, j] == 1: # n*m mergv, idvm = contra( self.tensors[self.current_site], self.order_left[self.current_site], self.contraction_psi[self.current_site - 1][0][j], self.contraction_psi[self.current_site - 1][1]) mergv, idvm = contra(mergv, idvm, v1, [2 * self.current_site]) else: mergv, idvm = contra( self.tensors[self.current_site], self.order_left[self.current_site], self.contraction_psi[self.current_site - 1][0][j], self.contraction_psi[self.current_site - 1][1]) mergv, idvm = contra(mergv, idvm, v2, [2 * self.current_site]) merg_psi.append(mergv) self.contraction_psi[self.current_site] = ([merg_psi, idvm]) self.contraction_z[self.current_site] = ([merg, idm])
def gradient_descent2(self): dpsi = [] dPsi = [] merged_idx2 = self.merged_idx[:] for k in range(len(self.merged_idx)): if self.merged_idx[k] % 2 == 1: merged_idx2[k] = merged_idx2[k] - 8 * self.n merge_psi, merge_psi_idx = contra( self.image_tensors[self.current_site], self.order_right[self.current_site], self.image_tensors[self.current_site + 1], self.order_right[self.current_site + 1]) if self.current_site == 0: dZ, dZ_idx = contra(self.merged_tensor, merged_idx2, self.contraction_z[self.current_site + 2][0], self.contraction_z[self.current_site + 2][1]) dPsi, dPsi_idx = contra( merge_psi, merge_psi_idx, self.contraction_psi2[self.current_site + 2][0], self.contraction_psi2[self.current_site + 2][1]) else: if self.current_site == self.n - 2: dZ, dZ_idx = contra( self.merged_tensor, merged_idx2, self.contraction_z[self.current_site - 1][0], self.contraction_z[self.current_site - 1][1]) dPsi, dPsi_idx = contra( merge_psi, merge_psi_idx, self.contraction_psi2[self.current_site - 1][0], self.contraction_psi2[self.current_site - 1][1]) else: merg_Z, idz = contra( self.merged_tensor, merged_idx2, self.contraction_z[self.current_site - 1][0], self.contraction_z[self.current_site - 1][1]) dZ, dZ_idx = contra( merg_Z, idz, self.contraction_z[self.current_site + 2][0], self.contraction_z[self.current_site + 2][1]) merg_Psi, idpsi = contra( merge_psi, merge_psi_idx, self.contraction_psi2[self.current_site - 1][0], self.contraction_psi2[self.current_site - 1][1]) dPsi, dPsi_idx = contra( merg_Psi, idpsi, self.contraction_psi2[self.current_site + 2][0], self.contraction_psi2[self.current_site + 2][1]) # for im1 in [1,2]: # for im2 in [1,2]: # dpsi=torch.zeros((dPsi[0][0]).size()).cuda() # im=(self.image[self.current_site,:]==im1)*(self.image[self.current_site+1,:]==im2) # for j in range(self.m): # if im[j]==1: # dpsi=2*dPsi[0][j]/self.psi[j]+dpsi # dmerge=tensor_slide(dmerge,self.merged_idx,[2-im1,2-im2],[self.current_site*2,self.current_site*2+2],dpsi,(dPsi[0][-1])) psi_1 = 1.0 / self.psi dPsi, dPsi_idx = contra(dPsi, dPsi_idx, psi_1, [-1]) dmerge = tensor_add(2 * dPsi, dPsi_idx, -2 * 4 * self.m * dZ / self.Z, dZ_idx) gnorm = torch.norm(dmerge) / 80 if (gnorm < 1.0): #% & & self.bond_dims(self.current_bond) <= 50; dmerge = dmerge / gnorm dmerge = tensor_add(self.merged_tensor, self.merged_idx, self.learning_rate * dmerge, dPsi_idx) return dmerge
def gradient_descent25(self, j, k): self.current_site = j self.merged_tensor, self.merged_idx = contra(self.tensors[j], self.order_left[j], self.tensors[k], self.order_left[k]) merged_idx2 = self.merged_idx[:] psi_merg, psi_merg_idx = contra(self.image_tensors[j], self.order_right[j], self.image_tensors[k], self.order_right[k]) for l in range(len(self.merged_idx)): if self.merged_idx[l] % 2 == 1: merged_idx2[l] = merged_idx2[l] - 8 * self.n mer_l, mer_l_idx = contra(self.tensors[0], self.order_left[0], self.tensors[0], self.order[0]) psi_l, psi_l_idx = contra(self.tensors[0], self.order_left[0], self.image_tensors[0], self.order_right[0]) for i in range(1, j): mer_l, mer_l_idx = contra(mer_l, mer_l_idx, self.tensors[i], self.order_left[i]) mer_l, mer_l_idx = contra(mer_l, mer_l_idx, self.tensors[i], self.order[i]) psi_l, psi_l_idx = contra(psi_l, psi_l_idx, self.tensors[i], self.order_left[i]) psi_l, psi_l_idx = contra(psi_l, psi_l_idx, self.image_tensors[i], self.order_right[i]) mer_r, mer_r_idx = contra(self.tensors[self.n - 1], self.order_left[self.n - 1], self.tensors[self.n - 1], self.order[self.n - 1]) psi_r, psi_r_idx = contra(self.tensors[self.n - 1], self.order_left[self.n - 1], self.image_tensors[self.n - 1], self.order_right[self.n - 1]) for i in np.arange(self.n - 2, k, -1): mer_r, mer_r_idx = contra(mer_r, mer_r_idx, self.tensors[i], self.order_left[i]) mer_r, mer_r_idx = contra(mer_r, mer_r_idx, self.tensors[i], self.order[i]) psi_r, psi_r_idx = contra(psi_r, psi_r_idx, self.tensors[i], self.order_left[i]) psi_r, psi_r_idx = contra(psi_r, psi_r_idx, self.image_tensors[i], self.order_right[i]) mer_m, mer_m_idx = contra(self.tensors[j + 1], self.order_left[j + 1], self.tensors[j + 1], self.order[j + 1]) psi_m, psi_m_idx = contra(self.tensors[j + 1], self.order_left[j + 1], self.image_tensors[j + 1], self.order_right[j + 1]) for i in range(j + 2, k): mer_m, mer_m_idx = contra(mer_m, mer_m_idx, self.tensors[i], self.order_left[i]) mer_m, mer_m_idx = contra(mer_m, mer_m_idx, self.tensors[i], self.order[i]) psi_m, psi_m_idx = contra(psi_m, psi_m_idx, self.tensors[i], self.order_left[i]) psi_m, psi_m_idx = contra(psi_m, psi_m_idx, self.image_tensors[i], self.order_right[i]) dZ, dZ_idx = contra(mer_l, mer_l_idx, self.merged_tensor, merged_idx2) dZ, dZ_idx = contra(dZ, dZ_idx, mer_r, mer_r_idx) dZ, dZ_idx = contra(dZ, dZ_idx, mer_m, mer_m_idx) dpsi, dpsi_idx = contra(psi_l, psi_l_idx, psi_merg, psi_merg_idx) dpsi, dpsi_idx = contra(dpsi, dpsi_idx, psi_r, psi_r_idx) dpsi, dpsi_idx = contra(dpsi, dpsi_idx, psi_m, psi_m_idx) psi_1 = 1.0 / self.psi dpsi, dpsi_idx = contra(dpsi, dpsi_idx, psi_1, [-1]) dmerge = tensor_add(2 * dpsi / self.m, dpsi_idx, -2 * 4 * dZ / self.Z, dZ_idx) gnorm = torch.norm(dmerge) / 80 if (gnorm < 1.0): # % & & self.bond_dims(self.current_bond) <= 50; dmerge = dmerge / gnorm dmerge = tensor_add(self.merged_tensor, self.merged_idx, self.learning_rate * dmerge, dpsi_idx) return dmerge
def contraction_updat_twosite2(self): if self.going_righ == 0: if self.current_site == self.n - 2: merg, idm = contra(self.tensors[self.n - 1], self.order[self.n - 1], self.tensors[self.n - 1], self.order_left[self.n - 1]) # self.contraction_z[self.current_site+1]=merg merg_psi, idm_psi = contra(self.image_tensors[self.n - 1], self.order_right[self.n - 1], self.tensors[self.n - 1], self.order_left[self.n - 1]) else: merg, idm = contra( self.tensors[self.current_site + 1], self.order_left[self.current_site + 1], self.contraction_z[self.current_site + 2][0], self.contraction_z[self.current_site + 2][1]) merg, idm = contra(merg, idm, self.tensors[self.current_site + 1], self.order[self.current_site + 1]) merg_psi, idm_psi = contra( self.tensors[self.current_site + 1], self.order_left[self.current_site + 1], self.contraction_psi2[self.current_site + 2][0], self.contraction_psi2[self.current_site + 2][1]) merg_psi, idm_psi = contra( merg_psi, idm_psi, self.image_tensors[self.current_site + 1], self.order_right[self.current_site + 1]) self.contraction_psi2[self.current_site + 1] = ([merg_psi, idm_psi]) self.contraction_z[self.current_site + 1] = ([merg, idm]) if self.going_righ == 1: if self.current_site == 0: merg, idm = contra(self.tensors[0], self.order[0], self.tensors[0], self.order_left[0]) # self.contraction_z[self.current_site+1]=merg merg_psi, idm_psi = contra(self.image_tensors[0], self.order_right[0], self.tensors[0], self.order_left[0]) else: merg, idm = contra( self.tensors[self.current_site], self.order_left[self.current_site], self.contraction_z[self.current_site - 1][0], self.contraction_z[self.current_site - 1][1]) merg, idm = contra(merg, idm, self.tensors[self.current_site], self.order[self.current_site]) merg_psi, idm_psi = contra( self.tensors[self.current_site], self.order_left[self.current_site], self.contraction_psi2[self.current_site - 1][0], self.contraction_psi2[self.current_site - 1][1]) merg_psi, idm_psi = contra( merg_psi, idm_psi, self.image_tensors[self.current_site], self.order_right[self.current_site]) self.contraction_psi2[self.current_site] = ([ merg_psi, idm_psi ]) self.contraction_z[self.current_site] = ([merg, idm])