def test_copy_node_add_to_node_collection():
    container = set()
    with NodeCollection(container):
        a = tn.CopyNode(rank=4,
                        dimension=3,
                        name='copier1',
                        axis_names=[str(n) for n in range(4)])
        b = tn.CopyNode(rank=2,
                        dimension=3,
                        name='copier2',
                        axis_names=[str(n) for n in range(2)])
    assert container == {a, b}
Exemplo n.º 2
0
def batch_node(num_inputs, batch_dim):
    """
    Return a network of small CopyNodes which emulates a large CopyNode

    This network is used for reproducing the standard batch functionality 
    available in Pytorch, and requires connecting the `num_inputs` edges
    returned by batch_node to the respective batch indices of our inputs.
    The sole remaining dangling edge will then give the batch index of 
    whatever contraction occurs later with the input.

    Args:
        num_inputs: The number of batch indices to contract together
        batch_dim:  The batch dimension we intend to reproduce

    Returns:
        edge_list:  List of edges of our composite CopyNode object
    """
    # For small numbers of edges, just use a single CopyNode
    num_edges = num_inputs + 1
    if num_edges < 4:
        node = tn.CopyNode(rank=num_edges, dimension=batch_dim)
        return node.get_all_edges()

    # Initialize list of free edges with output of trivial identity mats
    input_node = tn.Node(torch.eye(batch_dim))
    edge_list, dummy_list = zip(
        *[input_node.copy().get_all_edges() for _ in range(num_edges)])

    # Contract dummy edges as a binary tree via third-order tensors
    dummy_len = len(dummy_list)
    while dummy_len > 4:
        odd = dummy_len % 2 == 1
        half_len = dummy_len // 2

        # Apply third order tensor to contract two dummy indices together
        temp_list = []
        for i in range(half_len):
            temp_node = tn.CopyNode(rank=3, dimension=batch_dim)
            temp_node[1] ^ dummy_list[2 * i]
            temp_node[2] ^ dummy_list[2 * i + 1]
            temp_list.append(temp_node[0])
        if odd:
            temp_list.append(dummy_list[-1])

        dummy_list = temp_list
        dummy_len = len(dummy_list)

    # Contract the 3 or less dummy indices together
    last_node = tn.CopyNode(rank=dummy_len, dimension=batch_dim)
    [last_node[i] ^ dummy_list[i] for i in range(dummy_len)]

    return edge_list
def test_copy_node_load(tmp_path, backend):
  node = tn.CopyNode(
      rank=4,
      dimension=3,
      name='copier',
      axis_names=[str(n) for n in range(4)],
      backend=backend)
  with h5py.File(tmp_path / 'node', 'w') as node_file:
    node_group = node_file.create_group('node_data')
    node_group.create_dataset('signature', data=node.signature)
    node_group.create_dataset('backend', data=node.backend.name)
    node_group.create_dataset(
        'copy_node_dtype', data=np.dtype(node.copy_node_dtype).name)
    node_group.create_dataset('name', data=node.name)
    node_group.create_dataset('shape', data=node.shape)
    node_group.create_dataset(
        'axis_names',
        data=np.array(node.axis_names, dtype=object),
        dtype=string_type)
    node_group.create_dataset(
        'edges',
        data=np.array([edge.name for edge in node.edges], dtype=object),
        dtype=string_type)

    loaded_node = CopyNode._load_node(node_data=node_file["node_data/"])
    assert loaded_node.name == node.name
    assert loaded_node.signature == node.signature
    assert set(loaded_node.axis_names) == set(node.axis_names)
    assert (set(edge.name for edge in loaded_node.edges) == set(
        edge.name for edge in node.edges))
    assert loaded_node.get_dimension(axis=1) == node.get_dimension(axis=1)
    assert loaded_node.get_rank() == node.get_rank()
    assert loaded_node.shape == node.shape
    assert loaded_node.copy_node_dtype == node.copy_node_dtype
