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
@@ -14,7 +14,9 @@
14
14
 
15
15
  """Utility methods for efficiently preparing two qubit states."""
16
16
 
17
- from typing import List, TYPE_CHECKING
17
+ from __future__ import annotations
18
+
19
+ from typing import TYPE_CHECKING
18
20
 
19
21
  import numpy as np
20
22
 
@@ -38,12 +40,8 @@ def _1q_matrices_to_ops(g0, g1, q0, q1, include_identity=False):
38
40
 
39
41
 
40
42
  def prepare_two_qubit_state_using_sqrt_iswap(
41
- q0: 'cirq.Qid',
42
- q1: 'cirq.Qid',
43
- state: 'cirq.STATE_VECTOR_LIKE',
44
- *,
45
- use_sqrt_iswap_inv: bool = True,
46
- ) -> List['cirq.Operation']:
43
+ q0: cirq.Qid, q1: cirq.Qid, state: cirq.STATE_VECTOR_LIKE, *, use_sqrt_iswap_inv: bool = True
44
+ ) -> list[cirq.Operation]:
47
45
  """Prepares the given 2q state from |00> using at-most 1 √iSWAP gate + single qubit rotations.
48
46
 
49
47
  Entangled states are prepared using exactly 1 √iSWAP gate while product states are prepared
@@ -77,8 +75,8 @@ def prepare_two_qubit_state_using_sqrt_iswap(
77
75
 
78
76
 
79
77
  def prepare_two_qubit_state_using_cz(
80
- q0: 'cirq.Qid', q1: 'cirq.Qid', state: 'cirq.STATE_VECTOR_LIKE'
81
- ) -> List['cirq.Operation']:
78
+ q0: cirq.Qid, q1: cirq.Qid, state: cirq.STATE_VECTOR_LIKE
79
+ ) -> list[cirq.Operation]:
82
80
  """Prepares the given 2q state from |00> using at-most 1 CZ gate + single qubit rotations.
83
81
 
84
82
  Entangled states are prepared using exactly 1 CZ gate while product states are prepared
@@ -110,8 +108,8 @@ def prepare_two_qubit_state_using_cz(
110
108
 
111
109
 
112
110
  def prepare_two_qubit_state_using_iswap(
113
- q0: 'cirq.Qid', q1: 'cirq.Qid', state: 'cirq.STATE_VECTOR_LIKE', use_iswap_inv: bool = False
114
- ) -> List['cirq.Operation']:
111
+ q0: cirq.Qid, q1: cirq.Qid, state: cirq.STATE_VECTOR_LIKE, use_iswap_inv: bool = False
112
+ ) -> list[cirq.Operation]:
115
113
  """Prepares the given 2q state from |00> using at-most 1 ISWAP gate + single qubit rotations.
116
114
 
117
115
  Entangled states are prepared using exactly 1 ISWAP gate while product states are prepared
@@ -14,6 +14,8 @@
14
14
 
15
15
  """Tests for efficient two qubit state preparation methods."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  import copy
18
20
 
19
21
  import numpy as np
@@ -14,7 +14,9 @@
14
14
 
15
15
  """Utility methods for decomposing two-qubit unitaries into CZ gates."""
16
16
 
17
- from typing import cast, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING
17
+ from __future__ import annotations
18
+
19
+ from typing import cast, Iterable, Sequence, TYPE_CHECKING
18
20
 
19
21
  import numpy as np
20
22
 
@@ -24,15 +26,14 @@ from cirq.linalg.decompositions import extract_right_diag, num_cnots_required
24
26
  from cirq.transformers.analytical_decompositions import single_qubit_decompositions
25
27
  from cirq.transformers.eject_phased_paulis import eject_phased_paulis
26
28
  from cirq.transformers.eject_z import eject_z
27
- from cirq.transformers.merge_single_qubit_gates import merge_single_qubit_gates_to_phased_x_and_z
28
29
 
29
30
  if TYPE_CHECKING:
30
31
  import cirq
31
32
 
32
33
 
33
34
  def _remove_partial_czs_or_fail(
34
- operations: Iterable['cirq.Operation'], atol: float
35
- ) -> List['cirq.Operation']:
35
+ operations: Iterable[cirq.Operation], atol: float
36
+ ) -> list[cirq.Operation]:
36
37
  result = []
