def getPurity(w, h): with open('results/toricBoundaries_g_0.0', 'rb') as f: [upRow, downRow, leftRow, rightRow, openA, openB, A, B] = pickle.load(f) upRow = tn.Node(upRow) downRow = tn.Node(downRow) leftRow = tn.Node(leftRow) rightRow = tn.Node(rightRow) openA = tn.Node(openA) openB = tn.Node(openB) [cUp, dUp, te] = bops.svdTruncation(upRow, [0, 1], [2, 3], '>>') [cDown, dDown, te] = bops.svdTruncation(downRow, [0, 1], [2, 3], '>>') norm = pe.applyLocalOperators(cUp, dUp, cDown, dDown, leftRow, rightRow, A, B, w, h, [tn.Node(np.eye(d)) for i in range(w * h)]) leftRow = bops.multNode(leftRow, 1 / norm) res = pe.applyLocalOperators( cUp, dUp, cDown, dDown, leftRow, rightRow, A, B, w, h, [tn.Node(ru.proj0Tensor) for i in range(w * h * 4)]) # The density matrix is constructed of blocks of ones of size N and normalized by res. # Squaring it adds a factor of N * res. N = 2**(int(w * h / 4)) purity = N * res return purity
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 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 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
elif option == 'toricG': g = np.round(float(sys.argv[8]), 2) boundaryFile = 'toricBoundaries_g_' + str(g) topoOpt = sys.argv[9] newdir = dirname + 'toric_g_' + str(g) + '_n_' + str(n) + '_w_' + str(w) + '_h_' + str(h) + '_' + topoOpt argvl = 10 excludeIndices = [] if len(sys.argv) > argvl: for i in range(argvl, len(sys.argv)): excludeIndices.append(int(sys.argv[i])) with open(dirname + boundaryFile, 'rb') as f: [upRow, downRow, leftRow, rightRow, openA, openB, A, B] = pickle.load(f) [cUp, dUp, te] = bops.svdTruncation(upRow, [0, 1], [2, 3], '>>') [cDown, dDown, te] = bops.svdTruncation(downRow, [0, 1], [2, 3], '>>') norm = pe.applyLocalOperators(cUp, dUp, cDown, dDown, leftRow, rightRow, A, B, w, h, [tn.Node(np.eye(d)) for i in range(w * h)]) leftRow = bops.multNode(leftRow, 1 / norm**(2/w)) print(pe.applyLocalOperators(cUp, dUp, cDown, dDown, leftRow, rightRow, A, B, w, h, [tn.Node(np.eye(d)) for i in range(w * h)])) try: os.mkdir(newdir) except FileExistsError: pass option = 'complex' ru.renyiEntropy(n, w, h, M, option, theta, phi, pe.applyLocalOperators, [cUp, dUp, cDown, dDown, leftRow, rightRow, A, B, w, h], newdir + '/rep_' + str(rep), excludeIndices=excludeIndices)
LambdaD = tn.Node(np.eye(nonPhysicalLegs) / np.sqrt(nonPhysicalLegs), backend=None) steps = 50 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]) curr = bops.permute( bops.multiContraction(envOpBA, envOpAB, '45', '01'), [0, 2, 4, 6, 1, 3, 5, 7]) for i in range(2): [C, D, te] = bops.svdTruncation(curr, [0, 1, 2, 3], [4, 5, 6, 7], '>>', normalize=True) curr = bops.permute(bops.multiContraction(D, C, '23', '12'), [1, 3, 0, 5, 2, 4]) curr = bops.permute( bops.multiContraction(curr, envOpAB, '45', '01'), [0, 2, 4, 6, 1, 3, 5, 7]) currAB = curr 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(
def getNMatrices(E, subsystemNum): [N, Nbar, truncErr] = bops.svdTruncation(E, [E[0], E[2]], [E[1], E[3]], dir='>>', edgeName='S' + str(subsystemNum)) return N, Nbar
def getBMPS(hs, steps): for h in hs: h = np.round(h, 1) if int(h) == h: h = int(h) with open('ising/origTensors/ising_field_' + str(h) + '_A', 'rb') as f: ATensor = pickle.load(f) with open('ising/origTensors/ising_field_' + str(h) + '_B', 'rb') as f: BTensor = pickle.load(f) A = tn.Node(ATensor) A = bops.permute(A, [1, 2, 3, 0, 4]) B = tn.Node(BTensor) B = bops.permute(B, [1, 2, 3, 0, 4]) def toEnvOperator(op): result = bops.unifyLegs( bops.unifyLegs( bops.unifyLegs( bops.unifyLegs( bops.permute(op, [0, 4, 1, 5, 2, 6, 3, 7]), 6, 7), 4, 5), 2, 3), 0, 1) tn.remove_node(op) return result AEnv = toEnvOperator(bops.multiContraction(A, A, '4', '4*')) BEnv = toEnvOperator(bops.multiContraction(B, B, '4', '4*')) 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]) curr = bops.permute( bops.multiContraction(envOpBA, envOpAB, '45', '01'), [0, 2, 4, 6, 1, 3, 5, 7]) for i in range(2): [C, D, te] = bops.svdTruncation(curr, [0, 1, 2, 3], [4, 5, 6, 7], '>>', normalize=True) curr = bops.permute(bops.multiContraction(D, C, '23', '12'), [1, 3, 0, 5, 2, 4]) curr = bops.permute( bops.multiContraction(curr, envOpAB, '45', '01'), [0, 2, 4, 6, 1, 3, 5, 7]) b = 1 currAB = curr rowTensor = np.zeros((11, 4, 4, 11), dtype=complex) rowTensor[0, 3, 3, 0] = 1 rowTensor[1, 3, 3, 2] = 1 rowTensor[2, 3, 3, 3] = 1 rowTensor[3, 3, 0, 4] = 1 rowTensor[4, 0, 3, 1] = 1 rowTensor[5, 3, 3, 6] = 1 rowTensor[6, 3, 0, 7] = 1 rowTensor[7, 0, 3, 8] = 1 rowTensor[8, 3, 3, 5] = 1 row = tn.Node(rowTensor) print('60') upRow = bops.unifyLegs( bops.unifyLegs( bops.unifyLegs( bops.unifyLegs( bops.permute( bops.multiContraction(row, tn.Node(currAB.tensor), '12', '04'), [0, 2, 3, 4, 7, 1, 5, 6]), 5, 6), 5, 6), 0, 1), 0, 1) [C, D, te] = bops.svdTruncation(upRow, [0, 1], [2, 3], '>>', normalize=True) upRow = bops.multiContraction(D, C, '2', '0') [cUp, dUp, te] = bops.svdTruncation(upRow, [0, 1], [2, 3], '>>', normalize=True) GammaC, LambdaC, GammaD, LambdaD = peps.getBMPSRowOps( cUp, tn.Node(np.ones(cUp[2].dimension)), dUp, tn.Node(np.ones(dUp[2].dimension)), AEnv, BEnv, steps) cUp = bops.multiContraction(GammaC, LambdaC, '2', '0', isDiag2=True) dUp = bops.multiContraction(GammaD, LambdaD, '2', '0', isDiag2=True) upRow = bops.multiContraction(cUp, dUp, '2', '0') downRow = bops.copyState([upRow])[0] rightRow = peps.bmpsCols(upRow, downRow, AEnv, BEnv, steps, option='right', X=upRow) leftRow = peps.bmpsCols(upRow, downRow, AEnv, BEnv, steps, option='left', X=upRow) circle = bops.multiContraction( bops.multiContraction( bops.multiContraction(upRow, rightRow, '3', '0'), upRow, '5', '0'), leftRow, '70', '03') openA = tn.Node( np.transpose( np.reshape(np.kron(A.tensor, np.conj(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, np.conj(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]) dm = bops.multiContraction(circle, ABNet, '01234567', '01234567') ordered = np.round(np.reshape(dm.tensor, [16, 16]), 14) ordered /= np.trace(ordered) print(h, getM(ordered)) with open('ising/bmpsResults_' + str(h), 'wb') as f: pickle.dump( [upRow, downRow, leftRow, rightRow, openA, openB, A, B], f)
def toricVar(ls: np.array, op=E, color='blue'): w = 2 d = 2 chi = 4 with open('results/toricBoundaries', 'rb') as f: [upRow, downRow, leftRow, rightRow, openA, openB, A, B] = pickle.load(f) [cUp, dUp, te] = bops.svdTruncation(upRow, [0, 1], [2, 3], '>>') [cDown, dDown, te] = bops.svdTruncation(downRow, [0, 1], [2, 3], '>>') def getDoubleOp(op, d): return tn.Node( np.reshape( np.transpose( np.reshape(np.outer(op.tensor, op.tensor), [d] * 10), [0, 5, 1, 6, 2, 7, 3, 8, 4, 9]), [d**2] * 5)) doubleA = getDoubleOp(A, d) doubleB = getDoubleOp(B, d) def getDoubleRow(origRow, chi, d): openRow = np.reshape(origRow.tensor, [chi, d, d, d, d, chi]) doubleRow = tn.Node( np.reshape( np.transpose( np.reshape(np.outer(openRow, openRow), [chi, d, d, d, d, chi] + [chi, d, d, d, d, chi]), [0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11]), [chi**2, d**4, d**4, chi**2])) return doubleRow doubleUpRow = getDoubleRow(upRow, chi, d) doubleDownRow = getDoubleRow(downRow, chi, d) doubleRightRow = getDoubleRow(rightRow, chi, d) [doubleCUp, doubleDUp, te] = bops.svdTruncation(doubleUpRow, [0, 1], [2, 3], '>>') [doubleCDown, doubleDDown, te] = bops.svdTruncation(doubleDownRow, [0, 1], [2, 3], '>>') # qA = getDoubleOp(doubleA, d ** 2) # qB = getDoubleOp(doubleB, d ** 2) # qUpRow = getDoubleRow(doubleUpRow, chi**2, d**2) # qDownRow = getDoubleRow(doubleDownRow, chi**2, d**2) # qRightRow = getDoubleRow(doubleRightRow, chi**2, d**2) # [qCUp, qDUp, te] = bops.svdTruncation(qUpRow, [0, 1], [2, 3], '>>') # [qCDown, qDDown, te] = bops.svdTruncation(qDownRow, [0, 1], [2, 3], '>>') hs = ls * 2 vs = np.zeros(len(hs)) v2s = np.zeros(len(hs)) for i in range(len(hs)): h = hs[i] norm = pe.applyLocalOperators( cUp, dUp, cDown, dDown, leftRow, rightRow, A, B, w, h, [tn.Node(np.eye(d)) for i in range(w * h)]) leftRow = bops.multNode(leftRow, 1 / norm**(2 / w)) doubleLeftRow = getDoubleRow(leftRow, chi, d) ops = [op for i in range(w * h)] vs[i] = pe.applyLocalOperators(doubleCUp, doubleDUp, doubleCDown, doubleDDown, doubleLeftRow, doubleRightRow, doubleA, doubleB, w, h, ops) # qLeftRow = getDoubleRow(doubleLeftRow, chi**2, d**2) # ops = [tn.Node(np.eye(d**4)) for i in range(w * h)] # v2s[i] = pe.applyLocalOperators(qCUp, qDUp, qCDown, qDDown, qLeftRow, qRightRow, qA, qB, w, h, ops) print(vs) print([expected(l) for l in ls]) ban.linearRegression(ls * 4, vs, show=False, color=color)
def bmpsRowStep(gammaL, lambdaMid, gammaR, lambdaSide, envOp): row = bops.multiContraction(bops.multiContraction(bops.multiContraction( bops.multiContraction(lambdaSide, gammaL, '1', '0', isDiag1=True), lambdaMid, '2', '0', cleanOr1=True, cleanOr2=True, isDiag2=True), gammaR, '2', '0', cleanOr1=True, cleanOr2=True), lambdaSide, '3', '0', cleanOr1=True, isDiag2=True) opRow = bops.permute( bops.multiContraction(row, envOp, '12', '01', cleanOr1=True), [0, 2, 4, 5, 1, 3]) [U, S, V, truncErr] = bops.svdTruncation(opRow, [0, 1, 2], [3, 4, 5], dir='>*<', maxBondDim=chi) newLambdaMid = bops.multNode(S, 1 / np.sqrt(sum(S.tensor**2))) lambdaSideInv = tn.Node( np.array([1 / val if val > 1e-15 else 0 for val in lambdaSide.tensor], dtype=complex)) newGammaL = bops.multiContraction(lambdaSideInv, U, '1', '0', cleanOr2=True, isDiag1=True) splitter = tn.Node( bops.getLegsSplitterTensor(newGammaL[0].dimension, newGammaL[1].dimension)) newGammaL = bops.unifyLegs(newGammaL, 0, 1) newGammaR = bops.multiContraction(V, lambdaSideInv, '2', '0', cleanOr1=True, cleanOr2=True, isDiag2=True) newGammaR = bops.unifyLegs(newGammaR, 2, 3) newLambdaSide = bops.multiContraction(bops.multiContraction(lambdaSide, splitter, '1', '0', cleanOr1=True, isDiag1=True), splitter, '01', '01', cleanOr1=True, cleanOr2=True) temp = newLambdaSide newLambdaSide = tn.Node(np.diag(newLambdaSide.tensor)) tn.remove_node(temp) return newGammaL, newLambdaMid, newGammaR, newLambdaSide