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
@@ -12,8 +12,10 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from types import NotImplementedType
16
- from typing import Any, cast, Optional, Sequence, Tuple, Union
15
+ from __future__ import annotations
16
+
17
+ from types import EllipsisType, NotImplementedType
18
+ from typing import Any, cast, Sequence
17
19
 
18
20
  import numpy as np
19
21
  import pytest
@@ -23,7 +25,7 @@ import cirq
23
25
 
24
26
 
25
27
  class GateUsingWorkspaceForApplyUnitary(cirq.testing.SingleQubitGate):
26
- def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> Union[np.ndarray, NotImplementedType]:
28
+ def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> np.ndarray | NotImplementedType:
27
29
  args.available_buffer[...] = args.target_tensor
28
30
  args.target_tensor[...] = 0
29
31
  return args.available_buffer
@@ -42,10 +44,10 @@ class GateAllocatingNewSpaceForResult(cirq.testing.SingleQubitGate):
42
44
  def __init__(self):
43
45
  self._matrix = cirq.testing.random_unitary(2, random_state=4321)
44
46
 
45
- def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> Union[np.ndarray, NotImplementedType]:
47
+ def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> np.ndarray | NotImplementedType:
46
48
  assert len(args.axes) == 1
47
49
  a = args.axes[0]
48
- seed = cast(Tuple[Union[int, slice, 'ellipsis'], ...], (slice(None),))
50
+ seed = cast(tuple[int | slice | EllipsisType, ...], (slice(None),))
49
51
  zero = seed * a + (0, Ellipsis)
50
52
  one = seed * a + (1, Ellipsis)
51
53
  result = np.zeros(args.target_tensor.shape, args.target_tensor.dtype)
@@ -110,13 +112,13 @@ C_02_20H = cirq.ControlledGate(
110
112
  C2Restricted = cirq.ControlledGate(RestrictedGate(), control_values=[2], control_qid_shape=(3,))
111
113
 
112
114
 
113
- def test_init():
115
+ def test_init() -> None:
114
116
  gate = cirq.ControlledGate(cirq.Z)
115
117
  assert gate.sub_gate is cirq.Z
116
118
  assert gate.num_qubits() == 2
117
119
 
118
120
 
119
- def test_init2():
121
+ def test_init2() -> None:
120
122
  with pytest.raises(ValueError, match=r'cirq\.num_qubits\(control_values\) != num_controls'):
121
123
  cirq.ControlledGate(cirq.Z, num_controls=1, control_values=(1, 0))
122
124
  with pytest.raises(ValueError, match=r'len\(control_qid_shape\) != num_controls'):
@@ -186,7 +188,7 @@ def test_init2():
186
188
  assert cirq.qid_shape(gate) == (3, 3, 2)
187
189
 
188
190
 
189
- def test_validate_args():
191
+ def test_validate_args() -> None:
190
192
  a = cirq.NamedQubit('a')
191
193
  b = cirq.NamedQubit('b')
192
194
  c = cirq.NamedQubit('c')
@@ -232,7 +234,7 @@ def test_validate_args():
232
234
  _ = C2C2H.on(q3, p3, a)
233
235
 
234
236
 
235
- def test_eq():
237
+ def test_eq() -> None:
236
238
  eq = cirq.testing.EqualsTester()
237
239
  eq.add_equality_group(CY, cirq.ControlledGate(cirq.Y))
238
240
  eq.add_equality_group(CCH)
@@ -270,7 +272,7 @@ def test_eq():
270
272
  np.testing.assert_allclose(cirq.unitary(item), cirq.unitary(group[0]))
271
273
 
272
274
 
273
- def test_control():
275
+ def test_control() -> None:
274
276
  class G(cirq.testing.SingleQubitGate):
275
277
  def _has_mixture_(self):
276
278
  return True
@@ -299,7 +301,7 @@ def test_control():
299
301
  eq.add_equality_group(
300
302
  cirq.ControlledGate(g, num_controls=2),
301
303
  g.controlled(control_values=[1, 1]),
302
- g.controlled(control_qid_shape=[2, 2]),
304
+ g.controlled(control_qid_shape=(2, 2)),
303
305
  g.controlled(num_controls=2),
304
306
  g.controlled().controlled(),
305
307
  g.controlled(control_values=cirq.SumOfProducts([[1, 1]])),
@@ -312,14 +314,14 @@ def test_control():
312
314
  )
313
315
  eq.add_equality_group(g.controlled(control_values=[0]).controlled(control_values=[1]))
314
316
  eq.add_equality_group(
315
- cirq.ControlledGate(g, control_qid_shape=[4, 3]),
316
- g.controlled(control_qid_shape=[4, 3]),
317
- g.controlled(control_qid_shape=[3]).controlled(control_qid_shape=[4]),
317
+ cirq.ControlledGate(g, control_qid_shape=(4, 3)),
318
+ g.controlled(control_qid_shape=(4, 3)),
319
+ g.controlled(control_qid_shape=(3,)).controlled(control_qid_shape=(4,)),
318
320
  )
319
- eq.add_equality_group(g.controlled(control_qid_shape=[4]).controlled(control_qid_shape=[3]))
321
+ eq.add_equality_group(g.controlled(control_qid_shape=(4,)).controlled(control_qid_shape=(3,)))
320
322
 
321
323
 
322
- def test_unitary():
324
+ def test_unitary() -> None:
323
325
  cxa = cirq.ControlledGate(cirq.X ** sympy.Symbol('a'))
324
326
  assert not cirq.has_unitary(cxa)
325
327
  assert cirq.unitary(cxa, None) is None
@@ -424,7 +426,7 @@ def test_unitary():
424
426
  (C0C_xorH, False),
425
427
  ],
