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 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 applyHToM(HL, HR, H, M, k): k1 = k k2 = k + 1 # Add HL.opSum x h.identity(k1) x h.identity(k2) x I(Right) # and I(Left) x h.identity(k1) x h.identity(k2) x HR.opSum Hv = bops.multiContraction(HL.opSum, M, '0', '0') Hv = bops.addNodes(Hv, bops.multiContraction(M, HR.opSum, '3', '0')) # Add I(Left) x h.single(k1) x h.identity(k2) x I(Right) # And I(Left) x h.identity(k1) x h.single(k2) x I(Right) Hv = bops.addNodes(Hv, \ bops.permute(bops.multiContraction(M, H.singles[k1], '1', '0'), [0, 3, 1, 2])) Hv = bops.addNodes(Hv, \ bops.permute(bops.multiContraction(M, H.singles[k2], '2', '0'), [0, 1, 3, 2])) # Add HL.openOp x h.r2l(k1) x h.identity(k2) x I(Right) # And I(Left) x h.identity(k1) x h.l2r(k2) x HR.openOp HK1R2L = bops.permute(bops.multiContraction(M, H.r2l[k1], '1', '0'), [0, 4, 3, 1, 2]) Hv = bops.addNodes(Hv, \ bops.multiContraction(HL.openOp, HK1R2L, '02', '01')) HK2L2R = bops.permute(bops.multiContraction(M, H.l2r[k2], '2', '0'), [0, 1, 3, 4, 2]) Hv = bops.addNodes(Hv, \ bops.multiContraction(HK2L2R, HR.openOp, '43', '02')) # Add I(Left) x h.l2r(k1) x h.r2l(k2) x I(Right) HK1K2 = bops.multiContraction(M, H.l2r[k1], '1', '0') HK1K2 = bops.multiContraction(HK1K2, H.r2l[k2], '14', '02') HK1K2 = bops.permute(HK1K2, [0, 2, 3, 1]) Hv = bops.addNodes(Hv, HK1K2) return Hv
def getTridiagonal(HL, HR, H, k, psi, psiCompare=None): accuracy = 1e-10 # 1e-12 v = bops.multiContraction(psi[k], psi[k + 1], '2', '0') # Small innaccuracies ruin everything! v.set_tensor(v.get_tensor() / bops.getNodeNorm(v)) psiCopy = bops.copyState(psi) base = [] base.append(v) Hv = applyHToM(HL, HR, H, v, k) alpha = bops.multiContraction(v, Hv, '0123', '0123*').get_tensor() if psiCompare is not None: copyV = bops.copyState([v])[0] psiCopy = bops.assignNewSiteTensors(psiCopy, k, copyV, '>>')[0] E = stateEnergy(psi, H) w = bops.addNodes(Hv, bops.multNode(v, -alpha)) beta = bops.getNodeNorm(w) # Start with T as an array and turn into tridiagonal matrix at the end. Tarr = [[0, 0, 0]] Tarr[0][1] = alpha counter = 0 formBeta = 2 * beta # This is just some value to init formBeta > beta. while (beta > accuracy) and (counter <= 50) and (beta < formBeta): Tarr[counter][2] = beta Tarr.append([0, 0, 0]) Tarr[counter + 1][0] = beta counter += 1 v = bops.multNode(w, 1 / beta) base.append(v) if psiCompare is not None: copyV = bops.copyState([v])[0] psiCopy = bops.assignNewSiteTensors(psiCopy, k, copyV, '>>')[0] Hv = applyHToM(HL, HR, H, v, k) alpha = bops.multiContraction(v, Hv, '0123', '0123*').get_tensor() Tarr[counter][1] = alpha w = bops.addNodes(bops.addNodes(Hv, bops.multNode(v, -alpha)), \ bops.multNode(base[counter-1], -beta)) formBeta = beta beta = bops.getNodeNorm(w) T = np.zeros((len(Tarr), len(Tarr)), dtype=complex) T[0][0] = Tarr[0][1] if len(Tarr) > 1: T[0][1] = Tarr[0][2] for i in range(1, len(Tarr)-1): T[i][i-1] = Tarr[i][0] T[i][i] = Tarr[i][1] T[i][i+1] = Tarr[i][2] T[len(Tarr)-1][len(Tarr)-2] = Tarr[len(Tarr)-1][0] T[len(Tarr) - 1][len(Tarr) - 1] = Tarr[len(Tarr) - 1][1] return [T, base]
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 applyVecsToSite(site: tn.Node, vecUp: np.array, vecDown: np.array): up = bops.multiContraction(site, tn.Node(vecUp), '4', '0', cleanOr2=True) down = bops.multiContraction(site, tn.Node(vecDown), '4*', '0*', cleanOr2=True) dm = tn.Node(np.kron(up.tensor, down.tensor)) return dm
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 getRowDM(GammaL, LambdaL, GammaR, LambdaR, sites, d): c = bops.multiContraction(bops.multiContraction(LambdaR, GammaL, '1', '0', isDiag1=True), LambdaL, '2', '0', isDiag2=True) row = bops.multiContraction(bops.multiContraction(c, GammaR, '2', '0'), LambdaR, '3', '0', isDiag2=True) for i in range(sites): row = bops.multiContraction(row, GammaL, [len(row.edges) - 1], [0]) row = bops.multiContraction(row, LambdaL, [len(row.edges) - 1], [0], isDiag2=True) row = bops.multiContraction(row, GammaR, [len(row.edges) - 1], [0]) row = bops.multiContraction(row, LambdaR, [len(row.edges) - 1], [0], isDiag2=True) dm = bops.multiContraction(row, row, [0, len(row.edges) - 1], [0, len(row.edges) - 1, '*']) rho = np.reshape(dm.tensor, [d**((2 + 2 * sites)), d**((2 + 2 * sites))]) return rho / np.trace(rho)
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 getIdentity(psi, k, dir): psil = bops.copyState([psi[k]])[0] psilCopy = bops.copyState([psi[k]], conj=True)[0] if dir == '>>': result = bops.multiContraction(psil, psilCopy, '01', '01').tensor else: result = bops.multiContraction(psil, psilCopy, '12', '12').tensor for i in range(len(result)): for j in range(len(result[0])): result[i][j] = round(result[i][j], 2) return result
def projectS(psi, AEnd): projector0Tensor = np.zeros((2, 2)) projector0Tensor[0, 0] = 1 projector0 = tn.Node(projector0Tensor, backend=None) projector1Tensor = np.zeros((2, 2)) projector1Tensor[1, 1] = 1 projector1 = tn.Node(projector1Tensor, backend=None) for i in range(AEnd + 1): if i % 2 == 0: psi[i] = bops.permute(bops.multiContraction(psi[i], projector0, [1], [0]), [0, 2, 1]) else: psi[i] = bops.permute(bops.multiContraction(psi[i], projector1, [1], [0]), [0, 2, 1])
def horizontalPair(leftSite, rightSite, cleanLeft=True, cleanRight=True): pair = bops.multiContraction(leftSite, rightSite, '1', '3', cleanOr1=cleanLeft, cleanOr2=cleanRight) pair = bops.multiContraction(pair, ru.getPairUnitary(d), '37', '01') [left, right, te] = bops.svdTruncation(pair, [0, 1, 2, 6], [3, 4, 5, 7], '>>', maxBondDim=16) return bops.permute(left, [0, 4, 1, 2, 3]), bops.permute(right, [1, 2, 3, 0, 4])
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 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 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 twoCopiesEntanglement(circle, A, B): doubleCircle = tn.Node(np.kron(circle.tensor, circle.tensor)) doubleA = tn.Node(np.kron(A.tensor, A.tensor)) doubleB = tn.Node(np.kron(B.tensor, B.tensor)) AEnv = tn.Node(np.trace(A.get_tensor(), axis1=0, axis2=5)) BEnv = tn.Node(np.trace(B.get_tensor(), axis1=0, axis2=5)) ABNet = bops.permute( bops.multiContraction(bops.multiContraction(BEnv, AEnv, '1', '3'), bops.multiContraction(AEnv, BEnv, '1', '3'), '15', '03'), [5, 1, 0, 2, 3, 6, 4, 7]) n = bops.multiContraction(circle, ABNet, '01234567', '01234567').tensor p2 = bops.multiContraction(doubleCircle, ABNet, '01234567', '01234567').tensor return p2
def verticalPair(topSite, bottomSite, cleanTop=True, cleanBottom=True): pair = bops.multiContraction(topSite, bottomSite, '2', '0', cleanOr1=cleanTop, cleanOr2=cleanBottom) pair = bops.multiContraction(pair, ru.getPairUnitary(d), '37', '01', cleanOr1=True, cleanOr2=True) [top, bottom, te] = bops.svdTruncation(pair, [0, 1, 2, 6], [3, 4, 5, 7], '>>', maxBondDim=16) return bops.permute(top, [0, 1, 4, 2, 3]), bottom
def estimateOp(xRight, xLeft, upRow, downRow, A, ops): N = len(ops) curr = xLeft for i in range(int(N / 2)): closedA = tn.Node( np.trace(bops.multiContraction(ops[i * 2], A, '1', '0').tensor, axis1=0, axis2=5)) closedB = tn.Node( np.trace(bops.multiContraction(ops[i * 2 + 1], A, '1', '0').tensor, axis1=0, axis2=5)) closed = bops.permute( bops.multiContraction(closedA, closedB, '1', '3'), [0, 3, 2, 4, 1, 5]) curr = bops.multiContraction(bops.multiContraction( bops.multiContraction(curr, upRow, '0', '0'), closed, '023', '201', cleanOr1=True), downRow, '034', '012', cleanOr1=True) return bops.multiContraction(curr, xRight, '012', '012').tensor
def bmpsSides(cUp: tn.Node, dUp: tn.Node, cDown: tn.Node, dDown: tn.Node, AEnv: tn.Node, BEnv: tn.Node, steps, option='right'): envOpAB = bops.permute(bops.multiContraction(AEnv, BEnv, '1', '3'), [0, 3, 2, 4, 1, 5]) upRow = bops.multiContraction(cUp, dUp, '2', '0') downRow = bops.multiContraction(cDown, dDown, '2', '0') if option == 'right': X = tn.Node( np.ones((upRow[3].dimension, envOpAB[3].dimension, downRow[3].dimension), dtype=complex)) else: X = tn.Node( np.ones((upRow[0].dimension, envOpAB[2].dimension, downRow[0].dimension), dtype=complex)) for i in range(steps): if option == 'right': X = bops.multiContraction( bops.multiContraction(bops.multiContraction( X, upRow, '0', '3'), envOpAB, '340', '013', cleanOr1=True), downRow, '034', '312') else: X = bops.multiContraction(bops.multiContraction( bops.multiContraction(X, upRow, '0', '0'), envOpAB, '023', '201', cleanOr1=True), downRow, '034', '012', cleanOr1=True) norm = np.sqrt(bops.multiContraction(X, X, '012', '012*').tensor) X = bops.multNode(X, 1 / norm) return X
def exactPurity(l, xRight, xLeft, upRow, downRow, A, filename, d=2): curr = xLeft pair = bops.permute(bops.multiContraction(A, A, '2', '4'), [1, 6, 3, 7, 2, 8, 0, 5, 4, 9]) for i in range(int(l / 2)): curr = bops.multiContraction( bops.multiContraction(curr, upRow, '0', '0'), downRow, '1', '0') curr = bops.multiContraction( curr, pair, [0, i * 4 + 1, i * 4 + 2, i * 4 + 4, i * 4 + 5], '20145') curr = bops.permute(curr, [i * 4, i * 4 + 2, i * 4 + 1] + list(range(i * 2)) + [i * 4 + 3, i * 4 + 4] + list(range(i * 2, i * 4)) + [i * 4 + 5, i * 4 + 6]) dm = bops.multiContraction(curr, xRight, '012', '012') ordered = np.reshape(dm.tensor, [d**l, d**l]) / np.trace( np.reshape(dm.tensor, [d**l, d**l])) purity = sum(np.linalg.eigvalsh(np.matmul(ordered, ordered))) with open(filename + '_l_' + str(l), 'wb') as f: pickle.dump(purity, f) return purity
def get2ByNExplicit(l: int): with open('results/toricBoundaries', 'rb') as f: [upRow, downRow, leftRow, rightRow, openA, openB, A, B] = pickle.load(f) left = bops.multiContraction( downRow, bops.multiContraction(leftRow, upRow, '3', '0'), '3', '0') for i in range(1, l): left = bops.multiContraction( downRow, bops.multiContraction(left, upRow, [3 + 4 * i], '0', cleanOr1=True), '3', '0') circle = bops.multiContraction(left, downRow, [3 + 4 * l, 0], '03') openA = tn.Node( np.transpose( np.reshape(np.kron(A.tensor, A.tensor), [d**2, d**2, d**2, d**2, d, d]), [4, 0, 1, 2, 3, 5])) openB = tn.Node( np.transpose( np.reshape(np.kron(B.tensor, B.tensor), [d**2, d**2, d**2, d**2, d, d]), [4, 0, 1, 2, 3, 5])) ABNet = bops.permute( bops.multiContraction(bops.multiContraction(openB, openA, '2', '4'), bops.multiContraction(openA, openB, '2', '4'), '28', '16', cleanOr1=True, cleanOr2=True), [1, 5, 6, 13, 14, 9, 10, 2, 0, 4, 8, 12, 3, 7, 11, 15]) if l == 2: curr = bops.multiContraction(circle, ABNet, '234567', '456701') res = bops.permute( bops.multiContraction(curr, ABNet, '23450176', '01234567'), [0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15]) rdm = np.reshape(res.tensor, [2**8, 2**8]) rdm = rdm / np.trace(rdm) return rdm
def makeMeasurement(psi, site, toProject): localDM = bops.multiContraction(psi[site], psi[site], '02', '02*').tensor projectionProbability = np.trace(np.matmul(localDM, toProject)) / np.trace(localDM) # Project to the measured vector if np.random.uniform(0, 1) < projectionProbability: psi[site] = bops.permute( bops.multiContraction(psi[site], tn.Node(toProject), '1', '1', cleanOr1=True, cleanOr2=True), [0, 2, 1]) res = 1 else: psi[site] = bops.permute( bops.multiContraction(psi[site], tn.Node(np.eye(d) - toProject), '1', '1', cleanOr1=True, cleanOr2=True), [0, 2, 1]) res = 0 return res
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 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 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 singleHaarEstimation(psi: List[tn.Node], us: List[tn.Node], n: int, NA: int): psiCopy = bops.copyState(psi) projector0 = np.zeros((2, 2)) projector0[0, 0] = 1 projector1 = np.zeros((2, 2)) projector1[1, 1] = 1 measurementResults = np.array(NA) estimation = 1 for i in range(NA): psiCopy[i] = bops.permute( bops.multiContraction(psiCopy[i], us[i], '1', '1', cleanOr1=True), [0, 2, 1]) measurementResults[i] = makeMeasurement(psiCopy, i, projector0) if measurementResults: resultProjector = projector0 else: resultProjector = projector1 localEstimation = np.matmul(np.matmul(np.conj(np.transpose(us[i].tensor)), resultProjector), us[i].tensor) \ - np.eye(2) estimation *= np.trace(localEstimation**4) psiCopy = bops.shiftWorkingSite(psiCopy, i, '<<') return estimation
def trotterSweep(trotterGates, psi, startSite, endSite, maxBondDim=1024): psiCopy = bops.copyState(psi) truncErr = 0 N = len(psi) for k in [endSite - i for i in range(startSite, endSite)]: M = bops.multiContraction(psiCopy[k - 1], psiCopy[k], [2], [0]) M = bops.permute( bops.multiContraction(M, trotterGates[k - 1], [1, 2], [0, 1]), [0, 2, 3, 1]) [l, r, currTruncErr] = bops.svdTruncation(M, M[:2], M[2:], '<<', maxBondDim, leftName='site' + str(k - 1), rightName='site' + str(k), edgeName='v' + str(k)) if currTruncErr > truncErr: truncErr = currTruncErr psiCopy[k] = r psiCopy[k - 1] = l bops.multiContraction(r, r, [1, 2], [1, 2, '*']) for k in range(startSite, endSite): M = bops.multiContraction(psiCopy[k], psiCopy[k + 1], [2], [0]) M = bops.permute( bops.multiContraction(M, trotterGates[k], [1, 2], [0, 1]), [0, 2, 3, 1]) [l, r, currTruncErr] = bops.svdTruncation(M, M[:2], M[2:], '>>', maxBondDim, leftName='site' + str(k), rightName='site' + str(k + 1), edgeName='v' + str(k + 1)) if currTruncErr > truncErr: truncErr = currTruncErr psiCopy[k] = l psiCopy[k + 1] = r # For imaginary time propagation, renormalize state. norm = bops.getOverlap(psiCopy, psiCopy) psiCopy[N - 1].tensor = psiCopy[N - 1].tensor / math.sqrt(abs(norm)) return psiCopy, truncErr
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 getExplicit2by2(g=0): if g == 0: with open('results/toricBoundaries', 'rb') as f: [upRow, downRow, leftRow, rightRow, openA, openB, A, B] = pickle.load(f) else: with open('results/toricBoundaries_g_' + str(g), 'rb') as f: [upRow, downRow, leftRow, rightRow, openA, openB, A, B] = pickle.load(f) circle = bops.multiContraction( bops.multiContraction(bops.multiContraction(upRow, rightRow, '3', '0'), downRow, '5', '0'), leftRow, '70', '03') ABNet = bops.permute( bops.multiContraction(bops.multiContraction(openB, openA, '2', '4'), bops.multiContraction(openA, openB, '2', '4'), '28', '16', cleanOr1=True, cleanOr2=True), [1, 5, 6, 13, 14, 9, 10, 2, 0, 4, 8, 12, 3, 7, 11, 15]) dm = bops.multiContraction(circle, ABNet, '01234567', '01234567') ordered = np.round(np.reshape(dm.tensor, [16, 16]), 14) ordered /= np.trace(ordered) return ordered
d = 2 baseTensor = np.zeros((d, d, d), dtype=complex) for i in range(d): baseTensor[i, 0, i] = 1 #np.sqrt(np.cosh(beta)) for i in range(d): baseTensor[i, 1, i] = 0.5 * ( 1 - 2 * i) #np.sqrt(np.sinh(beta)) * (1 - 2 * i) # sigma_z base = tn.Node(baseTensor) A = bops.multiContraction(bops.multiContraction(bops.multiContraction( base, base, '2', '0'), base, '3', '0', cleanOr1=True), base, '4', '0', cleanOr1=True) AEnv = tn.Node(np.trace(A.get_tensor(), axis1=0, axis2=5)) GammaATensor = np.zeros((d, d, d), dtype=complex) GammaATensor[1, 1, 1] = 1 GammaATensor[0, 0, 0] = 1 GammaBTensor = np.zeros((d, d, d), dtype=complex) GammaBTensor[1, 1, 1] = 1 GammaBTensor[1, 1, 0] = -1 GammaBTensor[0, 0, 1] = 1 GammaBTensor[0, 0, 0] = 1 LambdaTensor = np.ones(d, dtype=complex)