cirq-core 1.5.0.dev20250409222543__py3-none-any.whl → 1.6.0__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 (732) hide show
  1. cirq/__init__.py +16 -17
  2. cirq/_compat.py +21 -20
  3. cirq/_compat_test.py +14 -34
  4. cirq/_doc.py +4 -2
  5. cirq/_import.py +8 -6
  6. cirq/_import_test.py +4 -2
  7. cirq/_version.py +6 -6
  8. cirq/_version_test.py +2 -2
  9. cirq/circuits/_block_diagram_drawer.py +11 -10
  10. cirq/circuits/_block_diagram_drawer_test.py +8 -6
  11. cirq/circuits/_box_drawing_character_data.py +8 -8
  12. cirq/circuits/_box_drawing_character_data_test.py +3 -1
  13. cirq/circuits/_bucket_priority_queue.py +9 -7
  14. cirq/circuits/_bucket_priority_queue_test.py +22 -20
  15. cirq/circuits/circuit.py +248 -172
  16. cirq/circuits/circuit_operation.py +73 -83
  17. cirq/circuits/circuit_operation_test.py +128 -90
  18. cirq/circuits/circuit_test.py +211 -151
  19. cirq/circuits/frozen_circuit.py +23 -60
  20. cirq/circuits/frozen_circuit_test.py +31 -8
  21. cirq/circuits/insert_strategy.py +7 -5
  22. cirq/circuits/insert_strategy_test.py +4 -2
  23. cirq/circuits/moment.py +88 -40
  24. cirq/circuits/moment_test.py +128 -51
  25. cirq/circuits/optimization_pass.py +5 -5
  26. cirq/circuits/optimization_pass_test.py +10 -10
  27. cirq/circuits/qasm_output.py +11 -11
  28. cirq/circuits/qasm_output_test.py +25 -22
  29. cirq/circuits/text_diagram_drawer.py +23 -38
  30. cirq/circuits/text_diagram_drawer_test.py +19 -17
  31. cirq/conftest.py +4 -3
  32. cirq/contrib/__init__.py +4 -4
  33. cirq/contrib/acquaintance/__init__.py +1 -1
  34. cirq/contrib/acquaintance/bipartite.py +5 -8
  35. cirq/contrib/acquaintance/bipartite_test.py +18 -13
  36. cirq/contrib/acquaintance/devices.py +2 -2
  37. cirq/contrib/acquaintance/devices_test.py +5 -3
  38. cirq/contrib/acquaintance/executor.py +5 -5
  39. cirq/contrib/acquaintance/executor_test.py +13 -9
  40. cirq/contrib/acquaintance/gates.py +18 -28
  41. cirq/contrib/acquaintance/gates_test.py +24 -20
  42. cirq/contrib/acquaintance/inspection_utils.py +8 -4
  43. cirq/contrib/acquaintance/inspection_utils_test.py +4 -2
  44. cirq/contrib/acquaintance/mutation_utils.py +4 -4
  45. cirq/contrib/acquaintance/mutation_utils_test.py +4 -2
  46. cirq/contrib/acquaintance/optimizers.py +4 -4
  47. cirq/contrib/acquaintance/optimizers_test.py +4 -1
  48. cirq/contrib/acquaintance/permutation.py +15 -27
  49. cirq/contrib/acquaintance/permutation_test.py +26 -17
  50. cirq/contrib/acquaintance/shift.py +4 -4
  51. cirq/contrib/acquaintance/shift_swap_network.py +4 -4
  52. cirq/contrib/acquaintance/shift_swap_network_test.py +9 -6
  53. cirq/contrib/acquaintance/shift_test.py +8 -6
  54. cirq/contrib/acquaintance/strategies/cubic.py +2 -2
  55. cirq/contrib/acquaintance/strategies/cubic_test.py +4 -2
  56. cirq/contrib/acquaintance/strategies/quartic_paired.py +6 -6
  57. cirq/contrib/acquaintance/strategies/quartic_paired_test.py +10 -6
  58. cirq/contrib/acquaintance/testing.py +2 -0
  59. cirq/contrib/acquaintance/topological_sort.py +2 -2
  60. cirq/contrib/acquaintance/topological_sort_test.py +3 -1
  61. cirq/contrib/bayesian_network/bayesian_network_gate.py +9 -10
  62. cirq/contrib/bayesian_network/bayesian_network_gate_test.py +14 -9
  63. cirq/contrib/circuitdag/circuit_dag.py +4 -4
  64. cirq/contrib/circuitdag/circuit_dag_test.py +17 -15
  65. cirq/contrib/custom_simulators/custom_state_simulator.py +5 -5
  66. cirq/contrib/custom_simulators/custom_state_simulator_test.py +22 -17
  67. cirq/contrib/graph_device/graph_device.py +12 -11
  68. cirq/contrib/graph_device/graph_device_test.py +18 -14
  69. cirq/contrib/graph_device/hypergraph.py +16 -14
  70. cirq/contrib/graph_device/hypergraph_test.py +13 -11
  71. cirq/contrib/graph_device/uniform_graph_device.py +6 -4
  72. cirq/contrib/graph_device/uniform_graph_device_test.py +11 -3
  73. cirq/contrib/hacks/disable_validation.py +6 -1
  74. cirq/contrib/hacks/disable_validation_test.py +3 -1
  75. cirq/contrib/json.py +31 -5
  76. cirq/contrib/json_test.py +6 -3
  77. cirq/contrib/json_test_data/DampedReadoutNoiseModel.json +12 -0
  78. cirq/contrib/json_test_data/DampedReadoutNoiseModel.repr +4 -0
  79. cirq/contrib/json_test_data/DepolarizingNoiseModel.json +12 -0
  80. cirq/contrib/json_test_data/DepolarizingNoiseModel.repr +4 -0
  81. cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.json +6 -0
  82. cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.repr +1 -0
  83. cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.json +5 -0
  84. cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.repr +1 -0
  85. cirq/contrib/json_test_data/ReadoutNoiseModel.json +12 -0
  86. cirq/contrib/json_test_data/ReadoutNoiseModel.repr +4 -0
  87. cirq/contrib/json_test_data/__init__.py +17 -0
  88. cirq/contrib/json_test_data/spec.py +32 -0
  89. cirq/contrib/noise_models/noise_models.py +119 -5
  90. cirq/contrib/noise_models/noise_models_test.py +37 -9
  91. cirq/contrib/paulistring/clifford_optimize.py +6 -4
  92. cirq/contrib/paulistring/clifford_optimize_test.py +6 -5
  93. cirq/contrib/paulistring/clifford_target_gateset.py +10 -10
  94. cirq/contrib/paulistring/clifford_target_gateset_test.py +13 -11
  95. cirq/contrib/paulistring/optimize.py +2 -0
  96. cirq/contrib/paulistring/optimize_test.py +4 -3
  97. cirq/contrib/paulistring/pauli_string_dag.py +2 -0
  98. cirq/contrib/paulistring/pauli_string_dag_test.py +3 -1
  99. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +255 -120
  100. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +398 -19
  101. cirq/contrib/paulistring/pauli_string_optimize.py +7 -1
  102. cirq/contrib/paulistring/pauli_string_optimize_test.py +5 -3
  103. cirq/contrib/paulistring/recombine.py +6 -4
  104. cirq/contrib/paulistring/recombine_test.py +3 -1
  105. cirq/contrib/paulistring/separate.py +9 -6
  106. cirq/contrib/paulistring/separate_test.py +3 -1
  107. cirq/contrib/qasm_import/_lexer.py +3 -2
  108. cirq/contrib/qasm_import/_lexer_test.py +49 -13
  109. cirq/contrib/qasm_import/_parser.py +547 -83
  110. cirq/contrib/qasm_import/_parser_test.py +988 -97
  111. cirq/contrib/qasm_import/exception.py +2 -0
  112. cirq/contrib/qasm_import/qasm.py +8 -2
  113. cirq/contrib/qasm_import/qasm_test.py +7 -4
  114. cirq/contrib/qcircuit/qcircuit_diagram_info.py +5 -5
  115. cirq/contrib/qcircuit/qcircuit_diagram_info_test.py +4 -1
  116. cirq/contrib/qcircuit/qcircuit_pdf.py +7 -3
  117. cirq/contrib/qcircuit/qcircuit_pdf_test.py +3 -1
  118. cirq/contrib/qcircuit/qcircuit_test.py +10 -8
  119. cirq/contrib/quantum_volume/quantum_volume.py +31 -27
  120. cirq/contrib/quantum_volume/quantum_volume_test.py +19 -16
  121. cirq/contrib/quimb/density_matrix.py +15 -14
  122. cirq/contrib/quimb/density_matrix_test.py +10 -7
  123. cirq/contrib/quimb/grid_circuits.py +5 -2
  124. cirq/contrib/quimb/grid_circuits_test.py +3 -0
  125. cirq/contrib/quimb/mps_simulator.py +20 -20
  126. cirq/contrib/quimb/mps_simulator_test.py +3 -0
  127. cirq/contrib/quimb/state_vector.py +12 -11
  128. cirq/contrib/quimb/state_vector_test.py +3 -0
  129. cirq/contrib/quirk/export_to_quirk.py +5 -3
  130. cirq/contrib/quirk/export_to_quirk_test.py +18 -16
  131. cirq/contrib/quirk/linearize_circuit.py +2 -0
  132. cirq/contrib/quirk/quirk_gate.py +18 -17
  133. cirq/contrib/routing/device.py +5 -3
  134. cirq/contrib/routing/device_test.py +2 -0
  135. cirq/contrib/routing/greedy.py +10 -21
  136. cirq/contrib/routing/greedy_test.py +4 -2
  137. cirq/contrib/routing/initialization.py +2 -2
  138. cirq/contrib/routing/initialization_test.py +5 -3
  139. cirq/contrib/routing/router.py +9 -5
  140. cirq/contrib/routing/router_test.py +2 -0
  141. cirq/contrib/routing/swap_network.py +3 -3
  142. cirq/contrib/routing/swap_network_test.py +3 -1
  143. cirq/contrib/routing/utils.py +2 -2
  144. cirq/contrib/routing/utils_test.py +3 -0
  145. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +15 -9
  146. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +3 -0
  147. cirq/contrib/svg/svg.py +3 -3
  148. cirq/contrib/svg/svg_test.py +8 -5
  149. cirq/devices/device.py +4 -4
  150. cirq/devices/device_test.py +7 -4
  151. cirq/devices/grid_device_metadata.py +10 -10
  152. cirq/devices/grid_device_metadata_test.py +3 -0
  153. cirq/devices/grid_qubit.py +29 -21
  154. cirq/devices/grid_qubit_test.py +3 -0
  155. cirq/devices/insertion_noise_model.py +7 -7
  156. cirq/devices/insertion_noise_model_test.py +7 -5
  157. cirq/devices/line_qubit.py +13 -13
  158. cirq/devices/line_qubit_test.py +2 -0
  159. cirq/devices/named_topologies.py +18 -29
  160. cirq/devices/named_topologies_test.py +13 -10
  161. cirq/devices/noise_model.py +3 -3
  162. cirq/devices/noise_model_test.py +19 -15
  163. cirq/devices/noise_properties.py +15 -6
  164. cirq/devices/noise_properties_test.py +34 -3
  165. cirq/devices/noise_utils.py +11 -9
  166. cirq/devices/noise_utils_test.py +2 -0
  167. cirq/devices/superconducting_qubits_noise_properties.py +23 -22
  168. cirq/devices/superconducting_qubits_noise_properties_test.py +6 -6
  169. cirq/devices/thermal_noise_model.py +107 -37
  170. cirq/devices/thermal_noise_model_test.py +21 -0
  171. cirq/devices/unconstrained_device.py +5 -3
  172. cirq/devices/unconstrained_device_test.py +2 -0
  173. cirq/experiments/__init__.py +4 -2
  174. cirq/experiments/benchmarking/__init__.py +17 -0
  175. cirq/experiments/benchmarking/parallel_xeb.py +677 -0
  176. cirq/experiments/benchmarking/parallel_xeb_test.py +447 -0
  177. cirq/experiments/fidelity_estimation.py +14 -8
  178. cirq/experiments/fidelity_estimation_test.py +3 -0
  179. cirq/experiments/n_qubit_tomography.py +17 -16
  180. cirq/experiments/n_qubit_tomography_test.py +8 -5
  181. cirq/experiments/purity_estimation.py +2 -0
  182. cirq/experiments/purity_estimation_test.py +2 -0
  183. cirq/experiments/qubit_characterizations.py +207 -103
  184. cirq/experiments/qubit_characterizations_test.py +40 -12
  185. cirq/experiments/random_quantum_circuit_generation.py +56 -70
  186. cirq/experiments/random_quantum_circuit_generation_test.py +11 -8
  187. cirq/experiments/readout_confusion_matrix.py +24 -22
  188. cirq/experiments/readout_confusion_matrix_test.py +2 -0
  189. cirq/experiments/single_qubit_readout_calibration.py +30 -15
  190. cirq/experiments/single_qubit_readout_calibration_test.py +5 -2
  191. cirq/experiments/t1_decay_experiment.py +9 -7
  192. cirq/experiments/t1_decay_experiment_test.py +13 -11
  193. cirq/experiments/t2_decay_experiment.py +16 -13
  194. cirq/experiments/t2_decay_experiment_test.py +2 -0
  195. cirq/experiments/two_qubit_xeb.py +64 -57
  196. cirq/experiments/two_qubit_xeb_test.py +10 -6
  197. cirq/experiments/xeb_fitting.py +39 -35
  198. cirq/experiments/xeb_sampling.py +37 -44
  199. cirq/experiments/xeb_sampling_test.py +3 -0
  200. cirq/experiments/xeb_simulation.py +14 -10
  201. cirq/experiments/xeb_simulation_test.py +5 -5
  202. cirq/experiments/z_phase_calibration.py +32 -29
  203. cirq/experiments/z_phase_calibration_test.py +3 -4
  204. cirq/interop/quirk/cells/__init__.py +1 -1
  205. cirq/interop/quirk/cells/all_cells.py +7 -2
  206. cirq/interop/quirk/cells/arithmetic_cells.py +29 -41
  207. cirq/interop/quirk/cells/arithmetic_cells_test.py +17 -14
  208. cirq/interop/quirk/cells/cell.py +19 -28
  209. cirq/interop/quirk/cells/cell_test.py +3 -0
  210. cirq/interop/quirk/cells/composite_cell.py +13 -28
  211. cirq/interop/quirk/cells/composite_cell_test.py +2 -0
  212. cirq/interop/quirk/cells/control_cells.py +15 -15
  213. cirq/interop/quirk/cells/control_cells_test.py +7 -5
  214. cirq/interop/quirk/cells/frequency_space_cells.py +4 -3
  215. cirq/interop/quirk/cells/frequency_space_cells_test.py +3 -1
  216. cirq/interop/quirk/cells/ignored_cells.py +3 -0
  217. cirq/interop/quirk/cells/ignored_cells_test.py +3 -1
  218. cirq/interop/quirk/cells/input_cells.py +7 -5
  219. cirq/interop/quirk/cells/input_cells_test.py +7 -5
  220. cirq/interop/quirk/cells/input_rotation_cells.py +15 -13
  221. cirq/interop/quirk/cells/input_rotation_cells_test.py +9 -7
  222. cirq/interop/quirk/cells/measurement_cells.py +5 -2
  223. cirq/interop/quirk/cells/measurement_cells_test.py +3 -1
  224. cirq/interop/quirk/cells/parse.py +22 -23
  225. cirq/interop/quirk/cells/parse_test.py +12 -10
  226. cirq/interop/quirk/cells/qubit_permutation_cells.py +5 -3
  227. cirq/interop/quirk/cells/qubit_permutation_cells_test.py +9 -7
  228. cirq/interop/quirk/cells/scalar_cells.py +4 -1
  229. cirq/interop/quirk/cells/scalar_cells_test.py +3 -1
  230. cirq/interop/quirk/cells/single_qubit_rotation_cells.py +5 -2
  231. cirq/interop/quirk/cells/single_qubit_rotation_cells_test.py +5 -3
  232. cirq/interop/quirk/cells/swap_cell.py +8 -6
  233. cirq/interop/quirk/cells/swap_cell_test.py +6 -4
  234. cirq/interop/quirk/cells/testing.py +6 -6
  235. cirq/interop/quirk/cells/testing_test.py +8 -6
  236. cirq/interop/quirk/cells/unsupported_cells.py +3 -0
  237. cirq/interop/quirk/cells/unsupported_cells_test.py +4 -2
  238. cirq/interop/quirk/url_to_circuit.py +23 -36
  239. cirq/interop/quirk/url_to_circuit_test.py +4 -1
  240. cirq/json_resolver_cache.py +14 -12
  241. cirq/linalg/__init__.py +4 -6
  242. cirq/linalg/combinators.py +7 -5
  243. cirq/linalg/combinators_test.py +10 -7
  244. cirq/linalg/decompositions.py +24 -35
  245. cirq/linalg/decompositions_test.py +3 -1
  246. cirq/linalg/diagonalize.py +6 -4
  247. cirq/linalg/diagonalize_test.py +15 -14
  248. cirq/linalg/operator_spaces.py +14 -14
  249. cirq/linalg/operator_spaces_test.py +13 -11
  250. cirq/linalg/predicates.py +18 -9
  251. cirq/linalg/predicates_test.py +5 -0
  252. cirq/linalg/tolerance.py +6 -3
  253. cirq/linalg/tolerance_test.py +6 -4
  254. cirq/linalg/transformations.py +23 -20
  255. cirq/linalg/transformations_test.py +73 -43
  256. cirq/neutral_atoms/convert_to_neutral_atom_gates.py +9 -3
  257. cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +3 -1
  258. cirq/neutral_atoms/neutral_atom_devices.py +2 -0
  259. cirq/ops/__init__.py +2 -0
  260. cirq/ops/arithmetic_operation.py +21 -21
  261. cirq/ops/arithmetic_operation_test.py +7 -8
  262. cirq/ops/boolean_hamiltonian.py +23 -22
  263. cirq/ops/boolean_hamiltonian_test.py +12 -9
  264. cirq/ops/classically_controlled_operation.py +31 -36
  265. cirq/ops/classically_controlled_operation_test.py +121 -117
  266. cirq/ops/clifford_gate.py +98 -81
  267. cirq/ops/clifford_gate_test.py +72 -57
  268. cirq/ops/common_channels.py +44 -44
  269. cirq/ops/common_channels_test.py +83 -81
  270. cirq/ops/common_gate_families.py +9 -7
  271. cirq/ops/common_gate_families_test.py +11 -7
  272. cirq/ops/common_gates.py +164 -183
  273. cirq/ops/common_gates_test.py +135 -95
  274. cirq/ops/control_values.py +23 -26
  275. cirq/ops/control_values_test.py +22 -20
  276. cirq/ops/controlled_gate.py +64 -112
  277. cirq/ops/controlled_gate_test.py +130 -35
  278. cirq/ops/controlled_operation.py +24 -35
  279. cirq/ops/controlled_operation_test.py +8 -6
  280. cirq/ops/dense_pauli_string.py +38 -49
  281. cirq/ops/dense_pauli_string_test.py +4 -2
  282. cirq/ops/diagonal_gate.py +18 -31
  283. cirq/ops/diagonal_gate_test.py +13 -13
  284. cirq/ops/eigen_gate.py +29 -29
  285. cirq/ops/eigen_gate_test.py +45 -28
  286. cirq/ops/fourier_transform.py +14 -20
  287. cirq/ops/fourier_transform_test.py +15 -12
  288. cirq/ops/fsim_gate.py +43 -42
  289. cirq/ops/fsim_gate_test.py +29 -29
  290. cirq/ops/gate_features.py +2 -0
  291. cirq/ops/gate_features_test.py +5 -3
  292. cirq/ops/gate_operation.py +43 -65
  293. cirq/ops/gate_operation_test.py +46 -42
  294. cirq/ops/gateset.py +28 -40
  295. cirq/ops/gateset_test.py +4 -2
  296. cirq/ops/global_phase_op.py +45 -20
  297. cirq/ops/global_phase_op_test.py +44 -20
  298. cirq/ops/greedy_qubit_manager.py +10 -8
  299. cirq/ops/greedy_qubit_manager_test.py +5 -3
  300. cirq/ops/identity.py +14 -12
  301. cirq/ops/identity_test.py +24 -20
  302. cirq/ops/kraus_channel.py +11 -8
  303. cirq/ops/kraus_channel_test.py +14 -11
  304. cirq/ops/linear_combinations.py +65 -77
  305. cirq/ops/linear_combinations_test.py +14 -9
  306. cirq/ops/matrix_gates.py +21 -18
  307. cirq/ops/matrix_gates_test.py +16 -0
  308. cirq/ops/measure_util.py +15 -20
  309. cirq/ops/measure_util_test.py +2 -0
  310. cirq/ops/measurement_gate.py +26 -37
  311. cirq/ops/measurement_gate_test.py +2 -0
  312. cirq/ops/mixed_unitary_channel.py +12 -9
  313. cirq/ops/mixed_unitary_channel_test.py +14 -11
  314. cirq/ops/named_qubit.py +16 -13
  315. cirq/ops/named_qubit_test.py +15 -13
  316. cirq/ops/op_tree.py +9 -7
  317. cirq/ops/op_tree_test.py +22 -19
  318. cirq/ops/parallel_gate.py +15 -17
  319. cirq/ops/parallel_gate_test.py +18 -16
  320. cirq/ops/parity_gates.py +23 -25
  321. cirq/ops/parity_gates_test.py +36 -32
  322. cirq/ops/pauli_gates.py +22 -21
  323. cirq/ops/pauli_gates_test.py +29 -20
  324. cirq/ops/pauli_interaction_gate.py +15 -19
  325. cirq/ops/pauli_interaction_gate_test.py +10 -8
  326. cirq/ops/pauli_measurement_gate.py +23 -35
  327. cirq/ops/pauli_measurement_gate_test.py +2 -0
  328. cirq/ops/pauli_string.py +92 -120
  329. cirq/ops/pauli_string_phasor.py +52 -45
  330. cirq/ops/pauli_string_phasor_test.py +4 -5
  331. cirq/ops/pauli_string_raw_types.py +9 -7
  332. cirq/ops/pauli_string_raw_types_test.py +2 -0
  333. cirq/ops/pauli_string_test.py +31 -154
  334. cirq/ops/pauli_sum_exponential.py +12 -12
  335. cirq/ops/pauli_sum_exponential_test.py +12 -10
  336. cirq/ops/permutation_gate.py +8 -6
  337. cirq/ops/permutation_gate_test.py +10 -8
  338. cirq/ops/phased_iswap_gate.py +16 -16
  339. cirq/ops/phased_iswap_gate_test.py +17 -15
  340. cirq/ops/phased_x_gate.py +16 -17
  341. cirq/ops/phased_x_gate_test.py +18 -16
  342. cirq/ops/phased_x_z_gate.py +24 -22
  343. cirq/ops/phased_x_z_gate_test.py +17 -11
  344. cirq/ops/projector.py +16 -11
  345. cirq/ops/projector_test.py +19 -16
  346. cirq/ops/qid_util.py +7 -5
  347. cirq/ops/qid_util_test.py +2 -0
  348. cirq/ops/qubit_manager.py +11 -9
  349. cirq/ops/qubit_manager_test.py +6 -4
  350. cirq/ops/qubit_order.py +11 -14
  351. cirq/ops/qubit_order_or_list.py +4 -2
  352. cirq/ops/qubit_order_test.py +12 -10
  353. cirq/ops/random_gate_channel.py +12 -10
  354. cirq/ops/random_gate_channel_test.py +14 -11
  355. cirq/ops/raw_types.py +109 -129
  356. cirq/ops/raw_types_test.py +63 -57
  357. cirq/ops/state_preparation_channel.py +7 -7
  358. cirq/ops/state_preparation_channel_test.py +11 -9
  359. cirq/ops/swap_gates.py +13 -15
  360. cirq/ops/swap_gates_test.py +19 -17
  361. cirq/ops/tags.py +5 -3
  362. cirq/ops/tags_test.py +4 -2
  363. cirq/ops/three_qubit_gates.py +43 -76
  364. cirq/ops/three_qubit_gates_test.py +19 -17
  365. cirq/ops/two_qubit_diagonal_gate.py +13 -13
  366. cirq/ops/two_qubit_diagonal_gate_test.py +10 -8
  367. cirq/ops/uniform_superposition_gate.py +5 -3
  368. cirq/ops/uniform_superposition_gate_test.py +5 -3
  369. cirq/ops/wait_gate.py +17 -14
  370. cirq/ops/wait_gate_test.py +9 -6
  371. cirq/protocols/__init__.py +0 -3
  372. cirq/protocols/act_on_protocol.py +8 -6
  373. cirq/protocols/act_on_protocol_test.py +15 -12
  374. cirq/protocols/apply_channel_protocol.py +10 -14
  375. cirq/protocols/apply_channel_protocol_test.py +2 -0
  376. cirq/protocols/apply_mixture_protocol.py +13 -42
  377. cirq/protocols/apply_mixture_protocol_test.py +7 -5
  378. cirq/protocols/apply_unitary_protocol.py +39 -34
  379. cirq/protocols/apply_unitary_protocol_test.py +4 -1
  380. cirq/protocols/approximate_equality_protocol.py +2 -0
  381. cirq/protocols/approximate_equality_protocol_test.py +2 -0
  382. cirq/protocols/circuit_diagram_info_protocol.py +58 -42
  383. cirq/protocols/circuit_diagram_info_protocol_test.py +70 -12
  384. cirq/protocols/commutes_protocol.py +8 -7
  385. cirq/protocols/commutes_protocol_test.py +2 -0
  386. cirq/protocols/control_key_protocol.py +6 -4
  387. cirq/protocols/control_key_protocol_test.py +3 -1
  388. cirq/protocols/decompose_protocol.py +49 -48
  389. cirq/protocols/decompose_protocol_test.py +27 -16
  390. cirq/protocols/equal_up_to_global_phase_protocol.py +2 -0
  391. cirq/protocols/equal_up_to_global_phase_protocol_test.py +9 -6
  392. cirq/protocols/has_stabilizer_effect_protocol.py +7 -5
  393. cirq/protocols/has_stabilizer_effect_protocol_test.py +7 -5
  394. cirq/protocols/has_unitary_protocol.py +10 -6
  395. cirq/protocols/has_unitary_protocol_test.py +13 -8
  396. cirq/protocols/hash_from_pickle_test.py +2 -11
  397. cirq/protocols/inverse_protocol.py +13 -16
  398. cirq/protocols/inverse_protocol_test.py +5 -3
  399. cirq/protocols/json_serialization.py +35 -54
  400. cirq/protocols/json_serialization_test.py +14 -21
  401. cirq/protocols/json_test_data/CXSWAP.json +46 -0
  402. cirq/protocols/json_test_data/CXSWAP.repr +13 -0
  403. cirq/protocols/json_test_data/CZSWAP.json +46 -0
  404. cirq/protocols/json_test_data/CZSWAP.repr +13 -0
  405. cirq/protocols/json_test_data/CircuitOperation.json +6 -3
  406. cirq/protocols/json_test_data/CircuitOperation.repr_inward +4 -2
  407. cirq/protocols/json_test_data/Moment.json +24 -1
  408. cirq/protocols/json_test_data/Moment.repr +6 -1
  409. cirq/protocols/json_test_data/ThermalNoiseModel.json +32 -0
  410. cirq/protocols/json_test_data/ThermalNoiseModel.repr +1 -0
  411. cirq/protocols/json_test_data/spec.py +6 -2
  412. cirq/protocols/kraus_protocol.py +47 -7
  413. cirq/protocols/kraus_protocol_test.py +86 -12
  414. cirq/protocols/measurement_key_protocol.py +15 -16
  415. cirq/protocols/measurement_key_protocol_test.py +13 -11
  416. cirq/protocols/mixture_protocol.py +7 -5
  417. cirq/protocols/mixture_protocol_test.py +4 -2
  418. cirq/protocols/mul_protocol.py +2 -3
  419. cirq/protocols/mul_protocol_test.py +2 -0
  420. cirq/protocols/pauli_expansion_protocol.py +6 -3
  421. cirq/protocols/pauli_expansion_protocol_test.py +5 -3
  422. cirq/protocols/phase_protocol.py +2 -0
  423. cirq/protocols/phase_protocol_test.py +3 -1
  424. cirq/protocols/pow_protocol.py +11 -16
  425. cirq/protocols/pow_protocol_test.py +2 -0
  426. cirq/protocols/qasm.py +14 -20
  427. cirq/protocols/qasm_test.py +6 -3
  428. cirq/protocols/qid_shape_protocol.py +8 -8
  429. cirq/protocols/qid_shape_protocol_test.py +3 -1
  430. cirq/protocols/resolve_parameters.py +5 -3
  431. cirq/protocols/resolve_parameters_test.py +8 -7
  432. cirq/protocols/trace_distance_bound.py +6 -4
  433. cirq/protocols/trace_distance_bound_test.py +3 -1
  434. cirq/protocols/unitary_protocol.py +17 -7
  435. cirq/protocols/unitary_protocol_test.py +12 -2
  436. cirq/qis/channels.py +6 -2
  437. cirq/qis/channels_test.py +20 -16
  438. cirq/qis/clifford_tableau.py +21 -19
  439. cirq/qis/clifford_tableau_test.py +2 -2
  440. cirq/qis/entropy.py +14 -3
  441. cirq/qis/entropy_test.py +3 -1
  442. cirq/qis/measures.py +13 -13
  443. cirq/qis/measures_test.py +20 -14
  444. cirq/qis/noise_utils.py +2 -0
  445. cirq/qis/noise_utils_test.py +9 -7
  446. cirq/qis/quantum_state_representation.py +7 -8
  447. cirq/qis/states.py +58 -56
  448. cirq/qis/states_test.py +2 -0
  449. cirq/sim/classical_simulator.py +23 -22
  450. cirq/sim/classical_simulator_test.py +2 -0
  451. cirq/sim/clifford/clifford_simulator.py +23 -21
  452. cirq/sim/clifford/clifford_simulator_test.py +7 -4
  453. cirq/sim/clifford/clifford_tableau_simulation_state.py +10 -7
  454. cirq/sim/clifford/clifford_tableau_simulation_state_test.py +5 -5
  455. cirq/sim/clifford/stabilizer_ch_form_simulation_state.py +8 -6
  456. cirq/sim/clifford/stabilizer_ch_form_simulation_state_test.py +8 -6
  457. cirq/sim/clifford/stabilizer_sampler.py +9 -7
  458. cirq/sim/clifford/stabilizer_sampler_test.py +4 -2
  459. cirq/sim/clifford/stabilizer_simulation_state.py +14 -13
  460. cirq/sim/clifford/stabilizer_simulation_state_test.py +6 -4
  461. cirq/sim/clifford/stabilizer_state_ch_form.py +13 -11
  462. cirq/sim/clifford/stabilizer_state_ch_form_test.py +4 -2
  463. cirq/sim/density_matrix_simulation_state.py +26 -27
  464. cirq/sim/density_matrix_simulation_state_test.py +10 -8
  465. cirq/sim/density_matrix_simulator.py +30 -28
  466. cirq/sim/density_matrix_simulator_test.py +48 -48
  467. cirq/sim/density_matrix_utils.py +13 -11
  468. cirq/sim/density_matrix_utils_test.py +38 -36
  469. cirq/sim/mux.py +33 -31
  470. cirq/sim/mux_test.py +3 -0
  471. cirq/sim/simulation_product_state.py +15 -15
  472. cirq/sim/simulation_product_state_test.py +29 -26
  473. cirq/sim/simulation_state.py +29 -38
  474. cirq/sim/simulation_state_base.py +21 -32
  475. cirq/sim/simulation_state_test.py +15 -13
  476. cirq/sim/simulation_utils.py +5 -2
  477. cirq/sim/simulation_utils_test.py +5 -2
  478. cirq/sim/simulator.py +90 -106
  479. cirq/sim/simulator_base.py +33 -45
  480. cirq/sim/simulator_base_test.py +20 -15
  481. cirq/sim/simulator_test.py +23 -14
  482. cirq/sim/sparse_simulator.py +19 -17
  483. cirq/sim/sparse_simulator_test.py +41 -40
  484. cirq/sim/state_vector.py +15 -12
  485. cirq/sim/state_vector_simulation_state.py +31 -31
  486. cirq/sim/state_vector_simulation_state_test.py +16 -14
  487. cirq/sim/state_vector_simulator.py +17 -14
  488. cirq/sim/state_vector_simulator_test.py +2 -0
  489. cirq/sim/state_vector_test.py +6 -3
  490. cirq/study/flatten_expressions.py +16 -15
  491. cirq/study/flatten_expressions_test.py +13 -11
  492. cirq/study/resolver.py +18 -17
  493. cirq/study/resolver_test.py +22 -20
  494. cirq/study/result.py +17 -27
  495. cirq/study/result_test.py +2 -0
  496. cirq/study/sweepable.py +12 -10
  497. cirq/study/sweepable_test.py +3 -0
  498. cirq/study/sweeps.py +42 -61
  499. cirq/study/sweeps_test.py +33 -0
  500. cirq/testing/__init__.py +7 -11
  501. cirq/testing/_compat_test_data/module_a/__init__.py +1 -0
  502. cirq/testing/_compat_test_data/module_a/module_b/__init__.py +1 -0
  503. cirq/testing/_compat_test_data/module_a/sub/__init__.py +1 -0
  504. cirq/testing/circuit_compare.py +8 -17
  505. cirq/testing/circuit_compare_test.py +2 -0
  506. cirq/testing/consistent_act_on.py +13 -11
  507. cirq/testing/consistent_act_on_test.py +5 -3
  508. cirq/testing/consistent_channels.py +2 -0
  509. cirq/testing/consistent_channels_test.py +10 -8
  510. cirq/testing/consistent_controlled_gate_op.py +5 -5
  511. cirq/testing/consistent_controlled_gate_op_test.py +18 -18
  512. cirq/testing/consistent_decomposition.py +2 -2
  513. cirq/testing/consistent_decomposition_test.py +4 -2
  514. cirq/testing/consistent_pauli_expansion.py +2 -0
  515. cirq/testing/consistent_pauli_expansion_test.py +3 -1
  516. cirq/testing/consistent_phase_by.py +2 -0
  517. cirq/testing/consistent_phase_by_test.py +3 -1
  518. cirq/testing/consistent_protocols.py +14 -20
  519. cirq/testing/consistent_protocols_test.py +13 -11
  520. cirq/testing/consistent_qasm.py +6 -4
  521. cirq/testing/consistent_qasm_test.py +7 -7
  522. cirq/testing/consistent_resolve_parameters.py +2 -0
  523. cirq/testing/consistent_specified_has_unitary.py +2 -2
  524. cirq/testing/consistent_specified_has_unitary_test.py +6 -4
  525. cirq/testing/consistent_unitary.py +1 -0
  526. cirq/testing/consistent_unitary_test.py +4 -2
  527. cirq/testing/deprecation.py +5 -2
  528. cirq/testing/deprecation_test.py +5 -2
  529. cirq/testing/devices.py +7 -4
  530. cirq/testing/devices_test.py +7 -4
  531. cirq/testing/equals_tester.py +4 -2
  532. cirq/testing/equals_tester_test.py +21 -17
  533. cirq/testing/equivalent_basis_map.py +6 -4
  534. cirq/testing/equivalent_basis_map_test.py +6 -4
  535. cirq/testing/equivalent_repr_eval.py +6 -4
  536. cirq/testing/equivalent_repr_eval_test.py +5 -3
  537. cirq/testing/gate_features.py +2 -0
  538. cirq/testing/gate_features_test.py +7 -5
  539. cirq/testing/json.py +19 -15
  540. cirq/testing/json_test.py +5 -3
  541. cirq/testing/lin_alg_utils.py +10 -11
  542. cirq/testing/lin_alg_utils_test.py +14 -12
  543. cirq/testing/logs.py +7 -6
  544. cirq/testing/logs_test.py +9 -7
  545. cirq/testing/no_identifier_qubit.py +4 -2
  546. cirq/testing/no_identifier_qubit_test.py +5 -3
  547. cirq/testing/op_tree.py +2 -0
  548. cirq/testing/op_tree_test.py +4 -1
  549. cirq/testing/order_tester.py +2 -0
  550. cirq/testing/order_tester_test.py +8 -6
  551. cirq/testing/pytest_utils.py +2 -0
  552. cirq/testing/pytest_utils_test.py +4 -2
  553. cirq/testing/random_circuit.py +21 -20
  554. cirq/testing/random_circuit_test.py +12 -9
  555. cirq/testing/repr_pretty_tester.py +1 -0
  556. cirq/testing/repr_pretty_tester_test.py +5 -3
  557. cirq/testing/routing_devices.py +4 -1
  558. cirq/testing/routing_devices_test.py +9 -6
  559. cirq/testing/sample_circuits.py +4 -1
  560. cirq/testing/sample_circuits_test.py +3 -1
  561. cirq/testing/sample_gates.py +3 -0
  562. cirq/testing/sample_gates_test.py +5 -2
  563. cirq/transformers/__init__.py +11 -4
  564. cirq/transformers/align.py +9 -7
  565. cirq/transformers/align_test.py +2 -0
  566. cirq/transformers/analytical_decompositions/__init__.py +3 -6
  567. cirq/transformers/analytical_decompositions/clifford_decomposition.py +18 -16
  568. cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +2 -0
  569. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +19 -16
  570. cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
  571. cirq/transformers/analytical_decompositions/cphase_to_fsim.py +11 -9
  572. cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +5 -3
  573. cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +5 -3
  574. cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +5 -3
  575. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +141 -44
  576. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +35 -1
  577. cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +8 -7
  578. cirq/transformers/analytical_decompositions/single_qubit_decompositions_test.py +2 -0
  579. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +7 -4
  580. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +3 -0
  581. cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +11 -19
  582. cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +8 -33
  583. cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +9 -11
  584. cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -0
  585. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +91 -27
  586. cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +36 -7
  587. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +20 -21
  588. cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +8 -6
  589. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +13 -15
  590. cirq/transformers/analytical_decompositions/two_qubit_to_ms_test.py +3 -1
  591. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +39 -41
  592. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -0
  593. cirq/transformers/drop_empty_moments.py +5 -3
  594. cirq/transformers/drop_empty_moments_test.py +4 -2
  595. cirq/transformers/drop_negligible_operations.py +7 -5
  596. cirq/transformers/drop_negligible_operations_test.py +2 -0
  597. cirq/transformers/dynamical_decoupling.py +49 -42
  598. cirq/transformers/dynamical_decoupling_test.py +223 -205
  599. cirq/transformers/eject_phased_paulis.py +28 -26
  600. cirq/transformers/eject_phased_paulis_test.py +12 -9
  601. cirq/transformers/eject_z.py +12 -12
  602. cirq/transformers/eject_z_test.py +2 -2
  603. cirq/transformers/expand_composite.py +6 -4
  604. cirq/transformers/expand_composite_test.py +3 -1
  605. cirq/transformers/gauge_compiling/__init__.py +3 -1
  606. cirq/transformers/gauge_compiling/cphase_gauge.py +2 -0
  607. cirq/transformers/gauge_compiling/cphase_gauge_test.py +2 -0
  608. cirq/transformers/gauge_compiling/cz_gauge.py +2 -0
  609. cirq/transformers/gauge_compiling/cz_gauge_test.py +1 -0
  610. cirq/transformers/gauge_compiling/gauge_compiling.py +45 -41
  611. cirq/transformers/gauge_compiling/gauge_compiling_test.py +2 -0
  612. cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +1 -0
  613. cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +5 -1
  614. cirq/transformers/gauge_compiling/iswap_gauge.py +2 -0
  615. cirq/transformers/gauge_compiling/iswap_gauge_test.py +1 -0
  616. cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -0
  617. cirq/transformers/gauge_compiling/spin_inversion_gauge_test.py +2 -0
  618. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +7 -6
  619. cirq/transformers/gauge_compiling/sqrt_cz_gauge_test.py +2 -0
  620. cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +2 -0
  621. cirq/transformers/gauge_compiling/sqrt_iswap_gauge_test.py +2 -0
  622. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +6 -3
  623. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +3 -0
  624. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +12 -9
  625. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +9 -7
  626. cirq/transformers/insertion_sort.py +8 -6
  627. cirq/transformers/insertion_sort_test.py +3 -1
  628. cirq/transformers/measurement_transformers.py +29 -29
  629. cirq/transformers/measurement_transformers_test.py +2 -0
  630. cirq/transformers/merge_k_qubit_gates.py +12 -10
  631. cirq/transformers/merge_k_qubit_gates_test.py +18 -18
  632. cirq/transformers/merge_single_qubit_gates.py +197 -20
  633. cirq/transformers/merge_single_qubit_gates_test.py +177 -5
  634. cirq/transformers/noise_adding.py +5 -3
  635. cirq/transformers/noise_adding_test.py +2 -0
  636. cirq/transformers/optimize_for_target_gateset.py +19 -17
  637. cirq/transformers/optimize_for_target_gateset_test.py +11 -8
  638. cirq/transformers/qubit_management_transformers.py +13 -11
  639. cirq/transformers/qubit_management_transformers_test.py +5 -3
  640. cirq/transformers/randomized_measurements.py +16 -14
  641. cirq/transformers/randomized_measurements_test.py +10 -4
  642. cirq/transformers/routing/initial_mapper.py +6 -4
  643. cirq/transformers/routing/initial_mapper_test.py +2 -0
  644. cirq/transformers/routing/line_initial_mapper.py +16 -14
  645. cirq/transformers/routing/line_initial_mapper_test.py +9 -7
  646. cirq/transformers/routing/mapping_manager.py +10 -10
  647. cirq/transformers/routing/mapping_manager_test.py +2 -0
  648. cirq/transformers/routing/route_circuit_cqc.py +33 -31
  649. cirq/transformers/routing/route_circuit_cqc_test.py +15 -13
  650. cirq/transformers/routing/visualize_routed_circuit.py +8 -7
  651. cirq/transformers/routing/visualize_routed_circuit_test.py +4 -2
  652. cirq/transformers/stratify.py +17 -15
  653. cirq/transformers/stratify_test.py +3 -0
  654. cirq/transformers/symbolize.py +103 -0
  655. cirq/transformers/symbolize_test.py +62 -0
  656. cirq/transformers/synchronize_terminal_measurements.py +10 -10
  657. cirq/transformers/synchronize_terminal_measurements_test.py +12 -10
  658. cirq/transformers/tag_transformers.py +97 -0
  659. cirq/transformers/tag_transformers_test.py +103 -0
  660. cirq/transformers/target_gatesets/compilation_target_gateset.py +21 -19
  661. cirq/transformers/target_gatesets/compilation_target_gateset_test.py +20 -16
  662. cirq/transformers/target_gatesets/cz_gateset.py +7 -5
  663. cirq/transformers/target_gatesets/cz_gateset_test.py +21 -19
  664. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +9 -7
  665. cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +25 -25
  666. cirq/transformers/transformer_api.py +34 -47
  667. cirq/transformers/transformer_api_test.py +9 -8
  668. cirq/transformers/transformer_primitives.py +39 -49
  669. cirq/transformers/transformer_primitives_test.py +10 -17
  670. cirq/value/abc_alt.py +6 -4
  671. cirq/value/abc_alt_test.py +5 -3
  672. cirq/value/angle.py +11 -12
  673. cirq/value/angle_test.py +5 -3
  674. cirq/value/classical_data.py +27 -27
  675. cirq/value/classical_data_test.py +11 -8
  676. cirq/value/condition.py +26 -24
  677. cirq/value/condition_test.py +2 -0
  678. cirq/value/digits.py +14 -11
  679. cirq/value/digits_test.py +2 -0
  680. cirq/value/duration.py +23 -20
  681. cirq/value/duration_test.py +2 -0
  682. cirq/value/linear_dict.py +25 -30
  683. cirq/value/linear_dict_test.py +10 -8
  684. cirq/value/measurement_key.py +12 -12
  685. cirq/value/measurement_key_test.py +2 -0
  686. cirq/value/periodic_value.py +4 -4
  687. cirq/value/periodic_value_test.py +11 -7
  688. cirq/value/probability.py +3 -1
  689. cirq/value/probability_test.py +4 -2
  690. cirq/value/product_state.py +15 -13
  691. cirq/value/product_state_test.py +4 -1
  692. cirq/value/random_state.py +2 -0
  693. cirq/value/random_state_test.py +5 -3
  694. cirq/value/timestamp.py +11 -7
  695. cirq/value/timestamp_test.py +14 -12
  696. cirq/value/type_alias.py +4 -4
  697. cirq/value/value_equality_attr.py +8 -9
  698. cirq/value/value_equality_attr_test.py +14 -11
  699. cirq/vis/density_matrix.py +3 -3
  700. cirq/vis/density_matrix_test.py +20 -17
  701. cirq/vis/heatmap.py +24 -37
  702. cirq/vis/heatmap_test.py +3 -0
  703. cirq/vis/histogram.py +9 -6
  704. cirq/vis/histogram_test.py +5 -2
  705. cirq/vis/state_histogram.py +10 -8
  706. cirq/vis/state_histogram_test.py +7 -5
  707. cirq/vis/vis_utils.py +4 -1
  708. cirq/vis/vis_utils_test.py +4 -1
  709. cirq/work/collector.py +12 -18
  710. cirq/work/collector_test.py +15 -10
  711. cirq/work/observable_grouping.py +6 -7
  712. cirq/work/observable_grouping_test.py +10 -9
  713. cirq/work/observable_measurement.py +47 -45
  714. cirq/work/observable_measurement_data.py +22 -17
  715. cirq/work/observable_measurement_data_test.py +4 -1
  716. cirq/work/observable_measurement_test.py +48 -29
  717. cirq/work/observable_readout_calibration.py +5 -2
  718. cirq/work/observable_readout_calibration_test.py +5 -2
  719. cirq/work/observable_settings.py +13 -22
  720. cirq/work/observable_settings_test.py +9 -7
  721. cirq/work/pauli_sum_collector.py +12 -10
  722. cirq/work/pauli_sum_collector_test.py +9 -9
  723. cirq/work/sampler.py +42 -43
  724. cirq/work/sampler_test.py +31 -24
  725. cirq/work/zeros_sampler.py +6 -4
  726. cirq/work/zeros_sampler_test.py +7 -5
  727. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/METADATA +7 -8
  728. cirq_core-1.6.0.dist-info/RECORD +1241 -0
  729. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/WHEEL +1 -1
  730. cirq_core-1.5.0.dev20250409222543.dist-info/RECORD +0 -1216
  731. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/licenses/LICENSE +0 -0
  732. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/top_level.txt +0 -0
