def test_reachable_disconnected_2(backend):
  nodes = [tn.Node(np.random.rand(2, 2, 2), backend=backend) for _ in range(4)]
  nodes[1][1] ^ nodes[2][0]  #connect 2nd and third node
  assert set(tn.reachable([nodes[0],
                           nodes[1]])) == {nodes[0], nodes[1], nodes[2]}
  nodes[2][1] ^ nodes[3][0]  #connect third and fourth node
  assert set(tn.reachable([nodes[0], nodes[1]])) == set(nodes)
Exemple #2
0
def test_real_physics_with_tensors(backend):
    # Calcuate the expected value in numpy
    a_vals = np.ones([2, 3, 4, 5])
    b_vals = np.ones([4, 6, 7])
    c_vals = np.ones([5, 6, 8])
    contract1 = np.tensordot(a_vals, b_vals, [[2], [0]])
    contract2 = np.tensordot(c_vals, contract1, [[0], [2]])
    final_result = np.trace(contract2, axis1=0, axis2=4)
    # Build the network
    a = tn.Node(np.ones([2, 3, 4, 5]), name="T", backend=backend)
    b = tn.Node(np.ones([4, 6, 7]), name="A", backend=backend)
    c = tn.Node(np.ones([5, 6, 8]), name="B", backend=backend)
    e1 = tn.connect(a[2], b[0], "edge")
    e2 = tn.connect(c[0], a[3], "edge2")
    e3 = tn.connect(b[1], c[1], "edge3")
    tn.check_correct({a, b, c})
    node_result = tn.contract(e1)
    np.testing.assert_allclose(node_result.tensor, contract1)
    tn.check_correct(tn.reachable(node_result))
    node_result = tn.contract(e2)
    np.testing.assert_allclose(node_result.tensor, contract2)
    tn.check_correct(tn.reachable(node_result))
    val = tn.contract(e3)
    tn.check_correct(tn.reachable(val))
    np.testing.assert_allclose(val.tensor, final_result)
Exemple #3
0
def test_reachable_2(backend):
    a = tn.Node(np.zeros((3, 5)), backend=backend)
    b = tn.Node(np.zeros((3, 4, 5)), backend=backend)
    e1 = tn.connect(a[0], b[0])
    e2 = tn.connect(a[1], b[2])
    nodes = [a, b]
    edges = [e1, e2]
    assert set(nodes) == tn.reachable(edges[0])
    assert set(nodes) == tn.reachable(edges)
Exemple #4
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
Exemple #5
0
def test_with_tensors(backend):
    a = tn.Node(np.eye(2) * 2, name="T", backend=backend)
    b = tn.Node(np.eye(2) * 3, name="A", backend=backend)
    e1 = tn.connect(a[0], b[0], "edge")
    e2 = tn.connect(a[1], b[1], "edge2")
    tn.check_correct({a, b})
    result = tn.contract(e1)
    tn.check_correct(tn.reachable(result))
    val = tn.contract(e2)
    tn.check_correct(tn.reachable(val))
    np.testing.assert_allclose(val.tensor, 12.0)
Exemple #6
0
def test_reduced_density_contraction(backend):
    if backend == "pytorch":
        pytest.skip("pytorch doesn't support complex numbers")
    a = tn.Node(np.array([[0.0, 1.0j], [-1.0j, 0.0]], dtype=np.complex64),
                backend=backend)
    tn.reduced_density([a[0]])
    result = tn.contractors.greedy(tn.reachable(a), ignore_edge_order=True)
    np.testing.assert_allclose(result.tensor, np.eye(2))
Exemple #7
0
def test_split_node_qr(backend):
    a = tn.Node(np.random.rand(2, 3, 4, 5, 6), backend=backend)
    left_edges = []
    for i in range(3):
        left_edges.append(a[i])
    right_edges = []
    for i in range(3, 5):
        right_edges.append(a[i])
    left, _ = tn.split_node_qr(a, left_edges, right_edges)
    tn.check_correct(tn.reachable(left))
    np.testing.assert_allclose(a.tensor, tn.contract(left[3]).tensor)
