Exemple #1
0
def multiContraction(node1: tn.Node,
                     node2: tn.Node,
                     edges1,
                     edges2,
                     nodeName=None,
                     cleanOr1=False,
                     cleanOr2=False,
                     isDiag1=False,
                     isDiag2=False) -> tn.Node:
    if node1 is None or node2 is None:
        return None
    if edges1[len(edges1) - 1] == '*':
        copy1 = copyState([node1], conj=True)[0]
        edges1 = edges1[0:len(edges1) - 1]
    else:
        copy1 = copyState([node1])[0]
    if edges2[len(edges2) - 1] == '*':
        copy2 = copyState([node2], conj=True)[0]
        edges2 = edges2[0:len(edges2) - 1]
    else:
        copy2 = copyState([node2])[0]

    if cleanOr1:
        tn.remove_node(node1)
    if cleanOr2:
        tn.remove_node(node2)
    if isDiag1 and isDiag2:
        return tn.Node(copy1.tensor * copy2.tensor)
    elif isDiag1 and not isDiag2:
        return contractDiag(copy2, copy1.tensor, int(edges2[0]))
    elif isDiag2 and not isDiag1:
        return contractDiag(copy1, copy2.tensor, int(edges1[0]))
    for i in range(len(edges1)):
        copy1[int(edges1[i])] ^ copy2[int(edges2[i])]
    return tn.contract_between(copy1, copy2, name=nodeName)
Exemple #2
0
def getOverlap(psi1Orig: List[tn.Node], psi2Orig: List[tn.Node]):
    psi1 = copyState(psi1Orig)
    psi2 = copyState(psi2Orig, conj=True)
    psi1[0][0] ^ psi2[0][0]
    psi1[0][1] ^ psi2[0][1]
    contracted = tn.contract_between(psi1[0], psi2[0], name='contracted')
    for i in range(1, len(psi1) - 1):
        psi1[i][1] ^ psi2[i][1]
        contracted[0] ^ psi1[i][0]
        contracted[1] ^ psi2[i][0]
        contracted = tn.contract_between(
            tn.contract_between(contracted, psi1[i]), psi2[i])
    psi1[len(psi1) - 1][1] ^ psi2[len(psi1) - 1][1]
    psi1[len(psi1) - 1][2] ^ psi2[len(psi1) - 1][2]
    contracted[0] ^ psi1[len(psi1) - 1][0]
    contracted[1] ^ psi2[len(psi1) - 1][0]
    contracted = tn.contract_between(
        tn.contract_between(contracted, psi1[len(psi1) - 1]),
        psi2[len(psi1) - 1])

    result = contracted.tensor
    tn.remove_node(contracted)
    removeState(psi1)
    removeState(psi2)
    return result
Exemple #3
0
def test_remove_after_flatten(backend):
    a = tn.Node(np.ones((2, 2)), backend=backend)
    b = tn.Node(np.ones((2, 2)), backend=backend)
    tn.connect(a[0], b[0])
    tn.connect(a[1], b[1])
    tn.flatten_all_edges({a, b})
    tn.remove_node(a)
Exemple #4
0
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
Exemple #5
0
def unifyLegs(node: tn.Node,
              leg1: int,
              leg2: int,
              cleanOriginal=True) -> tn.Node:
    shape = node.get_tensor().shape
    newTensor = np.reshape(
        node.get_tensor(),
        list(shape[:leg1]) + [shape[leg1] * shape[leg2]] +
        list(shape[leg2 + 1:]))
    if cleanOriginal:
        tn.remove_node(node)
    return tn.Node(newTensor)
Exemple #6
0
def assignNewSiteTensors(psi, k, M, dir, getOrthogonal=False):
    [sitek, sitekPlus1, truncErr] = svdTruncation(M, [M[0], M[1]], [M[2], M[3]], dir, \
            leftName=('site' + str(k)), rightName=('site' + str(k+1)), edgeName = ('v' + str(k+1)))
    tn.remove_node(psi[k])
    psi[k] = sitek
    # if k > 0:
    #     psi[k-1][2] ^ psi[k]
    tn.remove_node(psi[k + 1])
    psi[k + 1] = sitekPlus1
    # if k+2 < len(psi):
    #     psi[k+1][2] ^ psi[k+2][0]
    return [psi, truncErr]
