def copy(nodes: Iterable[BaseNode], conjugate: bool = False) -> Tuple[dict, dict]: """Copy the given nodes and their edges. This will return a dictionary linking original nodes/edges to their copies. Args: nodes: An `Iterable` (Usually a `List` or `Set`) of `Nodes`. conjugate: Boolean. Whether to conjugate all of the nodes (useful for calculating norms and reduced density matrices). Returns: A tuple containing: node_dict: A dictionary mapping the nodes to their copies. edge_dict: A dictionary mapping the edges to their copies. """ #TODO: add support for copying CopyTensor if conjugate: node_dict = { node: Node(node.backend.conj(node.tensor), name=node.name, axis_names=node.axis_names, backend=node.backend.name) for node in nodes } else: node_dict = { node: Node(node.tensor, name=node.name, axis_names=node.axis_names, backend=node.backend.name) for node in nodes } edge_dict = {} for edge in get_all_edges(nodes): node1 = edge.node1 axis1 = edge.node1.get_axis_number(edge.axis1) if not edge.is_dangling(): node2 = edge.node2 axis2 = edge.node2.get_axis_number(edge.axis2) new_edge = Edge(node_dict[node1], axis1, edge.name, node_dict[node2], axis2) new_edge.set_signature(edge.signature) else: new_edge = Edge(node_dict[node1], axis1, edge.name) node_dict[node1].add_edge(new_edge, axis1) if not edge.is_dangling(): node_dict[node2].add_edge(new_edge, axis2) edge_dict[edge] = new_edge return node_dict, edge_dict
def copy(nodes: Iterable[BaseNode], conjugate: bool = False) -> Tuple[dict, dict]: """Copy the given nodes and their edges. This will return a tuple linking original nodes/edges to their copies. If nodes A and B are connected but only A is passed in to be copied, the edge between them will become a dangling edge. Args: nodes: An Iterable (Usually a `list` or `set`) of `nodes`. conjugate: Boolean. Whether to conjugate all of the nodes (useful for calculating norms and reduced density matrices). Returns: A tuple containing: 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: node_dict[node] = node.copy(conjugate) 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: new_edge = Edge(node_dict[node1], axis1, edge.name) node_dict[node1].add_edge(new_edge, axis1) edge_dict[edge] = new_edge continue node2 = edge.node2 axis2 = edge.node2.get_axis_number(edge.axis2) # copy node2 but not node1 if node1 not in node_dict: new_edge = Edge(node_dict[node2], axis2, edge.name) node_dict[node2].add_edge(new_edge, axis2) edge_dict[edge] = new_edge continue # both nodes should be copied new_edge = Edge(node_dict[node1], axis1, edge.name, node_dict[node2], axis2) new_edge.set_signature(edge.signature) node_dict[node2].add_edge(new_edge, axis2) node_dict[node1].add_edge(new_edge, axis1) edge_dict[edge] = new_edge return node_dict, edge_dict