Exemple #8
0
def test_split_node_full_svd(backend):
    unitary1 = np.array([[1.0, 1.0], [1.0, -1.0]]) / np.sqrt(2.0)
    unitary2 = np.array([[0.0, 1.0], [1.0, 0.0]])
    singular_values = np.array([9.1, 7.5], dtype=np.float32)
    val = np.dot(unitary1, np.dot(np.diag(singular_values), (unitary2.T)))
    a = tn.Node(val, backend=backend)
    e1 = a[0]
    e2 = a[1]
    _, s, _, _, = tn.split_node_full_svd(a, [e1], [e2])
    tn.check_correct(tn.reachable(s))
    np.testing.assert_allclose(s.tensor, np.diag([9.1, 7.5]), rtol=1e-5)
Exemple #9
0
 def execute(self, probs_autocalc: bool = True) -> Execution_result:
   if not isinstance(probs_autocalc, bool):
     raise TypeError("probs_autocalc is a bool parametr")
   for i in range(len(self._edges) - 1):
     self.ci(i, i + 1)
   nodes = tn.reachable(self._edges[0])
   result_node = tn.contractors.greedy(nodes, self._edges)
   result = Execution_result(result_node, probs_autocalc=probs_autocalc)
   for i in range(len(result_node.tensor.shape)):
     self._edges[i] = result_node.get_edge(i)
   return result
Exemple #10
0
def test_real_physics(dtype, num_charges):
    # Calcuate the expected value in numpy
    t1 = get_random_symmetric((20, 20, 20, 20), [False, False, False, False],
                              num_charges,
                              dtype=dtype)
    t2 = get_random_symmetric((20, 20, 20), [True, False, True],
                              num_charges,
                              dtype=dtype)
    t3 = get_random_symmetric((20, 20, 20), [True, True, False],
                              num_charges,
                              dtype=dtype)

    t1_dense = t1.todense()
    t2_dense = t2.todense()
    t3_dense = t3.todense()
    adense = tn.Node(t1_dense, name="T", backend='numpy')
    bdense = tn.Node(t2_dense, name="A", backend='numpy')
    cdense = tn.Node(t3_dense, name="B", backend='numpy')

    e1 = tn.connect(adense[2], bdense[0], "edge")
    e2 = tn.connect(cdense[0], adense[3], "edge2")
    e3 = tn.connect(bdense[1], cdense[1], "edge3")
    node_result = tn.contract(e1)
    node_result = tn.contract(e2)
    final_result = tn.contract(e3)

    # Build the network
    a = tn.Node(t1, name="T", backend='symmetric')
    b = tn.Node(t2, name="A", backend='symmetric')
    c = tn.Node(t3, name="B", backend='symmetric')
    e1 = tn.connect(a[2], b[0], "edge")
    e2 = tn.connect(c[0], a[3], "edge2")
    e3 = tn.connect(b[1], c[1], "edge3")
    tn.check_correct(tn.reachable(a))
    node_result = tn.contract(e1)
    tn.check_correct(tn.reachable(node_result))
    node_result = tn.contract(e2)
    tn.check_correct(tn.reachable(node_result))
    val = tn.contract(e3)
    tn.check_correct(tn.reachable(val))
    np.testing.assert_allclose(val.tensor.todense(), final_result.tensor)
Exemple #11
0
def test_complicated_edge_reordering(backend):
    a = tn.Node(np.zeros((2, 3, 4)), backend=backend)
    b = tn.Node(np.zeros((2, 5)), backend=backend)
    c = tn.Node(np.zeros((3, )), backend=backend)
    d = tn.Node(np.zeros((4, 5)), backend=backend)
    e_ab = tn.connect(a[0], b[0])
    e_bd = tn.connect(b[1], d[1])
    e_ac = tn.connect(a[1], c[0])
    e_ad = tn.connect(a[2], d[0])
    result = tn.contract(e_bd)
    a.reorder_edges([e_ac, e_ab, e_ad])
    tn.check_correct(tn.reachable(result))
    assert a.shape == (3, 2, 4)