Exemplo n.º 4
0
def test_add_copy_node(backend):
    net = tensornetwork.TensorNetwork(backend=backend)
    a = net.add_node(
        tensornetwork.CopyNode(3,
                               3,
                               name="TestName",
                               axis_names=['a', 'b', 'c']))
    assert a in net
Exemplo n.º 5
0
def test_add_copy_node_from_node_object(backend):
  a = tn.CopyNode(
      3, 3, name="TestName", axis_names=['a', 'b', 'c'], backend=backend)
  assert a.shape == (3, 3, 3)
  assert isinstance(a, tn.CopyNode)
  assert a.name == "TestName"
  assert a.axis_names == ['a', 'b', 'c']
  b = tn.Node(np.eye(3), backend=backend)
  e = a[0] ^ b[0]
  c = tn.contract(e)
  np.testing.assert_allclose(c.tensor, a.tensor)
Exemplo n.º 6
0
def test_contract_copy_node_dangling_edge_value_error(backend):
    a = tn.Node(np.array([1, 2, 3]), backend=backend)
    b = tn.Node(np.array([10, 20, 30]), backend=backend)
    c = tn.Node(np.array([5, 6, 7]), backend=backend)
    cn = tn.CopyNode(rank=4, dimension=3, backend=backend)
    tn.connect(a[0], cn[0])
    tn.connect(b[0], cn[1])
    tn.connect(c[0], cn[2])

    with pytest.raises(ValueError):
        tn.contract_copy_node(cn)