37
38
  for op in operations:
38
39
  if isinstance(op.gate, ops.CZPowGate):
@@ -49,13 +50,13 @@ def _remove_partial_czs_or_fail(
49
50
 
50
51
 
51
52
  def two_qubit_matrix_to_cz_operations(
52
- q0: 'cirq.Qid',
53
- q1: 'cirq.Qid',
53
+ q0: cirq.Qid,
54
+ q1: cirq.Qid,
54
55
  mat: np.ndarray,
55
56
  allow_partial_czs: bool,
56
57
  atol: float = 1e-8,
57
58
  clean_operations: bool = True,
58
- ) -> List[ops.Operation]:
59
+ ) -> list[ops.Operation]:
59
60
  """Decomposes a two-qubit operation into Z/XY/CZ gates.
60
61
 
61
62
  Args:
@@ -79,19 +80,19 @@ def two_qubit_matrix_to_cz_operations(
79
80
  if clean_operations:
80
81
  if not allow_partial_czs:
81
82
  # CZ^t is not allowed for any $t$ except $t=1$.
82
- return _remove_partial_czs_or_fail(cleanup_operations(operations), atol=atol)
83
- return cleanup_operations(operations)
83
+ return _remove_partial_czs_or_fail(cleanup_operations(operations, atol=atol), atol=atol)
84
+ return cleanup_operations(operations, atol=atol)
84
85
  return operations
85
86
 
86
87
 
87
88
  def two_qubit_matrix_to_diagonal_and_cz_operations(
88
- q0: 'cirq.Qid',
89
- q1: 'cirq.Qid',
89
+ q0: cirq.Qid,
90
+ q1: cirq.Qid,
90
91
  mat: np.ndarray,
91
92
  allow_partial_czs: bool = False,
92
93
  atol: float = 1e-8,
93
94
  clean_operations: bool = True,
94
- ) -> Tuple[np.ndarray, List['cirq.Operation']]:
95
+ ) -> tuple[np.ndarray, list[cirq.Operation]]:
95
96
  """Decomposes a 2-qubit unitary to a diagonal and the remaining operations.
96
97
 
97
98
  For a 2-qubit unitary V, return ops, a list of operations and
@@ -136,7 +137,7 @@ def two_qubit_matrix_to_diagonal_and_cz_operations(
136
137
  )
137
138
 
138
139
 
139
- def _xx_interaction_via_full_czs(q0: 'cirq.Qid', q1: 'cirq.Qid', x: float):
140
+ def _xx_interaction_via_full_czs(q0: cirq.Qid, q1: cirq.Qid, x: float):
140
141
  a = x * -2 / np.pi
141
142
  yield ops.H(q1)
142
143
  yield ops.CZ(q0, q1)
@@ -145,7 +146,7 @@ def _xx_interaction_via_full_czs(q0: 'cirq.Qid', q1: 'cirq.Qid', x: float):
145
146
  yield ops.H(q1)
146
147
 
147
148
 
148
- def _xx_yy_interaction_via_full_czs(q0: 'cirq.Qid', q1: 'cirq.Qid', x: float, y: float):
149
+ def _xx_yy_interaction_via_full_czs(q0: cirq.Qid, q1: cirq.Qid, x: float, y: float):
149
150
  a = x * -2 / np.pi
150
151
  b = y * -2 / np.pi
151
152
  yield ops.X(q0) ** 0.5
