cirq-core 1.6.0.dev20250520054601__py3-none-any.whl → 1.6.0.dev20250520181654__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cirq-core might be problematic. Click here for more details.

Files changed (289) hide show
  1. cirq/_compat.py +15 -17
  2. cirq/_compat_test.py +6 -9
  3. cirq/_doc.py +2 -2
  4. cirq/_import.py +6 -6
  5. cirq/_version.py +1 -1
  6. cirq/_version_test.py +1 -1
  7. cirq/circuits/_block_diagram_drawer.py +9 -10
  8. cirq/circuits/_box_drawing_character_data.py +6 -8
  9. cirq/circuits/_bucket_priority_queue.py +7 -7
  10. cirq/circuits/circuit.py +118 -125
  11. cirq/circuits/circuit_operation.py +38 -52
  12. cirq/circuits/circuit_test.py +4 -4
  13. cirq/circuits/frozen_circuit.py +13 -23
  14. cirq/circuits/moment.py +23 -29
  15. cirq/circuits/optimization_pass.py +4 -4
  16. cirq/circuits/optimization_pass_test.py +4 -6
  17. cirq/circuits/qasm_output.py +11 -11
  18. cirq/circuits/text_diagram_drawer.py +21 -36
  19. cirq/contrib/acquaintance/bipartite.py +5 -8
  20. cirq/contrib/acquaintance/executor.py +5 -5
  21. cirq/contrib/acquaintance/executor_test.py +3 -3
  22. cirq/contrib/acquaintance/gates.py +16 -26
  23. cirq/contrib/acquaintance/gates_test.py +3 -3
  24. cirq/contrib/acquaintance/mutation_utils.py +4 -4
  25. cirq/contrib/acquaintance/optimizers.py +4 -4
  26. cirq/contrib/acquaintance/permutation.py +15 -27
  27. cirq/contrib/acquaintance/shift.py +3 -3
  28. cirq/contrib/acquaintance/shift_swap_network.py +4 -4
  29. cirq/contrib/acquaintance/strategies/cubic.py +2 -2
  30. cirq/contrib/acquaintance/strategies/quartic_paired.py +6 -6
  31. cirq/contrib/bayesian_network/bayesian_network_gate.py +9 -10
  32. cirq/contrib/circuitdag/circuit_dag.py +2 -2
  33. cirq/contrib/custom_simulators/custom_state_simulator.py +3 -3
  34. cirq/contrib/custom_simulators/custom_state_simulator_test.py +4 -4
  35. cirq/contrib/graph_device/graph_device.py +5 -5
  36. cirq/contrib/graph_device/hypergraph.py +12 -12
  37. cirq/contrib/graph_device/uniform_graph_device.py +4 -4
  38. cirq/contrib/paulistring/clifford_optimize.py +2 -2
  39. cirq/contrib/paulistring/clifford_target_gateset.py +7 -7
  40. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +31 -31
  41. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +23 -23
  42. cirq/contrib/paulistring/recombine.py +3 -3
  43. cirq/contrib/paulistring/separate.py +2 -2
  44. cirq/contrib/qasm_import/_parser.py +20 -32
  45. cirq/contrib/qcircuit/qcircuit_diagram_info.py +3 -5
  46. cirq/contrib/quantum_volume/quantum_volume.py +24 -24
  47. cirq/contrib/quimb/density_matrix.py +12 -14
  48. cirq/contrib/quimb/mps_simulator.py +20 -20
  49. cirq/contrib/quimb/state_vector.py +6 -10
  50. cirq/contrib/quirk/export_to_quirk.py +3 -3
  51. cirq/contrib/quirk/quirk_gate.py +15 -15
  52. cirq/contrib/routing/device.py +3 -3
  53. cirq/contrib/routing/greedy.py +10 -21
  54. cirq/contrib/routing/initialization.py +2 -2
  55. cirq/contrib/routing/swap_network.py +3 -3
  56. cirq/contrib/routing/utils.py +2 -2
  57. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +8 -8
  58. cirq/contrib/svg/svg.py +3 -3
  59. cirq/devices/grid_device_metadata.py +10 -10
  60. cirq/devices/grid_qubit.py +20 -20
  61. cirq/devices/insertion_noise_model.py +5 -5
  62. cirq/devices/line_qubit.py +13 -13
  63. cirq/devices/named_topologies.py +18 -29
  64. cirq/devices/noise_model.py +3 -3
  65. cirq/devices/noise_properties.py +2 -2
  66. cirq/devices/noise_properties_test.py +1 -3
  67. cirq/devices/noise_utils.py +7 -7
  68. cirq/devices/superconducting_qubits_noise_properties.py +21 -21
  69. cirq/devices/superconducting_qubits_noise_properties_test.py +5 -7
  70. cirq/devices/thermal_noise_model.py +14 -14
  71. cirq/devices/unconstrained_device.py +2 -2
  72. cirq/experiments/benchmarking/parallel_xeb.py +29 -31
  73. cirq/experiments/n_qubit_tomography.py +5 -7
  74. cirq/experiments/qubit_characterizations.py +29 -40
  75. cirq/experiments/qubit_characterizations_test.py +1 -1
  76. cirq/experiments/random_quantum_circuit_generation.py +19 -33
  77. cirq/experiments/random_quantum_circuit_generation_test.py +6 -6
  78. cirq/experiments/readout_confusion_matrix.py +14 -14
  79. cirq/experiments/single_qubit_readout_calibration.py +12 -12
  80. cirq/experiments/t2_decay_experiment.py +7 -7
  81. cirq/experiments/two_qubit_xeb.py +32 -32
  82. cirq/experiments/two_qubit_xeb_test.py +5 -5
  83. cirq/experiments/xeb_fitting.py +25 -25
  84. cirq/experiments/xeb_sampling.py +22 -33
  85. cirq/experiments/xeb_simulation.py +5 -5
  86. cirq/experiments/xeb_simulation_test.py +3 -3
  87. cirq/experiments/z_phase_calibration.py +19 -19
  88. cirq/interop/quirk/cells/arithmetic_cells.py +23 -36
  89. cirq/interop/quirk/cells/cell.py +9 -21
  90. cirq/interop/quirk/cells/composite_cell.py +7 -22
  91. cirq/interop/quirk/cells/control_cells.py +8 -8
  92. cirq/interop/quirk/cells/input_cells.py +4 -4
  93. cirq/interop/quirk/cells/input_rotation_cells.py +5 -5
  94. cirq/interop/quirk/cells/parse.py +20 -23
  95. cirq/interop/quirk/cells/qubit_permutation_cells.py +3 -3
  96. cirq/interop/quirk/cells/swap_cell.py +3 -3
  97. cirq/interop/quirk/cells/testing.py +5 -7
  98. cirq/interop/quirk/url_to_circuit.py +17 -33
  99. cirq/json_resolver_cache.py +6 -6
  100. cirq/linalg/decompositions.py +20 -31
  101. cirq/linalg/diagonalize.py +4 -4
  102. cirq/linalg/diagonalize_test.py +3 -4
  103. cirq/linalg/operator_spaces.py +5 -5
  104. cirq/linalg/predicates.py +7 -7
  105. cirq/linalg/transformations.py +20 -20
  106. cirq/ops/arithmetic_operation.py +13 -15
  107. cirq/ops/boolean_hamiltonian.py +17 -17
  108. cirq/ops/classically_controlled_operation.py +13 -25
  109. cirq/ops/clifford_gate.py +31 -35
  110. cirq/ops/clifford_gate_test.py +2 -3
  111. cirq/ops/common_channels.py +30 -32
  112. cirq/ops/common_gates.py +64 -74
  113. cirq/ops/control_values.py +12 -12
  114. cirq/ops/controlled_gate.py +15 -30
  115. cirq/ops/controlled_gate_test.py +5 -5
  116. cirq/ops/controlled_operation.py +12 -25
  117. cirq/ops/controlled_operation_test.py +5 -5
  118. cirq/ops/dense_pauli_string.py +23 -34
  119. cirq/ops/dense_pauli_string_test.py +1 -2
  120. cirq/ops/diagonal_gate.py +9 -20
  121. cirq/ops/diagonal_gate_test.py +1 -3
  122. cirq/ops/eigen_gate.py +11 -23
  123. cirq/ops/eigen_gate_test.py +6 -8
  124. cirq/ops/fourier_transform.py +5 -5
  125. cirq/ops/fsim_gate.py +14 -14
  126. cirq/ops/gate_operation.py +23 -44
  127. cirq/ops/gateset.py +23 -37
  128. cirq/ops/gateset_test.py +2 -2
  129. cirq/ops/global_phase_op.py +8 -10
  130. cirq/ops/greedy_qubit_manager.py +6 -6
  131. cirq/ops/identity.py +9 -9
  132. cirq/ops/kraus_channel.py +7 -7
  133. cirq/ops/linear_combinations.py +29 -48
  134. cirq/ops/matrix_gates.py +8 -8
  135. cirq/ops/measure_util.py +13 -14
  136. cirq/ops/measurement_gate.py +18 -29
  137. cirq/ops/mixed_unitary_channel.py +8 -8
  138. cirq/ops/named_qubit.py +10 -10
  139. cirq/ops/op_tree.py +7 -7
  140. cirq/ops/parallel_gate.py +5 -5
  141. cirq/ops/parity_gates.py +14 -14
  142. cirq/ops/pauli_gates.py +8 -10
  143. cirq/ops/pauli_interaction_gate.py +6 -6
  144. cirq/ops/pauli_measurement_gate.py +11 -23
  145. cirq/ops/pauli_string.py +35 -52
  146. cirq/ops/pauli_string_phasor.py +4 -14
  147. cirq/ops/pauli_string_raw_types.py +3 -3
  148. cirq/ops/pauli_sum_exponential.py +2 -2
  149. cirq/ops/permutation_gate.py +4 -4
  150. cirq/ops/phased_iswap_gate.py +9 -9
  151. cirq/ops/phased_x_gate.py +10 -10
  152. cirq/ops/phased_x_z_gate.py +11 -11
  153. cirq/ops/projector.py +6 -6
  154. cirq/ops/qubit_manager.py +6 -6
  155. cirq/ops/qubit_order.py +3 -3
  156. cirq/ops/random_gate_channel.py +4 -4
  157. cirq/ops/raw_types.py +48 -70
  158. cirq/ops/state_preparation_channel.py +3 -3
  159. cirq/ops/swap_gates.py +9 -9
  160. cirq/ops/tags.py +2 -4
  161. cirq/ops/three_qubit_gates.py +20 -38
  162. cirq/ops/two_qubit_diagonal_gate.py +5 -5
  163. cirq/ops/uniform_superposition_gate.py +2 -2
  164. cirq/ops/wait_gate.py +5 -5
  165. cirq/protocols/act_on_protocol_test.py +3 -3
  166. cirq/protocols/apply_channel_protocol.py +8 -14
  167. cirq/protocols/apply_mixture_protocol.py +14 -16
  168. cirq/protocols/apply_mixture_protocol_test.py +5 -6
  169. cirq/protocols/apply_unitary_protocol.py +17 -19
  170. cirq/protocols/circuit_diagram_info_protocol.py +19 -30
  171. cirq/protocols/decompose_protocol.py +30 -34
  172. cirq/protocols/inverse_protocol.py +7 -7
  173. cirq/protocols/json_serialization.py +32 -51
  174. cirq/protocols/json_serialization_test.py +9 -10
  175. cirq/protocols/kraus_protocol.py +4 -4
  176. cirq/protocols/kraus_protocol_test.py +3 -3
  177. cirq/protocols/measurement_key_protocol.py +11 -13
  178. cirq/protocols/mixture_protocol.py +4 -4
  179. cirq/protocols/qasm.py +11 -13
  180. cirq/protocols/qid_shape_protocol.py +6 -8
  181. cirq/qis/clifford_tableau.py +12 -12
  182. cirq/qis/measures.py +7 -7
  183. cirq/qis/quantum_state_representation.py +3 -3
  184. cirq/qis/states.py +51 -51
  185. cirq/sim/classical_simulator.py +10 -10
  186. cirq/sim/clifford/clifford_simulator.py +6 -6
  187. cirq/sim/clifford/clifford_tableau_simulation_state_test.py +1 -3
  188. cirq/sim/clifford/stabilizer_sampler.py +4 -4
  189. cirq/sim/clifford/stabilizer_state_ch_form.py +3 -3
  190. cirq/sim/density_matrix_simulation_state.py +15 -15
  191. cirq/sim/density_matrix_simulator.py +11 -11
  192. cirq/sim/density_matrix_utils.py +9 -9
  193. cirq/sim/mux.py +9 -9
  194. cirq/sim/simulation_product_state.py +9 -9
  195. cirq/sim/simulation_product_state_test.py +2 -2
  196. cirq/sim/simulation_state.py +14 -27
  197. cirq/sim/simulation_state_base.py +8 -24
  198. cirq/sim/simulation_utils.py +3 -4
  199. cirq/sim/simulator.py +28 -43
  200. cirq/sim/simulator_base.py +12 -25
  201. cirq/sim/simulator_base_test.py +6 -6
  202. cirq/sim/simulator_test.py +7 -7
  203. cirq/sim/sparse_simulator.py +8 -8
  204. cirq/sim/state_vector.py +8 -8
  205. cirq/sim/state_vector_simulation_state.py +17 -17
  206. cirq/sim/state_vector_simulator.py +4 -4
  207. cirq/study/flatten_expressions.py +12 -14
  208. cirq/study/resolver.py +9 -11
  209. cirq/study/result.py +11 -24
  210. cirq/study/sweepable.py +5 -5
  211. cirq/study/sweeps.py +27 -40
  212. cirq/testing/circuit_compare.py +5 -5
  213. cirq/testing/consistent_controlled_gate_op_test.py +7 -11
  214. cirq/testing/consistent_protocols.py +10 -10
  215. cirq/testing/consistent_protocols_test.py +7 -7
  216. cirq/testing/consistent_qasm.py +4 -4
  217. cirq/testing/consistent_qasm_test.py +2 -3
  218. cirq/testing/devices.py +4 -5
  219. cirq/testing/equals_tester.py +2 -2
  220. cirq/testing/equivalent_basis_map.py +4 -4
  221. cirq/testing/equivalent_repr_eval.py +3 -3
  222. cirq/testing/json.py +14 -14
  223. cirq/testing/logs.py +3 -3
  224. cirq/testing/no_identifier_qubit.py +2 -3
  225. cirq/testing/random_circuit.py +7 -7
  226. cirq/testing/random_circuit_test.py +3 -3
  227. cirq/transformers/analytical_decompositions/clifford_decomposition.py +16 -16
  228. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +13 -13
  229. cirq/transformers/analytical_decompositions/cphase_to_fsim.py +5 -5
  230. cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +3 -3
  231. cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +3 -3
  232. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +4 -4
  233. cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +6 -7
  234. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +2 -2
  235. cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +7 -7
  236. cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +4 -4
  237. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +7 -7
  238. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +11 -11
  239. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +5 -5
  240. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +14 -14
  241. cirq/transformers/dynamical_decoupling.py +13 -13
  242. cirq/transformers/dynamical_decoupling_test.py +4 -4
  243. cirq/transformers/eject_phased_paulis.py +16 -16
  244. cirq/transformers/eject_z.py +5 -7
  245. cirq/transformers/gauge_compiling/gauge_compiling.py +38 -38
  246. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +2 -2
  247. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +8 -8
  248. cirq/transformers/insertion_sort.py +5 -5
  249. cirq/transformers/measurement_transformers.py +14 -14
  250. cirq/transformers/merge_k_qubit_gates_test.py +1 -3
  251. cirq/transformers/merge_single_qubit_gates_test.py +1 -3
  252. cirq/transformers/qubit_management_transformers.py +5 -5
  253. cirq/transformers/routing/initial_mapper.py +4 -4
  254. cirq/transformers/routing/line_initial_mapper.py +9 -9
  255. cirq/transformers/routing/mapping_manager.py +7 -7
  256. cirq/transformers/routing/route_circuit_cqc.py +27 -27
  257. cirq/transformers/routing/visualize_routed_circuit.py +4 -4
  258. cirq/transformers/stratify.py +8 -8
  259. cirq/transformers/synchronize_terminal_measurements.py +6 -6
  260. cirq/transformers/target_gatesets/compilation_target_gateset.py +8 -8
  261. cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -2
  262. cirq/transformers/target_gatesets/cz_gateset.py +4 -4
  263. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +5 -5
  264. cirq/transformers/transformer_api.py +11 -26
  265. cirq/transformers/transformer_primitives.py +24 -36
  266. cirq/transformers/transformer_primitives_test.py +3 -3
  267. cirq/value/classical_data.py +18 -18
  268. cirq/value/condition.py +8 -8
  269. cirq/value/digits.py +7 -7
  270. cirq/value/duration.py +12 -12
  271. cirq/value/linear_dict.py +8 -12
  272. cirq/value/measurement_key.py +8 -8
  273. cirq/value/product_state.py +9 -9
  274. cirq/value/value_equality_attr.py +4 -4
  275. cirq/vis/heatmap.py +23 -35
  276. cirq/work/collector.py +9 -17
  277. cirq/work/observable_grouping.py +4 -7
  278. cirq/work/observable_measurement.py +29 -41
  279. cirq/work/observable_measurement_data.py +14 -14
  280. cirq/work/observable_measurement_test.py +2 -2
  281. cirq/work/observable_settings.py +9 -10
  282. cirq/work/pauli_sum_collector.py +5 -5
  283. cirq/work/sampler.py +17 -17
  284. cirq/work/zeros_sampler.py +3 -3
  285. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/METADATA +1 -1
  286. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/RECORD +289 -289
  287. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/WHEEL +1 -1
  288. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/licenses/LICENSE +0 -0
  289. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/top_level.txt +0 -0