426
428
  )
427
- def test_controlled_gate_is_consistent(gate: cirq.Gate, should_decompose_to_target):
429
+ def test_controlled_gate_is_consistent(gate: cirq.Gate, should_decompose_to_target) -> None:
428
430
  _test_controlled_gate_is_consistent(gate, should_decompose_to_target)
429
431
 
430
432
 
@@ -464,7 +466,7 @@ def test_nontrivial_controlled_gate_is_consistent(
464
466
  control_qid_shape: Sequence[int],
465
467
  control_values: Any,
466
468
  should_decompose_to_target: bool,
467
- ):
469
+ ) -> None:
468
470
  _test_controlled_gate_is_consistent(
469
471
  gate, should_decompose_to_target, control_qid_shape, control_values
470
472
  )
@@ -473,7 +475,7 @@ def test_nontrivial_controlled_gate_is_consistent(
473
475
  def _test_controlled_gate_is_consistent(
474
476
  gate: cirq.Gate,
475
477
  should_decompose_to_target: bool,
476
- control_qid_shape: Optional[Sequence[int]] = None,
478
+ control_qid_shape: Sequence[int] | None = None,
477
479
  control_values: Any = None,
478
480
  ):
479
481
  cgate = cirq.ControlledGate(
@@ -494,7 +496,41 @@ def _test_controlled_gate_is_consistent(
494
496
  np.testing.assert_allclose(cirq.unitary(cgate), cirq.unitary(circuit), atol=1e-13)
495
497
 
496
498
 
497
- def test_pow_inverse():
499
+ @pytest.mark.parametrize(
500
+ 'sub_gate, expected_decomposition',
501
+ [
502
+ (cirq.X, [cirq.CX]),
503
+ (cirq.CX, [cirq.CCX]),
504
+ (cirq.XPowGate(), [cirq.CXPowGate()]),
505
+ (cirq.CXPowGate(), [cirq.CCXPowGate()]),
506
+ (cirq.Z, [cirq.CZ]),
507
+ (cirq.CZ, [cirq.CCZ]),
508
+ (cirq.ZPowGate(), [cirq.CZPowGate()]),
509
+ (cirq.CZPowGate(), [cirq.CCZPowGate()]),
510
+ ],
511
+ )
512
+ def test_controlled_gate_decomposition_uses_canonical_version(
513
+ sub_gate: cirq.Gate, expected_decomposition: list[cirq.Gate]
514
+ ) -> None:
515
+ cgate = cirq.ControlledGate(sub_gate, num_controls=1)
516
+ qubits = cirq.LineQubit.range(1 + sub_gate.num_qubits())
517
+ dec = cirq.decompose_once(cgate.on(*qubits))
518
+ assert dec == [gate.on(*qubits) for gate in expected_decomposition]
519
+
520
+
521
+ @pytest.mark.parametrize(
522
+ 'sub_gate, expected_decomposition', [(cirq.Z, [cirq.CZ]), (cirq.ZPowGate(), [cirq.CZPowGate()])]
523
+ )
524
+ def test_controlled_gate_full_decomposition(
525
+ sub_gate: cirq.Gate, expected_decomposition: list[cirq.Gate]
526
+ ) -> None:
527
+ cgate = cirq.ControlledGate(sub_gate, num_controls=1)
528
+ qubits = cirq.LineQubit.range(1 + sub_gate.num_qubits())
529
+ dec = cirq.decompose(cgate.on(*qubits))
530
+ assert dec == [gate.on(*qubits) for gate in expected_decomposition]
531
+
532
+
533
+ def test_pow_inverse() -> None:
498
534
  assert cirq.inverse(CRestricted, None) is None
499
535
  assert cirq.pow(CRestricted, 1.5, None) is None
500
536
  assert cirq.pow(CY, 1.5) == cirq.ControlledGate(cirq.Y**1.5)
@@ -513,7 +549,7 @@ def test_pow_inverse():
513
549
  assert cirq.inverse(C2Y) == C2Y**-1 == C2Y
514
550
 
515
551
 
516
- def test_extrapolatable_effect():
552
+ def test_extrapolatable_effect() -> None:
517
553
  a = cirq.NamedQubit('a')
518
554
  b = cirq.NamedQubit('b')
519
555
 
@@ -524,7 +560,7 @@ def test_extrapolatable_effect():
524
560
  assert cirq.ControlledGate(cirq.Z) ** 0.5 == cirq.ControlledGate(cirq.Z**0.5)
525
561
 
526
562
 
527
- def test_reversible():
563
+ def test_reversible() -> None:
528
564
  assert cirq.inverse(cirq.ControlledGate(cirq.S)) == cirq.ControlledGate(cirq.S**-1)
529
565
  assert cirq.inverse(cirq.ControlledGate(cirq.S, num_controls=4)) == cirq.ControlledGate(
530
566
  cirq.S**-1, num_controls=4
@@ -542,7 +578,7 @@ class UnphaseableGate(cirq.Gate):
542
578
 
543
579
 
544
580
  @pytest.mark.parametrize('resolve_fn', [cirq.resolve_parameters, cirq.resolve_parameters_once])
545
- def test_parameterizable(resolve_fn):
581
+ def test_parameterizable(resolve_fn) -> None:
546
582
  a = sympy.Symbol('a')
547
583
  cy = cirq.ControlledGate(cirq.Y)
548
584
  cya = cirq.ControlledGate(cirq.YPowGate(exponent=a))
@@ -557,7 +593,7 @@ def test_parameterizable(resolve_fn):
557
593
  resolve_fn(cchan, cirq.ParamResolver({'a': 0.1}))
558
594
 
559
595
 
560
- def test_circuit_diagram_info():
596
+ def test_circuit_diagram_info() -> None:
561
597
  assert cirq.circuit_diagram_info(CY) == cirq.CircuitDiagramInfo(
562
598
  wire_symbols=('@', 'Y'), exponent=1
563
599
  )
@@ -609,7 +645,7 @@ class MultiH(cirq.Gate):
609
645
  return True
610
646
 
611
647
 
612
- def test_circuit_diagram_product_of_sums():
648
+ def test_circuit_diagram_product_of_sums() -> None:
613
649
  qubits = cirq.LineQubit.range(3)
614
650
  c = cirq.Circuit()
615
651
  c.append(cirq.ControlledGate(MultiH(2))(*qubits))
@@ -625,9 +661,9 @@ def test_circuit_diagram_product_of_sums():
625
661
  """,
626
662
  )
627
663
 
628
- qubits = cirq.LineQid.for_qid_shape((3, 3, 3, 2))
664
+ qids = cirq.LineQid.for_qid_shape((3, 3, 3, 2))
629
665
  c = cirq.Circuit(
630
- MultiH(1)(*qubits[3:]).controlled_by(*qubits[:3], control_values=[1, (0, 1), (2, 0)])
666
+ MultiH(1)(*qids[3:]).controlled_by(*qids[:3], control_values=[1, (0, 1), (2, 0)])
631
667
  )
632
668
 
633
669
  cirq.testing.assert_has_diagram(
@@ -644,7 +680,7 @@ def test_circuit_diagram_product_of_sums():
644
680
  )
645
681
 
646
682
 
647
- def test_circuit_diagram_sum_of_products():
683
+ def test_circuit_diagram_sum_of_products() -> None:
648
684
  q = cirq.LineQubit.range(4)
649
685
  c = cirq.Circuit(C_xorH.on(*q[:3]), C_01_10_11H.on(*q[:3]), C0C_xorH.on(*q))
650
686
  cirq.testing.assert_has_diagram(
@@ -659,8 +695,8 @@ def test_circuit_diagram_sum_of_products():
659
695
  3: ─────────────────────H───────
660
696
  """,
661
697
  )
662
- q = cirq.LineQid.for_qid_shape((2, 3, 2))
663
- c = cirq.Circuit(C_02_20H(*q))
698
+ qid = cirq.LineQid.for_qid_shape((2, 3, 2))
699
+ c = cirq.Circuit(C_02_20H(*qid))
664
700
  cirq.testing.assert_has_diagram(
665
701
  c,
666
702
  """
@@ -682,7 +718,7 @@ class MockGate(cirq.testing.TwoQubitGate):
682
718
  return True
683
719
 
684
720
 
685
- def test_uninformed_circuit_diagram_info():
721
+ def test_uninformed_circuit_diagram_info() -> None:
686
722
  qbits = cirq.LineQubit.range(3)
687
723
  mock_gate = MockGate()
688
724
  cgate = cirq.ControlledGate(mock_gate)(*qbits)
@@ -695,7 +731,7 @@ def test_uninformed_circuit_diagram_info():
695
731
  assert mock_gate.captured_diagram_args == args
696
732
 
697
733
 
698
- def test_bounded_effect():
734
+ def test_bounded_effect() -> None:
699
735
  assert cirq.trace_distance_bound(CY**0.001) < 0.01
700
736
  assert cirq.approx_eq(cirq.trace_distance_bound(CCH), 1.0)
701
737
  foo = sympy.Symbol('foo')
@@ -715,11 +751,11 @@ def test_bounded_effect():
715
751
  C_02_20H,
716
752
  ],
717
753
  )
718
- def test_repr(gate):
754
+ def test_repr(gate) -> None:
719
755
  cirq.testing.assert_equivalent_repr(gate)
720
756
 
721
757
 
722
- def test_str():
758
+ def test_str() -> None:
723
759
  assert str(cirq.ControlledGate(cirq.X)) == 'CX'
724
760
  assert str(cirq.ControlledGate(cirq.Z)) == 'CZ'
725
761
  assert str(cirq.ControlledGate(cirq.S)) == 'CS'
@@ -733,7 +769,66 @@ def test_str():
733
769
  assert str(C2Restricted) == 'C2Restricted'
734
770
 
735
771
 
736
- def test_controlled_mixture():
772
+ def test_controlled_mixture() -> None:
737
773
  c_yes = cirq.ControlledGate(sub_gate=cirq.phase_flip(0.25), num_controls=1)
738
774
  assert cirq.has_mixture(c_yes)
739
775
  assert cirq.approx_eq(cirq.mixture(c_yes), [(0.75, np.eye(4)), (0.25, cirq.unitary(cirq.CZ))])
776
+
777
+
778
+ @pytest.mark.parametrize(
779
+ 'num_controls, angle, control_values',
780
+ [
781
+ (1, np.pi / 4, ((1,),)),
782
+ (3, -np.pi / 2, ((1,), (1,), (1,))),
783
+ (2, 0.0, ((1,), (1,))),
784
+ (2, np.pi / 5, ((0,), (0,))),
785
+ (3, np.pi, ((1,), (0,), (1,))),
786
+ (4, -np.pi / 3, ((0,), (1,), (1,), (0,))),
787
+ ],
788
+ )
789
+ def test_controlled_global_phase_matrix_gate_decomposes(
790
+ num_controls, angle, control_values
791
+ ) -> None:
792
+ all_qubits = cirq.LineQubit.range(num_controls)
793
+ control_values = cirq.ops.control_values.ProductOfSums(control_values)
794
+ control_qid_shape = (2,) * num_controls
795
+ phase_value = np.exp(1j * angle)
796
+
797
+ cg_matrix = cirq.ControlledGate(
798
+ sub_gate=cirq.MatrixGate(np.array([[phase_value]])),
799
+ num_controls=num_controls,
800
+ control_values=control_values,
801
+ control_qid_shape=control_qid_shape,
802
+ )
803
+
804
+ decomposed = cirq.decompose(cg_matrix(*all_qubits))
805
+ assert not any(isinstance(op.gate, cirq.MatrixGate) for op in decomposed)
806
+ np.testing.assert_allclose(cirq.unitary(cirq.Circuit(decomposed)), cirq.unitary(cg_matrix))
807
+
808
+
809
+ @pytest.mark.parametrize('gate_type', [cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.CZPowGate])
810
+ @pytest.mark.parametrize('test_shift', np.pi * (np.random.default_rng(324).random(10) * 2 - 1))
811
+ def test_controlled_phase_extracted_before_decomposition(gate_type, test_shift) -> None:
812
+ test_shift = 0.123 # arbitrary
813
+
814
+ shifted_gate = gate_type(global_shift=test_shift).controlled()
815
+ unshifted_gate = gate_type().controlled()
816
+ qs = cirq.LineQubit.range(cirq.num_qubits(shifted_gate))
817
+ shifted_op = shifted_gate.on(*qs)
818
+ unshifted_op = unshifted_gate.on(*qs)
819
+ shifted_decomposition = cirq.decompose(shifted_op)
820
+ unshifted_decomposition = cirq.decompose(unshifted_op)
821
+
822
+ # No brute-force calculation. It's the standard decomposition plus Z for the controlled shift.
823
+ assert shifted_decomposition[:-1] == unshifted_decomposition
824
+ z_op = shifted_decomposition[-1]
825
+ assert z_op.qubits == (qs[0],)
826
+ z = z_op.gate
827
+ assert isinstance(z, cirq.ZPowGate)
828
+ np.testing.assert_approx_equal(z.exponent, test_shift)
829
+ assert z.global_shift == 0
830
+
831
+ # Sanity check that the decomposition is equivalent
832
+ np.testing.assert_allclose(
833
+ cirq.unitary(cirq.Circuit(shifted_decomposition)), cirq.unitary(shifted_op), atol=1e-10
834
+ )
@@ -12,19 +12,10 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from types import NotImplementedType
16
- from typing import (
17
- AbstractSet,
18
- Any,
19
- Collection,
20
- Dict,
21
- List,
22
- Optional,
23
- Sequence,
24
- Tuple,
25
- TYPE_CHECKING,
26
- Union,
27
- )
15
+ from __future__ import annotations
16
+
17
+ from types import EllipsisType, NotImplementedType
18
+ from typing import AbstractSet, Any, Collection, Sequence, TYPE_CHECKING
28
19
 
29
20
  import numpy as np
30
21
 
@@ -53,11 +44,9 @@ class ControlledOperation(raw_types.Operation):
53
44
 
54
45
  def __init__(
55
46
  self,
56
- controls: Sequence['cirq.Qid'],
57
- sub_operation: 'cirq.Operation',
58
- control_values: Optional[
59
- Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
60
- ] = None,
47
+ controls: Sequence[cirq.Qid],
48
+ sub_operation: cirq.Operation,
49
+ control_values: cv.AbstractControlValues | Sequence[int | Collection[int]] | None = None,
61
50
  ):
62
51
  """Initializes the controlled operation.
63
52
 
@@ -114,7 +103,7 @@ class ControlledOperation(raw_types.Operation):
114
103
  self._control_values = self._control_values & sub_operation.control_values
115
104
 
116
105
  @property
117
- def controls(self) -> Tuple['cirq.Qid', ...]:
106
+ def controls(self) -> tuple[cirq.Qid, ...]:
118
107
  return self._controls
119
108
 
120
109
  @property
@@ -122,11 +111,11 @@ class ControlledOperation(raw_types.Operation):
122
111
  return self._control_values
123
112
 
124
113
  @property
125
- def sub_operation(self) -> 'cirq.Operation':
114
+ def sub_operation(self) -> cirq.Operation:
126
115
  return self._sub_operation
127
116
 
128
117
  @property
129
- def gate(self) -> Optional['cirq.ControlledGate']:
118
+ def gate(self) -> cirq.ControlledGate | None:
130
119
  if self.sub_operation.gate is None:
131
120
  return None
132
121
  return controlled_gate.ControlledGate(
@@ -148,7 +137,7 @@ class ControlledOperation(raw_types.Operation):
148
137
  def _decompose_(self):
149
138
  return self._decompose_with_context_()
150
139
 
151
- def _decompose_with_context_(self, context: Optional['cirq.DecompositionContext'] = None):
140
+ def _decompose_with_context_(self, context: cirq.DecompositionContext | None = None):
152
141
  result = protocols.decompose_once_with_qubits(
153
142
  self.gate, self.qubits, NotImplemented, flatten=False, context=context
154
143
  )
@@ -176,12 +165,12 @@ class ControlledOperation(raw_types.Operation):
176
165
  )
177
166
  return sorted_controls, tuple(expanded_cvals), self.sub_operation
178
167
 
179
- def _apply_unitary_(self, args: 'protocols.ApplyUnitaryArgs') -> np.ndarray:
168
+ def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray:
180
169
  n = len(self.controls)
181
170
  sub_n = len(args.axes) - n
182
171
  sub_axes = args.axes[n:]
183
172
  for control_vals in self.control_values.expand():
184
- active: Tuple[Union['ellipsis', slice], ...] = (
173
+ active: tuple[EllipsisType | slice, ...] = (
185
174
  ...,
186
175
  *(slice(v, v + 1) for v in control_vals),
187
176
  *(slice(None),) * sub_n,
@@ -207,7 +196,7 @@ class ControlledOperation(raw_types.Operation):
207
196
  def _has_unitary_(self) -> bool:
208
197
  return protocols.has_unitary(self.sub_operation)
209
198
 
210
- def _qasm_(self, args: 'cirq.QasmArgs') -> Optional[str]:
199
+ def _qasm_(self, args: cirq.QasmArgs) -> str | None:
211
200
  if (
212
201
  hasattr(self._sub_operation, "gate")
213
202
  and len(self._controls) == 1
@@ -241,10 +230,10 @@ class ControlledOperation(raw_types.Operation):
241
230
  sub_tensor = sub_matrix.reshape(qid_shape[len(self.controls) :] * 2)
242
231
  for control_vals in self.control_values.expand():
243
232
  active = (*(v for v in control_vals), *(slice(None),) * sub_n) * 2
244
- tensor[active] = sub_tensor
233
+ tensor[active] = sub_tensor # type: ignore[index]
245
234
  return tensor.reshape((np.prod(qid_shape, dtype=np.int64).item(),) * 2)
246
235
 
247
- def _unitary_(self) -> Union[np.ndarray, NotImplementedType]:
236
+ def _unitary_(self) -> np.ndarray | NotImplementedType:
248
237
  sub_matrix = protocols.unitary(self.sub_operation, None)
249
238
  if sub_matrix is None:
250
239
  return NotImplemented
@@ -253,7 +242,7 @@ class ControlledOperation(raw_types.Operation):
253
242
  def _has_mixture_(self) -> bool:
254
243
  return protocols.has_mixture(self.sub_operation)
255
244
 
256
- def _mixture_(self) -> Optional[List[Tuple[float, np.ndarray]]]:
245
+ def _mixture_(self) -> list[tuple[float, np.ndarray]] | None:
257
246
  sub_mixture = protocols.mixture(self.sub_operation, None)
258
247
  if sub_mixture is None:
259
248
  return None
@@ -287,12 +276,12 @@ class ControlledOperation(raw_types.Operation):
287
276
  return protocols.parameter_names(self.sub_operation)
288
277
 
289
278
  def _resolve_parameters_(
290
- self, resolver: 'cirq.ParamResolver', recursive: bool
291
- ) -> 'ControlledOperation':
279
+ self, resolver: cirq.ParamResolver, recursive: bool
280
+ ) -> ControlledOperation:
292
281
  new_sub_op = protocols.resolve_parameters(self.sub_operation, resolver, recursive)
293
282
  return ControlledOperation(self.controls, new_sub_op, self.control_values)
294
283
 
295
- def _trace_distance_bound_(self) -> Optional[float]:
284
+ def _trace_distance_bound_(self) -> float | None:
296
285
  if self._is_parameterized_():
297
286
  return None
298
287
  u = protocols.unitary(self.sub_operation, default=None)
@@ -301,15 +290,15 @@ class ControlledOperation(raw_types.Operation):
301
290
  angle_list = np.append(np.angle(np.linalg.eigvals(u)), 0)
302
291
  return protocols.trace_distance_from_angle_list(angle_list)
303
292
 
304
- def __pow__(self, exponent: Any) -> 'ControlledOperation':
293
+ def __pow__(self, exponent: Any) -> ControlledOperation:
305
294
  new_sub_op = protocols.pow(self.sub_operation, exponent, NotImplemented)
306
295
  if new_sub_op is NotImplemented:
307
296
  return NotImplemented
308
297
  return ControlledOperation(self.controls, new_sub_op, self.control_values)
309
298
 
310
299
  def _circuit_diagram_info_(
311
- self, args: 'cirq.CircuitDiagramInfoArgs'
312
- ) -> Optional['protocols.CircuitDiagramInfo']:
300
+ self, args: cirq.CircuitDiagramInfoArgs
301
+ ) -> protocols.CircuitDiagramInfo | None:
313
302
  n = len(self.controls)
314
303
 
315
304
  sub_args = protocols.CircuitDiagramInfoArgs(
@@ -344,7 +333,7 @@ class ControlledOperation(raw_types.Operation):
344
333
  exponent_qubit_index=exponent_qubit_index,
345
334
  )
346
335
 
347
- def _json_dict_(self) -> Dict[str, Any]:
336
+ def _json_dict_(self) -> dict[str, Any]:
348
337
  return {
349
338
  'controls': self.controls,
350
339
  'control_values': self.control_values,
@@ -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 itertools
16
18
  import re
17
- from types import NotImplementedType
18
- from typing import cast, Tuple, Union
19
+ from types import EllipsisType, NotImplementedType
20
+ from typing import cast
19
21
 
20
22
  import numpy as np
21
23
  import pytest
@@ -26,7 +28,7 @@ from cirq import protocols
26
28
 
27
29
 
28
30
  class GateUsingWorkspaceForApplyUnitary(cirq.testing.SingleQubitGate):
29
- def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> Union[np.ndarray, NotImplementedType]:
31
+ def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> np.ndarray | NotImplementedType:
30
32
  args.available_buffer[...] = args.target_tensor
31
33
  args.target_tensor[...] = 0
32
34
  return args.available_buffer
@@ -45,10 +47,10 @@ class GateAllocatingNewSpaceForResult(cirq.testing.SingleQubitGate):
45
47
  def __init__(self):
46
48
  self._matrix = cirq.testing.random_unitary(2, random_state=1234)
47
49
 
48
- def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> Union[np.ndarray, NotImplementedType]:
50
+ def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> np.ndarray | NotImplementedType:
49
51
  assert len(args.axes) == 1
50
52
  a = args.axes[0]
51
- seed = cast(Tuple[Union[int, slice, 'ellipsis'], ...], (slice(None),))
53
+ seed = cast(tuple[int | slice | EllipsisType, ...], (slice(None),))
52
54
  zero = seed * a + (0, Ellipsis)
53
55
  one = seed * a + (1, Ellipsis)
54
56
  result = np.zeros(args.target_tensor.shape, args.target_tensor.dtype)
@@ -155,7 +157,7 @@ def test_str():
155
157
 
156
158
  class SingleQubitOp(cirq.Operation):
157
159
  @property
158
- def qubits(self) -> Tuple[cirq.Qid, ...]:
160
+ def qubits(self) -> tuple[cirq.Qid, ...]:
159
161
  return ()
160
162
 
161
163
  def with_qubits(self, *new_qubits: cirq.Qid):