@@ -160,9 +161,7 @@ def _xx_yy_interaction_via_full_czs(q0: 'cirq.Qid', q1: 'cirq.Qid', x: float, y:
160
161
  yield ops.X(q0) ** -0.5
161
162
 
162
163
 
163
- def _xx_yy_zz_interaction_via_full_czs(
164
- q0: 'cirq.Qid', q1: 'cirq.Qid', x: float, y: float, z: float
165
- ):
164
+ def _xx_yy_zz_interaction_via_full_czs(q0: cirq.Qid, q1: cirq.Qid, x: float, y: float, z: float):
166
165
  a = x * -2 / np.pi + 0.5
167
166
  b = y * -2 / np.pi + 0.5
168
167
  c = z * -2 / np.pi + 0.5
@@ -182,22 +181,87 @@ def _xx_yy_zz_interaction_via_full_czs(
182
181
  yield ops.H(q1)
183
182
 
184
183
 
185
- def cleanup_operations(operations: Sequence[ops.Operation]):
184
+ def cleanup_operations(operations: Sequence[ops.Operation], atol: float = 1e-8):
185
+ operations = _merge_single_qubit_gates(operations, atol=atol)
186
186
  circuit = circuits.Circuit(operations)
187
- circuit = merge_single_qubit_gates_to_phased_x_and_z(circuit)
188
187
  circuit = eject_phased_paulis(circuit)
189
188
  circuit = eject_z(circuit)
190
189
  circuit = circuits.Circuit(circuit.all_operations(), strategy=circuits.InsertStrategy.EARLIEST)
191
190
  return list(circuit.all_operations())
192
191
 
193
192
 
193
+ def _transform_single_qubit_operations_to_phased_x_and_z(
194
+ operations: Sequence[ops.Operation], atol: float
195
+ ) -> Sequence[ops.Operation]:
196
+ """Transforms operations on the same qubit to a PhasedXPowGate followed by a Z gate.
197
+
198
+ Args:
199
+ operations: sequence of operations on the same qubit
200
+ atol: a limit on the amount of absolute error introduced by the
201
+ transformation.
202
+ Returns:
203
+ A PhasedXPowGate followed by a Z gate. If one the gates is not needed, it will be omitted.
204
+ """
205
+ u = np.eye(2)
206
+ for op in operations:
207
+ u = protocols.unitary(op) @ u
208
+ return [
209
+ g(op.qubits[0])
210
+ for g in single_qubit_decompositions.single_qubit_matrix_to_phased_x_z(u, atol=atol)
211
+ ]
212
+
213
+
214
+ def _merge_single_qubit_gates(
215
+ operations: Sequence[ops.Operation], atol: float
216
+ ) -> Sequence[ops.Operation]:
217
+ """Merge consecutive single qubit gates.
218
+
219
+ Traverses the sequence of operations maintaining a list of consecutive single qubit
220
+ operations for each qubit. When a 2-qubit gate is encountered, it transforms pending
221
+ operations to a PhasedXPowGate followed by a Z gate.
222
+
223
+ Args:
224
+ operations: sequence of operations
225
+ atol: a limit on the amount of absolute error introduced by the
226
+ transformation.
227
+ Returns:
228
+ new sequence of operations after merging gates
229
+
230
+ Raises:
231
+ ValueError: if one of the operations is not on 1 or 2 qubits
232
+ """
233
+ merged_ops: list[ops.Operation] = []
234
+ pending_ops: dict[tuple[cirq.Qid, ...], list[ops.Operation]] = dict()
235
+ for op in operations:
236
+ if protocols.num_qubits(op) == 2:
237
+ for qubit_ops in pending_ops.values():
238
+ merged_ops.extend(
239
+ _transform_single_qubit_operations_to_phased_x_and_z(qubit_ops, atol=atol)
240
+ )
241
+ pending_ops.clear()
242
+ # Add the 2-qubit gate
243
+ merged_ops.append(op)
244
+ elif protocols.num_qubits(op) == 1:
245
+ if op.qubits not in pending_ops:
246
+ pending_ops[op.qubits] = []
247
+ pending_ops[op.qubits].append(op)
248
+ else:
249
+ raise ValueError(f'operation is on {protocols.num_qubits(op)} qubits, expected 1 or 2')
250
+ # Merge remaining pending operations
251
+ for qubit_ops in pending_ops.values():
252
+ merged_ops.extend(
253
+ _transform_single_qubit_operations_to_phased_x_and_z(qubit_ops, atol=atol)
254
+ )
255
+ return merged_ops
256
+
257
+
194
258
  def _kak_decomposition_to_operations(
195
- q0: 'cirq.Qid',
196
- q1: 'cirq.Qid',
259
+ q0: cirq.Qid,
260
+ q1: cirq.Qid,
197
261
  kak: linalg.KakDecomposition,
198
262
  allow_partial_czs: bool,
199
263
  atol: float = 1e-8,
200
- ) -> List[ops.Operation]:
264
+ ) -> list[ops.Operation]:
201
265
  """Assumes that the decomposition is canonical."""
202
266
  b0, b1 = kak.single_qubit_operations_before
203
267
  pre = [_do_single_on(b0, q0, atol=atol), _do_single_on(b1, q1, atol=atol)]
@@ -232,7 +296,7 @@ def _is_trivial_angle(rad: float, atol: float) -> bool:
232
296
 
233
297
 
234
298
  def _parity_interaction(
235
- q0: 'cirq.Qid', q1: 'cirq.Qid', rads: float, atol: float, gate: Optional[ops.Gate] = None
299
+ q0: cirq.Qid, q1: cirq.Qid, rads: float, atol: float, gate: ops.Gate | None = None
236
300
  ):
237
301
  """Yields a ZZ interaction framed by the given operation."""
238
302
  if abs(rads) < atol:
@@ -255,15 +319,15 @@ def _parity_interaction(
255
319
  yield g.on(q0), g.on(q1)
256
320
 
257
321
 
258
- def _do_single_on(u: np.ndarray, q: 'cirq.Qid', atol: float = 1e-8):
322
+ def _do_single_on(u: np.ndarray, q: cirq.Qid, atol: float = 1e-8):
259
323
  for gate in single_qubit_decompositions.single_qubit_matrix_to_gates(u, atol):
260
324
  yield gate(q)
261
325
 
262
326
 
263
327
  def _non_local_part(
264
- q0: 'cirq.Qid',
265
- q1: 'cirq.Qid',
266
- interaction_coefficients: Tuple[float, float, float],
328
+ q0: cirq.Qid,
329
+ q1: cirq.Qid,
330
+ interaction_coefficients: tuple[float, float, float],
267
331
  allow_partial_czs: bool,
268
332
  atol: float = 1e-8,
269
333
  ):
@@ -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 cmath
16
18
  import random
17
19
 
@@ -24,6 +26,7 @@ from cirq.testing import random_two_qubit_circuit_with_czs
24
26
  from cirq.transformers.analytical_decompositions.two_qubit_to_cz import (
25
27
  _is_trivial_angle,
26
28
  _parity_interaction,
29
+ cleanup_operations,
27
30
  two_qubit_matrix_to_diagonal_and_cz_operations,
28
31
  )
29
32
 
@@ -52,7 +55,7 @@ from cirq.transformers.analytical_decompositions.two_qubit_to_cz import (
52
55
  ]
53
56
  )(1e-8 * 2 / 3, 1e-8 * 4 / 3),
54
57
  )
55
- def test_is_trivial_angle(rad, expected):
58
+ def test_is_trivial_angle(rad, expected) -> None:
56
59
  tolerance = 1e-8
57
60
  out = _is_trivial_angle(rad, tolerance)
58
61
  assert out == expected, f'rad = {rad}'
@@ -149,7 +152,7 @@ def assert_ops_implement_unitary(q0, q1, operations, intended_effect, atol=0.01)
149
152
  )
150
153
  def test_two_to_ops_equivalent_and_bounded_for_known_and_random(
151
154
  max_partial_cz_depth, max_full_cz_depth, effect
152
- ):
155
+ ) -> None:
153
156
  q0 = cirq.NamedQubit('q0')
154
157
  q1 = cirq.NamedQubit('q1')
155
158
 
@@ -163,7 +166,7 @@ def test_two_to_ops_equivalent_and_bounded_for_known_and_random(
163
166
  assert_cz_depth_below(operations_with_full, max_full_cz_depth, True)
164
167
 
165
168
 
166
- def test_trivial_parity_interaction_corner_case():
169
+ def test_trivial_parity_interaction_corner_case() -> None:
167
170
  q0 = cirq.NamedQubit('q0')
168
171
  q1 = cirq.NamedQubit('q1')
169
172
  nearPi4 = np.pi / 4 * 0.99
@@ -172,7 +175,7 @@ def test_trivial_parity_interaction_corner_case():
172
175
  assert len(circuit) == 2
173
176
 
174
177
 
175
- def test_kak_decomposition_depth_full_cz():
178
+ def test_kak_decomposition_depth_full_cz() -> None:
176
179
  a, b = cirq.LineQubit.range(2)
177
180
 
178
181
  # Random.
@@ -210,7 +213,7 @@ def test_kak_decomposition_depth_full_cz():
210
213
  assert len(c) <= 4
211
214
 
212
215
 
213
- def test_kak_decomposition_depth_partial_cz():
216
+ def test_kak_decomposition_depth_partial_cz() -> None:
214
217
  a, b = cirq.LineQubit.range(2)
215
218
 
216
219
  # Random.
@@ -250,7 +253,7 @@ def test_kak_decomposition_depth_partial_cz():
250
253
  np.diag(np.exp(1j * np.pi * np.random.random(4))),
251
254
  ],
252
255
  )
253
- def test_decompose_to_diagonal_and_circuit(v):
256
+ def test_decompose_to_diagonal_and_circuit(v) -> None:
254
257
  b, c = cirq.LineQubit.range(2)
255
258
  diagonal, ops = two_qubit_matrix_to_diagonal_and_cz_operations(b, c, v, atol=1e-8)
256
259
  assert cirq.is_diagonal(diagonal)
@@ -259,7 +262,25 @@ def test_decompose_to_diagonal_and_circuit(v):
259
262
  cirq.testing.assert_allclose_up_to_global_phase(circuit_unitary, v, atol=2e-6)
260
263
 
261
264
 
262
- def test_remove_partial_czs_or_fail():
265
+ @pytest.mark.parametrize(
266
+ "mat, num_czs",
267
+ [
268
+ (cirq.unitary(random_two_qubit_circuit_with_czs(3)), 2),
269
+ (cirq.unitary(random_two_qubit_circuit_with_czs(2)), 2),
270
+ (cirq.unitary(random_two_qubit_circuit_with_czs(1)), 1),
271
+ (cirq.unitary(random_two_qubit_circuit_with_czs(0)), 0),
272
+ ],
273
+ )
274
+ def test_decompose_to_diagonal_and_circuit_returns_circuit_with_expected_number_of_czs(
275
+ mat, num_czs
276
+ ):
277
+ b, c = cirq.LineQubit.range(2)
278
+ _, ops = two_qubit_matrix_to_diagonal_and_cz_operations(b, c, mat, atol=1e-8)
279
+ circuit = cirq.Circuit(ops)
280
+ assert len(list(circuit.findall_operations_with_gate_type(cirq.CZPowGate))) == num_czs
281
+
282
+
283
+ def test_remove_partial_czs_or_fail() -> None:
263
284
  CZ = cirq.CZ(*cirq.LineQubit.range(2))
264
285
  assert (
265
286
  cirq.transformers.analytical_decompositions.two_qubit_to_cz._remove_partial_czs_or_fail(
@@ -274,3 +295,11 @@ def test_remove_partial_czs_or_fail():
274
295
  _ = cirq.transformers.analytical_decompositions.two_qubit_to_cz._remove_partial_czs_or_fail(
275
296
  [CZ**-0.5], atol=1e-9
276
297
  )
298
+
299
+
300
+ @pytest.mark.parametrize("gate", [cirq.CCZ, cirq.GlobalPhaseGate(1.0)])
301
+ def test_cleanup_operations_raises_if_op_not_on_1_or_2_qubits(gate: cirq.Gate) -> None:
302
+ qubits = cirq.LineQubit.range(gate.num_qubits())
303
+ op = gate.on(*qubits)
304
+ with pytest.raises(ValueError, match="expected 1 or 2"):
305
+ cleanup_operations([op], atol=1e-8)
@@ -14,7 +14,9 @@
14
14
 
15
15
  """Utility methods for decomposing two-qubit unitaries into FSim gates."""
16
16
 
17
- from typing import Iterable, Iterator, List, Optional, Sequence, TYPE_CHECKING, Union
17
+ from __future__ import annotations
18
+
19
+ from typing import Iterable, Iterator, Sequence, TYPE_CHECKING
18
20
 
19
21
  import numpy as np
20
22
 
@@ -25,11 +27,11 @@ if TYPE_CHECKING:
25
27
 
26
28
 
27
29
  def decompose_two_qubit_interaction_into_four_fsim_gates(
28
- interaction: Union['cirq.SupportsUnitary', np.ndarray],
30
+ interaction: cirq.SupportsUnitary | np.ndarray,
29
31
  *,
30
- fsim_gate: Union['cirq.FSimGate', 'cirq.ISwapPowGate'],
31
- qubits: Optional[Sequence['cirq.Qid']] = None,
32
- ) -> 'cirq.Circuit':
32
+ fsim_gate: cirq.FSimGate | cirq.ISwapPowGate,
33
+ qubits: Sequence[cirq.Qid] | None = None,
34
+ ) -> cirq.Circuit:
33
35
  """Decomposes operations into an FSimGate near theta=pi/2, phi=0.
34
36
 
35
37
  This decomposition is guaranteed to use exactly four of the given FSim
@@ -98,7 +100,7 @@ def decompose_two_qubit_interaction_into_four_fsim_gates(
98
100
  return result
99
101
 
100
102
 
101
- def _sticky_0_to_1(v: float, *, atol: float) -> Optional[float]:
103
+ def _sticky_0_to_1(v: float, *, atol: float) -> float | None:
102
104
  if 0 <= v <= 1:
103
105
  return v
104
106
  if 1 < v <= 1 + atol:
@@ -110,12 +112,12 @@ def _sticky_0_to_1(v: float, *, atol: float) -> Optional[float]:
110
112
 
111
113
  def _decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops(
112
114
  *,
113
- qubits: Sequence['cirq.Qid'],
114
- fsim_gate: 'cirq.FSimGate',
115
+ qubits: Sequence[cirq.Qid],
116
+ fsim_gate: cirq.FSimGate,
115
117
  canonical_x_kak_coefficient: float,
116
118
  canonical_y_kak_coefficient: float,
117
119
  atol: float = 1e-8,
118
- ) -> List['cirq.Operation']:
120
+ ) -> list[cirq.Operation]:
119
121
  x = canonical_x_kak_coefficient
120
122
  y = canonical_y_kak_coefficient
121
123
  assert 0 <= y <= x <= np.pi / 4
@@ -174,10 +176,10 @@ _B = _BGate()
174
176
 
175
177
 
176
178
  def _decompose_two_qubit_interaction_into_two_b_gates(
177
- interaction: Union['cirq.SupportsUnitary', np.ndarray, 'cirq.KakDecomposition'],
179
+ interaction: cirq.SupportsUnitary | np.ndarray | cirq.KakDecomposition,
178
180
  *,
179
- qubits: Sequence['cirq.Qid'],
180
- ) -> List['cirq.Operation']:
181
+ qubits: Sequence[cirq.Qid],
182
+ ) -> list[cirq.Operation]:
181
183
  kak = linalg.kak_decomposition(interaction)
182
184
 
183
185
  result = _decompose_interaction_into_two_b_gates_ignoring_single_qubit_ops(
@@ -192,8 +194,8 @@ def _decompose_two_qubit_interaction_into_two_b_gates(
192
194
 
193
195
 
194
196
  def _decompose_b_gate_into_two_fsims(
195
- *, fsim_gate: 'cirq.FSimGate', qubits: Sequence['cirq.Qid']
196
- ) -> List['cirq.Operation']:
197
+ *, fsim_gate: cirq.FSimGate, qubits: Sequence[cirq.Qid]
198
+ ) -> list[cirq.Operation]:
197
199
  kak = linalg.kak_decomposition(_B)
198
200
 
199
201
  result = _decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops(
@@ -211,8 +213,8 @@ def _decompose_b_gate_into_two_fsims(
211
213
 
212
214
 
213
215
  def _decompose_interaction_into_two_b_gates_ignoring_single_qubit_ops(
214
- qubits: Sequence['cirq.Qid'], kak_interaction_coefficients: Iterable[float]
215
- ) -> List['cirq.Operation']:
216
+ qubits: Sequence[cirq.Qid], kak_interaction_coefficients: Iterable[float]
217
+ ) -> list[cirq.Operation]:
216
218
  """Decompose using a minimal construction of two-qubit operations.
217
219
 
218
220
  References:
@@ -236,11 +238,8 @@ def _decompose_interaction_into_two_b_gates_ignoring_single_qubit_ops(
236
238
 
237
239
 
238
240
  def _fix_single_qubit_gates_around_kak_interaction(
239
- *,
240
- desired: 'cirq.KakDecomposition',
241
- operations: List['cirq.Operation'],
242
- qubits: Sequence['cirq.Qid'],
243
- ) -> Iterator['cirq.Operation']:
241
+ *, desired: cirq.KakDecomposition, operations: list[cirq.Operation], qubits: Sequence[cirq.Qid]
242
+ ) -> Iterator[cirq.Operation]:
244
243
  """Adds single qubit operations to complete a desired interaction.
245
244
 
246
245
  Args:
@@ -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
  import random
17
19
  from typing import Any
@@ -65,7 +67,7 @@ FEASIBLE_FSIM_GATES = [
65
67
 
66
68
 
67
69
  @pytest.mark.parametrize('obj', UNITARY_OBJS)
68
- def test_decompose_two_qubit_interaction_into_two_b_gates(obj: Any):
70
+ def test_decompose_two_qubit_interaction_into_two_b_gates(obj: Any) -> None:
69
71
  circuit = cirq.Circuit(
70
72
  _decompose_two_qubit_interaction_into_two_b_gates(obj, qubits=cirq.LineQubit.range(2))
71
73
  )
@@ -75,7 +77,7 @@ def test_decompose_two_qubit_interaction_into_two_b_gates(obj: Any):
75
77
  np.testing.assert_allclose(cirq.unitary(circuit), desired_unitary, atol=1e-6)
76
78
 
77
79
 
78
- def test_decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops_fail():
80
+ def test_decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops_fail() -> None:
79
81
  c = _decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops(
80
82
  qubits=cirq.LineQubit.range(2),
81
83
  fsim_gate=cirq.FSimGate(theta=np.pi / 2, phi=0),
@@ -98,7 +100,7 @@ def test_decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops_fail():
98
100
  @pytest.mark.parametrize('obj,fsim_gate', itertools.product(UNITARY_OBJS, FEASIBLE_FSIM_GATES))
99
101
  def test_decompose_two_qubit_interaction_into_four_fsim_gates_equivalence(
100
102
  obj: Any, fsim_gate: cirq.FSimGate
101
- ):
103
+ ) -> None:
102
104
  qubits = obj.qubits if isinstance(obj, cirq.Operation) else cirq.LineQubit.range(2)
103
105
  circuit = cirq.decompose_two_qubit_interaction_into_four_fsim_gates(obj, fsim_gate=fsim_gate)
104
106
  desired_unitary = obj if isinstance(obj, np.ndarray) else cirq.unitary(obj)
@@ -108,7 +110,7 @@ def test_decompose_two_qubit_interaction_into_four_fsim_gates_equivalence(
108
110
  assert cirq.approx_eq(circuit.unitary(qubit_order=qubits), desired_unitary, atol=1e-4)
109
111
 
110
112
 
111
- def test_decompose_two_qubit_interaction_into_four_fsim_gates_validate():
113
+ def test_decompose_two_qubit_interaction_into_four_fsim_gates_validate() -> None:
112
114
  iswap = cirq.FSimGate(theta=np.pi / 2, phi=0)
113
115
  with pytest.raises(ValueError, match='fsim_gate.theta'):
114
116
  cirq.decompose_two_qubit_interaction_into_four_fsim_gates(
@@ -127,7 +129,7 @@ def test_decompose_two_qubit_interaction_into_four_fsim_gates_validate():
127
129
  cirq.decompose_two_qubit_interaction_into_four_fsim_gates(np.eye(4), fsim_gate=fsim)
128
130
 
129
131
 
130
- def test_decompose_two_qubit_interaction_into_four_fsim_gates():
132
+ def test_decompose_two_qubit_interaction_into_four_fsim_gates() -> None:
131
133
  iswap = cirq.FSimGate(theta=np.pi / 2, phi=0)
132
134
 
133
135
  # Defaults to line qubits.
@@ -153,7 +155,7 @@ def test_decompose_two_qubit_interaction_into_four_fsim_gates():
153
155
  assert set(c.all_qubits()) == set(cirq.LineQubit.range(10, 12))
154
156
 
155
157
 
156
- def test_sticky_0_to_1():
158
+ def test_sticky_0_to_1() -> None:
157
159
  assert _sticky_0_to_1(-1, atol=1e-8) is None
158
160
 
159
161
  assert _sticky_0_to_1(-1e-6, atol=1e-8) is None
@@ -19,24 +19,22 @@ Gate compilation methods implemented here are following the paper below:
19
19
  arXiv:1603.07678
20
20
  """
21
21
 
22
- from typing import cast, Iterable, List, Optional, Tuple, TYPE_CHECKING
22
+ from __future__ import annotations
23
23
 
24
- import numpy as np
24
+ from typing import cast, Iterable, TYPE_CHECKING
25
25
 
26
26
  from cirq import linalg, ops, protocols
27
27
  from cirq.transformers.analytical_decompositions import single_qubit_decompositions, two_qubit_to_cz
28
28
 
29
29
  if TYPE_CHECKING:
30
+ import numpy as np
31
+
30
32
  import cirq
31
33
 
32
34
 
33
35
  def two_qubit_matrix_to_ion_operations(
34
- q0: 'cirq.Qid',
35
- q1: 'cirq.Qid',
36
- mat: np.ndarray,
37
- atol: float = 1e-8,
38
- clean_operations: bool = True,
39
- ) -> List[ops.Operation]:
36
+ q0: cirq.Qid, q1: cirq.Qid, mat: np.ndarray, atol: float = 1e-8, clean_operations: bool = True
37
+ ) -> list[ops.Operation]:
40
38
  """Decomposes a two-qubit operation into MS/single-qubit rotation gates.
41
39
 
42
40
  Args:
@@ -56,8 +54,8 @@ def two_qubit_matrix_to_ion_operations(
56
54
 
57
55
 
58
56
  def _kak_decomposition_to_operations(
59
- q0: 'cirq.Qid', q1: 'cirq.Qid', kak: linalg.KakDecomposition, atol: float = 1e-8
60
- ) -> List[ops.Operation]:
57
+ q0: cirq.Qid, q1: cirq.Qid, kak: linalg.KakDecomposition, atol: float = 1e-8
58
+ ) -> list[ops.Operation]:
61
59
  """Assumes that the decomposition is canonical."""
62
60
  b0, b1 = kak.single_qubit_operations_before
63
61
  pre = [_do_single_on(b0, q0, atol), _do_single_on(b1, q1, atol)]
@@ -74,13 +72,13 @@ def _kak_decomposition_to_operations(
74
72
  )
75
73
 
76
74
 
77
- def _do_single_on(u: np.ndarray, q: 'cirq.Qid', atol: float = 1e-8):
75
+ def _do_single_on(u: np.ndarray, q: cirq.Qid, atol: float = 1e-8):
78
76
  for gate in single_qubit_decompositions.single_qubit_matrix_to_gates(u, atol):
79
77
  yield gate(q)
80
78
 
81
79
 
82
80
  def _parity_interaction(
83
- q0: 'cirq.Qid', q1: 'cirq.Qid', rads: float, atol: float, gate: Optional[ops.Gate] = None
81
+ q0: cirq.Qid, q1: cirq.Qid, rads: float, atol: float, gate: ops.Gate | None = None
84
82
  ):
85
83
  """Yields an XX interaction framed by the given operation."""
86
84
 
@@ -98,9 +96,9 @@ def _parity_interaction(
98
96
 
99
97
 
100
98
  def _non_local_part(
101
- q0: 'cirq.Qid',
102
- q1: 'cirq.Qid',
103
- interaction_coefficients: Tuple[float, float, float],
99
+ q0: cirq.Qid,
100
+ q1: cirq.Qid,
101
+ interaction_coefficients: tuple[float, float, float],
104
102
  atol: float = 1e-8,
105
103
  ):
106
104
  """Yields non-local operation of KAK decomposition."""
@@ -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 random
16
18
 
17
19
  import numpy as np
@@ -130,7 +132,7 @@ def assert_ms_depth_below(operations, threshold):
130
132
  (2, _random_double_MS_effect()) for _ in range(10)
131
133
  ])
132
134
  # yapf: enable
133
- def test_two_to_ops(max_ms_depth: int, effect: np.ndarray):
135
+ def test_two_to_ops(max_ms_depth: int, effect: np.ndarray) -> None:
134
136
  q0 = cirq.NamedQubit('q0')
135
137
  q1 = cirq.NamedQubit('q1')
136
138