@@ -17,21 +17,7 @@ from __future__ import annotations
17
17
 
18
18
  import dataclasses
19
19
  import itertools
20
- from typing import (
21
- Any,
22
- Callable,
23
- cast,
24
- Container,
25
- Dict,
26
- Iterable,
27
- Iterator,
28
- List,
29
- Optional,
30
- Sequence,
31
- Tuple,
32
- TYPE_CHECKING,
33
- Union,
34
- )
20
+ from typing import Any, Callable, cast, Container, Iterable, Iterator, Sequence, TYPE_CHECKING
35
21
 
36
22
  import numpy as np
37
23
 
@@ -43,8 +29,8 @@ if TYPE_CHECKING:
43
29
 
44
30
  import cirq
45
31
 
46
- QidPairT = Tuple['cirq.Qid', 'cirq.Qid']
47
- GridQubitPairT = Tuple['cirq.GridQubit', 'cirq.GridQubit']
32
+ QidPairT = tuple['cirq.Qid', 'cirq.Qid']
33
+ GridQubitPairT = tuple['cirq.GridQubit', 'cirq.GridQubit']
48
34
 
49
35
 
50
36
  @dataclasses.dataclass(frozen=True)
@@ -117,7 +103,7 @@ class GridInteractionLayer(Container[GridQubitPairT]):
117
103
  pos = a.row % 2, (a.col - self.col_offset) % 2
