def getBMPSRowOps(GammaC, LambdaC, GammaD, LambdaD, AEnv, BEnv, steps): convergence = [] envOpAB = bops.permute(bops.multiContraction(AEnv, BEnv, '1', '3'), [0, 3, 2, 4, 1, 5]) envOpBA = bops.permute(bops.multiContraction(BEnv, AEnv, '1', '3'), [0, 3, 2, 4, 1, 5]) op = envOpBA for i in range(steps): oldGammaC, oldLambdaC, oldGammaD, oldLambdaD = GammaC, LambdaC, GammaD, LambdaD GammaC, LambdaC, GammaD, LambdaD = bmpsRowStep(GammaC, LambdaC, GammaD, LambdaD, op) GammaD, LambdaD, GammaC, LambdaC = bmpsRowStep(GammaD, LambdaD, GammaC, LambdaC, op) # if i > 0: # convergence.append( # checkConvergence(oldGammaC, oldLambdaC, oldGammaD, oldLambdaD, GammaC, LambdaC, GammaD, LambdaD, 2)) bops.removeState([oldGammaC, oldLambdaC, oldGammaD, oldLambdaD]) # cUp = bops.multiContraction(GammaC, LambdaC, '2', '0', isDiag2=True) # dUp = bops.multiContraction(GammaD, LambdaD, '2', '0', isDiag2=True) # GammaC, LambdaC, GammaD, LambdaD = bmpsRowStep(GammaC, LambdaC, GammaD, LambdaD, op) # cDown = bops.multiContraction(GammaC, LambdaC, '2', '0', isDiag2=True) # dDown = bops.multiContraction(GammaD, LambdaD, '2', '0', isDiag2=True) bops.removeState([ GammaC, LambdaC, GammaD, LambdaD, oldGammaC, oldLambdaC, oldGammaD, oldLambdaD ]) return GammaC, LambdaC, GammaD, LambdaD
def stateEnergy(psi: List[tn.Node], H: HOp): E = 0 for i in range(len(psi)): psiCopy = bops.copyState(psi) single_i = bops.copyState([H.singles[i]])[0] psiCopy[i] = bops.permute(tn.contract(psiCopy[i][1] ^ single_i[0], name=('site' + str(i))), [0, 2, 1]) E += bops.getOverlap(psiCopy, psi) bops.removeState(psiCopy) tn.remove_node(single_i) for i in range(len(psi) - 1): psiCopy = bops.copyState(psi) r2l = bops.copyState([H.r2l[i+1]])[0] l2r = bops.copyState([H.l2r[i]])[0] psiCopy[i][2] ^ psiCopy[i+1][0] psiCopy[i][1] ^ l2r[0] r2l[0] ^ psiCopy[i+1][1] l2r[2] ^ r2l[2] M = tn.contract_between(psiCopy[i], \ tn.contract_between(l2r, tn.contract_between(r2l, psiCopy[i+1]))) if bops.multiContraction(M, M, '0123', '0123*').tensor != 0: [psiCopy, te] = bops.assignNewSiteTensors(psiCopy, i, M, '>>') E += bops.getOverlap(psiCopy, psi) bops.removeState(psiCopy) tn.remove_node(r2l) tn.remove_node(l2r) return E
def renyiEntropy(n, N, M, randOption, estimateFunc, arguments, filename, d=2): start = datetime.now() avg = 0 for m in range(int(M * d**N)): ops = [ getNonUnitaryRandomOps(d, randOption, vecsNum=n) for i in range(N) ] estimation = 1 for i in range(n): expectation = wrapper(estimateFunc, arguments + [[op[i] for op in ops]]) estimation *= expectation mc = m % M avg = (avg * mc + estimation) / (mc + 1) if m % M == M - 1: with open( filename + '_n_' + str(n) + '_N_' + str(N) + '_' + randOption + '_M_' + str(M) + '_m_' + str(m), 'wb') as f: pickle.dump(avg, f) print(avg) avg = 0 for op in ops: bops.removeState(op) end = datetime.now() with open(filename + '_time_N_' + str(N) + '_M_' + str(M), 'wb') as f: pickle.dump((end - start).total_seconds(), f)
def singleMeasurement(psi: List[tn.Node], vs: List[List[np.array]]): vs = np.round(vs, 10) n = len(vs) NA = len(vs[0]) result = 1 for copy in range(n): psiCopy = bops.copyState(psi) for alpha in range(NA - 1, -1, -1): toEstimate = np.outer(vs[copy][alpha], np.conj(vs[np.mod(copy + 1, n)][alpha])) hermitianComponent = np.random.randint(2) if hermitianComponent: toMeasure = (toEstimate + np.conj(np.transpose(toEstimate))) else: toMeasure = (toEstimate - np.conj(np.transpose(toEstimate))) / 1j measureVals, measureVecs = np.linalg.eigh(toMeasure) projector = np.outer(measureVecs[:, 0], np.conj(measureVecs[:, 0])) measResult = makeMeasurement(psiCopy, alpha, projector) if measResult: if np.abs(measureVals[0]) < 1e-8: return 0 result *= measureVals[0] else: if np.abs(measureVals[1]) < 1e-8: return 0 result *= measureVals[1] if not hermitianComponent: result *= 1j psiCopy = bops.shiftWorkingSite(psiCopy, alpha, '<<') bops.removeState(psiCopy) return result
def expectationValue(currSites, op): left = leftRow for i in range(l): left = bops.multiContraction(left, cUp, '3', '0', cleanOr1=True) leftUp = toricCode.applyOpTosite(currSites[0][i * 2], op) leftDown = toricCode.applyOpTosite(currSites[1][i * 2], op) left = bops.multiContraction(left, leftUp, '23', '30', cleanOr1=True) left = bops.multiContraction(left, leftDown, '14', '30', cleanOr1=True) left = bops.permute( bops.multiContraction(left, dDown, '04', '21', cleanOr1=True), [3, 2, 1, 0]) left = bops.multiContraction(left, dUp, '3', '0', cleanOr1=True) rightUp = toricCode.applyOpTosite(currSites[0][i * 2 + 1], op) rightDown = toricCode.applyOpTosite(currSites[1][i * 2 + 1], op) left = bops.multiContraction(left, rightUp, '23', '30', cleanOr1=True) left = bops.multiContraction(left, rightDown, '14', '30', cleanOr1=True) left = bops.permute( bops.multiContraction(left, cDown, '04', '21', cleanOr1=True), [3, 2, 1, 0]) bops.removeState([leftUp, leftDown, rightDown, rightUp]) return bops.multiContraction(left, rightRow, '0123', '3210').tensor * 1
def localNonUnitaries(N, M, randOption, estimateFunc, arguments, filename, d=2): start = datetime.now() avg = 0 for m in range(int(M * d**N)): ops = [getNonUnitaryRandomOps(d, randOption)[0] for i in range(N)] expectation = wrapper(estimateFunc, arguments + [ops]) estimation = np.abs(expectation)**2 mc = m % M avg = (avg * mc + estimation) / (mc + 1) if m % M == M - 1: with open( filename + '_N_' + str(N) + '_' + randOption + '_M_' + str(M) + '_m_' + str(m), 'wb') as f: pickle.dump(avg, f) print(avg) avg = 0 bops.removeState(ops) end = datetime.now() with open(filename + '_time_N_' + str(N) + '_M_' + str(M), 'wb') as f: pickle.dump((end - start).total_seconds(), f)
def XXVar(statesDir: str, outDir: str, NA, theta, phi): maxBondDim = 100 res = np.zeros(2, dtype=complex) U = tn.Node( np.matmul(ru.getUPhi(np.pi * phi / 2, 2), ru.getUTheta(np.pi * theta / 2, 2))) with open(statesDir + 'psiXX_NA_' + str(NA) + '_NB_' + str(NA), 'rb') as f: psi = pickle.load(f) psiCopy = bops.relaxState(psi, 64) res[0] = bops.getOverlap(psi, psiCopy) bops.removeState(psi) for i in range(NA): psiCopy[i] = bops.permute( bops.multiContraction(psiCopy[i], U, '1', '0'), [0, 2, 1]) doublePsi = [None for j in range(len(psiCopy))] for j in range(len(psiCopy)): doublePsi[j] = doubleMPSSite(psiCopy[j]) doubleCopy = bops.copyState(doublePsi) for j in range(NA): doublePsi[j] = bops.permute( bops.multiContraction(doublePsi[j], E, '1', '0', cleanOr1=True), [0, 2, 1]) res[1] = bops.getOverlap(doublePsi, doubleCopy) with open( outDir + 'XXVar_NA_' + str(NA) + '_t_' + str(theta) + '_p_' + str(phi), 'wb') as f: pickle.dump(res, f) print(res)
def expectationValues(psi: List[tn.Node], vs: List[List[np.array]]): vs = np.round(vs, 10) n = len(vs) NA = len(vs[0]) result = 1 # result = np.eye(2, dtype=complex) for copy in range(n): psiCopy = bops.copyState(psi) for alpha in range(NA - 1, -1, -1): overlap = np.matmul(vs[copy][alpha], np.conj(vs[np.mod(copy + 1, n)][alpha])) toEstimate = np.outer(vs[copy][alpha], np.conj(vs[np.mod(copy + 1, n)][alpha])) if np.abs(np.round(overlap, 8)) == 2: toMeasure = toEstimate else: hermitianComponent = np.random.randint(2) if hermitianComponent: toMeasure = (toEstimate + np.conj(np.transpose(toEstimate))) else: toMeasure = (toEstimate - np.conj(np.transpose(toEstimate))) psiCopy[alpha] = bops.permute(bops.multiContraction(psiCopy[alpha], tn.Node(toMeasure), \ '1', '1'), [0, 2, 1]) psiCopy = bops.shiftWorkingSite(psiCopy, alpha, '<<') result *= bops.getOverlap(psiCopy, psi) # result = np.matmul(result, toMeasure) bops.removeState(psiCopy) return result
def applyLocalOperators(cUp, dUp, cDown, dDown, leftRow, rightRow, A, B, l, ops): left = leftRow for i in range(l): left = bops.multiContraction(left, cUp, '3', '0', cleanOr1=True) leftUp = applyOpTosite(B, ops[i * 4]) leftDown = applyOpTosite(A, ops[i * 4 + 1]) left = bops.multiContraction(left, leftUp, '23', '30', cleanOr1=True) left = bops.multiContraction(left, leftDown, '14', '30', cleanOr1=True) left = bops.permute( bops.multiContraction(left, dDown, '04', '21', cleanOr1=True), [3, 2, 1, 0]) left = bops.multiContraction(left, dUp, '3', '0', cleanOr1=True) rightUp = applyOpTosite(A, ops[i * 4 + 2]) rightDown = applyOpTosite(B, ops[i * 4 + 3]) left = bops.multiContraction(left, rightUp, '23', '30', cleanOr1=True) left = bops.multiContraction(left, rightDown, '14', '30', cleanOr1=True) left = bops.permute( bops.multiContraction(left, cDown, '04', '21', cleanOr1=True), [3, 2, 1, 0]) bops.removeState([leftUp, leftDown, rightDown, rightUp]) return bops.multiContraction(left, rightRow, '0123', '3210').tensor * 1
def getEMatrix(psi, startInd, endInd): psiDagger = bops.copyState(psi, conj=True) E = bops.multiContraction(psi[startInd], psiDagger[startInd], [1], [1]) for i in range(startInd + 1, endInd + 1): E = bops.multiContraction( E, bops.multiContraction(psi[i], psiDagger[i], [1], [1]), [1, 3], [0, 2]) bops.removeState(psiDagger) return E
def getP(d, s, us, estimateFunc, arguments): currUs = [tn.Node(np.eye(d)) for i in range(len(us))] for i in range(len(us)): currUs[i].tensor = np.matmul( np.matmul(us[i], projs[int(s & d**i > 0)]), np.conj(np.transpose(us[i]))) result = wrapper(estimateFunc, arguments + [currUs]) bops.removeState(currUs) return result
def applySwap(psi, psiP, startInd, endInd): psiDagger = bops.copyState(psi, conj=True) psiPDagger = bops.copyState(psi, conj=True) curr = bops.multiContraction(psi[startInd], psiDagger[startInd], [0], [0]) currP = bops.multiContraction(psiP[startInd], psiPDagger[startInd], [0], [0]) curr = bops.multiContraction(curr, currP, [2, 0], [0, 2]) for i in range(startInd + 1, endInd + 1): curr = bops.multiContraction(curr, psi[i], [0], [0]) curr = bops.multiContraction(curr, psiDagger[i], [0], [0]) curr = bops.multiContraction(curr, psiP[i], [0, 4], [0, 1]) curr = bops.multiContraction(curr, psiPDagger[i], [0, 1], [0, 1]) bops.removeState(psiPDagger) bops.removeState(psiPDagger) return curr
def getDensityMatrix(psi, A1Start, A1End, A2Start, A2End): psiCopy = bops.copyState(psi) for k in [len(psiCopy) - 1 - i for i in range(len(psiCopy) - A2End - 1)]: psiCopy = bops.shiftWorkingSite(psiCopy, k, '<<') E1 = getEMatrix(psiCopy, A1Start, A1End) bops.copyState([E1]) N1, N1bar = getNMatrices(E1, 1) N1bar.edges[0].name += '*' E2 = getEMatrix(psiCopy, A2Start, A2End) N2, N2bar = getNMatrices(E2, 2) N2bar.edges[0].name += '*' res = bops.multiContraction(bops.multiContraction(N1, N1bar, [0], [1]), bops.multiContraction(N2, N2bar, [1], [2]), [0, 3], [0, 3]) bops.removeState(psiCopy) return res
def renyiEntropy(n, w, h, M, randOption, theta, phi, estimateFunc, arguments, filename, d=2, excludeIndices=[]): start = datetime.now() avg = 0 N = w * h for m in range(M * 2**N * 10): ops = [ getNonUnitaryRandomOps(d, randOption, theta, phi, vecsNum=n) for i in range(N) ] for ind in excludeIndices: ops[ind] = [tn.Node(np.eye(d, dtype=complex)) for i in range(n)] estimation = 1 for i in range(n): expectation = wrapper(estimateFunc, arguments + [[op[i] for op in ops]]) estimation *= expectation if estimation > 40: b = 1 avg += estimation if m % M == M - 1: with open( filename + '_n_' + str(n) + '_w_' + str(w) + '_h_' + str(h) + '_' + randOption + '_M_' + str(M) + '_m_' + str(m), 'wb') as f: pickle.dump(avg, f) avg = 0 for op in ops: bops.removeState(op) end = datetime.now() with open(filename + '_time_N_' + str(N) + '_M_' + str(M), 'wb') as f: pickle.dump((end - start).total_seconds(), f)
def localVecsEstimate(psi: List[tn.Node], vs: List[List[np.array]], half='left'): vs = np.round(vs, 10) n = len(vs) result = 1 for copy in range(n): if half == 'left': NA = len(vs[0]) curr = bops.multiContraction(psi[NA], psi[NA], '12', '12*') sites = range(NA - 1, -1, -1) elif half == 'right': NA = len(psi) - len(vs[0]) curr = bops.multiContraction(psi[len(psi) - NA - 1], psi[len(psi) - NA - 1], '01', '01*') sites = range(NA, len(psi)) psiCopy = bops.copyState(psi) for alpha in sites: toEstimate = np.outer(vs[copy][alpha - NA], np.conj(vs[np.mod(copy + 1, n)][alpha - NA])) psiCopy[alpha] = bops.permute(bops.multiContraction(psiCopy[alpha], tn.Node(toEstimate), \ '1', '1'), [0, 2, 1]) if half == 'left': curr = bops.multiContraction(bops.multiContraction( psiCopy[alpha], curr, '2', '0', cleanOr2=True), psi[alpha], '12', '12*', cleanOr1=True) elif half == 'right': curr = bops.multiContraction(bops.multiContraction( curr, psiCopy[alpha], '0', '0', cleanOr2=True), psi[alpha], '01', '01*', cleanOr1=True) # psiCopy = bops.shiftWorkingSite(psiCopy, alpha, '<<') result *= np.trace(curr.tensor) tn.remove_node(curr) bops.removeState(psiCopy) return result
def applyO(psi, psiP, startInd, endInd): psiDagger = bops.copyState(psi, conj=True) psiPDagger = bops.copyState(psi, conj=True) OTensor = np.zeros((9, 9), dtype=complex) for i in range(3): for j in range(3): OTensor[i * 3 + i, j * 3 + j] = 1 OTensor = np.reshape(OTensor, [3, 3, 3, 3]) O = tn.Node(OTensor, name='O', backend=None) curr = bops.multiContraction(psi[endInd], psiDagger[endInd], [2], [2]) currP = bops.multiContraction(psiP[endInd], psiPDagger[endInd], [2], [2]) curr = bops.multiContraction(curr, O, [1, 3], [1, 3]) curr = bops.multiContraction(curr, currP, [2, 3], [1, 3]) for i in [endInd - j for j in range(1, endInd - startInd + 1)]: O = tn.Node(OTensor, name='O', backend=None) curr = bops.multiContraction(curr, psi[i], [0], [2]) curr = bops.multiContraction(curr, psiDagger[i], [0], [2]) curr = bops.multiContraction(curr, O, [3, 5], [1, 3]) curr = bops.multiContraction(curr, psiP[i], [0, 4], [2, 1]) curr = bops.multiContraction(curr, psiPDagger[i], [0, 3], [2, 1]) bops.removeState(psiPDagger) bops.removeState(psiPDagger) return curr
def randomMeasurement(psi, startInd, endInd): d = psi[0].tensor.shape[1] res = [-1] * (endInd - startInd) psiCopy = bops.copyState(psi) for k in [len(psiCopy) - 1 - i for i in range(len(psiCopy) - startInd - 1)]: psiCopy = bops.shiftWorkingSite(psiCopy, k, '<<') for i in range(startInd, endInd): rho = bops.multiContraction(psiCopy[i], psiCopy[i], '02', '02*') measurement = np.random.uniform(low=0, high=1) covered = 0 for s in range(len(rho.tensor)): if covered < measurement < covered + rho.tensor[s, s]: res[i - startInd] = s break covered += rho.tensor[s, s] projectorTensor = np.zeros((d, d), dtype=complex) projectorTensor[res[i - startInd], res[i - startInd]] = 1 projector = tn.Node(projectorTensor, backend=None) bops.applySingleSiteOp(psiCopy, projector, i) psiCopy = bops.shiftWorkingSite(psiCopy, i, '>>') psiCopy[i + 1].tensor /= np.sqrt(bops.getOverlap(psiCopy, psiCopy)) tn.remove_node(rho) bops.removeState(psiCopy) return res
def applyLocalOperators(cUp, dUp, cDown, dDown, leftRow, rightRow, A, B, w, h, ops): if w == 2: left = leftRow for i in range(int(h / 2)): left = bops.multiContraction(left, cUp, '3', '0', cleanOr1=True) leftUp = applyOpTosite(B, ops[i * 4]) leftDown = applyOpTosite(A, ops[i * 4 + 1]) left = bops.multiContraction(left, leftUp, '23', '30', cleanOr1=True) left = bops.multiContraction(left, leftDown, '14', '30', cleanOr1=True) left = bops.permute( bops.multiContraction(left, dDown, '04', '21', cleanOr1=True), [3, 2, 1, 0]) left = bops.multiContraction(left, dUp, '3', '0', cleanOr1=True) rightUp = applyOpTosite(A, ops[i * 4 + 2]) rightDown = applyOpTosite(B, ops[i * 4 + 3]) left = bops.multiContraction(left, rightUp, '23', '30', cleanOr1=True) left = bops.multiContraction(left, rightDown, '14', '30', cleanOr1=True) left = bops.permute( bops.multiContraction(left, cDown, '04', '21', cleanOr1=True), [3, 2, 1, 0]) bops.removeState([leftUp, leftDown, rightDown, rightUp]) return bops.multiContraction(left, rightRow, '0123', '3210').tensor * 1 elif w == 4: left = bops.multiContraction(leftRow, leftRow, '3', '0') for i in range(int(h / 2)): left = bops.multiContraction(left, cUp, '5', '0', cleanOr1=True) left0 = applyOpTosite(B, ops[i * 8]) left1 = applyOpTosite(A, ops[i * 8 + 1]) left2 = applyOpTosite(B, ops[i * 8 + 2]) left3 = applyOpTosite(A, ops[i * 8 + 3]) left = bops.multiContraction(left, left0, '45', '30', cleanOr1=True, cleanOr2=True) left = bops.multiContraction(left, left1, '36', '30', cleanOr1=True, cleanOr2=True) left = bops.multiContraction(left, left2, '26', '30', cleanOr1=True, cleanOr2=True) left = bops.multiContraction(left, left3, '16', '30', cleanOr1=True, cleanOr2=True) left = bops.permute( bops.multiContraction(left, dDown, '06', '21', cleanOr1=True), [5, 4, 3, 2, 1, 0]) left = bops.multiContraction(left, dUp, '5', '0', cleanOr1=True) right0 = applyOpTosite(A, ops[i * 8 + 4]) right1 = applyOpTosite(B, ops[i * 8 + 5]) right2 = applyOpTosite(A, ops[i * 8 + 6]) right3 = applyOpTosite(B, ops[i * 8 + 7]) left = bops.multiContraction(left, right0, '45', '30', cleanOr1=True, cleanOr2=True) left = bops.multiContraction(left, right1, '36', '30', cleanOr1=True, cleanOr2=True) left = bops.multiContraction(left, right2, '26', '30', cleanOr1=True, cleanOr2=True) left = bops.multiContraction(left, right3, '16', '30', cleanOr1=True, cleanOr2=True) left = bops.permute( bops.multiContraction(left, cDown, '06', '21', cleanOr1=True), [5, 4, 3, 2, 1, 0]) right = bops.multiContraction(rightRow, rightRow, '3', '0') res = bops.multiContraction(left, right, '012345', '543210').tensor * 1 return res
# print('<psi|hpsi> = ' + str(bops.getOverlap(psi, hpsi))) R2 = bops.getRenyiEntropy(psi, 2, int(len(psi) / 2 - 1)) NU = 200 etas = [1, 2, 3, N, int(N * 1.5), N * 2, int(N * 2.5), N * 3] results = [None] * len(etas) dt = J * 1e-2 for e in range(len(etas)): eta = etas[e] sum = 0 for n in range(NU): psiCopy = bops.copyState(psi) for j in range(eta): onsiteTermsA, neighborTermsA = getHAMatrices(N, C, Omega, delta) HA = dmrg.getDMRGH(N, onsiteTermsA, neighborTermsA) trotterGates = trotter.getTrotterGates(N, 2, onsiteTermsA, neighborTermsA, dt) for i in range(int(T / dt)): [psiCopy, truncErr] = trotter.trotterSweep(trotterGates, psiCopy, 0, int(len(psiCopy) / 2 - 1)) psiCopy2 = bops.copyState(psiCopy) projectS(psiCopy, int(len(psiCopy)/2 - 1)) p = bops.getOverlap(psiCopy, psiCopy2) sum += p * p bops.removeState(psiCopy) bops.removeState(psiCopy2) avg = sum / NU results[e] = avg * (2**int(len(psi)/2) * (2**int(len(psi)/2) + 1)) - 1 plt.plot(etas, [R2] * len(etas)) plt.plot(etas, results) plt.show()