Skip to content
Pasqal Documentation

Register

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 "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).

TYPE: Graph | int

spacing

Value set as the distance between the two closest qubits. The spacing argument is also available for all the class method constructors.

TYPE: float | None DEFAULT: 1.0

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76def __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)

Return a list of all possible qubit pairs in the register.

Return the dictionary of qubit coordinates.

Return a dictionary of distances for all qubit pairs in the register.

Return a dictionary of distances for the qubit pairs that are.

connected by an edge in the underlying NetworkX graph.

Return the EdgeView of the underlying NetworkX graph.

Return the minimum distance between two qubts in the register.

Total number of qubits in the register.

Return the NodeView of the underlying NetworkX graph.

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: int

Source code in qadence/register.py
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195@classmethod
def 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: int

Source code in qadence/register.py
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138@classmethod
def 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 the underlying NetworkX graph representing the register.

Source code in qadence/register.py
262
263
264
265
266
267def 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: list[tuple]

Source code in qadence/register.py
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103@classmethod
def 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: int

n_cells_col

Number of cells in each column.

TYPE: int

Source code in qadence/register.py
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256@classmethod
def 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: int

Source code in qadence/register.py
105
106
107
108
109
110
111
112
113
114
115
116
117
118@classmethod
def 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 the coordinates of all qubits in the register.

PARAMETER DESCRIPTION
scaling

Scaling value.

TYPE: float

Source code in qadence/register.py
320
321
322
323
324
325
326
327
328
329def 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: int

Source code in qadence/register.py
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177@classmethod
def 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: int

n_cells_col

Number of cells in each column.

TYPE: int

Source code in qadence/register.py
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235@classmethod
def 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)