def RandomPEPS_SU(N, M, Jk, dE, D_max, bc, t_list, iterations): # Tensor Network parameters D = D_max # virtual bond dimension d = 2 # physical bond dimension h = 0 # Hamiltonian: magnetic field coeffs Op = np.eye(d) / np.sqrt(3) Opi = [Op, Op, Op] Opj = [Op, Op, Op] Op_field = np.eye(d) # generating the PEPS structure matrix if bc == 'open': smat, imat = tnf.finitePEPSobcStructureMatrixGenerator(N, M) if bc == 'periodic': smat, imat = tnf.squareFinitePEPSpbcStructureMatrixGenerator(N * M) # generating tensors and bond vectors if bc == 'open': TT, LL = tnf.randomTensornetGenerator(smat, d, D) if bc == 'periodic': TT, LL = tnf.randomTensornetGenerator(smat, d, D) TT0, LL0 = cp.deepcopy(TT), cp.deepcopy(LL) # iterating the gPEPS algorithm s = time.time() for dt in t_list: for j in range(iterations): #print('N, D max, dt, j = ', N * M, D_max, dt, j) TT1, LL1 = BP.simpleUpdate(TT, LL, dt, Jk, h, Opi, Opj, Op_field, smat, D_max, 'SU') TT2, LL2 = BP.simpleUpdate(TT1, LL1, dt, Jk, h, Opi, Opj, Op_field, smat, D_max, 'SU') error = 0 for i in range(len(LL1)): error += np.sum(np.abs(LL1[i] - LL2[i])) #print('error = ', error) if error < dE * dt: TT = TT2 LL = LL2 break else: TT = TT2 LL = LL2 if error < dE * dt: break tot = time.time() - s return [TT0, LL0, TT, LL], tot
def RandomPEPS_BP(N, M, Jk, dE, D_max, t_max, epsilon, dumping, bc, t_list, iterations, TN=None): # Tensor Network parameters D = D_max # virtual bond dimension d = 2 # physical bond dimension h = 0 # Hamiltonian: magnetic field coeff Op = np.eye(d) / np.sqrt(3) Opi = [Op, Op, Op] Opj = [Op, Op, Op] Op_field = np.eye(d) # generating the PEPS structure matrix if bc == 'open': smat, imat = tnf.finitePEPSobcStructureMatrixGenerator(N, M) if bc == 'periodic': smat, imat = tnf.squareFinitePEPSpbcStructureMatrixGenerator(N * M) # generating tensors and bond vectors if TN: TT, LL = TN else: if bc == 'open': TT, LL = tnf.randomTensornetGenerator(smat, d, D) if bc == 'periodic': TT, LL = tnf.randomTensornetGenerator(smat, d, D) # constructing the dual double-edge factor graph graph = defg.defg() graph = BP.TNtoDEFGtransform(graph, TT, LL, smat) s = time.time() graph.sumProduct(t_max, epsilon, dumping) tot = time.time() - s graph.calculateFactorsBeliefs() return graph, tot
for i in range(len(Opi)): hij += np.kron(Opi[i], Opj[i]) hij = hij.reshape(p, p, p, p) # ######### CALCULATING ENERGIES ######## # #for e in environment_size: # E_gPEPS.append(np.real(BP.energy_per_site_with_environment([N, M], e, TT_gPEPS, LL_gPEPS, smat, Jk, h, Opi, Opj, Op_field))) # E_BP.append(np.real(BP.energy_per_site_with_environment([N, M], e, TT_BP, LL_BP, smat, Jk, h, Opi, Opj, Op_field))) # E_BP_factor_belief.append(np.real(BP.BP_energy_per_site_using_factor_belief_with_environment(graph, e, [N, M], smat, Jk, h, Opi, Opj, Op_field))) Dp = [D ** 2, 2 * (D ** 2)] TT_BP_bmps = BP.absorbAllTensorNetWeights(TT_BP_bmps, LL_BP, smat) TT_BP_bmps = tnf.PEPS_OBC_broadcast_to_Itai(TT_BP_bmps, [N, M], p, D) BP_peps = bmps.peps(N, M) for t, T in enumerate(TT_BP_bmps): i, j = np.unravel_index(t, [N, M]) BP_peps.set_site(T, i, j) for dp_idx, dp in enumerate(Dp): print('BP: D, Dp = ', D, dp) rho_BP_bmps = bmps.calculate_PEPS_2RDM(BP_peps, dp) rho_BP_bmps_sum = cp.deepcopy(rho_BP_bmps[0]) for i in range(1, len(rho_BP_bmps)): rho_BP_bmps_sum += rho_BP_bmps[i] E_BP_bmps[D_idx, dp_idx] = np.real(np.einsum(rho_BP_bmps_sum, [0, 1, 2, 3], hij, [0, 2, 1, 3]) / (N * M)) TT_gPEPS_bmps = BP.absorbAllTensorNetWeights(TT_gPEPS_bmps, LL_gPEPS, smat) TT_gPEPS_bmps = tnf.PEPS_OBC_broadcast_to_Itai(TT_gPEPS_bmps, [N, M], p, D)
def Heisenberg_PEPS_gPEPS(N, M, Jk, dE, D_max, bc, t_list, iterations): # Tensor Network parameters d = 2 # virtual bond dimension p = 2 # physical bond dimension h = 0 # Hamiltonian: magnetic field coeffs gPEPS_energy = [] print('running Heisenberg_PEPS_SU: D = ', D_max) pauli_z = np.array([[1, 0], [0, -1]]) pauli_y = np.array([[0, -1j], [1j, 0]]) pauli_x = np.array([[0, 1], [1, 0]]) sz = 0.5 * pauli_z sy = 0.5 * pauli_y sx = 0.5 * pauli_x Opi = [sx, sy, sz] Opj = [sx, sy, sz] Op_field = np.eye(p) # generating the PEPS structure matrix if bc == 'open': smat, imat = tnf.finitePEPSobcStructureMatrixGenerator(N, M) if bc == 'periodic': smat, imat = tnf.squareFinitePEPSpbcStructureMatrixGenerator(N * M) ''' smat = np.array([[1, 2, 3, 4, 0, 0, 0, 0], [1, 2, 0, 0, 3, 4, 0, 0], [0, 0, 1, 2, 0, 0, 3, 4], [0, 0, 0, 0, 1, 2, 3, 4]]) ''' n, m = smat.shape # generating tensors and bond vectors if bc == 'open': TT, LL = tnf.randomTensornetGenerator(smat, p, d) if bc == 'periodic': TT, LL = tnf.randomTensornetGenerator(smat, p, d) # iterating the gPEPS algorithm for dt in t_list: for j in range(iterations): #print('N, D max, dt, j = ', N * M, D_max, dt, j) TT1, LL1 = BP.simpleUpdate(TT, LL, dt, Jk, h, Opi, Opj, Op_field, smat, D_max, 'gPEPS') TT2, LL2 = BP.simpleUpdate(TT1, LL1, dt, Jk, h, Opi, Opj, Op_field, smat, D_max, 'gPEPS') energy1 = BP.energyPerSite(TT1, LL1, smat, Jk, h, Opi, Opj, Op_field) energy2 = BP.energyPerSite(TT2, LL2, smat, Jk, h, Opi, Opj, Op_field) gPEPS_energy.append(energy1) gPEPS_energy.append(energy2) #print(energy1, energy2) if np.abs(energy1 - energy2) < dE * dt: TT = TT2 LL = LL2 break else: TT = TT2 LL = LL2 return [TT, LL, gPEPS_energy]
def Heisenberg_PEPS_BP(N, M, Jk, dE, D_max, t_max, epsilon, dumping, bc, t_list, iterations, TN=None): # Tensor Network parameters d = D_max # virtual bond dimension p = 2 # physical bond dimension h = 0 # Hamiltonian: magnetic field coeffs BP_energy = [] print('running Heisenberg_PEPS_BP: D = ', D_max) # pauli matrices pauli_z = np.array([[1, 0], [0, -1]]) pauli_y = np.array([[0, -1j], [1j, 0]]) pauli_x = np.array([[0, 1], [1, 0]]) sz = 0.5 * pauli_z sy = 0.5 * pauli_y sx = 0.5 * pauli_x Opi = [sx, sy, sz] Opj = [sx, sy, sz] Op_field = np.eye(p) # generating the PEPS structure matrix if bc == 'open': smat, imat = tnf.finitePEPSobcStructureMatrixGenerator(N, M) if bc == 'periodic': smat, imat = tnf.squareFinitePEPSpbcStructureMatrixGenerator(N * M) ''' smat = np.array([[1, 2, 3, 4, 0, 0, 0, 0], [1, 2, 0, 0, 3, 4, 0, 0], [0, 0, 1, 2, 0, 0, 3, 4], [0, 0, 0, 0, 1, 2, 3, 4]]) ''' n, m = smat.shape # generating tensors and bond vectors if TN: TT, LL = TN else: if bc == 'open': TT, LL = tnf.randomTensornetGenerator(smat, p, d) if bc == 'periodic': TT, LL = tnf.randomTensornetGenerator(smat, p, d) # constructing the dual double-edge factor graph graph = defg.defg() graph = BP.TNtoDEFGtransform(graph, TT, LL, smat) graph.sumProduct(t_max, epsilon, dumping) # iterating the BP truncation algorithm for dt in t_list: for j in range(iterations): #print('BP_N, D max, dt, j = ', N, D_max, dt, j) TT1, LL1 = BP.simpleUpdate(TT, LL, dt, Jk, h, Opi, Opj, Op_field, smat, D_max, 'BP', graph) graph.sumProduct(t_max, epsilon, dumping, 'init_with_old_messages') energy1 = BP.BPenergyPerSite(graph, smat, Jk, h, Opi, Opj, Op_field) TT2, LL2 = BP.simpleUpdate(TT1, LL1, dt, Jk, h, Opi, Opj, Op_field, smat, D_max, 'BP', graph) graph.sumProduct(t_max, epsilon, dumping, 'init_with_old_messages') energy2 = BP.BPenergyPerSite(graph, smat, Jk, h, Opi, Opj, Op_field) BP_energy.append(np.real(energy1)) BP_energy.append(np.real(energy2)) #print(energy1, energy2) if np.abs(energy1 - energy2) < dE * dt: TT = TT2 LL = LL2 break else: TT = TT2 LL = LL2 return [graph, TT, LL, BP_energy]
file_name = date + experimentNum + PEPSsize # Set lists for ttd (total trace distance) ttd_SU_bMPO = np.zeros((1, n), dtype=float) ttd_SU_BP = np.zeros((1, n), dtype=float) ttd_bMPO16_bMPO32 = np.zeros((1, n), dtype=float) # Run experiment for i in range(n): print('\n') print('i:', i) rho_SU_0_bmps_single, rho_SU, rho_BP = randomPEPSmainFunction(N, M) rho_SU_0_bmps16_single = rho_SU_0_bmps_single[0] rho_SU_0_bmps32_single = rho_SU_0_bmps_single[1] for j in range(N): ttd_SU_bMPO[0][i] += BP.traceDistance(rho_SU_0_bmps16_single[j], rho_SU[j]) / N ttd_SU_BP[0][i] += BP.traceDistance(rho_BP[j], rho_SU[j]) / N ttd_bMPO16_bMPO32[0][i] += BP.traceDistance( rho_SU_0_bmps16_single[j], rho_SU_0_bmps32_single[j]) / N av_ttd_SU_bMPO = np.sum(ttd_SU_bMPO) / n av_ttd_SU_BP = np.sum(ttd_SU_BP) / n av_ttd_bMPO16_bMPO32 = np.sum(ttd_bMPO16_bMPO32) / n # Display to screen print('\n') print('----------------------------------------------------------------') print(' RESULTS ') print('----------------------------------------------------------------') print(' Average total trace-distance (bMPO16 - bMPO32) = %.12f' % av_ttd_bMPO16_bMPO32) print(' Average total trace-distance (SU - bMPO16) = %.12f' %
def randomPEPSmainFunction(N, M): # PEPS parameters bc = 'open' dE = 1e-5 t_max = 200 dumping = 0.2 epsilon = 1e-5 D_max = [3] mu = -1 sigma = 0 Jk = np.random.normal(mu, sigma, np.int((N - 1) * M + (M - 1) * N)) dt = [0.1, 0.05, 0.01] iterations = 10 Dp = [4, 8] d = 2 smat, imat = tnf.finitePEPSobcStructureMatrixGenerator(N, M) # Set lists BP_data = [] SU_data = [] rho_SU = [] rho_SU_0_bmps = [] rho_SU_0_bmps_single = [] # Run Simple Update & Belief Propagation for D in D_max: b, time_su = rpeps.RandomPEPS_SU(N, M, Jk, dE, D, bc, dt, iterations) TT0, LL0 = b[0], b[1] a, time_bp = rpeps.RandomPEPS_BP(N, M, Jk, dE, D, t_max, epsilon, dumping, bc, dt, iterations, [TT0, LL0]) BP_data.append(a) SU_data.append(b) # Arrange single site rdms order in list as in bmpslib indices = [] counter = 0 counter2 = N * (M - 1) - 1 + (N - 1) * (M - 1) + 1 counter3 = 0 while counter3 < N: indices += range(counter, counter + M - 1) indices.append(counter2) counter += (M - 1) counter2 += 1 counter3 += 1 indices.pop() # Caclualting reduced density matrices for ii in range(len(D_max)): graph = BP_data[ii] TT_SU_0, LL_SU_0, TT_SU, LL_SU = SU_data[ii] TT_SU_0_bmps = cp.deepcopy(TT_SU_0) # RDMS using BP and SU for i in range(len(TT_SU)): rho_SU.append(BP.singleSiteRDM(i, TT_SU, LL_SU, smat)) rho_BP = graph.calculateRDMSfromFactorBeliefs() # RDMS using BMPO from bmpslib TT_SU_0_bmps = BP.absorbAllTensorNetWeights(TT_SU_0_bmps, LL_SU_0, smat) TT_SU_0_bmps = tnf.PEPS_OBC_broadcast_to_Itai(TT_SU_0_bmps, [N, M], d, D_max[ii]) SU_0_peps = bmps.peps(N, M) for t, T in enumerate(TT_SU_0_bmps): i, j = np.unravel_index(t, [N, M]) SU_0_peps.set_site(T, i, j) for dp_idx, dp in enumerate(Dp): print('Dp:', dp) rho_SU_0_bmps.append(bmps.calculate_PEPS_2RDM(SU_0_peps, dp)) rho_SU_0_bmps_single.append([]) for jj in indices: rho_SU_0_bmps_single[dp_idx].append( np.einsum(rho_SU_0_bmps[dp_idx][jj], [0, 1, 2, 2], [0, 1])) rho_SU_0_bmps_single[dp_idx].append( np.einsum(rho_SU_0_bmps[dp_idx][jj], [1, 1, 2, 3], [2, 3])) return rho_SU_0_bmps_single, rho_SU, rho_BP
ATD_tot = [] BP_iters = [] tSU_iters = [] print('\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=') print('| D = {} |'.format(D_max)) print('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=') for e in range(num_experiments): print('experiment = ', e) # draw some random PEPS Tensor Network tensors, weights = smg.randomTensornetGenerator(smat, d, D_max) interactionConstants = -np.random.rand(m) BPU_graph = defg.defg() BPU_graph = su.TNtoDEFGtransform(BPU_graph, tensors, weights, smat) BPU_graph.sumProduct(t_max, epsilon, dumping, initializeMessages=1, printTime=0, RDMconvergence=0) counter = 0 for dt in timeStep: for i in range(BPU_iterations): counter += 1 if i % 45 == 0: print('i, dt = ', i, dt) weights_prev = cp.deepcopy(weights) tensors_next, weights_next = su.simpleUpdate( tensors,
Sy = 0.5 * Y Sx = 0.5 * X Opi = [Sx, Sy, Sz] Opj = [Sx, Sy, Sz] Op_field = np.eye(d) for e in range(num_experiments): # draw some random PEPS Tensor Network tensors, weights = smg.randomTensornetGenerator(smat, d, bond_dimension) # draw some random uniform(-1, 0) ATH couplings interactionConstants = -np.random.rand(m) #interactionConstants = [-1] * m # calculate the BP fixed point messages and the two-body RDMs BPU_graph = defg.defg() BPU_graph = su.TNtoDEFGtransform(BPU_graph, tensors, weights, smat) BPU_graph.sumProduct(t_max, epsilon, dumping, initializeMessages=1, printTime=0, RDMconvergence=0) BP_rdm = [] for j in range(m): BP_rdm.append( tsu.BPdoubleSiteRDM1(j, cp.deepcopy(tensors), cp.deepcopy(weights), smat, cp.deepcopy(BPU_graph.messages_n2f))) # run BPU until convergence criteria is met # the convergence criteria is taken to be an upper bound over the Averaged Trace Distance (ATD) Between # two consecutive BPU iterations two body RDMs --- ATD < 1e-6
tSU_iters = [] print('\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=') print('| D = {} |'.format(D_max)) print('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=') for e in range(num_experiments): #if e % 10 == 0: print(e) # draw some random PEPS Tensor Network tensors, weights = smg.randomTensornetGenerator(smat, d, D_max) BP_tensors, BP_weights = cp.deepcopy(tensors), cp.deepcopy(weights) # constructing the dual double-edge factor graph and run a single BP iteration graph = defg.defg() graph = su.TNtoDEFGtransform(graph, BP_tensors, BP_weights, smat) graph.sumProduct(1, epsilon, dumping, initializeMessages=1, printTime=0, RDMconvergence=0) BP_rdm = [] for j in range(m): BP_rdm.append( tsu.BPdoubleSiteRDM1(j, BP_tensors, BP_weights, smat, cp.deepcopy(graph.messages_n2f))) # run BP and calculate two body rdms between two consecutive BP iterations for t in range(t_max): graph.sumProduct(1,
weights_tsu, smat, D_max) error = np.sum(np.abs(np.asarray(weights_tsu) - np.asarray(weights_tsu_next))) errors_tsu.append(error) if error < dw: print('The error is: {}'.format(error)) tensors_tsu = tensors_tsu_next weights_tsu = weights_tsu_next break tensors_tsu = tensors_tsu_next weights_tsu = weights_tsu_next # constructing the dual double-edge factor graph graph = defg.defg() graph = su.TNtoDEFGtransform(graph, tensors_tsu, weights_tsu, smat) s = time.time() graph.sumProduct(t_max, epsilon, dumping, printTime=1) tot = time.time() - s graph.calculateFactorsBeliefs() tSU_1rdm = [] for i in range(n): tSU_1rdm.append(su.singleSiteRDM(i, tensors_tsu, weights_tsu, smat)) plt.figure() plt.plot(range(len(errors_tsu)), errors_tsu) plt.show()
''' for i in range(iterations): tensors_tsu_next, weights_tsu_next = tsu.trivialsimpleUpdate(tensors_tsu, weights_tsu, smat, D_max) error = np.sum(np.abs(np.asarray(weights_tsu) - np.asarray(weights_tsu_next))) errors_tsu.append(error) if error < dw: print('The error is: {}'.format(error)) tensors_tsu = tensors_tsu_next weights_tsu = weights_tsu_next break tensors_tsu = tensors_tsu_next weights_tsu = weights_tsu_next ''' # constructing the dual double-edge factor graph pre_graph = defg.defg() pre_graph = su.TNtoDEFGtransform(pre_graph, tensors_su, weights_su, smat) s = time.time() pre_graph.sumProduct(t_max, epsilon, dumping, printTime=1, RDMconvergence=0) pre_tot = time.time() - s pre_graph.calculateFactorsBeliefs() for i in range(iterations): tensors_su_next, weights_su_next = su.simpleUpdate(tensors_su, weights_su, timeStep, interactionConstants, 0, Opi, Opj, Op_field, smat,
Opj = [Sx, Sy, Sz] Op_field = np.eye(d) timeStep = 0.1 interactionConstants = [-1] * m dE = 1e-5 flag = 1 counter = 0 energyPerSite = [] magZ0 = [] # run simple update tensorsNew, lambdasNew = cp.deepcopy(tensors), cp.deepcopy(lambdas) while flag: energyPerSite.append( np.real( su.energyPerSite(tensorsNew, lambdasNew, structureMat, interactionConstants, 0, Opi, Opj, Op_field))) magZ0.append( su.singleSiteExpectation(0, tensorsNew, lambdasNew, structureMat, Sz)) tensorsNew, lambdasNew = su.simpleUpdate( tensors=tensorsNew, weights=lambdasNew, timeStep=timeStep, interactionConst=interactionConstants, fieldConst=0, iOperators=Opi, jOperators=Opj, fieldOperators=Op_field, smat=structureMat, Dmax=D, type='SU') if counter >= 1:
def randomPEPSmainFunction(): #np.random.seed(seed=9) N, M = 4, 4 bc = 'open' dE = 1e-5 t_max = 200 dumping = 0.2 epsilon = 1e-5 D_max = [3] mu = -1 sigma = 0 Jk = np.random.normal(mu, sigma, np.int((N - 1) * M + (M - 1) * N)) dt = [0.5, 0.1, 0.05, 0.01, 0.005] iterations = 10 Dp = [16, 32] d = 2 smat, imat = tnf.finitePEPSobcStructureMatrixGenerator(N, M) BP_data = [] SU_data = [] for D in D_max: b, time_su = hmf.RandomPEPS_SU(N, M, Jk, dE, D, bc, dt, iterations) TT0, LL0 = b[0], b[1] a, time_bp = hmf.RandomPEPS_BP(N, M, Jk, dE, D, t_max, epsilon, dumping, bc, dt, iterations, [TT0, LL0]) BP_data.append(a) SU_data.append(b) rho_SU = [] rho_SU_0_bmps = [] rho_SU_0_bmps_single = [] data_bp = BP_data data_su = SU_data indices = [] counter = 0 counter2 = N * (M - 1) - 1 + (N - 1) * (M - 1) + 1 counter3 = 0 while counter3 < N: indices += range(counter, counter + M - 1) indices.append(counter2) counter += (M - 1) counter2 += 1 counter3 += 1 indices.pop() print('calc_rdms') for ii in range(len(D_max)): graph = data_bp[ii] TT_SU_0, LL_SU_0, TT_SU, LL_SU = data_su[ii] TT_SU_0_bmps = cp.deepcopy(TT_SU_0) # ######### CALCULATING REDUCED DENSITY MATRICES ######## # for i in range(len(TT_SU)): rho_SU.append(BP.singleSiteRDM(i, TT_SU, LL_SU, smat)) rho_BP = graph.calculateRDMSfromFactorBeliefs() TT_SU_0_bmps = BP.absorbAllTensorNetWeights(TT_SU_0_bmps, LL_SU_0, smat) TT_SU_0_bmps = tnf.PEPS_OBC_broadcast_to_Itai(TT_SU_0_bmps, [N, M], d, D_max[ii]) SU_0_peps = bmps.peps(N, M) for t, T in enumerate(TT_SU_0_bmps): i, j = np.unravel_index(t, [N, M]) SU_0_peps.set_site(T, i, j) for dp_idx, dp in enumerate(Dp): print('Dp:', dp) rho_SU_0_bmps.append(bmps.calculate_PEPS_2RDM(SU_0_peps, dp)) rho_SU_0_bmps_single.append([]) for jj in indices: rho_SU_0_bmps_single[dp_idx].append( np.einsum(rho_SU_0_bmps[dp_idx][jj], [0, 1, 2, 2], [0, 1])) rho_SU_0_bmps_single[dp_idx].append( np.einsum(rho_SU_0_bmps[dp_idx][jj], [1, 1, 2, 3], [2, 3])) return rho_SU_0_bmps_single, rho_SU, rho_BP