Exemple #7
0
def permute(node: tn.Node, permutation) -> tn.Node:
    if node is None:
        return None
    axisNames = []
    for i in range(len(permutation)):
        axisNames.append(node.edges[permutation[i]].name)
    result = tn.Node(np.transpose(node.tensor, permutation))
    if len(set(axisNames)) == len(axisNames):
        result.add_axis_names(axisNames)
    for i in range(len(axisNames)):
        result.get_edge(i).set_name(axisNames[i])
    result.set_name(node.name)
    tn.remove_node(node)
    return result
Exemple #8
0
def test_remove_node(backend):
    a = tn.Node(np.eye(2), backend=backend)
    b = tn.Node(np.eye(2), backend=backend)
    tn.connect(a[0], b[0])
    broken_edges_by_name, broken_edges_by_axis = tn.remove_node(b)
    assert broken_edges_by_name == {"0": a[0]}
    assert broken_edges_by_axis == {0: a[0]}
Exemple #9
0
def test_remove_node_trace_edge(backend):
    a = tn.Node(np.ones((2, 2, 2)), backend=backend)
    b = tn.Node(np.ones(2), backend=backend)
    tn.connect(a[0], b[0])
    tn.connect(a[1], a[2])
    _, broken_edges = tn.remove_node(a)
    assert 0 in broken_edges
    assert 1 not in broken_edges
    assert 2 not in broken_edges
    assert broken_edges[0] is b[0]
Exemple #10
0
def addNodes(node1, node2, cleanOr1=False, cleanOr2=False):
    # TODO asserts
    if node1 is None:
        if node2 is None:
            res = None
        else:
            res = node2
    else:
        if node2 is None:
            res = node1
        else:
            result = copyState([node1])[0]
            result.set_tensor(result.get_tensor() + node2.get_tensor())
            res = result
    if cleanOr1:
        tn.remove_node(node1)
    if cleanOr2:
        tn.remove_node(node2)
    return res
Exemple #11
0
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
Exemple #12
0
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
Exemple #13
0
def shiftWorkingSite(psi: List[tn.Node], k, dir, maxBondDim=None):
    if dir == '<<':
        pair = multiContraction(psi[k - 1],
                                psi[k], [2], [0],
                                cleanOr1=True,
                                cleanOr2=True)
        if maxBondDim is None:
            [l, r, I] = svdTruncation(pair, [0, 1], [2, 3], '<<')
        else:
            [l, r, I] = svdTruncation(pair, [0, 1], [2, 3],
                                      '<<',
                                      maxBondDim=maxBondDim)
        psi[k - 1] = l
        psi[k] = r
        tn.remove_node(pair)
    else:
        pair = tn.contract(psi[k][2] ^ psi[k + 1][0])
        [l, r, I] = svdTruncation(pair, [0, 1], [2, 3],
                                  '>>',
                                  maxBondDim=maxBondDim)
        psi[k] = l
        psi[k + 1] = r
        tn.remove_node(pair)
    return psi
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
Exemple #15
0
def test_remove_node(backend):
    a = tn.Node(np.ones((2, 2, 2)),
                axis_names=["test", "names", "ignore"],
                backend=backend)
    b = tn.Node(np.ones((2, 2)), backend=backend)
    c = tn.Node(np.ones((2, 2)), backend=backend)
    tn.connect(a["test"], b[0])
    tn.connect(a[1], c[0])
    broken_edges_name, broken_edges_axis = tn.remove_node(a)
    assert "test" in broken_edges_name
    assert broken_edges_name["test"] is b[0]
    assert "names" in broken_edges_name
    assert broken_edges_name["names"] is c[0]
    assert "ignore" not in broken_edges_name
    assert 0 in broken_edges_axis
    assert 1 in broken_edges_axis
    assert 2 not in broken_edges_axis
    assert broken_edges_axis[0] is b[0]
    assert broken_edges_axis[1] is c[0]