118
104
  return pos == (0, 0) or pos == (1, self.stagger)
119
105
 
120
- def _json_dict_(self) -> Dict[str, Any]:
106
+ def _json_dict_(self) -> dict[str, Any]:
121
107
  return protocols.obj_to_dict_helper(self, ['col_offset', 'vertical', 'stagger'])
122
108
 
123
109
  def __repr__(self) -> str:
@@ -253,7 +239,7 @@ def generate_library_of_2q_circuits(
253
239
  q1: cirq.Qid = devices.LineQubit(1),
254
240
  random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
255
241
  tags: Sequence[Any] = (),
256
- ) -> List[cirq.Circuit]:
242
+ ) -> list[cirq.Circuit]:
257
243
  """Generate a library of two-qubit Circuits.
258
244
 
259
245
  For single-qubit gates, this uses PhasedXZGates where the axis-in-XY-plane is one
@@ -309,18 +295,18 @@ class CircuitLibraryCombination:
309
295
  `get_random_combinations_for_pairs`.
310
296
  """
311
297
 
312
- layer: Optional[Any]
298
+ layer: Any | None
313
299
  combinations: np.ndarray
314
- pairs: List[QidPairT]
300
+ pairs: list[QidPairT]
315
301
 
316
302
 
317
303
  def _get_random_combinations(
318
304
  n_library_circuits: int,
319
305
  n_combinations: int,
320
306
  *,
321
- pair_gen: Iterator[Tuple[List[QidPairT], Any]],
307
+ pair_gen: Iterator[tuple[list[QidPairT], Any]],
322
308
  random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
323
- ) -> List[CircuitLibraryCombination]:
309
+ ) -> list[CircuitLibraryCombination]:
324
310
  """For qubit pairs, prepare a set of combinations to efficiently sample
325
311
  parallel two-qubit XEB circuits.
326
312
 
@@ -370,7 +356,7 @@ def get_random_combinations_for_device(
370
356
  *,
371
357
  pattern: Sequence[GridInteractionLayer] = HALF_GRID_STAGGERED_PATTERN,
372
358
  random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
373
- ) -> List[CircuitLibraryCombination]:
359
+ ) -> list[CircuitLibraryCombination]:
374
360
  """For a given device, prepare a set of combinations to efficiently sample