Exemple #12
0
def test_fft():
    n = 3
    initial_state = [complex(0)] * (1 << n)
    initial_state[1] = 1j
    initial_state[5] = -1
    initial_node = tn.Node(np.array(initial_state).reshape((2, ) * n))

    fft_out = fft.add_fft([initial_node[k] for k in range(n)])
    result = tn.contractors.greedy(tn.reachable(fft_out[0].node1), fft_out)
    tn.flatten_edges(fft_out)
    actual = result.tensor
    expected = np.fft.fft(initial_state, norm="ortho")
    np.testing.assert_allclose(expected, actual)
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
def test_solutions():
    edge_order = sat_tensornetwork.sat_tn([
        (1, 2, -3),
    ])
    solutions = tensornetwork.contractors.greedy(
        tensornetwork.reachable(edge_order[0].node1), edge_order).tensor
    assert solutions[0][0][0] == 1
    # Only unaccepted value.
    assert solutions[0][0][1] == 0
    assert solutions[0][1][0] == 1
    assert solutions[0][1][1] == 1
    assert solutions[1][0][0] == 1
    assert solutions[1][0][1] == 1
    assert solutions[1][1][0] == 1
    assert solutions[1][1][1] == 1
Exemple #15
0
    def get_state_vector(self):
        """
      Returns resulting state vector as a tensor of rank 1.
      Round values to 3 decimal points.
    """
        # connect all nodes and evaluate all tensors stored in it
        self.evaluate_patch()

        if len(self.network) > 1:
            for index in reversed(range(1, len(self.network) - 1)):
                self.network[index + 1][0] ^ self.network[index][1]
            self.network[1][0] ^ self.network[0][0]
        nodes = tn.reachable(self.network[1])
        result = tn.contractors.greedy(nodes, ignore_edge_order=True)
        # round the result to three decimals
        state_vecor = np.round(result.tensor, 3)
        return state_vecor
def sat_count_tn(clauses: List[Tuple[int, int, int]]) -> Set[tn.BaseNode]:
    """Create a 3SAT Count TensorNetwork.

  After full contraction, the final node will be the count of all possible
  solutions to the given 3SAT problem.

  Args:
    clauses: A list of 3 int tuples. Each element in the tuple corresponds to a
      variable in the clause. If that int is negative, that variable is negated
      in the clause.

  Returns:
    nodes: The set of nodes
  """
    var_edges1 = sat_tn(clauses)
    var_edges2 = sat_tn(clauses)
    for edge1, edge2 in zip(var_edges1, var_edges2):
        edge1 ^ edge2
    # TODO(chaseriley): Support diconnected SAT graphs.
    return tn.reachable(var_edges1[0].node1)
def contract_network(nodes, contractor='auto', edge_order=None):
    """
    Contract a tensor network that has already been 'wired' together

    Args:
        nodes:      One or more nodes in the network of interest. All 
                    nodes connected to this one will get contracted
        contractor: Name of the TensorNetwork contractor used to contract
                    the network. Options include 'greedy', 'optimal', 
                    'bucket', 'branch', and 'auto' (default)
        edge_order: When expanding to a dense tensor, giving a list of the
                    dangling edges of the tensor is required to set the
                    order of the indices of the (large) output tensor

    Returns:
        output:     Pytorch tensor containing the contracted network, 
                    which here will always be a scalar or batch vector
    """
    contractor = getattr(tn.contractors, contractor)
    output = contractor(tn.reachable(nodes), output_edge_order=edge_order)
    return output.tensor
Exemple #18
0
def test_reachable_raises_value_error():
    with pytest.raises(ValueError):
        tn.reachable({})
Exemple #19
0
# define network edges
tn.connect(iso_l[0], iso_l_con[0])
tn.connect(iso_l[1], un_l[2])
tn.connect(iso_c[0], un_l[3])
tn.connect(iso_c[1], un_r[2])
tn.connect(iso_r[0], un_r[3])
tn.connect(iso_r[1], iso_r_con[1])
tn.connect(un_l[0], un_l_con[0])
tn.connect(un_l[1], op[3])
tn.connect(un_r[0], op[4])
tn.connect(un_r[1], op[5])
tn.connect(op[0], un_l_con[1])
tn.connect(op[1], un_r_con[0])
tn.connect(op[2], un_r_con[1])
tn.connect(un_l_con[2], iso_l_con[1])
tn.connect(un_l_con[3], iso_c_con[0])
tn.connect(un_r_con[2], iso_c_con[1])
tn.connect(un_r_con[3], iso_r_con[0])

# define output edges
output_edge_order = [
    iso_l_con[2], iso_c_con[2], iso_r_con[2], iso_l[2], iso_c[2], iso_r[2]
]

# solve for optimal order and contract the network
t0 = time.time()
T2 = contractors.branch(tn.reachable(op),
                        output_edge_order=output_edge_order).get_tensor()
print("tn.contractors: time to contract = ", time.time() - t0)
Exemple #20
0
def test_reachable_disconnected_1(backend):
    nodes = [
        tn.Node(np.random.rand(2, 2, 2), backend=backend) for _ in range(4)
    ]
    nodes[0][1] ^ nodes[1][0]
    nodes[2][1] ^ nodes[3][0]
    assert set(tn.reachable([nodes[0], nodes[2]])) == set(nodes)

    assert set(tn.reachable([nodes[0]])) == {nodes[0], nodes[1]}
    assert set(tn.reachable([nodes[1]])) == {nodes[0], nodes[1]}
    assert set(tn.reachable([nodes[0], nodes[1]])) == {nodes[0], nodes[1]}

    assert set(tn.reachable([nodes[2]])) == {nodes[2], nodes[3]}
    assert set(tn.reachable([nodes[3]])) == {nodes[2], nodes[3]}
    assert set(tn.reachable([nodes[2], nodes[3]])) == {nodes[2], nodes[3]}

    assert set(tn.reachable([nodes[0], nodes[1], nodes[2]])) == set(nodes)
    assert set(tn.reachable([nodes[0], nodes[1], nodes[3]])) == set(nodes)
    assert set(tn.reachable([nodes[0], nodes[2], nodes[3]])) == set(nodes)
    assert set(tn.reachable([nodes[1], nodes[2], nodes[3]])) == set(nodes)
Exemple #21
0
def test_reachable(backend):
    nodes = [
        tn.Node(np.random.rand(2, 2, 2), backend=backend) for _ in range(10)
    ]
    _ = [nodes[n][0] ^ nodes[n + 1][1] for n in range(len(nodes) - 1)]
    assert set(nodes) == tn.reachable(nodes[0])