def svdTruncation(node: tn.Node, leftEdges: List[tn.Edge], rightEdges: List[tn.Edge], \
                  dir: str, maxBondDim=1024, leftName='U', rightName='V',  edgeName=None):
    maxBondDim = getAppropriateMaxBondDim(maxBondDim, leftEdges, rightEdges)
    if dir == '>>':
        leftEdgeName = edgeName
        rightEdgeName = None
    else:
        leftEdgeName = None
        rightEdgeName = edgeName

    [U, S, V, truncErr] = tn.split_node_full_svd(node, leftEdges, rightEdges, max_singular_values=maxBondDim, \
                                       left_name=leftName, right_name=rightName, \
                                       left_edge_name=leftEdgeName, right_edge_name=rightEdgeName)
    if dir == '>>':
        l = copyState([U])[0]
        r = copyState([tn.contract_between(S, V, name=V.name)])[0]
    else:
        l = copyState([tn.contract_between(U, S, name=U.name)])[0]
        r = copyState([V])[0]
    tn.remove_node(U)
    tn.remove_node(S)
    tn.remove_node(V)
    return [l, r, truncErr]
Exemple #17
0
def svdTruncation(node: tn.Node,
                  leftEdges: List[int],
                  rightEdges: List[int],
                  dir: str,
                  maxBondDim=128,
                  leftName='U',
                  rightName='V',
                  edgeName='default',
                  normalize=False,
                  maxTrunc=8):
    maxBondDim = getAppropriateMaxBondDim(maxBondDim,
                                          [node.edges[e] for e in leftEdges],
                                          [node.edges[e] for e in rightEdges])
    if dir == '>>':
        leftEdgeName = edgeName
        rightEdgeName = None
    else:
        leftEdgeName = None
        rightEdgeName = edgeName

    [U, S, V,
     truncErr] = tn.split_node_full_svd(node,
                                        [node.edges[e] for e in leftEdges],
                                        [node.edges[e] for e in rightEdges],
                                        max_singular_values=maxBondDim,
                                        left_name=leftName,
                                        right_name=rightName,
                                        left_edge_name=leftEdgeName,
                                        right_edge_name=rightEdgeName)
    s = S
    S = tn.Node(np.diag(S.tensor))
    tn.remove_node(s)
    norm = np.sqrt(sum(S.tensor**2))
    if maxTrunc > 0:
        meaningful = sum(np.round(S.tensor / norm, maxTrunc) > 0)
        S.tensor = S.tensor[:meaningful]
        U.tensor = np.transpose(np.transpose(U.tensor)[:meaningful])
        V.tensor = V.tensor[:meaningful]
    if normalize:
        S = multNode(S, 1 / norm)
    for e in S.edges:
        e.name = edgeName
    if dir == '>>':
        l = copyState([U])[0]
        r = multiContraction(S,
                             V,
                             '1',
                             '0',
                             cleanOr1=True,
                             cleanOr2=True,
                             isDiag1=True)
    elif dir == '<<':
        l = multiContraction(U,
                             S, [len(U.edges) - 1],
                             '0',
                             cleanOr1=True,
                             cleanOr2=True,
                             isDiag2=True)
        r = copyState([V])[0]
    elif dir == '>*<':
        v = V
        V = copyState([V])[0]
        tn.remove_node(v)
        u = U
        U = copyState([U])[0]
        tn.remove_node(u)
        return [U, S, V, truncErr]

    tn.remove_node(U)
    tn.remove_node(S)
    tn.remove_node(V)
    return [l, r, truncErr]
Exemple #18
0
def removeState(psi):
    for i in range(len(psi)):
        tn.remove_node(psi[i])
Exemple #19
0
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