Source code for surface_sim.layouts.util

"""Module that implement some utility functions."""

from collections import deque
from itertools import count

import networkx as nx

from .layout import Layout
from .plotter import Coordinates


[docs] def set_coords(layout: Layout, override: bool = False) -> None: """Sets the coordinates of the nodes in the layout. Parameters ---------- layout The layout to set the coordinates of. """ if (not override) and (nx.get_node_attributes(layout.graph, "coords") != {}): raise ValueError("'layout' already has coordinates, use 'override' flag.") # Get the shift in the coordinate for a given direction. def get_shift(direction: str) -> int: if direction in ("south", "west"): return -1 return 1 nodes = list(layout.graph.nodes) # graph nodes init_node = nodes.pop() # initial node init_coord: Coordinates = (0, 0) # initial coordinates set_nodes: set[str] = set() # Nodes we have already set the coordinates of. queue: deque[tuple[str, Coordinates]] = ( deque() ) # Queue of nodes to set the coordinates of. queue.appendleft((init_node, init_coord)) while queue: node, coords = queue.pop() layout.graph.nodes[node]["coords"] = coords set_nodes.add(node) for _, nbr_node, ord_dir in layout.graph.edges(node, data="direction"): if nbr_node not in set_nodes: card_dirs = ord_dir.split("_") shifts = tuple(map(get_shift, card_dirs)) nbr_coords = list(map(sum, zip(coords, shifts))) queue.appendleft((nbr_node, nbr_coords))
def index_chain(layout: Layout, init_node: str) -> None: """Indexes the chain of qubits in the layout. Parameters ---------- layout The layout to index the chain of. init_node The initial qubit of the chain. Raises ------ ValueError If the initial qubit is not in the graph. ValueError If any qubit is not connected to any other qubits. ValueError If any qubit is connected to more than 2 other qubits. """ nodes = list(layout.graph.nodes) chain_inds = count(0, 1) if init_node not in nodes: raise ValueError("init_node not in graph") set_nodes: set[str] = set() queue: deque[str] = deque() queue.appendleft(init_node) while queue: node = queue.pop() ind = next(chain_inds) layout.graph.nodes[node]["chain_ind"] = ind set_nodes.add(node) neighbors = list(layout.graph.adj[node]) num_neighbors = len(neighbors) if num_neighbors > 2: raise ValueError( f"Qubit {node} is connected to {num_neighbors} other qubits, expected at most 2." ) if num_neighbors == 0: raise ValueError( f"Qubit {node} is not connected to any other qubits, expected at least 1." ) for nbr_node in neighbors: if nbr_node not in set_nodes: queue.appendleft(nbr_node) for node in nodes: if node not in set_nodes: layout.graph.nodes[node]["chain_ind"] = None