Skip to content

Commit 2d84676

Browse files
dstrain115maffoo
andauthored
Change qubit str representation (#5343)
* Change qubit str representation - Changes grid qubit string representation from (x, y) to q(x, y) and line qubit from 1 to q1. - This will make the string representation more distinctive. - Added _circuit_diagram_info_ for Qid objects to make circuit diagrams customizable for qubits. This allows us to keep circuit diagrams largely unchanged. - Other components such as pauli strings, that rely on qubit str representation for formatting are changed. This is a BREAKING CHANGE for anyone relying on string representation of qubits. Fixes: #2405 * Fix a bunch of tests. * A few more errors. * Switch to q(0) and fix a bunch of tests. * Formatting and more tests fixed. * Fix more tests. * Fix two last tests. * Fix bb84 example. * Fix contrib and notebook tests. * Update cirq-core/cirq/sim/simulator_test.py Co-authored-by: Matthew Neeley <[email protected]> * Update cirq-core/cirq/circuits/circuit.py Co-authored-by: Matthew Neeley <[email protected]> * Revert Grid Device to use circuit diagram names instead. Co-authored-by: Matthew Neeley <[email protected]>
1 parent b1a5a39 commit 2d84676

40 files changed

+314
-262
lines changed

cirq-core/cirq/circuits/circuit.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1187,7 +1187,7 @@ def to_text_diagram_drawer(
11871187
Args:
11881188
use_unicode_characters: Determines if unicode characters are
11891189
allowed (as opposed to ascii-only diagrams).
1190-
qubit_namer: Names qubits in diagram. Defaults to str.
1190+
qubit_namer: Names qubits in diagram. Defaults to using _circuit_diagram_info_ or str.
11911191
transpose: Arranges qubit wires vertically instead of horizontally.
11921192
include_tags: Whether to include tags in the operation.
11931193
draw_moment_groups: Whether to draw moment symbol or not
@@ -1210,7 +1210,9 @@ def to_text_diagram_drawer(
12101210
label_map = {labels[i]: i for i in range(len(labels))}
12111211

12121212
def default_namer(label_entity):
1213-
return str(label_entity) + ('' if transpose else ': ')
1213+
info = protocols.circuit_diagram_info(label_entity, default=None)
1214+
qubit_name = info.wire_symbols[0] if info else str(label_entity)
1215+
return qubit_name + ('' if transpose else ': ')
12141216

12151217
if qubit_namer is None:
12161218
qubit_namer = default_namer

cirq-core/cirq/circuits/circuit_operation_test.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ def test_string_format():
577577
== f"""\
578578
[ 0: ───X───X─── ]
579579
[ │ ]
580-
[ 1: ───H───@─── ](qubit_map={{1: 2}}, parent_path=('outer', 'inner'),\
580+
[ 1: ───H───@─── ](qubit_map={{q(1): q(2)}}, parent_path=('outer', 'inner'),\
581581
repetition_ids=['a', 'b', 'c'])"""
582582
)
583583
assert (
@@ -611,7 +611,7 @@ def test_string_format():
611611
assert (
612612
str(op3)
613613
== f"""\
614-
[ 0: ───X^b───M('m')─── ](qubit_map={{0: 1}}, \
614+
[ 0: ───X^b───M('m')─── ](qubit_map={{q(0): q(1)}}, \
615615
key_map={{m: p}}, params={{b: 2}})"""
616616
)
617617
assert (

cirq-core/cirq/circuits/qasm_output_test.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ def test_reset():
563563
include "qelib1.inc";
564564
565565
566-
// Qubits: [0, 1]
566+
// Qubits: [q(0), q(1)]
567567
qreg q[2];
568568
569569

cirq-core/cirq/contrib/qcircuit/qcircuit_test.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ def test_other_diagram():
118118
expected_diagram = r"""
119119
\Qcircuit @R=1em @C=0.75em {
120120
\\
121-
&\lstick{\text{0}}& \qw&\targ \qw&\qw\\
122-
&\lstick{\text{1}}& \qw&\gate{\text{Y}} \qw&\qw\\
123-
&\lstick{\text{2}}& \qw&\gate{\text{Z}} \qw&\qw\\
121+
&\lstick{\text{q(0)}}& \qw&\targ \qw&\qw\\
122+
&\lstick{\text{q(1)}}& \qw&\gate{\text{Y}} \qw&\qw\\
123+
&\lstick{\text{q(2)}}& \qw&\gate{\text{Z}} \qw&\qw\\
124124
\\
125125
}""".strip()
126126
assert_has_qcircuit_diagram(circuit, expected_diagram)
@@ -148,10 +148,10 @@ def test_two_cx_diagram():
148148
expected_diagram = r"""
149149
\Qcircuit @R=1em @C=0.75em {
150150
\\
151-
&\lstick{\text{0}}& \qw&\control \qw & \qw &\control \qw & \qw &\qw\\
152-
&\lstick{\text{1}}& \qw& \qw\qwx&\control \qw & \qw\qwx&\control \qw &\qw\\
153-
&\lstick{\text{2}}& \qw&\targ \qw\qwx& \qw\qwx&\targ \qw\qwx& \qw\qwx&\qw\\
154-
&\lstick{\text{3}}& \qw& \qw &\targ \qw\qwx& \qw &\targ \qw\qwx&\qw\\
151+
&\lstick{\text{q(0)}}& \qw&\control \qw & \qw &\control \qw & \qw &\qw\\
152+
&\lstick{\text{q(1)}}& \qw& \qw\qwx&\control \qw & \qw\qwx&\control \qw &\qw\\
153+
&\lstick{\text{q(2)}}& \qw&\targ \qw\qwx& \qw\qwx&\targ \qw\qwx& \qw\qwx&\qw\\
154+
&\lstick{\text{q(3)}}& \qw& \qw &\targ \qw\qwx& \qw &\targ \qw\qwx&\qw\\
155155
\\
156156
}""".strip()
157157
assert_has_qcircuit_diagram(circuit, expected_diagram)
@@ -164,8 +164,8 @@ def test_sqrt_iswap_diagram():
164164
expected_diagram = r"""
165165
\Qcircuit @R=1em @C=0.75em {
166166
\\
167-
&\lstick{\text{0}}& \qw&\multigate{1}{\text{ISWAP}^{0.5}} \qw&\qw\\
168-
&\lstick{\text{1}}& \qw&\ghost{\text{ISWAP}^{0.5}} \qw&\qw\\
167+
&\lstick{\text{q(0)}}& \qw&\multigate{1}{\text{ISWAP}^{0.5}} \qw&\qw\\
168+
&\lstick{\text{q(1)}}& \qw&\ghost{\text{ISWAP}^{0.5}} \qw&\qw\\
169169
\\
170170
}""".strip()
171171
assert_has_qcircuit_diagram(circuit, expected_diagram)

cirq-core/cirq/contrib/quantum_volume/quantum_volume_test.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,10 @@ def test_sample_heavy_set_with_parity():
9797
result = cirq.ResultDict(
9898
params=cirq.ParamResolver({}),
9999
measurements={
100-
'0': np.array([[1], [0]]),
101-
'1': np.array([[0], [1]]),
102-
'2': np.array([[1], [1]]),
103-
'3': np.array([[0], [0]]),
100+
'q(0)': np.array([[1], [0]]),
101+
'q(1)': np.array([[0], [1]]),
102+
'q(2)': np.array([[1], [1]]),
103+
'q(3)': np.array([[0], [0]]),
104104
},
105105
)
106106
sampler.run = MagicMock(return_value=result)

cirq-core/cirq/contrib/quimb/mps_simulator_test.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -214,19 +214,19 @@ def test_measurement_1qubit():
214214
simulator = ccq.mps_simulator.MPSSimulator()
215215

216216
result = simulator.run(circuit, repetitions=100)
217-
assert sum(result.measurements['1'])[0] < 80
218-
assert sum(result.measurements['1'])[0] > 20
217+
assert sum(result.measurements['q(1)'])[0] < 80
218+
assert sum(result.measurements['q(1)'])[0] > 20
219219

220220

221221
def test_reset():
222222
q = cirq.LineQubit(0)
223223
simulator = ccq.mps_simulator.MPSSimulator()
224224
c = cirq.Circuit(cirq.X(q), cirq.reset(q), cirq.measure(q))
225-
assert simulator.sample(c)['0'][0] == 0
225+
assert simulator.sample(c)['q(0)'][0] == 0
226226
c = cirq.Circuit(cirq.H(q), cirq.reset(q), cirq.measure(q))
227-
assert simulator.sample(c)['0'][0] == 0
227+
assert simulator.sample(c)['q(0)'][0] == 0
228228
c = cirq.Circuit(cirq.reset(q), cirq.measure(q))
229-
assert simulator.sample(c)['0'][0] == 0
229+
assert simulator.sample(c)['q(0)'][0] == 0
230230

231231

232232
def test_measurement_2qubits():
@@ -236,7 +236,7 @@ def test_measurement_2qubits():
236236
simulator = ccq.mps_simulator.MPSSimulator()
237237

238238
repetitions = 1024
239-
measurement = simulator.run(circuit, repetitions=repetitions).measurements['0,2']
239+
measurement = simulator.run(circuit, repetitions=repetitions).measurements['q(0),q(2)']
240240

241241
result_counts = {'00': 0, '01': 0, '10': 0, '11': 0}
242242
for i in range(repetitions):
@@ -309,7 +309,7 @@ def test_empty_step_result():
309309
step_result = next(sim.simulate_moment_steps(cirq.Circuit(cirq.measure(q0))))
310310
assert (
311311
str(step_result)
312-
== """0=0
312+
== """q(0)=0
313313
TensorNetwork([
314314
Tensor(shape=(2,), inds=('i_0',), tags=set()),
315315
])"""
@@ -322,7 +322,7 @@ def test_step_result_repr_pretty():
322322
step_result = next(sim.simulate_moment_steps(cirq.Circuit(cirq.measure(q0))))
323323
cirq.testing.assert_repr_pretty(
324324
step_result,
325-
"""0=0
325+
"""q(0)=0
326326
TensorNetwork([
327327
Tensor(shape=(2,), inds=('i_0',), tags=set()),
328328
])""",
@@ -441,7 +441,7 @@ def test_run_no_repetitions():
441441
simulator = ccq.mps_simulator.MPSSimulator()
442442
circuit = cirq.Circuit(cirq.H(q0), cirq.measure(q0))
443443
result = simulator.run(circuit, repetitions=0)
444-
assert len(result.measurements['0']) == 0
444+
assert len(result.measurements['q(0)']) == 0
445445

446446

447447
def test_run_parameters_not_resolved():

cirq-core/cirq/contrib/routing/swap_network_test.py

+10-9
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,15 @@ def test_swap_network_str():
7070
swap_network = ccr.SwapNetwork(routed_circuit, initial_mapping)
7171
actual_str = str(swap_network)
7272
expected_str = """
73-
(0, 0): ───0───ZZ───0───╲0╱───1────────1─────────1───ZZ───1───╲0╱───3────────3─────────3───ZZ───3───╲0╱───4───
74-
│ │ │ │
75-
(1, 0): ───1───ZZ───1───╱1╲───0───ZZ───0───╲0╱───3───ZZ───3───╱1╲───1───ZZ───1───╲0╱───4───ZZ───4───╱1╲───3───
76-
│ │
77-
(2, 0): ───2───ZZ───2───╲0╱───3───ZZ───3───╱1╲───0───ZZ───0───╲0╱───4───ZZ───4───╱1╲───1───ZZ───1───╲0╱───2───
78-
│ │ │ │
79-
(3, 0): ───3───ZZ───3───╱1╲───2───ZZ───2───╲0╱───4───ZZ───4───╱1╲───0───ZZ───0───╲0╱───2───ZZ───2───╱1╲───1───
80-
│ │
81-
(4, 0): ───4────────4─────────4───ZZ───4───╱1╲───2────────2─────────2───ZZ───2───╱1╲───0────────0─────────0───
73+
(0, 0): ───q(0)───ZZ───q(0)───╲0╱───q(1)────────q(1)─────────q(1)───ZZ───q(1)───╲0╱───q(3)────────q(3)─────────q(3)───ZZ───q(3)───╲0╱───q(4)───
74+
75+
(1, 0): ───q(1)───ZZ───q(1)───╱1╲───q(0)───ZZ───q(0)───╲0╱───q(3)───ZZ───q(3)───╱1╲───q(1)───ZZ───q(1)───╲0╱───q(4)───ZZ───q(4)───╱1╲───q(3)───
76+
77+
(2, 0): ───q(2)───ZZ───q(2)───╲0╱───q(3)───ZZ───q(3)───╱1╲───q(0)───ZZ───q(0)───╲0╱───q(4)───ZZ───q(4)───╱1╲───q(1)───ZZ───q(1)───╲0╱───q(2)───
78+
79+
(3, 0): ───q(3)───ZZ───q(3)───╱1╲───q(2)───ZZ───q(2)───╲0╱───q(4)───ZZ───q(4)───╱1╲───q(0)───ZZ───q(0)───╲0╱───q(2)───ZZ───q(2)───╱1╲───q(1)───
80+
81+
(4, 0): ───q(4)────────q(4)─────────q(4)───ZZ───q(4)───╱1╲───q(2)────────q(2)─────────q(2)───ZZ───q(2)───╱1╲───q(0)────────q(0)─────────q(0)───
8282
""".strip()
83+
print(actual_str)
8384
assert actual_str == expected_str

cirq-core/cirq/devices/grid_qubit.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,14 @@ def __repr__(self) -> str:
254254
return f"cirq.GridQid({self.row}, {self.col}, dimension={self.dimension})"
255255

256256
def __str__(self) -> str:
257-
return f"({self.row}, {self.col}) (d={self.dimension})"
257+
return f"q({self.row}, {self.col}) (d={self.dimension})"
258+
259+
def _circuit_diagram_info_(
260+
self, args: 'cirq.CircuitDiagramInfoArgs'
261+
) -> 'cirq.CircuitDiagramInfo':
262+
return protocols.CircuitDiagramInfo(
263+
wire_symbols=(f"({self.row}, {self.col}) (d={self.dimension})",)
264+
)
258265

259266
def _json_dict_(self) -> Dict[str, Any]:
260267
return protocols.obj_to_dict_helper(self, ['row', 'col', 'dimension'])
@@ -403,7 +410,12 @@ def __repr__(self) -> str:
403410
return f"cirq.GridQubit({self.row}, {self.col})"
404411

405412
def __str__(self) -> str:
406-
return f"({self.row}, {self.col})"
413+
return f"q({self.row}, {self.col})"
414+
415+
def _circuit_diagram_info_(
416+
self, args: 'cirq.CircuitDiagramInfoArgs'
417+
) -> 'cirq.CircuitDiagramInfo':
418+
return protocols.CircuitDiagramInfo(wire_symbols=(f"({self.row}, {self.col})",))
407419

408420
def _json_dict_(self) -> Dict[str, Any]:
409421
return protocols.obj_to_dict_helper(self, ['row', 'col'])

cirq-core/cirq/devices/grid_qubit_test.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,17 @@ def test_pickled_hash():
5353

5454

5555
def test_str():
56-
assert str(cirq.GridQubit(5, 2)) == '(5, 2)'
57-
assert str(cirq.GridQid(5, 2, dimension=3)) == '(5, 2) (d=3)'
56+
assert str(cirq.GridQubit(5, 2)) == 'q(5, 2)'
57+
assert str(cirq.GridQid(5, 2, dimension=3)) == 'q(5, 2) (d=3)'
58+
59+
60+
def test_circuit_info():
61+
assert cirq.circuit_diagram_info(cirq.GridQubit(5, 2)) == cirq.CircuitDiagramInfo(
62+
wire_symbols=('(5, 2)',)
63+
)
64+
assert cirq.circuit_diagram_info(cirq.GridQid(5, 2, dimension=3)) == cirq.CircuitDiagramInfo(
65+
wire_symbols=('(5, 2) (d=3)',)
66+
)
5867

5968

6069
def test_repr():

cirq-core/cirq/devices/line_qubit.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,12 @@ def __repr__(self) -> str:
190190
return f"cirq.LineQid({self.x}, dimension={self.dimension})"
191191

192192
def __str__(self) -> str:
193-
return f"{self.x} (d={self.dimension})"
193+
return f"q({self.x}) (d={self.dimension})"
194+
195+
def _circuit_diagram_info_(
196+
self, args: 'cirq.CircuitDiagramInfoArgs'
197+
) -> 'cirq.CircuitDiagramInfo':
198+
return protocols.CircuitDiagramInfo(wire_symbols=(f"{self.x} (d={self.dimension})",))
194199

195200
def _json_dict_(self) -> Dict[str, Any]:
196201
return protocols.obj_to_dict_helper(self, ['x', 'dimension'])
@@ -241,7 +246,12 @@ def __repr__(self) -> str:
241246
return f"cirq.LineQubit({self.x})"
242247

243248
def __str__(self) -> str:
244-
return f"{self.x}"
249+
return f"q({self.x})"
250+
251+
def _circuit_diagram_info_(
252+
self, args: 'cirq.CircuitDiagramInfoArgs'
253+
) -> 'cirq.CircuitDiagramInfo':
254+
return protocols.CircuitDiagramInfo(wire_symbols=(f"{self.x}",))
245255

246256
def _json_dict_(self) -> Dict[str, Any]:
247257
return protocols.obj_to_dict_helper(self, ['x'])

cirq-core/cirq/devices/line_qubit_test.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ def test_eq():
3535

3636

3737
def test_str():
38-
assert str(cirq.LineQubit(5)) == '5'
39-
assert str(cirq.LineQid(5, dimension=3)) == '5 (d=3)'
38+
assert str(cirq.LineQubit(5)) == 'q(5)'
39+
assert str(cirq.LineQid(5, dimension=3)) == 'q(5) (d=3)'
4040

4141

4242
def test_repr():

cirq-core/cirq/ion/ion_device_test.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,11 @@ def test_validate_circuit_repeat_measurement_keys():
202202

203203

204204
def test_ion_device_str():
205-
assert str(ion_device(3)) == "0───1───2"
205+
assert str(ion_device(3)) == "q(0)───q(1)───q(2)"
206206

207207

208208
def test_ion_device_pretty_repr():
209-
cirq.testing.assert_repr_pretty(ion_device(3), "0───1───2")
209+
cirq.testing.assert_repr_pretty(ion_device(3), "q(0)───q(1)───q(2)")
210210
cirq.testing.assert_repr_pretty(ion_device(3), "IonDevice(...)", cycle=True)
211211

212212

cirq-core/cirq/neutral_atoms/neutral_atom_devices_test.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,10 @@ def test_str():
276276
assert (
277277
str(square_device(2, 2)).strip()
278278
== """
279-
(0, 0)───(0, 1)
280-
│ │
281-
│ │
282-
(1, 0)───(1, 1)
279+
q(0, 0)───q(0, 1)
280+
281+
282+
q(1, 0)───q(1, 1)
283283
""".strip()
284284
)
285285

@@ -288,10 +288,10 @@ def test_repr_pretty():
288288
cirq.testing.assert_repr_pretty(
289289
square_device(2, 2),
290290
"""
291-
(0, 0)───(0, 1)
292-
│ │
293-
│ │
294-
(1, 0)───(1, 1)
291+
q(0, 0)───q(0, 1)
292+
293+
294+
q(1, 0)───q(1, 1)
295295
""".strip(),
296296
)
297297
cirq.testing.assert_repr_pretty(square_device(2, 2), "cirq.NeutralAtomDevice(...)", cycle=True)

cirq-core/cirq/ops/classically_controlled_operation_test.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def test_qasm():
208208
include "qelib1.inc";
209209
210210
211-
// Qubits: [0, 1]
211+
// Qubits: [q(0), q(1)]
212212
qreg q[2];
213213
creg m_a[1];
214214
@@ -416,7 +416,7 @@ def test_decompose():
416416
def test_str():
417417
q0 = cirq.LineQubit(0)
418418
op = cirq.X(q0).with_classical_controls('a')
419-
assert str(op) == 'X(0).with_classical_controls(a)'
419+
assert str(op) == 'X(q(0)).with_classical_controls(a)'
420420

421421

422422
def test_scope_local():

cirq-core/cirq/ops/controlled_gate_test.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -514,11 +514,11 @@ def test_circuit_diagram():
514514
cirq.testing.assert_has_diagram(
515515
c,
516516
"""
517-
0: ───@──────
517+
0: ───@─────────
518518
519-
1: ───H(1)───
519+
1: ───H(q(1))───
520520
521-
2: ───H(2)───
521+
2: ───H(q(2))───
522522
""",
523523
)
524524

@@ -530,13 +530,13 @@ def test_circuit_diagram():
530530
cirq.testing.assert_has_diagram(
531531
c,
532532
"""
533-
0 (d=3): ───@────────────
533+
0 (d=3): ───@───────────────
534534
535-
1 (d=3): ───(0,1)────────
535+
1 (d=3): ───(0,1)───────────
536536
537-
2 (d=3): ───(0,2)────────
537+
2 (d=3): ───(0,2)───────────
538538
539-
3 (d=2): ───H(3 (d=2))───
539+
3 (d=2): ───H(q(3) (d=2))───
540540
""",
541541
)
542542

0 commit comments

Comments
 (0)