def sat_tn(clauses: List[Tuple[int, int, int]]) -> List[tn.Edge]:
    """Create a 3SAT TensorNetwork of the given 3SAT clauses.

    After full contraction, this network will be a tensor of size (2, 2, ..., 2)
    with the rank being the same as the number of variables. Each element of the
    final tensor represents whether the given assignment satisfies all of the
    clauses. For example, if final_node.get_tensor()[0][1][1] == 1, then the
    assiment (False, True, True) satisfies all clauses.

  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:
    net: The 3SAT TensorNetwork.
    var_edges: The edges for the given variables.

  Raises:
    ValueError: If any of the clauses have a 0 in them.
  """
    for clause in clauses:
        if 0 in clause:
            raise ValueError("0's are not allowed in the clauses.")
    var_set = set()
    for clause in clauses:
        var_set |= {abs(x) for x in clause}
    num_vars = max(var_set)
    var_nodes = []
    var_edges = []

    # Prepare the variable nodes.
    for _ in range(num_vars):
        new_node = tn.Node(np.ones(2, dtype=np.int32))
        var_nodes.append(new_node)
        var_edges.append(new_node[0])

    # Create the nodes for each clause
    for clause in clauses:
        a, b, c, = clause
        clause_tensor = np.ones((2, 2, 2), dtype=np.int32)
        clause_tensor[(-np.sign(a) + 1) // 2, (-np.sign(b) + 1) // 2,
                      (-np.sign(c) + 1) // 2] = 0
        clause_node = tn.Node(clause_tensor)

        # Connect the variable to the clause through a copy tensor.
        for i, var in enumerate(clause):
            copy_tensor_node = tn.CopyNode(3, 2)
            clause_node[i] ^ copy_tensor_node[0]
            var_edges[abs(var) - 1] ^ copy_tensor_node[1]
            var_edges[abs(var) - 1] = copy_tensor_node[2]

    return var_edges
def test_copy_node_save_structure(tmp_path, backend):
    node = tn.CopyNode(rank=4,
                       dimension=3,
                       name='copier',
                       axis_names=[str(n) for n in range(4)],
                       backend=backend)
    with h5py.File(tmp_path / 'nodes', 'w') as node_file:
        node_group = node_file.create_group('test_node')
        node._save_node(node_group)
        assert set(list(node_file.keys())) == {"test_node"}
        assert set(list(node_file['test_node'])) == {
            "signature", 'name', 'edges', 'backend', 'shape', 'axis_names',
            'copy_node_dtype', "type"
        }
Exemplo n.º 9
0
def test_contract_copy_node(backend):
    a = tn.Node(np.array([1, 2, 3]), backend=backend)
    b = tn.Node(np.array([10, 20, 30]), backend=backend)
    c = tn.Node(np.array([5, 6, 7]), backend=backend)
    d = tn.Node(np.array([1, -1, 1]), backend=backend)
    cn = tn.CopyNode(rank=4, dimension=3, backend=backend)
    tn.connect(a[0], cn[0])
    tn.connect(b[0], cn[1])
    tn.connect(c[0], cn[2])
    tn.connect(d[0], cn[3])

    val = tn.contract_copy_node(cn)
    result = val.tensor
    assert list(result.shape) == []
    np.testing.assert_allclose(result, 50 - 240 + 630)
Exemplo n.º 10
0
def test_copy_copynode_method(backend):
  a = tn.CopyNode(3, 3, 'mynode', axis_names=['a', 'b', 'c'], backend=backend)
  a.add_edge(tn.Edge(a, 0, name='named_edge1'), 0)
  a.add_edge(tn.Edge(a, 1, name='named_edge2'), 1)
  a.add_edge(tn.Edge(a, 2, name='named_edge3'), 2)
  b = a.copy()
  assert a.name == b.name
  assert a.shape == b.shape
  assert a.axis_names == b.axis_names
  assert a.rank == b.rank
  assert a.backend == b.backend
  assert a.dtype == b.dtype
  for i in range(len(a.edges)):
    assert a[i].name == b[i].name
  np.testing.assert_allclose(a.tensor, b.tensor)
def test_add_copy_node_from_node_object(backend):
    net = tensornetwork.TensorNetwork(backend=backend)
    a = net.add_node(
        tensornetwork.CopyNode(3,
                               3,
                               name="TestName",
                               axis_names=['a', 'b', 'c']))
    assert a in net
    assert a.shape == (3, 3, 3)
    assert isinstance(a, tensornetwork.CopyNode)
    assert a.name == "TestName"
    assert a.axis_names == ['a', 'b', 'c']
    b = net.add_node(np.eye(3))
    e = a[0] ^ b[0]
    c = net.contract(e)
    np.testing.assert_allclose(c.tensor, a.tensor)
Exemplo n.º 12
0
def test_copy_tensor_parallel_edges(backend):
    a = tn.Node(np.diag([1., 2, 3]), backend=backend)
    b = tn.Node(np.array([10, 20, 30], dtype=np.float64), backend=backend)
    cn = tn.CopyNode(rank=3, dimension=3, backend=backend)
    edge1 = tn.connect(a[0], cn[0])
    edge2 = tn.connect(a[1], cn[1])
    edge3 = tn.connect(b[0], cn[2])

    result = cn.compute_contracted_tensor()
    assert list(result.shape) == []
    np.testing.assert_allclose(result, 10 + 40 + 90)

    for edge in [edge1, edge2, edge3]:
        val = tn.contract(edge)
    result = val.tensor
    assert list(result.shape) == []
    np.testing.assert_allclose(result, 10 + 40 + 90)
Exemplo n.º 13
0
def test_contract_copy_node_connected_neighbors(backend):
    a = tn.Node(np.array([[1, 2, 3], [10, 20, 30]]), backend=backend)
    b = tn.Node(np.array([[2, 1, 1], [2, 2, 2]]), backend=backend)
    c = tn.Node(np.array([3, 4, 4]), backend=backend)
    cn = tn.CopyNode(rank=3, dimension=3, backend=backend)
    tn.connect(a[0], b[0])
    tn.connect(a[1], cn[0])
    tn.connect(b[1], cn[1])
    tn.connect(c[0], cn[2])

    n = tn.contract_copy_node(cn)

    assert len(n.edges) == 2
    assert n.edges[0] == n.edges[1]

    val = tn.contract_parallel(n.edges[0])
    result = val.tensor
    assert list(result.shape) == []
    np.testing.assert_allclose(result, 26 + 460)
def test_copy_node_save_data(tmp_path, backend):
    node = tn.CopyNode(rank=4,
                       dimension=3,
                       name='copier',
                       axis_names=[str(n) for n in range(4)],
                       backend=backend)
    with h5py.File(tmp_path / 'nodes', 'w') as node_file:
        node_group = node_file.create_group('copier')
        node._save_node(node_group)
        assert node_file['copier/signature'][()] == node.signature
        assert node_file['copier/backend'][()] == node.backend.name
        assert node_file['copier/type'][()] == type(node).__name__
        assert node_file['copier/name'][()] == node.name
        assert node_file['copier/copy_node_dtype'][()] == np.dtype(
            node.copy_node_dtype).name
        assert set(node_file['copier/shape'][()]) == set(node.shape_tensor)
        assert set(node_file['copier/axis_names'][()]) == set(node.axis_names)
        assert (set(node_file['copier/edges'][()]) == set(
            edge.name for edge in node.edges))
Exemplo n.º 15
0
def test_copy_tensor(backend):
    a = tn.Node(np.array([1, 2, 3], dtype=np.float64), backend=backend)
    b = tn.Node(np.array([10, 20, 30], dtype=np.float64), backend=backend)
    c = tn.Node(np.array([5, 6, 7], dtype=np.float64), backend=backend)
    d = tn.Node(np.array([1, -1, 1], dtype=np.float64), backend=backend)
    cn = tn.CopyNode(rank=4, dimension=3, backend=backend)
    edge1 = tn.connect(a[0], cn[0])
    edge2 = tn.connect(b[0], cn[1])
    edge3 = tn.connect(c[0], cn[2])
    edge4 = tn.connect(d[0], cn[3])

    result = cn.compute_contracted_tensor()
    assert list(result.shape) == []
    np.testing.assert_allclose(result, 50 - 240 + 630)

    for edge in [edge1, edge2, edge3, edge4]:
        val = tn.contract(edge)
    result = val.tensor
    assert list(result.shape) == []
    np.testing.assert_allclose(result, 50 - 240 + 630)
def test_node_mul_input_error():
  #pylint: disable=unused-variable
  #pytype: disable=unsupported-operands
  node1 = Node(tensor=2, backend='numpy')
  node2 = Node(tensor=np.array([[10, 10], [10, 10]]), backend='numpy')

  del node1._tensor
  with pytest.raises(AttributeError):
    result = node1 * node2
    result = node2 * node1

  node1.tensor = 1
  node2 = 'str'
  copynode = tn.CopyNode(rank=4, dimension=3)
  with pytest.raises(TypeError):
    result = node1 * node2
    result = node1 * copynode

  node2 = Node(tensor=np.array([[10, 10], [10, 10]]), backend='pytorch')
  with pytest.raises(TypeError):
    result = node1 * node2
def test_default_names_add_node_object(backend):
    net = tensornetwork.TensorNetwork(backend=backend)
    a = net.add_node(tensornetwork.CopyNode(3, 3))
    assert a.name is not None
    assert len(a.axis_names) == 3
Exemplo n.º 18
0
def test_add_node_twice_raise_value_error(backend):
    net = tensornetwork.TensorNetwork(backend=backend)
    a = net.add_node(tensornetwork.CopyNode(3, 3))
    with pytest.raises(ValueError):
        net.add_node(a)
Exemplo n.º 19
0
def test_default_names_add_node_object(backend):
    a = tn.CopyNode(3, 3, backend=backend)
    assert a.name is not None
    assert len(a.axis_names) == 3
Exemplo n.º 20
0
def regauge_B_symm_linear_problem_v1(B, AL, AR, p=0):
    Bn = tn.Node(B, axis_names=["p", "L", "R"])
    ALn = tn.Node(AL, axis_names=["p", "L", "R"])
    ARn = tn.Node(AR * np.exp(-1.j * p), axis_names=["p", "L", "R"])

    D = B.shape[2]

    ALn_c = tn.conj(ALn)
    ALn["L"] ^ ALn_c["L"]
    ALn["R"] ^ ALn_c["R"]
    PLn = tn.contract_between(ALn,
                              ALn_c,
                              output_edge_order=[ALn_c["p"], ALn["p"]],
                              axis_names=["p_in", "p_out"])

    ARn_c = tn.conj(ARn)
    ARn["L"] ^ ARn_c["L"]
    ARn["R"] ^ ARn_c["R"]
    PRn = tn.contract_between(ARn,
                              ARn_c,
                              output_edge_order=[ARn_c["p"], ARn["p"]],
                              axis_names=["p_in", "p_out"])

    PLRn = tn.Node(PLn.get_tensor() + PRn.get_tensor(),
                   axis_names=["p_in", "p_out"])

    E = tn.CopyNode(2, D, dtype=B.dtype)

    PLRn["p_out"] ^ ALn_c["p"]
    MLn = tn.contract_between(
        PLRn,
        ALn_c,
        output_edge_order=[PLRn["p_in"], ALn_c["L"], ALn_c["R"]],
        axis_names=["p_in", "L_in", "L_out"])
    MLn = tn.contract_between(
        MLn,
        E,
        output_edge_order=[MLn["L_out"], E[0], MLn["p_in"], MLn["L_in"], E[1]],
        axis_names=["L_out", "R_out", "p_in", "L_in", "R_in"],
        allow_outer_product=True)

    PLRn["p_out"] ^ ARn_c["p"]
    MRn = tn.contract_between(
        PLRn,
        ARn_c,
        output_edge_order=[PLRn["p_in"], ARn_c["L"], ARn_c["R"]],
        axis_names=["p_in", "R_out", "R_in"])
    MRn = tn.contract_between(
        MRn,
        E,
        output_edge_order=[E[0], MRn["R_out"], MRn["p_in"], E[1], MRn["R_in"]],
        axis_names=["L_out", "R_out", "p_in", "L_in", "R_in"],
        allow_outer_product=True)

    MLRn = tn.Node(MLn.get_tensor() - MRn.get_tensor(),
                   axis_names=["L_out", "R_out", "p_in", "L_in", "R_in"])

    MLRn["p_in"] ^ Bn["p"]
    MLRn["L_in"] ^ Bn["L"]
    MLRn["R_in"] ^ Bn["R"]
    target_n = tn.contract_between(
        MLRn, Bn, output_edge_order=[MLRn["L_out"], MLRn["R_out"]])
    target_vec = target_n.get_tensor().ravel()

    ARn["p"] ^ MLRn["p_in"]
    ARn["R"] ^ MLRn["R_in"]

    bigM_Rn = tn.contract_between(ARn,
                                  MLRn,
                                  output_edge_order=[
                                      MLRn["L_out"], MLRn["R_out"],
                                      MLRn["L_in"], ARn["L"]
                                  ])

    ALn["p"] ^ MLRn["p_in"]
    ALn["L"] ^ MLRn["L_in"]

    bigM_Ln = tn.contract_between(ALn,
                                  MLRn,
                                  output_edge_order=[
                                      MLRn["L_out"], MLRn["R_out"], ALn["R"],
                                      MLRn["R_in"]
                                  ])

    bigMn = tn.Node(bigM_Rn.get_tensor() - bigM_Ln.get_tensor(),
                    axis_names=["L_out", "R_out", "L_in", "R_in"])
    mat = bigMn.get_tensor().reshape((D**2, D**2))

    return mat, target_vec