375
361
  parallel two-qubit XEB circuits.
376
362
 
@@ -422,9 +408,9 @@ def get_random_combinations_for_device(
422
408
  def get_random_combinations_for_pairs(
423
409
  n_library_circuits: int,
424
410
  n_combinations: int,
425
- all_pairs: List[List[QidPairT]],
411
+ all_pairs: list[list[QidPairT]],
426
412
  random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
427
- ) -> List[CircuitLibraryCombination]:
413
+ ) -> list[CircuitLibraryCombination]:
428
414
  """For an explicit nested list of pairs, prepare a set of combinations to efficiently sample
429
415
  parallel two-qubit XEB circuits.
430
416
 
@@ -463,12 +449,12 @@ def get_random_combinations_for_pairs(
463
449
  )
464
450
 
465
451
 
466
- def _pairs_from_moment(moment: cirq.Moment) -> List[QidPairT]:
452
+ def _pairs_from_moment(moment: cirq.Moment) -> list[QidPairT]:
467
453
  """Helper function in `get_random_combinations_for_layer_circuit` pair generator.
468
454
 
469
455
  The moment should contain only two qubit operations, which define a list of qubit pairs.
470
456
  """
471
- pairs: List[QidPairT] = []
457
+ pairs: list[QidPairT] = []
472
458
  for op in moment.operations:
473
459
  if len(op.qubits) != 2:
474
460
  raise ValueError("Layer circuit contains non-2-qubit operations.")
@@ -482,7 +468,7 @@ def get_random_combinations_for_layer_circuit(
482
468
  n_combinations: int,
483
469
  layer_circuit: cirq.Circuit,
484
470
  random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
485
- ) -> List[CircuitLibraryCombination]:
471
+ ) -> list[CircuitLibraryCombination]:
486
472
  """For a layer circuit, prepare a set of combinations to efficiently sample
487
473
  parallel two-qubit XEB circuits.
488
474
 
