How to use the tensornetwork.network_components.Node function in tensornetwork

To help you get started, we’ve selected a few tensornetwork examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github google / TensorNetwork / tensornetwork / matrixproductstates / base_mps.py View on Github external
contractions. Available backends are currently 'numpy', 'tensorflow',
        'pytorch', 'jax'
    """
    if center_position < 0 or center_position >= len(tensors):
      raise ValueError(
          'center_position = {} not between 0 <= center_position < {}'.format(
              center_position, len(tensors)))

    # we're no longer connecting MPS nodes because it's barely needed
    # the dtype is deduced from the tensor object.
    self.nodes = [
        Node(tensors[n], backend=backend, name='node{}'.format(n))
        for n in range(len(tensors))
    ]

    self.connector_matrix = Node(
        connector_matrix,
        backend=backend) if connector_matrix is not None else connector_matrix
    self.center_position = center_position
github google / TensorNetwork / tensornetwork / network_operations.py View on Github external
right_axis_names.append(node.axis_names[edge.axis1] if edge.node1 is node
                              else node.axis_names[edge.axis2])
    left_axis_names.append(edge_name)
  else:
    left_axis_names = None
    right_axis_names = None

  backend = node.backend
  node.reorder_edges(left_edges + right_edges)
  q, r = backend.qr_decomposition(node.tensor, len(left_edges))
  left_node = Node(
      q, name=left_name, axis_names=left_axis_names, backend=backend)
  for i, edge in enumerate(left_edges):
    left_node.add_edge(edge, i)
    edge.update_axis(i, node, i, left_node)
  right_node = Node(
      r, name=right_name, axis_names=right_axis_names, backend=backend)
  for i, edge in enumerate(right_edges):
    # i + 1 to account for the new edge.
    right_node.add_edge(edge, i + 1)
    edge.update_axis(i + len(left_edges), node, i + 1, right_node)
  connect(left_node.edges[-1], right_node.edges[0], name=edge_name)
  return left_node, right_node
github google / TensorNetwork / tensornetwork / matrixproductstates / base_mps.py View on Github external
#          -- A*--
      # and evolve it to the right by contracting tensors at site2 > site1
      # if site2 is in `sites2`, calculate the observable
      #
      #  ---A--........-- A--------
      # |   |             |        |
      # |  op1(site1)    op2(site2)|
      # |   |             |        |
      #  ---A--........-- A*-------

      for n in range(site1 + 1, n2 + 1):
        if n in right_sites:
          R = rs[n % N]
          A = Node(self.nodes[n % N], backend=self.backend)
          conj_A = conj(A)
          O2 = Node(op2, backend=self.backend)
          A[0] ^ L[0]
          conj_A[0] ^ L[1]
          O2[0] ^ conj_A[1]
          O2[1] ^ A[1]
          R[0] ^ A[2]
          R[1] ^ conj_A[2]
          res = L @ A @ O2 @ conj_A @ R
          c.append(res.tensor)

        if n < n2:
          L = self.apply_transfer_operator(n % N, 'left', L)
    return c
github google / TensorNetwork / tensornetwork / matrixproductstates / base_mps.py View on Github external
raise ValueError('site2 = {} has to be larger than site2 = {}'.format(
          site2, site1))
    if site2 != site1 + 1:
      raise ValueError(
          'Found site2 ={}, site1={}. Only nearest neighbor gates are currently '
          'supported'.format(site2, site1))

    if (max_singular_values or
        max_truncation_err) and self.center_position not in (site1, site2):
      raise ValueError(
          'center_position = {}, but gate is applied at sites {}, {}. '
          'Truncation should only be done if the gate '
          'is applied at the center position of the MPS'.format(
              self.center_position, site1, site2))

    gate_node = Node(gate, backend=self.backend)

    self.nodes[site1][2] ^ self.nodes[site2][0]
    gate_node[2] ^ self.nodes[site1][1]
    gate_node[3] ^ self.nodes[site2][1]
    left_edges = [self.nodes[site1][0], gate_node[0]]
    right_edges = [gate_node[1], self.nodes[site2][2]]
    result = self.nodes[site1] @ self.nodes[site2] @ gate_node
    U, S, V, tw = split_node_full_svd(
        result,
        left_edges=left_edges,
        right_edges=right_edges,
        max_singular_values=max_singular_values,
        max_truncation_err=max_truncation_err,
        left_name=self.nodes[site1].name,
        right_name=self.nodes[site2].name)
    V.reorder_edges([S[1]] + right_edges)
github google / TensorNetwork / tensornetwork / network_operations.py View on Github external
node_dict: A dictionary mapping the nodes to their copies.
      edge_dict: A dictionary mapping the edges to their copies.
  """
  node_dict = {}
  for node in nodes:
    if isinstance(node, CopyNode):
      node_dict[node] = CopyNode(
          node.rank,
          node.dimension,
          name=node.name,
          axis_names=node.axis_names,
          backend=node.backend,
          dtype=node.dtype)
    else:
      if conjugate:
        node_dict[node] = Node(
            node.backend.conj(node.tensor),
            name=node.name,
            axis_names=node.axis_names,
            backend=node.backend)
      else:
        node_dict[node] = Node(
            node.tensor,
            name=node.name,
            axis_names=node.axis_names,
            backend=node.backend)
  edge_dict = {}
  for edge in get_all_edges(nodes):
    node1 = edge.node1
    axis1 = edge.node1.get_axis_number(edge.axis1)
    # edge dangling or node2 does not need to be copied
    if edge.is_dangling() or edge.node2 not in node_dict:
github google / TensorNetwork / tensornetwork / network_components.py View on Github external
if not hasattr(node, 'backend'):
      raise TypeError('Node {} of type {} has no `backend`'.format(
          node, type(node)))

  if node1.backend.name != node2.backend.name:
    raise ValueError("node {}  and node {} have different backends. "
                     "Cannot perform outer product".format(node1, node2))

  backend = node1.backend
  if node1.get_rank() == 0 or node2.get_rank() == 0:
    new_tensor = backend.multiply(node1.tensor, node2.tensor)
  else:
    new_tensor = backend.outer_product(node1.tensor, node2.tensor)
  node1_axis_names = node1.axis_names
  node2_axis_names = node2.axis_names
  new_node = Node(
      tensor=new_tensor, name=name, axis_names=axis_names, backend=backend)
  additional_axes = len(node1.tensor.shape)

  for i, edge in enumerate(node1.edges):
    edge.update_axis(i, node1, i, new_node)
  for i, edge in enumerate(node2.edges):
    edge.update_axis(i, node2, i + additional_axes, new_node)

  for i, edge in enumerate(node1.edges + node2.edges):
    new_node.add_edge(edge, i, True)

  node1.fresh_edges(node1_axis_names)
  node2.fresh_edges(node2_axis_names)

  return new_node
github google / TensorNetwork / tensornetwork / matrixproductstates / infinite_mps.py View on Github external
r.tensor /= self.backend.trace(r.tensor)
    r.tensor = (r.tensor +
                self.backend.transpose(self.backend.conj(r.tensor),
                                       (1, 0))) / 2.0
    # eigvals_left and u_left are both `Tensor` objects
    eigvals_right, u_right = self.backend.eigh(r.tensor)
    eigvals_right /= self.backend.norm(eigvals_right)
    if pseudo_inverse_cutoff:
      mask = eigvals_right <= pseudo_inverse_cutoff

    inveigvals_right = 1.0 / eigvals_right
    if pseudo_inverse_cutoff:
      inveigvals_right = self.backend.index_update(inveigvals_right, mask, 0.0)

    sqrtr = Node(
        ncon([u_right,
              self.backend.diag(self.backend.sqrt(eigvals_right))],
             [[-1, 1], [1, -2]],
             backend=self.backend.name),
        backend=self.backend)

    inv_sqrtr = Node(
        ncon([
            self.backend.diag(self.backend.sqrt(inveigvals_right)),
            self.backend.conj(u_right)
        ], [[-1, 1], [-2, 1]],
             backend=self.backend.name),
        backend=self.backend)

    tmp = Node(
        ncon([sqrtl, sqrtr], [[-1, 1], [1, -2]], backend=self.backend.name),
github google / TensorNetwork / tensornetwork / network_operations.py View on Github external
Raises:
    AttributeError: If `node` has no `backend` attribute, or if 
      `node` has no tensor.
    ValueError: If either `permutation` is not the same as expected or
      if you try to permute with a trace edge.
  """

  if not hasattr(node, 'backend'):
    raise AttributeError('Node {} of type {} has no `backend`'.format(
        node, type(node)))

  perm = [node.get_axis_number(p) for p in permutation]
  if not axis_names:
    axis_names = node.axis_names

  new_node = Node(
      node.tensor,
      name=name,
      axis_names=node.axis_names,
      backend=node.backend)
  return new_node.reorder_axes(perm)
github google / TensorNetwork / tensornetwork / network_operations.py View on Github external
for edge in right_edges:
      right_axis_names.append(node.axis_names[edge.axis1] if edge.node1 is node
                              else node.axis_names[edge.axis2])
    left_axis_names.append(edge_name)
  else:
    left_axis_names = None
    right_axis_names = None
  backend = node.backend
  node.reorder_edges(left_edges + right_edges)
  r, q = backend.rq_decomposition(node.tensor, len(left_edges))
  left_node = Node(
      r, name=left_name, axis_names=left_axis_names, backend=backend)
  for i, edge in enumerate(left_edges):
    left_node.add_edge(edge, i)
    edge.update_axis(i, node, i, left_node)
  right_node = Node(
      q, name=right_name, axis_names=right_axis_names, backend=backend)
  for i, edge in enumerate(right_edges):
    # i + 1 to account for the new edge.
    right_node.add_edge(edge, i + 1)
    edge.update_axis(i + len(left_edges), node, i + 1, right_node)
  connect(left_node.edges[-1], right_node.edges[0], name=edge_name)
  return left_node, right_node