@@ -20,7 +20,9 @@ References:
20
20
  https://arxiv.org/abs/2105.06074
21
21
  """
22
22
 
23
- from typing import Optional, Sequence, Tuple, TYPE_CHECKING
23
+ from __future__ import annotations
24
+
25
+ from typing import Sequence, TYPE_CHECKING
24
26
 
25
27
  import numpy as np
26
28
  import sympy
@@ -34,7 +36,7 @@ if TYPE_CHECKING:
34
36
 
35
37
 
36
38
  def parameterized_2q_op_to_sqrt_iswap_operations(
37
- op: 'cirq.Operation', *, use_sqrt_iswap_inv: bool = False
39
+ op: cirq.Operation, *, use_sqrt_iswap_inv: bool = False
38
40
  ) -> protocols.decompose_protocol.DecomposeResult:
39
41
  """Tries to decompose a parameterized 2q operation into √iSWAP's + parameterized 1q rotations.
40
42
 
@@ -68,9 +70,7 @@ def parameterized_2q_op_to_sqrt_iswap_operations(
68
70
  return NotImplemented
69
71
 
70
72
 
71
- def _sqrt_iswap_inv(
72
- a: 'cirq.Qid', b: 'cirq.Qid', use_sqrt_iswap_inv: bool = True
73
- ) -> 'cirq.OP_TREE':
73
+ def _sqrt_iswap_inv(a: cirq.Qid, b: cirq.Qid, use_sqrt_iswap_inv: bool = True) -> cirq.OP_TREE:
74
74
  """Optree implementing `cirq.SQRT_ISWAP_INV(a, b)` using √iSWAPs.
75
75
 
76
76
  Args:
@@ -89,7 +89,7 @@ def _sqrt_iswap_inv(
89
89
 
90
90
 
91
91
  def _cphase_symbols_to_sqrt_iswap(
92
- a: 'cirq.Qid', b: 'cirq.Qid', turns: 'cirq.TParamVal', use_sqrt_iswap_inv: bool = True
92
+ a: cirq.Qid, b: cirq.Qid, turns: cirq.TParamVal, use_sqrt_iswap_inv: bool = True
93
93
  ):
94
94
  """Implements `cirq.CZ(a, b) ** turns` using two √iSWAPs and single qubit rotations.
95
95
 
@@ -136,7 +136,7 @@ def _cphase_symbols_to_sqrt_iswap(
136
136
 
137
137
 
138
138
  def _swap_symbols_to_sqrt_iswap(
139
- a: 'cirq.Qid', b: 'cirq.Qid', turns: 'cirq.TParamVal', use_sqrt_iswap_inv: bool = True
139
+ a: cirq.Qid, b: cirq.Qid, turns: cirq.TParamVal, use_sqrt_iswap_inv: bool = True
140
140
  ):
141
141
  """Implements `cirq.SWAP(a, b) ** turns` using two √iSWAPs and single qubit rotations.
142
142
 
@@ -170,7 +170,7 @@ def _swap_symbols_to_sqrt_iswap(
170
170
 
171
171
 
172
172
  def _iswap_symbols_to_sqrt_iswap(
173
- a: 'cirq.Qid', b: 'cirq.Qid', turns: 'cirq.TParamVal', use_sqrt_iswap_inv: bool = True
173
+ a: cirq.Qid, b: cirq.Qid, turns: cirq.TParamVal, use_sqrt_iswap_inv: bool = True
174
174
  ):
175
175
  """Implements `cirq.ISWAP(a, b) ** turns` using two √iSWAPs and single qubit rotations.
176
176
 
@@ -202,10 +202,10 @@ def _iswap_symbols_to_sqrt_iswap(
202
202
 
203
203
 
204
204
  def _fsim_symbols_to_sqrt_iswap(
205
- a: 'cirq.Qid',
206
- b: 'cirq.Qid',
207
- theta: 'cirq.TParamVal',
208
- phi: 'cirq.TParamVal',
205
+ a: cirq.Qid,
206
+ b: cirq.Qid,
207
+ theta: cirq.TParamVal,
208
+ phi: cirq.TParamVal,
209
209
  use_sqrt_iswap_inv: bool = True,
210
210
  ):
211
211
  """Implements `cirq.FSimGate(theta, phi)(a, b)` using two √iSWAPs and single qubit rotations.
@@ -229,16 +229,16 @@ def _fsim_symbols_to_sqrt_iswap(
229
229
 
230
230
 
231
231
  def two_qubit_matrix_to_sqrt_iswap_operations(
232
- q0: 'cirq.Qid',
233
- q1: 'cirq.Qid',
232
+ q0: cirq.Qid,
233
+ q1: cirq.Qid,
234
234
  mat: np.ndarray,
235
235
  *,
236
- required_sqrt_iswap_count: Optional[int] = None,
236
+ required_sqrt_iswap_count: int | None = None,
237
237
  use_sqrt_iswap_inv: bool = False,
238
238
  atol: float = 1e-8,
239
239
  check_preconditions: bool = True,
240
240
  clean_operations: bool = False,
241
- ) -> Sequence['cirq.Operation']:
241
+ ) -> Sequence[cirq.Operation]:
242
242
  """Decomposes a two-qubit operation into ZPow/XPow/YPow/sqrt-iSWAP gates.
243
243
 
244
244
  This method uses the KAK decomposition of the matrix to determine how many
@@ -300,13 +300,13 @@ def two_qubit_matrix_to_sqrt_iswap_operations(
300
300
 
301
301
 
302
302
  def _kak_decomposition_to_sqrt_iswap_operations(
303
- q0: 'cirq.Qid',
304
- q1: 'cirq.Qid',
303
+ q0: cirq.Qid,
304
+ q1: cirq.Qid,
305
305
  kak: linalg.KakDecomposition,
306
- required_sqrt_iswap_count: Optional[int] = None,
306
+ required_sqrt_iswap_count: int | None = None,
307
307
  use_sqrt_iswap_inv: bool = False,
308
308
  atol: float = 1e-8,
309
- ) -> Sequence['cirq.Operation']:
309
+ ) -> Sequence[cirq.Operation]:
310
310
  single_qubit_operations, _ = _single_qubit_matrices_with_sqrt_iswap(
311
311
  kak, required_sqrt_iswap_count, atol=atol
312
312
  )
@@ -325,14 +325,14 @@ def _kak_decomposition_to_sqrt_iswap_operations(
325
325
 
326
326
 
327
327
  def _decomp_to_operations(
328
- q0: 'cirq.Qid',
329
- q1: 'cirq.Qid',
330
- two_qubit_gate: 'cirq.Gate',
331
- single_qubit_operations: Sequence[Tuple[np.ndarray, np.ndarray]],
328
+ q0: cirq.Qid,
329
+ q1: cirq.Qid,
330
+ two_qubit_gate: cirq.Gate,
331
+ single_qubit_operations: Sequence[tuple[np.ndarray, np.ndarray]],
332
332
  u0_before: np.ndarray = np.eye(2),
333
333
  u0_after: np.ndarray = np.eye(2),
334
334
  atol: float = 1e-8,
335
- ) -> Sequence['cirq.Operation']:
335
+ ) -> Sequence[cirq.Operation]:
336
336
  """Converts a sequence of single-qubit unitary matrices on two qubits into a
337
337
  list of operations with interleaved two-qubit gates."""
338
338
  two_qubit_op = two_qubit_gate(q0, q1)
@@ -401,10 +401,8 @@ def _decomp_to_operations(
401
401
 
402
402
 
403
403
  def _single_qubit_matrices_with_sqrt_iswap(
404
- kak: 'cirq.KakDecomposition',
405
- required_sqrt_iswap_count: Optional[int] = None,
406
- atol: float = 1e-8,
407
- ) -> Tuple[Sequence[Tuple[np.ndarray, np.ndarray]], complex]:
404
+ kak: cirq.KakDecomposition, required_sqrt_iswap_count: int | None = None, atol: float = 1e-8
405
+ ) -> tuple[Sequence[tuple[np.ndarray, np.ndarray]], complex]:
408
406
  """Computes the sequence of interleaved single-qubit unitary matrices in the
409
407
  sqrt-iSWAP decomposition."""
410
408
  decomposers = [
@@ -430,7 +428,7 @@ def _single_qubit_matrices_with_sqrt_iswap(
430
428
 
431
429
 
432
430
  def _in_0_region(
433
- interaction_coefficients: Tuple[float, float, float], weyl_tol: float = 1e-8
431
+ interaction_coefficients: tuple[float, float, float], weyl_tol: float = 1e-8
434
432
  ) -> bool:
435
433
  """Tests if (x, y, z) ~= (0, 0, 0) assuming x, y, z are canonical."""
436
434
  x, y, z = interaction_coefficients
@@ -438,7 +436,7 @@ def _in_0_region(
438
436
 
439
437
 
440
438
  def _in_1sqrt_iswap_region(
441
- interaction_coefficients: Tuple[float, float, float], weyl_tol: float = 1e-8
439
+ interaction_coefficients: tuple[float, float, float], weyl_tol: float = 1e-8
442
440
  ) -> bool:
443
441
  """Tests if (x, y, z) ~= (π/8, π/8, 0), assuming x, y, z are canonical."""
444
442
  x, y, z = interaction_coefficients
@@ -446,7 +444,7 @@ def _in_1sqrt_iswap_region(
446
444
 
447
445
 
448
446
  def _in_2sqrt_iswap_region(
449
- interaction_coefficients: Tuple[float, float, float], weyl_tol: float = 1e-8
447
+ interaction_coefficients: tuple[float, float, float], weyl_tol: float = 1e-8
450
448
  ) -> bool:
451
449
  """Tests if (x, y, z) is inside or within weyl_tol of the volume
452
450
  x >= y + |z| assuming x, y, z are canonical.
@@ -463,7 +461,7 @@ def _in_2sqrt_iswap_region(
463
461
 
464
462
 
465
463
  def _in_3sqrt_iswap_region(
466
- interaction_coefficients: Tuple[float, float, float], weyl_tol: float = 1e-8
464
+ interaction_coefficients: tuple[float, float, float], weyl_tol: float = 1e-8
467
465
  ) -> bool:
468
466
  """Any two-qubit operation is decomposable into three SQRT_ISWAP gates.
469
467
 
@@ -476,8 +474,8 @@ def _in_3sqrt_iswap_region(
476
474
 
477
475
 
478
476
  def _decomp_0_matrices(
479
- kak: 'cirq.KakDecomposition', atol: float = 1e-8
480
- ) -> Tuple[Sequence[Tuple[np.ndarray, np.ndarray]], complex]:
477
+ kak: cirq.KakDecomposition, atol: float = 1e-8
478
+ ) -> tuple[Sequence[tuple[np.ndarray, np.ndarray]], complex]:
481
479
  """Returns the single-qubit matrices for the 0-SQRT_ISWAP decomposition.
482
480
 
483
481
  Assumes canonical x, y, z and (x, y, z) = (0, 0, 0) within tolerance.
@@ -494,8 +492,8 @@ def _decomp_0_matrices(
494
492
 
495
493
 
496
494
  def _decomp_1sqrt_iswap_matrices(
497
- kak: 'cirq.KakDecomposition', atol: float = 1e-8
498
- ) -> Tuple[Sequence[Tuple[np.ndarray, np.ndarray]], complex]:
495
+ kak: cirq.KakDecomposition, atol: float = 1e-8
496
+ ) -> tuple[Sequence[tuple[np.ndarray, np.ndarray]], complex]:
499
497
  """Returns the single-qubit matrices for the 1-SQRT_ISWAP decomposition.
500
498
 
501
499
  Assumes canonical x, y, z and (x, y, z) = (π/8, π/8, 0) within tolerance.
@@ -507,8 +505,8 @@ def _decomp_1sqrt_iswap_matrices(
507
505
 
508
506
 
509
507
  def _decomp_2sqrt_iswap_matrices(
510
- kak: 'cirq.KakDecomposition', atol: float = 1e-8
511
- ) -> Tuple[Sequence[Tuple[np.ndarray, np.ndarray]], complex]:
508
+ kak: cirq.KakDecomposition, atol: float = 1e-8
509
+ ) -> tuple[Sequence[tuple[np.ndarray, np.ndarray]], complex]:
512
510
  """Returns the single-qubit matrices for the 2-SQRT_ISWAP decomposition.
513
511
 
514
512
  Assumes canonical x, y, z and x >= y + |z| within tolerance. For x, y, z
@@ -570,8 +568,8 @@ def _decomp_2sqrt_iswap_matrices(
570
568
 
571
569
 
572
570
  def _decomp_3sqrt_iswap_matrices(
573
- kak: 'cirq.KakDecomposition', atol: float = 1e-8
574
- ) -> Tuple[Sequence[Tuple[np.ndarray, np.ndarray]], complex]:
571
+ kak: cirq.KakDecomposition, atol: float = 1e-8
572
+ ) -> tuple[Sequence[tuple[np.ndarray, np.ndarray]], complex]:
575
573
  """Returns the single-qubit matrices for the 3-SQRT_ISWAP decomposition.
576
574
 
577
575
  Assumes any canonical x, y, z. Three sqrt-iSWAP gates are only needed if
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import itertools
16
18
 
17
19
  import numpy as np
@@ -14,7 +14,9 @@
14
14
 
15
15
  """Transformer pass that removes empty moments from a circuit."""
16
16
 
17
- from typing import Optional, TYPE_CHECKING
17
+ from __future__ import annotations
18
+
19
+ from typing import TYPE_CHECKING
18
20
 
19
21
  from cirq.transformers import transformer_api, transformer_primitives
20
22
 
@@ -24,8 +26,8 @@ if TYPE_CHECKING:
24
26
 
25
27
  @transformer_api.transformer
26
28
  def drop_empty_moments(
27
- circuit: 'cirq.AbstractCircuit', *, context: Optional['cirq.TransformerContext'] = None
28
- ) -> 'cirq.Circuit':
29
+ circuit: cirq.AbstractCircuit, *, context: cirq.TransformerContext | None = None
30
+ ) -> cirq.Circuit:
29
31
  """Removes empty moments from a circuit.
30
32
 
31
33
  Args:
@@ -12,10 +12,12 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import cirq
16
18
 
17
19
 
18
- def test_drop():
20
+ def test_drop() -> None:
19
21
  q1 = cirq.NamedQubit('q1')
20
22
  q2 = cirq.NamedQubit('q2')
21
23
  cirq.testing.assert_same_circuits(
@@ -28,7 +30,7 @@ def test_drop():
28
30
  )
29
31
 
30
32
 
31
- def test_drop_empty_moments():
33
+ def test_drop_empty_moments() -> None:
32
34
  q1, q2 = cirq.LineQubit.range(2)
33
35
  c_nested = cirq.FrozenCircuit(
34
36
  cirq.Moment(), cirq.Moment(), cirq.Moment([cirq.CNOT(q1, q2)]), cirq.Moment()
@@ -14,7 +14,9 @@
14
14
 
15
15
  """Transformer pass that removes operations with tiny effects."""
16
16
 
17
- from typing import Optional, TYPE_CHECKING
17
+ from __future__ import annotations
18
+
19
+ from typing import TYPE_CHECKING
18
20
 
19
21
  from cirq import protocols
20
22
  from cirq.transformers import transformer_api, transformer_primitives
@@ -25,11 +27,11 @@ if TYPE_CHECKING:
25
27
 
26
28
  @transformer_api.transformer
27
29
  def drop_negligible_operations(
28
- circuit: 'cirq.AbstractCircuit',
30
+ circuit: cirq.AbstractCircuit,
29
31
  *,
30
- context: Optional['cirq.TransformerContext'] = None,
32
+ context: cirq.TransformerContext | None = None,
31
33
  atol: float = 1e-8,
32
- ) -> 'cirq.Circuit':
34
+ ) -> cirq.Circuit:
33
35
  """Removes operations with tiny effects.
34
36
 
35
37
  An operation `op` is considered to have a tiny effect if
@@ -47,7 +49,7 @@ def drop_negligible_operations(
47
49
  if context is None:
48
50
  context = transformer_api.TransformerContext()
49
51
 
50
- def map_func(op: 'cirq.Operation', _: int) -> 'cirq.OP_TREE':
52
+ def map_func(op: cirq.Operation, _: int) -> cirq.OP_TREE:
51
53
  return (
52
54
  op
53
55
  if protocols.num_qubits(op) > 10
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import cirq
16
18
 
17
19
  NO_COMPILE_TAG = "no_compile_tag"
@@ -14,13 +14,16 @@
14
14
 
15
15
  """Transformer pass that adds dynamical decoupling operations to a circuit."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  from functools import reduce
18
20
  from itertools import cycle
19
- from typing import Dict, Optional, Tuple, TYPE_CHECKING, Union
21
+ from typing import TYPE_CHECKING
20
22
 
21
23
  import numpy as np
22
24
 
23
- from cirq import circuits, ops, protocols
25
+ from cirq import ops, protocols
26
+ from cirq.circuits import Circuit, FrozenCircuit, Moment
24
27
  from cirq.protocols import unitary_protocol
25
28
  from cirq.protocols.has_stabilizer_effect_protocol import has_stabilizer_effect
26
29
  from cirq.protocols.has_unitary_protocol import has_unitary
@@ -31,7 +34,7 @@ if TYPE_CHECKING:
31
34
  import cirq
32
35
 
33
36
 
34
- def _get_dd_sequence_from_schema_name(schema: str) -> Tuple[ops.Gate, ...]:
37
+ def _get_dd_sequence_from_schema_name(schema: str) -> tuple[ops.Gate, ...]:
35
38
  """Gets dynamical decoupling sequence from a schema name."""
36
39
  match schema:
37
40
  case 'DEFAULT':
@@ -48,17 +51,17 @@ def _get_dd_sequence_from_schema_name(schema: str) -> Tuple[ops.Gate, ...]:
48
51
  raise ValueError('Invalid schema name.')
49
52
 
50
53
 
51
- def _pauli_up_to_global_phase(gate: ops.Gate) -> Union[ops.Pauli, None]:
54
+ def _pauli_up_to_global_phase(gate: ops.Gate) -> ops.Pauli | None:
52
55
  for pauli_gate in [ops.X, ops.Y, ops.Z]:
53
56
  if protocols.equal_up_to_global_phase(gate, pauli_gate):
54
57
  return pauli_gate
55
58
  return None
56
59
 
57
60
 
58
- def _validate_dd_sequence(dd_sequence: Tuple[ops.Gate, ...]) -> None:
61
+ def _validate_dd_sequence(dd_sequence: tuple[ops.Gate, ...]) -> None:
59
62
  """Validates a given dynamical decoupling sequence.
60
63
 
61
- The sequence should only consists of Pauli gates and is essentially an identity gate.
64
+ The sequence should only consist of Pauli gates and is essentially an identity gate.
62
65
 
63
66
  Args:
64
67
  dd_sequence: Input dynamical sequence to be validated.
@@ -79,14 +82,14 @@ def _validate_dd_sequence(dd_sequence: Tuple[ops.Gate, ...]) -> None:
79
82
 
80
83
  if not protocols.equal_up_to_global_phase(product, np.eye(2)):
81
84
  raise ValueError(
82
- 'Invalid dynamical decoupling sequence. Expect sequence production equals'
85
+ 'Invalid dynamical decoupling sequence. Expect sequence product equals'
83
86
  f' identity up to a global phase, got {product}.'.replace('\n', ' ')
84
87
  )
85
88
 
86
89
 
87
90
  def _parse_dd_sequence(
88
- schema: Union[str, Tuple[ops.Gate, ...]],
89
- ) -> Tuple[Tuple[ops.Gate, ...], Dict[ops.Gate, ops.Pauli]]:
91
+ schema: str | tuple[ops.Gate, ...],
92
+ ) -> tuple[tuple[ops.Gate, ...], dict[ops.Gate, ops.Pauli]]:
90
93
  """Parses and returns dynamical decoupling sequence and its associated pauli map from schema."""
91
94
  dd_sequence = None
92
95
  if isinstance(schema, str):
@@ -96,7 +99,7 @@ def _parse_dd_sequence(
96
99
  dd_sequence = schema
97
100
 
98
101
  # Map gate to Pauli gate. This is necessary as dd sequence might contain gates like X^-1.
99
- pauli_map: Dict[ops.Gate, ops.Pauli] = {}
102
+ pauli_map: dict[ops.Gate, ops.Pauli] = {}
100
103
  for gate in dd_sequence:
101
104
  pauli_gate = _pauli_up_to_global_phase(gate)
102
105
  if pauli_gate is not None:
@@ -111,7 +114,7 @@ def _is_single_qubit_operation(operation: ops.Operation) -> bool:
111
114
  return len(operation.qubits) == 1
112
115
 
113
116
 
114
- def _is_single_qubit_gate_moment(moment: circuits.Moment) -> bool:
117
+ def _is_single_qubit_gate_moment(moment: Moment) -> bool:
115
118
  return all(_is_single_qubit_operation(op) for op in moment)
116
119
 
117
120
 
@@ -119,10 +122,8 @@ def _is_clifford_op(op: ops.Operation) -> bool:
119
122
  return has_unitary(op) and has_stabilizer_effect(op)
120
123
 
121
124
 
122
- def _calc_busy_moment_range_of_each_qubit(
123
- circuit: circuits.FrozenCircuit,
124
- ) -> Dict[ops.Qid, list[int]]:
125
- busy_moment_range_by_qubit: Dict[ops.Qid, list[int]] = {
125
+ def _calc_busy_moment_range_of_each_qubit(circuit: FrozenCircuit) -> dict[ops.Qid, list[int]]:
126
+ busy_moment_range_by_qubit: dict[ops.Qid, list[int]] = {
126
127
  q: [len(circuit), -1] for q in circuit.all_qubits()
127
128
  }
128
129
  for moment_id, moment in enumerate(circuit):
@@ -132,12 +133,12 @@ def _calc_busy_moment_range_of_each_qubit(
132
133
  return busy_moment_range_by_qubit
133
134
 
134
135
 
135
- def _is_insertable_moment(moment: circuits.Moment, single_qubit_gate_moments_only: bool) -> bool:
136
+ def _is_insertable_moment(moment: Moment, single_qubit_gate_moments_only: bool) -> bool:
136
137
  return not single_qubit_gate_moments_only or _is_single_qubit_gate_moment(moment)
137
138
 
138
139
 
139
140
  def _merge_single_qubit_ops_to_phxz(
140
- q: ops.Qid, operations: Tuple[ops.Operation, ...]
141
+ q: ops.Qid, operations: tuple[ops.Operation, ...]
141
142
  ) -> ops.Operation:
142
143
  """Merges [op1, op2, ...] and returns an equivalent op"""
143
144
  if len(operations) == 1:
@@ -148,9 +149,7 @@ def _merge_single_qubit_ops_to_phxz(
148
149
  return gate.on(q)
149
150
 
150
151
 
151
- def _try_merge_single_qubit_ops_of_two_moments(
152
- m1: circuits.Moment, m2: circuits.Moment
153
- ) -> Tuple[circuits.Moment, ...]:
152
+ def _try_merge_single_qubit_ops_of_two_moments(m1: Moment, m2: Moment) -> tuple[Moment, ...]:
154
153
  """Merge single qubit ops of 2 moments if possible, returns 2 moments otherwise."""
155
154
  for q in m1.qubits & m2.qubits:
156
155
  op1 = m1.operation_at(q)
@@ -167,12 +166,10 @@ def _try_merge_single_qubit_ops_of_two_moments(
167
166
  # ops_on_q may contain 1 op or 2 ops.
168
167
  ops_on_q = [op for op in [m.operation_at(q) for m in [m1, m2]] if op is not None]
169
168
  merged_ops.add(_merge_single_qubit_ops_to_phxz(q, tuple(ops_on_q)))
170
- return (circuits.Moment(merged_ops),)
169
+ return (Moment(merged_ops),)
171
170
 
172
171
 
173
- def _calc_pulled_through(
174
- moment: circuits.Moment, input_pauli_ops: ops.PauliString
175
- ) -> ops.PauliString:
172
+ def _calc_pulled_through(moment: Moment, input_pauli_ops: ops.PauliString) -> ops.PauliString:
176
173
  """Calculates the pulled_through such that circuit(input_pauli_ops, moment.clifford_ops) is
177
174
  equivalent to circuit(moment.clifford_ops, pulled_through).
178
175
  """
@@ -182,7 +179,7 @@ def _calc_pulled_through(
182
179
  return input_pauli_ops.after(clifford_ops_in_moment)
183
180
 
184
181
 
185
- def _get_stop_qubits(moment: circuits.Moment) -> set[ops.Qid]:
182
+ def _get_stop_qubits(moment: Moment) -> set[ops.Qid]:
186
183
  stop_pulling_through_qubits: set[ops.Qid] = set()
187
184
  for op in moment:
188
185
  if (not _is_clifford_op(op) and not _is_single_qubit_operation(op)) or not has_unitary(
@@ -204,20 +201,20 @@ def _need_merge_pulled_through(op_at_q: ops.Operation, is_at_last_busy_moment: b
204
201
 
205
202
  @transformer_api.transformer
206
203
  def add_dynamical_decoupling(
207
- circuit: 'cirq.AbstractCircuit',
204
+ circuit: cirq.AbstractCircuit,
208
205
  *,
209
- context: Optional['cirq.TransformerContext'] = None,
210
- schema: Union[str, Tuple[ops.Gate, ...]] = 'DEFAULT',
206
+ context: cirq.TransformerContext | None = None,
207
+ schema: str | tuple[ops.Gate, ...] = 'DEFAULT',
211
208
  single_qubit_gate_moments_only: bool = True,
212
- ) -> 'cirq.Circuit':
209
+ ) -> cirq.Circuit:
213
210
  """Adds dynamical decoupling gate operations to a given circuit.
214
- This transformer might add new moments thus change structure of the original circuit.
211
+ This transformer might add new moments and thus change the structure of the original circuit.
215
212
 
216
213
  Args:
217
214
  circuit: Input circuit to transform.
218
215
  context: `cirq.TransformerContext` storing common configurable options for transformers.
219
216
  schema: Dynamical decoupling schema name or a dynamical decoupling sequence.
220
- If a schema is specified, provided dynamical decouping sequence will be used.
217
+ If a schema is specified, the provided dynamical decoupling sequence will be used.
221
218
  Otherwise, customized dynamical decoupling sequence will be applied.
222
219
  single_qubit_gate_moments_only: If set True, dynamical decoupling operation will only be
223
220
  added in single-qubit gate moments.
@@ -231,7 +228,7 @@ def add_dynamical_decoupling(
231
228
  busy_moment_range_by_qubit = _calc_busy_moment_range_of_each_qubit(orig_circuit)
232
229
 
233
230
  # Stores all the moments of the output circuit chronologically.
234
- transformed_moments: list[circuits.Moment] = []
231
+ transformed_moments: list[Moment] = []
235
232
  # A PauliString stores the result of 'pulling' Pauli gates past each operations
236
233
  # right before the current moment.
237
234
  pulled_through: ops.PauliString = ops.PauliString()
@@ -274,17 +271,27 @@ def add_dynamical_decoupling(
274
271
  dd_iter_by_qubits[q] = cycle(base_dd_sequence)
275
272
  # Need to insert a new moment before current moment
276
273
  if new_moment_ops:
277
- # Fill insertable idle moments in the new moment using dd sequence
278
- for q in orig_circuit.all_qubits() - stop_pulling_through_qubits:
279
- if busy_moment_range_by_qubit[q][0] < moment_id <= busy_moment_range_by_qubit[q][1]:
280
- new_moment_ops.append(_update_pulled_through(q, next(dd_iter_by_qubits[q])))
281
274
  moments_to_be_appended = _try_merge_single_qubit_ops_of_two_moments(
282
- transformed_moments.pop(), circuits.Moment(new_moment_ops)
275
+ transformed_moments[-1], Moment(new_moment_ops)
283
276
  )
284
- transformed_moments.extend(moments_to_be_appended)
277
+ if len(moments_to_be_appended) == 1:
278
+ transformed_moments.pop()
279
+ transformed_moments.append(moments_to_be_appended[0])
280
+ else: # Fill insertable idle moments in the new moment using dd sequence
281
+ for q in orig_circuit.all_qubits() - stop_pulling_through_qubits:
282
+ if (
283
+ busy_moment_range_by_qubit[q][0]
284
+ < moment_id
285
+ <= busy_moment_range_by_qubit[q][1]
286
+ ):
287
+ new_moment_ops.append(_update_pulled_through(q, next(dd_iter_by_qubits[q])))
288
+ moments_to_be_appended = _try_merge_single_qubit_ops_of_two_moments(
289
+ transformed_moments.pop(), Moment(new_moment_ops)
290
+ )
291
+ transformed_moments.extend(moments_to_be_appended)
285
292
 
286
293
  # Step 2, calc updated_moment with insertions / merges.
287
- updated_moment_ops: set['cirq.Operation'] = set()
294
+ updated_moment_ops: set[cirq.Operation] = set()
288
295
  for q in orig_circuit.all_qubits():
289
296
  op_at_q = moment.operation_at(q)
290
297
  remaining_pulled_through_gate = pulled_through.get(q)
@@ -313,7 +320,7 @@ def add_dynamical_decoupling(
313
320
  updated_moment_ops.add(updated_op)
314
321
 
315
322
  if updated_moment_ops:
316
- updated_moment = circuits.Moment(updated_moment_ops)
323
+ updated_moment = Moment(updated_moment_ops)
317
324
  transformed_moments.append(updated_moment)
318
325
 
319
326
  # Step 3, update pulled through.
@@ -327,8 +334,8 @@ def add_dynamical_decoupling(
327
334
  if ending_moment_ops:
328
335
  transformed_moments.extend(
329
336
  _try_merge_single_qubit_ops_of_two_moments(
330
- transformed_moments.pop(), circuits.Moment(ending_moment_ops)
337
+ transformed_moments.pop(), Moment(ending_moment_ops)
331
338
  )
332
339
  )
333
340
 
334
- return circuits.Circuit(transformed_moments)
341
+ return Circuit.from_moments(*transformed_moments)