@@ -622,7 +608,7 @@ def random_rotations_between_grid_interaction_layers_circuit(
622
608
  return circuit
623
609
 
624
610
 
625
- def _coupled_qubit_pairs(qubits: List[cirq.GridQubit]) -> List[GridQubitPairT]:
611
+ def _coupled_qubit_pairs(qubits: list[cirq.GridQubit]) -> list[GridQubitPairT]:
626
612
  pairs = []
627
613
  qubit_set = set(qubits)
628
614
  for qubit in qubits:
@@ -661,14 +647,14 @@ class _RandomSingleQubitLayerFactory:
661
647
 
662
648
 
663
649
  class _FixedSingleQubitLayerFactory:
664
- def __init__(self, fixed_single_qubit_layer: Dict[cirq.Qid, cirq.Gate]) -> None:
650
+ def __init__(self, fixed_single_qubit_layer: dict[cirq.Qid, cirq.Gate]) -> None:
665
651
  self.fixed_single_qubit_layer = fixed_single_qubit_layer
666
652
 
667
653
  def new_layer(self, previous_single_qubit_layer: cirq.Moment) -> cirq.Moment:
668
654
  return circuits.Moment(v.on(q) for q, v in self.fixed_single_qubit_layer.items())
669
655
 
670
656
 
671
- _SingleQubitLayerFactory = Union[_FixedSingleQubitLayerFactory, _RandomSingleQubitLayerFactory]
657
+ _SingleQubitLayerFactory = _FixedSingleQubitLayerFactory | _RandomSingleQubitLayerFactory
672
658
 
673
659
 
674
660
  def _single_qubit_gates_arg_to_factory(
@@ -687,7 +673,7 @@ def _single_qubit_gates_arg_to_factory(
687
673
 
688
674
 
689
675
  def _two_qubit_layer(
690
- coupled_qubit_pairs: List[GridQubitPairT],
676
+ coupled_qubit_pairs: list[GridQubitPairT],
691
677
  two_qubit_op_factory: Callable[
692
678
  [cirq.GridQubit, cirq.GridQubit, np.random.RandomState], cirq.OP_TREE
693
679
  ],
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import itertools
18
- from typing import Callable, cast, Dict, Iterable, List, Optional, Sequence, Set, Tuple
18
+ from typing import Callable, cast, Iterable, Sequence
19
19
 
20
20
  import networkx as nx
21
21
  import numpy as np
@@ -35,7 +35,7 @@ from cirq.experiments.random_quantum_circuit_generation import (
35
35
  random_rotations_between_two_qubit_circuit,
36
36
  )
37
37
 
38
- SINGLE_QUBIT_LAYER = Dict[cirq.GridQubit, Optional[cirq.Gate]]
38
+ SINGLE_QUBIT_LAYER = dict[cirq.GridQubit, cirq.Gate | None]
39
39
 
40
40
 
41
41
  def test_random_rotation_between_two_qubit_circuit():
@@ -404,7 +404,7 @@ def test_grid_interaction_layer_repr():
404
404
 
405
405
 
406
406
  def _validate_single_qubit_layers(
407
- qubits: Set[cirq.GridQubit], moments: Sequence[cirq.Moment], non_repeating_layers: bool = True
407
+ qubits: set[cirq.GridQubit], moments: Sequence[cirq.Moment], non_repeating_layers: bool = True
408
408
  ) -> None:
409
409
  previous_single_qubit_gates: SINGLE_QUBIT_LAYER = {q: None for q in qubits}
410
410
 
@@ -422,7 +422,7 @@ def _validate_single_qubit_layers(
422
422
 
423
423
 
424
424
  def _validate_two_qubit_layers(
425
- qubits: Set[cirq.GridQubit],
425
+ qubits: set[cirq.GridQubit],
426
426
  moments: Sequence[cirq.Moment],
427
427
  pattern: Sequence[cirq.experiments.GridInteractionLayer],
428
428
  ) -> None:
@@ -447,8 +447,8 @@ def _validate_two_qubit_layers(
447
447
 
448
448
 
449
449
  def _coupled_qubit_pairs(
450
- qubits: Set[cirq.GridQubit],
451
- ) -> List[Tuple[cirq.GridQubit, cirq.GridQubit]]:
450
+ qubits: set[cirq.GridQubit],
451
+ ) -> list[tuple[cirq.GridQubit, cirq.GridQubit]]:
452
452
  pairs = []
453
453
  for qubit in qubits:
454
454
 
@@ -17,7 +17,7 @@
17
17
  from __future__ import annotations
18
18
 
19
19
  import time
20
- from typing import Any, cast, Dict, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
20
+ from typing import Any, cast, Sequence, TYPE_CHECKING
21
21
 
22
22
  import numpy as np
23
23
  import scipy.optimize
@@ -61,8 +61,8 @@ class TensoredConfusionMatrices:
61
61
 
62
62
  def __init__(
63
63
  self,
64
- confusion_matrices: Union[np.ndarray, Sequence[np.ndarray]],
65
- measure_qubits: Union[Sequence[cirq.Qid], Sequence[Sequence[cirq.Qid]]],
64
+ confusion_matrices: np.ndarray | Sequence[np.ndarray],
65
+ measure_qubits: Sequence[cirq.Qid] | Sequence[Sequence[cirq.Qid]],
66
66
  *,
67
67
  repetitions: int,
68
68
  timestamp: float,
@@ -114,7 +114,7 @@ class TensoredConfusionMatrices:
114
114
  self._measure_qubits = tuple(tuple(q) for q in measure_qubits)
115
115
  self._qubits = tuple(sorted(set(q for ql in measure_qubits for q in ql)))
116
116
  self._qubits_to_idx = {q: i for i, q in enumerate(self._qubits)}
117
- self._cache: Dict[Tuple[cirq.Qid, ...], np.ndarray] = {}
117
+ self._cache: dict[tuple[cirq.Qid, ...], np.ndarray] = {}
118
118
  if sum(len(q) for q in self._measure_qubits) != len(self._qubits):
119
119
  raise ValueError(f"Repeated qubits not allowed in measure_qubits: {measure_qubits}.")
120
120
 
@@ -157,27 +157,27 @@ class TensoredConfusionMatrices:
157
157
  return self._timestamp
158
158
 
159
159
  @property
160
- def confusion_matrices(self) -> Tuple[np.ndarray, ...]:
160
+ def confusion_matrices(self) -> tuple[np.ndarray, ...]:
161
161
  """List of confusion matrices corresponding to `measure_qubits` qubit pattern."""
162
162
  return self._confusion_matrices
163
163
 
164
164
  @property
165
- def measure_qubits(self) -> Tuple[Tuple[cirq.Qid, ...], ...]:
165
+ def measure_qubits(self) -> tuple[tuple[cirq.Qid, ...], ...]:
166
166
  """Calibrated qubit pattern for which individual confusion matrices were computed."""
167
167
  return self._measure_qubits
168
168
 
169
169
  @property
170
- def qubits(self) -> Tuple[cirq.Qid, ...]:
170
+ def qubits(self) -> tuple[cirq.Qid, ...]:
171
171
  """Sorted list of all calibrated qubits."""
172
172
  return self._qubits
173
173
 
174
- def _get_vars(self, qubit_pattern: Sequence[cirq.Qid]) -> List[int]:
174
+ def _get_vars(self, qubit_pattern: Sequence[cirq.Qid]) -> list[int]:
175
175
  in_vars = [2 * self._qubits_to_idx[q] for q in qubit_pattern]
176
176
  out_vars = [2 * self._qubits_to_idx[q] + 1 for q in qubit_pattern]
177
177
  return in_vars + out_vars
178
178
 
179
179
  def _confusion_matrix(self, qubits: Sequence[cirq.Qid]) -> np.ndarray:
180
- ein_input: List[np.ndarray | List[int]] = []
180
+ ein_input: list[np.ndarray | list[int]] = []
181
181
  for qs, cm in zip(self.measure_qubits, self.confusion_matrices):
182
182
  ein_input.extend([cm.reshape((2, 2) * len(qs)), self._get_vars(qs)])
183
183
  ein_out = self._get_vars(qubits)
@@ -185,7 +185,7 @@ class TensoredConfusionMatrices:
185
185
  ret = np.einsum(*ein_input, ein_out).reshape((2 ** len(qubits),) * 2)
186
186
  return ret / ret.sum(axis=1)
187
187
 
188
- def confusion_matrix(self, qubits: Optional[Sequence[cirq.Qid]] = None) -> np.ndarray:
188
+ def confusion_matrix(self, qubits: Sequence[cirq.Qid] | None = None) -> np.ndarray:
189
189
  """Returns a single confusion matrix constructed for the given set of qubits.
190
190
 
191
191
  The single `2 ** len(qubits) x 2 ** len(qubits)` confusion matrix is constructed
@@ -213,7 +213,7 @@ class TensoredConfusionMatrices:
213
213
  self._cache[key] = self._confusion_matrix(qubits)
214
214
  return self._cache[key]
215
215
 
216
- def correction_matrix(self, qubits: Optional[Sequence[cirq.Qid]] = None) -> np.ndarray:
216
+ def correction_matrix(self, qubits: Sequence[cirq.Qid] | None = None) -> np.ndarray:
217
217
  """Returns a single correction matrix constructed for the given set of qubits.
218
218
 
219
219
  A correction matrix is the inverse of confusion matrix and can be used to apply corrections
@@ -242,7 +242,7 @@ class TensoredConfusionMatrices:
242
242
  def apply(
243
243
  self,
244
244
  result: np.ndarray,
245
- qubits: Optional[Sequence[cirq.Qid]] = None,
245
+ qubits: Sequence[cirq.Qid] | None = None,
246
246
  *,
247
247
  method='least_squares',
248
248
  ) -> np.ndarray:
@@ -375,7 +375,7 @@ class TensoredConfusionMatrices:
375
375
  f")"
376
376
  )
377
377
 
378
- def _json_dict_(self) -> Dict[str, Any]:
378
+ def _json_dict_(self) -> dict[str, Any]:
379
379
  return {
380
380
  'confusion_matrices': self.confusion_matrices,
381
381
  'measure_qubits': self.measure_qubits,
@@ -426,7 +426,7 @@ class TensoredConfusionMatrices:
426
426
 
427
427
  def measure_confusion_matrix(
428
428
  sampler: cirq.Sampler,
429
- qubits: Union[Sequence[cirq.Qid], Sequence[Sequence[cirq.Qid]]],
429
+ qubits: Sequence[cirq.Qid] | Sequence[Sequence[cirq.Qid]],
430
430
  repetitions: int = 1000,
431
431
  ) -> TensoredConfusionMatrices:
432
432
  """Prepares `TensoredConfusionMatrices` for the n qubits in the input.
@@ -18,7 +18,7 @@ from __future__ import annotations
18
18
 
19
19
  import dataclasses
20
20
  import time
21
- from typing import Any, cast, Dict, Iterable, List, Optional, TYPE_CHECKING
21
+ from typing import Any, cast, Iterable, TYPE_CHECKING
22
22
 
23
23
  import matplotlib.pyplot as plt
24
24
  import numpy as np
@@ -47,12 +47,12 @@ class SingleQubitReadoutCalibrationResult:
47
47
  timestamp: The time the data was taken, in seconds since the epoch.
48
48
  """
49
49
 
50
- zero_state_errors: Dict[cirq.Qid, float]
51
- one_state_errors: Dict[cirq.Qid, float]
50
+ zero_state_errors: dict[cirq.Qid, float]
51
+ one_state_errors: dict[cirq.Qid, float]
52
52
  repetitions: int
53
53
  timestamp: float
54
54
 
55
- def _json_dict_(self) -> Dict[str, Any]:
55
+ def _json_dict_(self) -> dict[str, Any]:
56
56
  return {
57
57
  'zero_state_errors': list(self.zero_state_errors.items()),
58
58
  'one_state_errors': list(self.one_state_errors.items()),
@@ -62,7 +62,7 @@ class SingleQubitReadoutCalibrationResult:
62
62
 
63
63
  def plot_heatmap(
64
64
  self,
65
- axs: Optional[tuple[plt.Axes, plt.Axes]] = None,
65
+ axs: tuple[plt.Axes, plt.Axes] | None = None,
66
66
  annotation_format: str = '0.1%',
67
67
  **plot_kwargs: Any,
68
68
  ) -> tuple[plt.Axes, plt.Axes]:
@@ -110,16 +110,16 @@ class SingleQubitReadoutCalibrationResult:
110
110
 
111
111
  def plot_integrated_histogram(
112
112
  self,
113
- ax: Optional[plt.Axes] = None,
113
+ ax: plt.Axes | None = None,
114
114
  cdf_on_x: bool = False,
115
115
  axis_label: str = 'Readout error rate',
116
116
  semilog: bool = True,
117
117
  median_line: bool = True,
118
- median_label: Optional[str] = 'median',
118
+ median_label: str | None = 'median',
119
119
  mean_line: bool = False,
120
- mean_label: Optional[str] = 'mean',
120
+ mean_label: str | None = 'mean',
121
121
  show_zero: bool = False,
122
- title: Optional[str] = None,
122
+ title: str | None = None,
123
123
  **kwargs,
124
124
  ) -> plt.Axes:
125
125
  """Plot the readout errors using cirq.integrated_histogram().
@@ -238,8 +238,8 @@ def estimate_parallel_single_qubit_readout_errors(
238
238
  qubits: Iterable[cirq.Qid],
239
239
  trials: int = 20,
240
240
  repetitions: int = 1000,
241
- trials_per_batch: Optional[int] = None,
242
- bit_strings: Optional[np.ndarray] = None,
241
+ trials_per_batch: int | None = None,
242
+ bit_strings: np.ndarray | None = None,
243
243
  ) -> SingleQubitReadoutCalibrationResult:
244
244
  """Estimate single qubit readout error using parallel operations.
245
245
 
@@ -300,7 +300,7 @@ def estimate_parallel_single_qubit_readout_errors(
300
300
  if trials_per_batch <= 0:
301
301
  raise ValueError("Must provide non-zero trials_per_batch for readout calibration.")
302
302
 
303
- all_sweeps: List[study.Sweepable] = []
303
+ all_sweeps: list[study.Sweepable] = []
304
304
  num_batches = (trials + trials_per_batch - 1) // trials_per_batch
305
305
 
306
306
  # Initialize circuits
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import enum
18
- from typing import Any, List, Optional, TYPE_CHECKING, Union
18
+ from typing import Any, TYPE_CHECKING
19
19
 
20
20
  import pandas as pd
21
21
  import sympy
@@ -46,9 +46,9 @@ def t2_decay(
46
46
  max_delay: cirq.DURATION_LIKE,
47
47
  min_delay: cirq.DURATION_LIKE = None,
48
48
  repetitions: int = 1000,
49
- delay_sweep: Optional[study.Sweep] = None,
50
- num_pulses: Optional[List[int]] = None,
51
- ) -> Union[cirq.experiments.T2DecayResult, List[cirq.experiments.T2DecayResult]]:
49
+ delay_sweep: study.Sweep | None = None,
50
+ num_pulses: list[int] | None = None,
51
+ ) -> cirq.experiments.T2DecayResult | list[cirq.experiments.T2DecayResult]:
52
52
  """Runs a t2 transverse relaxation experiment.
53
53
 
54
54
  Initializes a qubit into a superposition state, evolves the system using
@@ -259,7 +259,7 @@ def _cpmg_circuit(qubit: cirq.Qid, delay_var: sympy.Symbol, max_pulses: int) ->
259
259
  return circuit
260
260
 
261
261
 
262
- def _cpmg_sweep(num_pulses: List[int]):
262
+ def _cpmg_sweep(num_pulses: list[int]):
263
263
  """Returns a sweep for a circuit created by _cpmg_circuit.
264
264
 
265
265
  The circuit in _cpmg_circuit parameterizes the pulses, so this function
@@ -354,7 +354,7 @@ class T2DecayResult:
354
354
  """
355
355
  return self._expectation_pauli_y
356
356
 
357
- def plot_expectations(self, ax: Optional[plt.Axes] = None, **plot_kwargs: Any) -> plt.Axes:
357
+ def plot_expectations(self, ax: plt.Axes | None = None, **plot_kwargs: Any) -> plt.Axes:
358
358
  """Plots the expectation values of Pauli operators versus delay time.
359
359
 
360
360
  Args:
@@ -395,7 +395,7 @@ class T2DecayResult:
395
395
  fig.show()
396
396
  return ax
397
397
 
398
- def plot_bloch_vector(self, ax: Optional[plt.Axes] = None, **plot_kwargs: Any) -> plt.Axes:
398
+ def plot_bloch_vector(self, ax: plt.Axes | None = None, **plot_kwargs: Any) -> plt.Axes:
399
399
  """Plots the estimated length of the Bloch vector versus time.
400
400
 
401
401
  This plot estimates the Bloch Vector by squaring the Pauli expectation
@@ -20,7 +20,7 @@ import functools
20
20
  import itertools
21
21
  from dataclasses import dataclass
22
22
  from types import MappingProxyType
23
- from typing import Any, cast, Dict, Mapping, Optional, Sequence, Tuple, TYPE_CHECKING
23
+ from typing import Any, cast, Mapping, Sequence, TYPE_CHECKING
24
24
 
25
25
  import networkx as nx
26
26
  import numpy as np
@@ -49,7 +49,7 @@ if TYPE_CHECKING:
49
49
  import cirq
50
50
 
51
51
 
52
- def _grid_qubits_for_sampler(sampler: cirq.Sampler) -> Optional[Sequence[cirq.GridQubit]]:
52
+ def _grid_qubits_for_sampler(sampler: cirq.Sampler) -> Sequence[cirq.GridQubit] | None:
53
53
  if hasattr(sampler, 'processor'):
54
54
  device = sampler.processor.get_device()
55
55
  return sorted(device.metadata.qubit_set)
@@ -62,9 +62,9 @@ def _manhattan_distance(qubit1: cirq.GridQubit, qubit2: cirq.GridQubit) -> int:
62
62
 
63
63
  def qubits_and_pairs(
64
64
  sampler: cirq.Sampler,
65
- qubits: Optional[Sequence[cirq.GridQubit]] = None,
66
- pairs: Optional[Sequence[tuple[cirq.GridQubit, cirq.GridQubit]]] = None,
67
- ) -> Tuple[Sequence[cirq.GridQubit], Sequence[tuple[cirq.GridQubit, cirq.GridQubit]]]:
65
+ qubits: Sequence[cirq.GridQubit] | None = None,
66
+ pairs: Sequence[tuple[cirq.GridQubit, cirq.GridQubit]] | None = None,
67
+ ) -> tuple[Sequence[cirq.GridQubit], Sequence[tuple[cirq.GridQubit, cirq.GridQubit]]]:
68
68
  """Extract qubits and pairs from sampler.
69
69
 
70
70
 
@@ -107,7 +107,7 @@ class TwoQubitXEBResult:
107
107
  fidelities: pd.DataFrame
108
108
 
109
109
  @functools.cached_property
110
- def _qubit_pair_map(self) -> Dict[Tuple[cirq.GridQubit, cirq.GridQubit], int]:
110
+ def _qubit_pair_map(self) -> dict[tuple[cirq.GridQubit, cirq.GridQubit], int]:
111
111
  if isinstance(self.fidelities.index[0][0], ops.Qid):
112
112
  return {
113
113
  (min(q0, q1), max(q0, q1)): i for i, (q0, q1) in enumerate(self.fidelities.index)
@@ -118,10 +118,10 @@ class TwoQubitXEBResult:
118
118
  }
119
119
 
120
120
  @functools.cached_property
121
- def all_qubit_pairs(self) -> Tuple[Tuple[cirq.GridQubit, cirq.GridQubit], ...]:
121
+ def all_qubit_pairs(self) -> tuple[tuple[cirq.GridQubit, cirq.GridQubit], ...]:
122
122
  return tuple(sorted(self._qubit_pair_map.keys()))
123
123
 
124
- def plot_heatmap(self, ax: Optional[plt.Axes] = None, **plot_kwargs) -> plt.Axes:
124
+ def plot_heatmap(self, ax: plt.Axes | None = None, **plot_kwargs) -> plt.Axes:
125
125
  """plot the heatmap of XEB errors.
126
126
 
127
127
  Args:
@@ -135,7 +135,7 @@ class TwoQubitXEBResult:
135
135
  show_plot = not ax
136
136
  if not isinstance(ax, plt.Axes):
137
137
  fig, ax = plt.subplots(1, 1, figsize=(8, 8))
138
- heatmap_data: Dict[Tuple[cirq.GridQubit, ...], float] = {
138
+ heatmap_data: dict[tuple[cirq.GridQubit, ...], float] = {
139
139
  pair: self.xeb_error(*pair) for pair in self.all_qubit_pairs
140
140
  }
141
141
 
@@ -147,7 +147,7 @@ class TwoQubitXEBResult:
147
147
  return ax
148
148
 
149
149
  def plot_fitted_exponential(
150
- self, q0: cirq.GridQubit, q1: cirq.GridQubit, ax: Optional[plt.Axes] = None, **plot_kwargs
150
+ self, q0: cirq.GridQubit, q1: cirq.GridQubit, ax: plt.Axes | None = None, **plot_kwargs
151
151
  ) -> plt.Axes:
152
152
  """plot the fitted model to for xeb error of a qubit pair.
153
153
 
@@ -199,11 +199,11 @@ class TwoQubitXEBResult:
199
199
  """Return the XEB error of a qubit pair."""
200
200
  return 1 - self.xeb_fidelity(q0, q1)
201
201
 
202
- def all_errors(self) -> Dict[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
202
+ def all_errors(self) -> dict[tuple[cirq.GridQubit, cirq.GridQubit], float]:
203
203
  """Return the XEB error of all qubit pairs."""
204
204
  return {(q0, q1): self.xeb_error(q0, q1) for q0, q1 in self.all_qubit_pairs}
205
205
 
206
- def plot_histogram(self, ax: Optional[plt.Axes] = None, **plot_kwargs) -> plt.Axes:
206
+ def plot_histogram(self, ax: plt.Axes | None = None, **plot_kwargs) -> plt.Axes:
207
207
  """plot a histogram of all xeb errors.
208
208
 
209
209
  Args:
@@ -223,7 +223,7 @@ class TwoQubitXEBResult:
223
223
  return ax
224
224
 
225
225
  @cached_method
226
- def pauli_error(self) -> Dict[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
226
+ def pauli_error(self) -> dict[tuple[cirq.GridQubit, cirq.GridQubit], float]:
227
227
  """Return the Pauli error of all qubit pairs."""
228
228
  return {
229
229
  pair: noise_utils.decay_constant_to_pauli_error(
@@ -246,7 +246,7 @@ class InferredXEBResult:
246
246
  xeb_result: TwoQubitXEBResult
247
247
 
248
248
  @property
249
- def all_qubit_pairs(self) -> Sequence[Tuple[cirq.GridQubit, cirq.GridQubit]]:
249
+ def all_qubit_pairs(self) -> Sequence[tuple[cirq.GridQubit, cirq.GridQubit]]:
250
250
  return self.xeb_result.all_qubit_pairs
251
251
 
252
252
  @cached_method
@@ -255,12 +255,12 @@ class InferredXEBResult:
255
255
  return self.rb_result.pauli_error()
256
256
 
257
257
  @cached_method
258
- def two_qubit_pauli_error(self) -> Mapping[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
258
+ def two_qubit_pauli_error(self) -> Mapping[tuple[cirq.GridQubit, cirq.GridQubit], float]:
259
259
  """Return the two-qubit Pauli error for all pairs."""
260
260
  return MappingProxyType(self.xeb_result.pauli_error())
261
261
 
262
262
  @cached_method
263
- def inferred_pauli_error(self) -> Mapping[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
263
+ def inferred_pauli_error(self) -> Mapping[tuple[cirq.GridQubit, cirq.GridQubit], float]:
264
264
  """Return the inferred Pauli error for all pairs."""
265
265
  single_q_paulis = self.rb_result.pauli_error()
266
266
  xeb = self.xeb_result.pauli_error()
@@ -272,7 +272,7 @@ class InferredXEBResult:
272
272
  return MappingProxyType({pair: _pauli_error(*pair) for pair in self.all_qubit_pairs})
273
273
 
274
274
  @cached_method
275
- def inferred_decay_constant(self) -> Mapping[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
275
+ def inferred_decay_constant(self) -> Mapping[tuple[cirq.GridQubit, cirq.GridQubit], float]:
276
276
  """Return the inferred decay constant for all pairs."""
277
277
  return MappingProxyType(
278
278
  {
@@ -282,7 +282,7 @@ class InferredXEBResult:
282
282
  )
283
283
 
284
284
  @cached_method
285
- def inferred_xeb_error(self) -> Mapping[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
285
+ def inferred_xeb_error(self) -> Mapping[tuple[cirq.GridQubit, cirq.GridQubit], float]:
286
286
  """Return the inferred XEB error for all pairs."""
287
287
  return MappingProxyType(
288
288
  {
@@ -293,7 +293,7 @@ class InferredXEBResult:
293
293
 
294
294
  def _target_errors(
295
295
  self, target_error: str
296
- ) -> Mapping[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
296
+ ) -> Mapping[tuple[cirq.GridQubit, cirq.GridQubit], float]:
297
297
  """Returns requested error.
298
298
 
299
299
  The requested error must be one of 'pauli', 'decay_constant', or 'xeb'.
@@ -315,7 +315,7 @@ class InferredXEBResult:
315
315
  return error_funcs[target_error]()
316
316
 
317
317
  def plot_heatmap(
318
- self, target_error: str = 'pauli', ax: Optional[plt.Axes] = None, **plot_kwargs
318
+ self, target_error: str = 'pauli', ax: plt.Axes | None = None, **plot_kwargs
319
319
  ) -> plt.Axes:
320
320
  """plot the heatmap of the target errors.
321
321
 
@@ -329,7 +329,7 @@ class InferredXEBResult:
329
329
  if not isinstance(ax, plt.Axes):
330
330
  fig, ax = plt.subplots(1, 1, figsize=(8, 8))
331
331
  heatmap_data = cast(
332
- Mapping[Tuple['cirq.GridQubit', ...], float], self._target_errors(target_error)
332
+ Mapping[tuple['cirq.GridQubit', ...], float], self._target_errors(target_error)
333
333
  )
334
334
 
335
335
  name = f'{target_error} error' if target_error != 'decay_constant' else 'decay constant'
@@ -343,7 +343,7 @@ class InferredXEBResult:
343
343
  def plot_histogram(
344
344
  self,
345
345
  target_error: str = 'pauli',
346
- ax: Optional[plt.Axes] = None,
346
+ ax: plt.Axes | None = None,
347
347
  kind: str = 'two_qubit',
348
348
  **plot_kwargs,
349
349
  ) -> plt.Axes:
@@ -398,20 +398,20 @@ class InferredXEBResult:
398
398
 
399
399
  def parallel_xeb_workflow(
400
400
  sampler: cirq.Sampler,
401
- qubits: Optional[Sequence[cirq.GridQubit]] = None,
401
+ qubits: Sequence[cirq.GridQubit] | None = None,
402
402
  entangling_gate: cirq.Gate = ops.CZ,
403
403
  n_repetitions: int = 10**4,
404
404
  n_combinations: int = 10,
405
405
  n_circuits: int = 20,
406
406
  cycle_depths: Sequence[int] = (5, 25, 50, 100, 200, 300),
407
407
  random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
408
- ax: Optional[plt.Axes] = None,
409
- pairs: Optional[Sequence[tuple[cirq.GridQubit, cirq.GridQubit]]] = None,
410
- pool: Optional[multiprocessing.pool.Pool] = None,
408
+ ax: plt.Axes | None = None,
409
+ pairs: Sequence[tuple[cirq.GridQubit, cirq.GridQubit]] | None = None,
410
+ pool: multiprocessing.pool.Pool | None = None,
411
411
  batch_size: int = 9,
412
412
  tags: Sequence[Any] = (),
413
413
  **plot_kwargs,
414
- ) -> Tuple[pd.DataFrame, Sequence[cirq.Circuit], pd.DataFrame]:
414
+ ) -> tuple[pd.DataFrame, Sequence[cirq.Circuit], pd.DataFrame]:
415
415
  """A utility method that runs the full XEB workflow.
416
416
 
417
417
  Args:
@@ -488,15 +488,15 @@ def parallel_xeb_workflow(
488
488
 
489
489
  def parallel_two_qubit_xeb(
490
490
  sampler: cirq.Sampler,
491
- qubits: Optional[Sequence[cirq.GridQubit]] = None,
491
+ qubits: Sequence[cirq.GridQubit] | None = None,
492
492
  entangling_gate: cirq.Gate = ops.CZ,
493
493
  n_repetitions: int = 10**4,
494
494
  n_combinations: int = 10,
495
495
  n_circuits: int = 20,
496
496
  cycle_depths: Sequence[int] = (5, 25, 50, 100, 200, 300),
497
497
  random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
498
- ax: Optional[plt.Axes] = None,
499
- pairs: Optional[Sequence[tuple[cirq.GridQubit, cirq.GridQubit]]] = None,
498
+ ax: plt.Axes | None = None,
499
+ pairs: Sequence[tuple[cirq.GridQubit, cirq.GridQubit]] | None = None,
500
500
  batch_size: int = 9,
501
501
  tags: Sequence[Any] = (),
502
502
  **plot_kwargs,
@@ -545,7 +545,7 @@ def parallel_two_qubit_xeb(
545
545
 
546
546
  def run_rb_and_xeb(
547
547
  sampler: cirq.Sampler,
548
- qubits: Optional[Sequence[cirq.GridQubit]] = None,
548
+ qubits: Sequence[cirq.GridQubit] | None = None,
549
549
  repetitions: int = 10**3,
550
550
  num_circuits: int = 20,
551
551
  num_clifford_range: Sequence[int] = tuple(
@@ -555,7 +555,7 @@ def run_rb_and_xeb(
555
555
  depths_xeb: Sequence[int] = (5, 25, 50, 100, 200, 300),
556
556
  xeb_combinations: int = 10,
557
557
  random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
558
- pairs: Optional[Sequence[tuple[cirq.GridQubit, cirq.GridQubit]]] = None,
558
+ pairs: Sequence[tuple[cirq.GridQubit, cirq.GridQubit]] | None = None,
559
559
  batch_size: int = 9,
560
560
  tags: Sequence[Any] = (),
561
561
  ) -> InferredXEBResult: