예제 #1
0
def mps_product(mps, input_tensor):
    input_tensor = tn.replicate_nodes(input_tensor)
    mps = tn.replicate_nodes(mps)

    # Fully connect mps
    for i in range(len(mps) - 1):
        mps[i]['r'] ^ mps[i + 1]['l']

    # Connect inputs to mps
    for i, node in enumerate(mps):
        node['in'] ^ input_tensor[i]['in']

    return mps + input_tensor
예제 #2
0
def test_replicate_nodes(backend):
    a = tn.Node(np.random.rand(10, 10), backend=backend)
    b = tn.Node(np.random.rand(10, 10), backend=backend)
    c = tn.Node(np.random.rand(10, 10), backend=backend)
    tn.connect(a[1], b[0])
    tn.connect(b[1], c[0])
    [a_copy, b_copy] = tn.replicate_nodes([a, b])
    assert b_copy in tn.reachable([a_copy])
    assert not set([a_copy, b_copy]).issubset(tn.reachable([c]))
    assert len(b_copy.get_all_dangling()) == 1
def VRL_train(five_tuple,
              k,
              data,
              H,
              H_core,
              omega,
              lr=0.00001,
              epochs=int(1e4),
              lam=1):
    s, a, P_mat, R_vec, gamma = five_tuple
    energy_history = []
    Pbar = pkbar.Pbar(name='progress', target=epochs)
    op = optim.SGD([data], lr=lr, momentum=0.9, weight_decay=5e-4)

    for e in range(epochs):
        spins = []
        core = []
        edge = []
        energy = 0
        regularity = 0

        op.zero_grad()

        for i in range(k):
            H_core[i] = tensor_completion(H_core[i], H[i], omega[i])
            core.append(tn.replicate_nodes(H_core[i]))
            edge.append([])
            for c in core[i]:
                edge[i] += c.get_all_dangling()

        for i in range(k):
            spins.append(K_Spin(s, a, i + 1, data=data, softmax=True))
            for j in range(i + 1):
                edge[i][j] ^ spins[i].qubits[j][0]

        for i in range(k):
            energy -= contractors.branch(tn.reachable(core[i]),
                                         nbranch=1).get_tensor()
        energy_history.append(energy)

        for j in range(s):
            regularity += (1 - torch.sum(data[j * a:(j + 1) * a], 0))**2
        target = energy + lam * regularity

        target.backward()
        op.step()
        Pbar.update(e)

    return spins, energy_history
예제 #4
0
    def __gradient__(self, input_idx: int) -> np.ndarray:
        """
        Calculates the gradient of the inner-product <MPS|input_tensor>
        with respect to the bond tensor.

        :param input_tensor: tensor formed from the input vector
        :return: d<MPS|input_tensor>/d{bond}
        """
        proj = self.__projection__(input_idx)
        bond = self.mps.get_contracted_bond()

        leftmost = self.__leftmost__()

        if leftmost:
            proj[0]['in'] ^ bond['in1']
            proj[1]['in'] ^ bond['in2']
            proj[2]['in'] ^ bond['r']
        else:
            proj[0]['in'] ^ bond['l']
            proj[1]['in'] ^ bond['in1']
            proj[2]['in'] ^ bond['in2']
            proj[3]['in'] ^ bond['r']

        mps_prod = tn.contractors.auto(proj + [bond]) - tn.Node(self.Ys[:, input_idx])
        mps_prod.add_axis_names(['out'])
        proj2 = tn.replicate_nodes(proj)

        if leftmost:
            in1_edge = proj2[0]['in']
            in2_edge = proj2[1]['in']
            r_edge = proj2[2]['in']
            edge_order = [r_edge, in1_edge, in2_edge]
        else:
            l_edge = proj2[0]['in']
            in1_edge = proj2[1]['in']
            in2_edge = proj2[2]['in']
            r_edge = proj2[3]['in']
            edge_order = [l_edge, r_edge, in1_edge, in2_edge]

        edge_order.append(mps_prod['out'])
        return tn.contractors.auto([mps_prod] + proj2, output_edge_order=edge_order).tensor
예제 #5
0
 def get_right(self):
     return tn.replicate_nodes(self.tensors[self.output_idx + 2:])