Exemple #22
0
        def f(input_vec, entanglers1, entanglers2, isometries1, isometries2,
              bias_var, kernel_dims):
            input_vv = []
            step = int(kernel_dims // 4)
            for i in range(4):
                for ii in range(4):
                    input_vv.append(
                        tf.reshape(
                            input_vec[i * step:i * step + step,
                                      ii * step:ii * step + step, 0],
                            (1, step**2)))
            input_vec = tf.concat(input_vv, axis=0)
            input_vec = tf.reshape(input_vec, (16, step**2))
            input_vec = tf.unstack(input_vec)
            input_nodes = []
            for e_iv in input_vec:
                input_nodes.append(tn.Node(e_iv))

            e_nodes1 = tn.Node(entanglers1)
            e_nodes2 = tn.Node(entanglers2)

            isometries_nodes1 = []
            for eiso in isometries1:
                isometries_nodes1.append(tn.Node(eiso))
            isometries_nodes2 = tn.Node(isometries2)

            e_nodes1[0] ^ input_nodes[5][0]
            e_nodes1[1] ^ input_nodes[6][0]
            e_nodes1[2] ^ input_nodes[9][0]
            e_nodes1[3] ^ input_nodes[10][0]

            e_nodes1[4] ^ isometries_nodes1[0][3]
            e_nodes1[5] ^ isometries_nodes1[1][2]
            e_nodes1[6] ^ isometries_nodes1[2][1]
            e_nodes1[7] ^ isometries_nodes1[3][0]

            input_nodes[0][0] ^ isometries_nodes1[0][0]
            input_nodes[1][0] ^ isometries_nodes1[0][1]
            input_nodes[4][0] ^ isometries_nodes1[0][2]

            input_nodes[2][0] ^ isometries_nodes1[1][0]
            input_nodes[3][0] ^ isometries_nodes1[1][1]
            input_nodes[7][0] ^ isometries_nodes1[1][3]

            input_nodes[8][0] ^ isometries_nodes1[2][0]
            input_nodes[12][0] ^ isometries_nodes1[2][2]
            input_nodes[13][0] ^ isometries_nodes1[2][3]

            input_nodes[11][0] ^ isometries_nodes1[3][1]
            input_nodes[14][0] ^ isometries_nodes1[3][2]
            input_nodes[15][0] ^ isometries_nodes1[3][3]

            isometries_nodes1[0][4] ^ e_nodes2[0]
            isometries_nodes1[1][4] ^ e_nodes2[1]
            isometries_nodes1[2][4] ^ e_nodes2[2]
            isometries_nodes1[3][4] ^ e_nodes2[3]

            e_nodes2[4] ^ isometries_nodes2[0]
            e_nodes2[5] ^ isometries_nodes2[1]
            e_nodes2[6] ^ isometries_nodes2[2]
            e_nodes2[7] ^ isometries_nodes2[3]

            nodes = tn.reachable(isometries_nodes2)
            result = tn.contractors.greedy(nodes)
            result = result.tensor
            return result + bias_var
Exemple #23
0
def test_reachable_raises(backend):
    nodes = [tn.Node(np.random.rand(2, 2, 2), backend=backend), 5]
    with pytest.raises(TypeError):
        tn.reachable(nodes)
Exemple #24
0
def binary_mera_energy(hamiltonian, state, isometry, disentangler):
  """Computes the energy using a layer of uniform binary MERA.

  Args:
    hamiltonian: The hamiltonian (rank-6 tensor) defined at the bottom of the
      MERA layer.
    state: The 3-site reduced state (rank-6 tensor) defined at the top of the
      MERA layer.
    isometry: The isometry tensor (rank 3) of the binary MERA.
    disentangler: The disentangler tensor (rank 4) of the binary MERA.

  Returns:
    The energy.
  """
  backend = "jax"

  out = []
  for dirn in ('left', 'right'):
    iso_l = tensornetwork.Node(isometry, backend=backend)
    iso_c = tensornetwork.Node(isometry, backend=backend)
    iso_r = tensornetwork.Node(isometry, backend=backend)

    iso_l_con = tensornetwork.conj(iso_l)
    iso_c_con = tensornetwork.conj(iso_c)
    iso_r_con = tensornetwork.conj(iso_r)

    op = tensornetwork.Node(hamiltonian, backend=backend)
    rho = tensornetwork.Node(state, backend=backend)

    un_l = tensornetwork.Node(disentangler, backend=backend)
    un_l_con = tensornetwork.conj(un_l)

    un_r = tensornetwork.Node(disentangler, backend=backend)
    un_r_con = tensornetwork.conj(un_r)

    tensornetwork.connect(iso_l[2], rho[0])
    tensornetwork.connect(iso_c[2], rho[1])
    tensornetwork.connect(iso_r[2], rho[2])

    tensornetwork.connect(iso_l[0], iso_l_con[0])
    tensornetwork.connect(iso_l[1], un_l[2])
    tensornetwork.connect(iso_c[0], un_l[3])
    tensornetwork.connect(iso_c[1], un_r[2])
    tensornetwork.connect(iso_r[0], un_r[3])
    tensornetwork.connect(iso_r[1], iso_r_con[1])

    if dirn == 'right':
      tensornetwork.connect(un_l[0], un_l_con[0])
      tensornetwork.connect(un_l[1], op[3])
      tensornetwork.connect(un_r[0], op[4])
      tensornetwork.connect(un_r[1], op[5])
      tensornetwork.connect(op[0], un_l_con[1])
      tensornetwork.connect(op[1], un_r_con[0])
      tensornetwork.connect(op[2], un_r_con[1])
    elif dirn == 'left':
      tensornetwork.connect(un_l[0], op[3])
      tensornetwork.connect(un_l[1], op[4])
      tensornetwork.connect(un_r[0], op[5])
      tensornetwork.connect(un_r[1], un_r_con[1])
      tensornetwork.connect(op[0], un_l_con[0])
      tensornetwork.connect(op[1], un_l_con[1])
      tensornetwork.connect(op[2], un_r_con[0])

    tensornetwork.connect(un_l_con[2], iso_l_con[1])
    tensornetwork.connect(un_l_con[3], iso_c_con[0])
    tensornetwork.connect(un_r_con[2], iso_c_con[1])
    tensornetwork.connect(un_r_con[3], iso_r_con[0])

    tensornetwork.connect(iso_l_con[2], rho[3])
    tensornetwork.connect(iso_c_con[2], rho[4])
    tensornetwork.connect(iso_r_con[2], rho[5])

    # FIXME: Check that this is giving us a good path!
    out.append(
        contractors.branch(tensornetwork.reachable(rho),
                           nbranch=2).get_tensor())

  return 0.5 * sum(out)
Exemple #25
0
def contract_network(edges: Sequence[tn.Edge]) -> tn.Node:
  network = set()    
  for edge in edges:
    network |= tn.reachable(edge)
  return cn.greedy(network, output_edge_order=edges)