Register
Quantum Registers
Section titled “Quantum Registers”
Register(support, spacing=1.0, device_specs=DEFAULT_DEVICE)
Section titled “
Register(support, spacing=1.0, device_specs=DEFAULT_DEVICE)
”A register of qubits including 2D coordinates.
Instantiating the Register class directly is only recommended for building custom registers.
For most uses where a predefined lattice is desired it is recommended to use the various
class methods available, e.g. Register.triangular_lattice.
| PARAMETER | DESCRIPTION |
|---|---|
support
|
A NetworkX graph or number of qubits. Nodes can include a
TYPE:
|
spacing
|
Value set as the distance between the two closest qubits. The spacing argument is also available for all the class method constructors.
TYPE:
|
Examples:
from qadence import Register
reg_all = Register.all_to_all(n_qubits = 4)reg_line = Register.line(n_qubits = 4)reg_circle = Register.circle(n_qubits = 4)reg_squre = Register.square(qubits_side = 2)reg_rect = Register.rectangular_lattice(qubits_row = 2, qubits_col = 2)reg_triang = Register.triangular_lattice(n_cells_row = 2, n_cells_col = 2)reg_honey = Register.honeycomb_lattice(n_cells_row = 2, n_cells_col = 2)Source code in qadence/register.py
34353637383940414243444546474849505152535455565758596061626364656667686970717273747576def __init__( self, support: nx.Graph | int, spacing: float | None = 1.0, device_specs: RydbergDevice = DEFAULT_DEVICE,): """ A register of qubits including 2D coordinates.
Instantiating the Register class directly is only recommended for building custom registers. For most uses where a predefined lattice is desired it is recommended to use the various class methods available, e.g. `Register.triangular_lattice`.
Arguments: support: A NetworkX graph or number of qubits. Nodes can include a `"pos"` attribute such that e.g.: `graph.nodes = {0: {"pos": (2,3)}, 1: {"pos": (0,0)}, ...}` which will be used in backends that need qubit coordinates. Passing a number of qubits calls `Register.all_to_all(n_qubits)`. spacing: Value set as the distance between the two closest qubits. The spacing argument is also available for all the class method constructors.
Examples: ```python exec="on" source="material-block" from qadence import Register
reg_all = Register.all_to_all(n_qubits = 4) reg_line = Register.line(n_qubits = 4) reg_circle = Register.circle(n_qubits = 4) reg_squre = Register.square(qubits_side = 2) reg_rect = Register.rectangular_lattice(qubits_row = 2, qubits_col = 2) reg_triang = Register.triangular_lattice(n_cells_row = 2, n_cells_col = 2) reg_honey = Register.honeycomb_lattice(n_cells_row = 2, n_cells_col = 2) ``` """ if device_specs is not None and not isinstance(device_specs, RydbergDevice): raise ValueError("Device specs are not valid. Please pass a `RydbergDevice` instance.")
self.device_specs = device_specs
self.graph = support if isinstance(support, nx.Graph) else alltoall_graph(support)
if spacing is not None and self.min_distance != 0.0: _scale_node_positions(self.graph, self.min_distance, spacing)
all_node_pairs
property
Section titled “
all_node_pairs
property
”Return a list of all possible qubit pairs in the register.
coords
property
Section titled “
coords
property
”Return the dictionary of qubit coordinates.
distances
property
Section titled “
distances
property
”Return a dictionary of distances for all qubit pairs in the register.
edge_distances
property
Section titled “
edge_distances
property
”Return a dictionary of distances for the qubit pairs that are.
connected by an edge in the underlying NetworkX graph.
edges
property
Section titled “
edges
property
”Return the EdgeView of the underlying NetworkX graph.
min_distance
property
Section titled “
min_distance
property
”Return the minimum distance between two qubts in the register.
n_qubits
property
Section titled “
n_qubits
property
”Total number of qubits in the register.
nodes
property
Section titled “
nodes
property
”Return the NodeView of the underlying NetworkX graph.
support
property
Section titled “
support
property
”Return the set of qubits in the register.
all_to_all(n_qubits, spacing=1.0, device_specs=DEFAULT_DEVICE)
classmethod
Section titled “
all_to_all(n_qubits, spacing=1.0, device_specs=DEFAULT_DEVICE)
classmethod
”Build a register with an all-to-all connectivity graph.
The graph is projected onto a 2D space and the qubit coordinates are set using a spring layout algorithm.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
Total number of qubits.
TYPE:
|
Source code in qadence/register.py
179180181182183184185186187188189190191192193194195@classmethoddef all_to_all( cls, n_qubits: int, spacing: float = 1.0, device_specs: RydbergDevice = DEFAULT_DEVICE,) -> Register: """ Build a register with an all-to-all connectivity graph.
The graph is projected onto a 2D space and the qubit coordinates are set using a spring layout algorithm.
Arguments: n_qubits: Total number of qubits. """ return cls(alltoall_graph(n_qubits), spacing, device_specs)
circle(n_qubits, spacing=1.0, device_specs=DEFAULT_DEVICE)
classmethod
Section titled “
circle(n_qubits, spacing=1.0, device_specs=DEFAULT_DEVICE)
classmethod
”Build a circle register.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
Total number of qubits.
TYPE:
|
Source code in qadence/register.py
120121122123124125126127128129130131132133134135136137138@classmethoddef circle( cls, n_qubits: int, spacing: float = 1.0, device_specs: RydbergDevice = DEFAULT_DEVICE,) -> Register: """ Build a circle register.
Arguments: n_qubits: Total number of qubits. """ graph = nx.grid_2d_graph(n_qubits, 1, periodic=True) graph = nx.relabel_nodes(graph, {(i, 0): i for i in range(n_qubits)}) coords = nx.circular_layout(graph) values = {i: {"pos": pos} for i, pos in coords.items()} nx.set_node_attributes(graph, values) return cls(graph, spacing, device_specs)
draw(show=True)
Section titled “
draw(show=True)
”Draw the underlying NetworkX graph representing the register.
Source code in qadence/register.py
262263264265266267def draw(self, show: bool = True) -> None: """Draw the underlying NetworkX graph representing the register.""" coords = {i: n["pos"] for i, n in self.graph.nodes.items()} nx.draw(self.graph, with_labels=True, pos=coords) if show: plt.gcf().show()
from_coordinates(coords, lattice=LatticeTopology.ARBITRARY, spacing=None, device_specs=DEFAULT_DEVICE)
classmethod
Section titled “
from_coordinates(coords, lattice=LatticeTopology.ARBITRARY, spacing=None, device_specs=DEFAULT_DEVICE)
classmethod
”Build a register from a list of qubit coordinates.
Each node is added to the underlying graph with the respective coordinates, but the edges are left empty.
| PARAMETER | DESCRIPTION |
|---|---|
coords
|
List of qubit coordinate tuples.
TYPE:
|
Source code in qadence/register.py
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99100101102103@classmethoddef from_coordinates( cls, coords: list[tuple], lattice: LatticeTopology | str = LatticeTopology.ARBITRARY, spacing: float | None = None, device_specs: RydbergDevice = DEFAULT_DEVICE,) -> Register: """ Build a register from a list of qubit coordinates.
Each node is added to the underlying graph with the respective coordinates, but the edges are left empty.
Arguments: coords: List of qubit coordinate tuples. """ graph = nx.Graph() for i, pos in enumerate(coords): graph.add_node(i, pos=pos) return cls(graph, spacing, device_specs)
honeycomb_lattice(n_cells_row, n_cells_col, spacing=1.0, device_specs=DEFAULT_DEVICE)
classmethod
Section titled “
honeycomb_lattice(n_cells_row, n_cells_col, spacing=1.0, device_specs=DEFAULT_DEVICE)
classmethod
”Build a honeycomb lattice register.
Each cell is an hexagon made up of six qubits.
| PARAMETER | DESCRIPTION |
|---|---|
n_cells_row
|
Number of cells in each row.
TYPE:
|
n_cells_col
|
Number of cells in each column.
TYPE:
|
Source code in qadence/register.py
237238239240241242243244245246247248249250251252253254255256@classmethoddef honeycomb_lattice( cls, n_cells_row: int, n_cells_col: int, spacing: float = 1.0, device_specs: RydbergDevice = DEFAULT_DEVICE,) -> Register: """ Build a honeycomb lattice register.
Each cell is an hexagon made up of six qubits.
Arguments: n_cells_row: Number of cells in each row. n_cells_col: Number of cells in each column. """ graph = nx.hexagonal_lattice_graph(n_cells_row, n_cells_col) graph = nx.relabel_nodes(graph, {(i, j): k for k, (i, j) in enumerate(graph.nodes)}) return cls(graph, spacing, device_specs)
line(n_qubits, spacing=1.0, device_specs=DEFAULT_DEVICE)
classmethod
Section titled “
line(n_qubits, spacing=1.0, device_specs=DEFAULT_DEVICE)
classmethod
”Build a line register.
| PARAMETER | DESCRIPTION |
|---|---|
n_qubits
|
Total number of qubits.
TYPE:
|
Source code in qadence/register.py
105106107108109110111112113114115116117118@classmethoddef line( cls, n_qubits: int, spacing: float = 1.0, device_specs: RydbergDevice = DEFAULT_DEVICE,) -> Register: """ Build a line register.
Arguments: n_qubits: Total number of qubits. """ return cls(line_graph(n_qubits), spacing, device_specs)
rescale_coords(scaling)
Section titled “
rescale_coords(scaling)
”Rescale the coordinates of all qubits in the register.
| PARAMETER | DESCRIPTION |
|---|---|
scaling
|
Scaling value.
TYPE:
|
Source code in qadence/register.py
320321322323324325326327328329def rescale_coords(self, scaling: float) -> Register: """ Rescale the coordinates of all qubits in the register.
Arguments: scaling: Scaling value. """ g = deepcopy(self.graph) _scale_node_positions(g, min_distance=1.0, spacing=scaling) return Register(g, spacing=None, device_specs=self.device_specs)
square(qubits_side, spacing=1.0, device_specs=DEFAULT_DEVICE)
classmethod
Section titled “
square(qubits_side, spacing=1.0, device_specs=DEFAULT_DEVICE)
classmethod
”Build a square register.
| PARAMETER | DESCRIPTION |
|---|---|
qubits_side
|
Number of qubits on one side of the square.
TYPE:
|
Source code in qadence/register.py
140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177@classmethoddef square( cls, qubits_side: int, spacing: float = 1.0, device_specs: RydbergDevice = DEFAULT_DEVICE,) -> Register: """ Build a square register.
Arguments: qubits_side: Number of qubits on one side of the square. """ n_points = 4 * (qubits_side - 1)
def gen_points() -> np.ndarray: rotate_left = np.array([[0.0, -1.0], [1.0, 0.0]]) increment = np.array([0.0, 1.0])
points = [np.array([0.0, 0.0])] counter = 1 while len(points) < n_points: points.append(points[-1] + increment)
counter = (counter + 1) % qubits_side if counter == 0: increment = rotate_left.dot(increment) counter = 1 points = np.array(points) # type: ignore[assignment] points -= np.mean(points, axis=0)
return points # type: ignore[return-value]
graph = nx.grid_2d_graph(n_points, 1, periodic=True) graph = nx.relabel_nodes(graph, {(i, 0): i for i in range(n_points)}) values = {i: {"pos": point} for i, point in zip(graph.nodes, gen_points())} nx.set_node_attributes(graph, values) return cls(graph, spacing, device_specs)
triangular_lattice(n_cells_row, n_cells_col, spacing=1.0, device_specs=DEFAULT_DEVICE)
classmethod
Section titled “
triangular_lattice(n_cells_row, n_cells_col, spacing=1.0, device_specs=DEFAULT_DEVICE)
classmethod
”Build a triangular lattice register.
Each cell is a triangle made up of three qubits.
| PARAMETER | DESCRIPTION |
|---|---|
n_cells_row
|
Number of cells in each row.
TYPE:
|
n_cells_col
|
Number of cells in each column.
TYPE:
|
Source code in qadence/register.py
218219220221222223224225226227228229230231232233234235@classmethoddef triangular_lattice( cls, n_cells_row: int, n_cells_col: int, spacing: float = 1.0, device_specs: RydbergDevice = DEFAULT_DEVICE,) -> Register: """ Build a triangular lattice register.
Each cell is a triangle made up of three qubits.
Arguments: n_cells_row: Number of cells in each row. n_cells_col: Number of cells in each column. """ return cls(triangular_lattice_graph(n_cells_row, n_cells_col), spacing, device_specs)