cirq-core 1.5.0.dev20250409225226__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.dev20250409225226.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.dev20250409225226.dist-info → cirq_core-1.6.0.dist-info}/WHEEL +1 -1
  730. cirq_core-1.5.0.dev20250409225226.dist-info/RECORD +0 -1216
  731. {cirq_core-1.5.0.dev20250409225226.dist-info → cirq_core-1.6.0.dist-info}/licenses/LICENSE +0 -0
  732. {cirq_core-1.5.0.dev20250409225226.dist-info → cirq_core-1.6.0.dist-info}/top_level.txt +0 -0
@@ -12,7 +12,11 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import Any, Callable, Optional, overload, TYPE_CHECKING, TypeVar, Union
15
+ # ruff: noqa: A001
16
+
17
+ from __future__ import annotations
18
+
19
+ from typing import Any, Callable, overload, TYPE_CHECKING, TypeVar
16
20
 
17
21
  if TYPE_CHECKING:
18
22
  import cirq
@@ -24,31 +28,28 @@ RaiseTypeErrorIfNotProvided: Any = ([],)
24
28
  TDefault = TypeVar('TDefault')
25
29
 
26
30
 
27
- # pylint: disable=function-redefined, redefined-builtin
28
31
  @overload
29
- def pow(val: 'cirq.Gate', exponent: Any) -> 'cirq.Gate':
32
+ def pow(val: cirq.Gate, exponent: Any) -> cirq.Gate:
30
33
  pass
31
34
 
32
35
 
33
36
  @overload
34
- def pow(val: 'cirq.Operation', exponent: Any) -> 'cirq.Operation':
37
+ def pow(val: cirq.Operation, exponent: Any) -> cirq.Operation:
35
38
  pass
36
39
 
37
40
 
38
41
  @overload
39
- def pow(val: 'cirq.Gate', exponent: Any, default: TDefault) -> Union[TDefault, 'cirq.Gate']:
42
+ def pow(val: cirq.Gate, exponent: Any, default: TDefault) -> TDefault | cirq.Gate:
40
43
  pass
41
44
 
42
45
 
43
46
  @overload
44
- def pow(
45
- val: 'cirq.Operation', exponent: Any, default: TDefault
46
- ) -> Union[TDefault, 'cirq.Operation']:
47
+ def pow(val: cirq.Operation, exponent: Any, default: TDefault) -> TDefault | cirq.Operation:
47
48
  pass
48
49
 
49
50
 
50
51
  @overload
51
- def pow(val: 'cirq.Circuit', exponent: int, default: TDefault) -> Union[TDefault, 'cirq.Circuit']:
52
+ def pow(val: cirq.Circuit, exponent: int, default: TDefault) -> TDefault | cirq.Circuit:
52
53
  pass
53
54
 
54
55
 
@@ -57,9 +58,6 @@ def pow(val: Any, exponent: Any, default: TDefault) -> Any:
57
58
  pass
58
59
 
59
60
 
60
- # pylint: enable=function-redefined
61
-
62
-
63
61
  def pow(val: Any, exponent: Any, default: Any = RaiseTypeErrorIfNotProvided) -> Any:
64
62
  """Returns `val**factor` of the given value, if defined.
65
63
 
@@ -84,7 +82,7 @@ def pow(val: Any, exponent: Any, default: Any = RaiseTypeErrorIfNotProvided) ->
84
82
  TypeError: `val` doesn't have a __pow__ method (or that method returned
85
83
  NotImplemented) and no `default` value was specified.
86
84
  """
87
- raiser: Optional[Callable] = getattr(val, '__pow__', None)
85
+ raiser: Callable | None = getattr(val, '__pow__', None)
88
86
  result = NotImplemented if raiser is None else raiser(exponent)
89
87
  if result is not NotImplemented:
90
88
  return result
@@ -96,6 +94,3 @@ def pow(val: Any, exponent: Any, default: Any = RaiseTypeErrorIfNotProvided) ->
96
94
  raise TypeError(
97
95
  f"object of type '{type(val)}' does have a __pow__ method, but it returned NotImplemented."
98
96
  )
99
-
100
-
101
- # pylint: enable=redefined-builtin
@@ -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 pytest
16
18
 
17
19
  import cirq
cirq/protocols/qasm.py CHANGED
@@ -12,9 +12,11 @@
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 string
16
18
  from types import NotImplementedType
17
- from typing import Any, Dict, Iterable, Optional, Tuple, TYPE_CHECKING, TypeVar, Union
19
+ from typing import Any, Iterable, Mapping, TYPE_CHECKING, TypeVar
18
20
 
19
21
  from typing_extensions import Protocol
20
22
 
@@ -36,9 +38,9 @@ class QasmArgs(string.Formatter):
36
38
  self,
37
39
  precision: int = 10,
38
40
  version: str = '2.0',
39
- qubit_id_map: Optional[Dict['cirq.Qid', str]] = None,
40
- meas_key_id_map: Optional[Dict[str, str]] = None,
41
- meas_key_bitcount: Optional[Dict[str, int]] = None,
41
+ qubit_id_map: Mapping[cirq.Qid, str] | None = None,
42
+ meas_key_id_map: dict[str, str] | None = None,
43
+ meas_key_bitcount: dict[str, int] | None = None,
42
44
  ) -> None:
43
45
  """Inits QasmArgs.
44
46
 
@@ -62,7 +64,7 @@ class QasmArgs(string.Formatter):
62
64
  def _format_number(self, value) -> str:
63
65
  """OpenQASM 2.0 does not support '1e-5' and wants '1.0e-5'"""
64
66
  s = f'{value}'
65
- if 'e' in s and not '.' in s:
67
+ if 'e' in s and '.' not in s:
66
68
  return s.replace('e', '.0e')
67
69
  return s
68
70
 
@@ -97,7 +99,7 @@ class SupportsQasm(Protocol):
97
99
  """
98
100
 
99
101
  @doc_private
100
- def _qasm_(self) -> Union[None, NotImplementedType, str]:
102
+ def _qasm_(self) -> None | NotImplementedType | str:
101
103
  pass
102
104
 
103
105
 
@@ -110,7 +112,7 @@ class SupportsQasmWithArgs(Protocol):
110
112
  """
111
113
 
112
114
  @doc_private
113
- def _qasm_(self, args: QasmArgs) -> Union[None, NotImplementedType, str]:
115
+ def _qasm_(self, args: QasmArgs) -> None | NotImplementedType | str:
114
116
  pass
115
117
 
116
118
 
@@ -123,20 +125,17 @@ class SupportsQasmWithArgsAndQubits(Protocol):
123
125
  """
124
126
 
125
127
  @doc_private
126
- def _qasm_(
127
- self, qubits: Tuple['cirq.Qid'], args: QasmArgs
128
- ) -> Union[None, NotImplementedType, str]:
128
+ def _qasm_(self, qubits: tuple[cirq.Qid], args: QasmArgs) -> None | NotImplementedType | str:
129
129
  pass
130
130
 
131
131
 
132
- # pylint: disable=function-redefined
133
132
  def qasm(
134
133
  val: Any,
135
134
  *,
136
- args: Optional[QasmArgs] = None,
137
- qubits: Optional[Iterable['cirq.Qid']] = None,
135
+ args: QasmArgs | None = None,
136
+ qubits: Iterable[cirq.Qid] | None = None,
138
137
  default: TDefault = RaiseTypeErrorIfNotProvided,
139
- ) -> Union[str, TDefault]:
138
+ ) -> str | TDefault:
140
139
  """Returns QASM code for the given value, if possible.
141
140
 
142
141
  Different values require different sets of arguments. The general rule of
@@ -169,10 +168,9 @@ def qasm(
169
168
  method = getattr(val, '_qasm_', None)
170
169
  result = NotImplemented
171
170
  if method is not None:
172
- kwargs: Dict[str, Any] = {}
171
+ kwargs: dict[str, Any] = {}
173
172
  if args is not None:
174
173
  kwargs['args'] = args
175
- # pylint: disable=not-callable
176
174
  if qubits is not None:
177
175
  kwargs['qubits'] = tuple(qubits)
178
176
  try:
@@ -182,7 +180,6 @@ def qasm(
182
180
  "cirq.qasm does not expect qubits or args to be specified"
183
181
  f"for the given value of type {type(val)}."
184
182
  ) from error
185
- # pylint: enable=not-callable
186
183
  if result is not None and result is not NotImplemented:
187
184
  return result
188
185
 
@@ -194,6 +191,3 @@ def qasm(
194
191
  f"object of type '{type(val)}' does have a _qasm_ method, "
195
192
  "but it returned NotImplemented or None."
196
193
  )
197
-
198
-
199
- # pylint: enable=function-redefined
@@ -11,6 +11,9 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
14
17
  import pytest
15
18
 
16
19
  import cirq
@@ -40,7 +43,7 @@ class ExpectsArgsQubits:
40
43
  return 'text'
41
44
 
42
45
 
43
- def test_qasm():
46
+ def test_qasm() -> None:
44
47
  assert cirq.qasm(NoMethod(), default=None) is None
45
48
  assert cirq.qasm(NoMethod(), default=5) == 5
46
49
  assert cirq.qasm(ReturnsText()) == 'text'
@@ -54,12 +57,12 @@ def test_qasm():
54
57
  assert cirq.qasm(ExpectsArgsQubits(), args=cirq.QasmArgs(), qubits=()) == 'text'
55
58
 
56
59
 
57
- def test_qasm_qubits_improperly_supplied():
60
+ def test_qasm_qubits_improperly_supplied() -> None:
58
61
  with pytest.raises(TypeError, match="does not expect qubits or args to be specified"):
59
62
  _ = cirq.qasm(cirq.Circuit(), qubits=[cirq.LineQubit(1)])
60
63
 
61
64
 
62
- def test_qasm_args_formatting():
65
+ def test_qasm_args_formatting() -> None:
63
66
  args = cirq.QasmArgs()
64
67
  assert args.format_field(0.01, '') == '0.01'
65
68
  assert args.format_field(0.01, 'half_turns') == 'pi*0.01'
@@ -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 __future__ import annotations
16
+
15
17
  from types import NotImplementedType
16
- from typing import Any, Sequence, Tuple, TypeVar, Union
18
+ from typing import Any, Sequence, TypeVar
17
19
 
18
20
  from typing_extensions import Protocol
19
21
 
@@ -22,7 +24,7 @@ from cirq._doc import doc_private, document
22
24
 
23
25
  # This is a special indicator value used by the methods to determine whether or
24
26
  # not the caller provided a 'default' argument. It must be of type
25
- # Tuple[int, ...] to ensure the method has the correct type signature in that
27
+ # tuple[int, ...] to ensure the method has the correct type signature in that
26
28
  # case. It is checked for using `is`, so it won't have a false positive if the
27
29
  # user provides a different (0,) value.
28
30
  RaiseTypeErrorIfNotProvided: Any = (0,)
@@ -37,7 +39,7 @@ class SupportsExplicitQidShape(Protocol):
37
39
  number qubits/qudits/qids, each with a specific number of quantum levels."""
38
40
 
39
41
  @doc_private
40
- def _qid_shape_(self) -> Union[Tuple[int, ...], NotImplementedType]:
42
+ def _qid_shape_(self) -> tuple[int, ...] | NotImplementedType:
41
43
  """A tuple specifying the number of quantum levels of each qid this
42
44
  object operates on, e.g. (2, 2, 2) for a three-qubit gate.
43
45
 
@@ -65,7 +67,7 @@ class SupportsExplicitNumQubits(Protocol):
65
67
  number of qubits."""
66
68
 
67
69
  @document
68
- def _num_qubits_(self) -> Union[int, NotImplementedType]:
70
+ def _num_qubits_(self) -> int | NotImplementedType:
69
71
  """The number of qubits, qudits, or qids this object operates on.
70
72
 
71
73
  This method is used by the global `cirq.num_qubits` method (and by
@@ -80,7 +82,7 @@ class SupportsExplicitNumQubits(Protocol):
80
82
 
81
83
  def qid_shape(
82
84
  val: Any, default: TDefault = RaiseTypeErrorIfNotProvided
83
- ) -> Union[Tuple[int, ...], TDefault]:
85
+ ) -> tuple[int, ...] | TDefault:
84
86
  """Returns a tuple describing the number of quantum levels of each
85
87
  qubit/qudit/qid `val` operates on.
86
88
 
@@ -134,9 +136,7 @@ def qid_shape(
134
136
  raise TypeError(f"object of type '{type(val)}' has no _num_qubits_ or _qid_shape_ methods.")
135
137
 
136
138
 
137
- def num_qubits(
138
- val: Any, default: TDefault = RaiseTypeErrorIfNotProvidedInt
139
- ) -> Union[int, TDefault]:
139
+ def num_qubits(val: Any, default: TDefault = RaiseTypeErrorIfNotProvidedInt) -> int | TDefault:
140
140
  """Returns the number of qubits, qudits, or qids `val` operates on.
141
141
 
142
142
  Args:
@@ -12,12 +12,14 @@
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 pytest
16
18
 
17
19
  import cirq
18
20
 
19
21
 
20
- def test_qid_shape():
22
+ def test_qid_shape() -> None:
21
23
  class ShapeObj:
22
24
  def _qid_shape_(self):
23
25
  return (1, 2, 3)
@@ -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 numbers
16
18
  from typing import AbstractSet, Any, cast, TYPE_CHECKING, TypeVar
17
19
 
@@ -48,7 +50,7 @@ class SupportsParameterization(Protocol):
48
50
  """
49
51
 
50
52
  @doc_private
51
- def _resolve_parameters_(self, resolver: 'cirq.ParamResolver', recursive: bool) -> Self:
53
+ def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> Self:
52
54
  """Resolve the parameters in the effect."""
53
55
 
54
56
 
@@ -133,7 +135,7 @@ def parameter_symbols(val: Any) -> AbstractSet[sympy.Symbol]:
133
135
 
134
136
 
135
137
  def resolve_parameters(
136
- val: T, param_resolver: 'cirq.ParamResolverOrSimilarType', recursive: bool = True
138
+ val: T, param_resolver: cirq.ParamResolverOrSimilarType, recursive: bool = True
137
139
  ) -> T:
138
140
  """Resolves symbol parameters in the effect using the param resolver.
139
141
 
@@ -195,6 +197,6 @@ def resolve_parameters(
195
197
  return val
196
198
 
197
199
 
198
- def resolve_parameters_once(val: Any, param_resolver: 'cirq.ParamResolverOrSimilarType'):
200
+ def resolve_parameters_once(val: Any, param_resolver: cirq.ParamResolverOrSimilarType):
199
201
  """Performs a single parameter resolution step using the param resolver."""
200
202
  return resolve_parameters(val, param_resolver, False)
@@ -12,15 +12,16 @@
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 pytest
16
18
  import sympy
17
19
 
18
20
  import cirq
19
- from cirq.study import ParamResolver
20
21
 
21
22
 
22
23
  @pytest.mark.parametrize('resolve_fn', [cirq.resolve_parameters, cirq.resolve_parameters_once])
23
- def test_resolve_parameters(resolve_fn):
24
+ def test_resolve_parameters(resolve_fn) -> None:
24
25
  class NoMethod:
25
26
  pass
26
27
 
@@ -38,7 +39,7 @@ def test_resolve_parameters(resolve_fn):
38
39
  def _is_parameterized_(self) -> bool:
39
40
  return self.parameter != 0
40
41
 
41
- def _resolve_parameters_(self, resolver: ParamResolver, recursive: bool):
42
+ def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool):
42
43
  self.parameter = resolver.value_of(self.parameter, recursive)
43
44
  return self
44
45
 
@@ -74,7 +75,7 @@ def test_resolve_parameters(resolve_fn):
74
75
  assert resolve_fn(1j, resolver) == 1j
75
76
 
76
77
 
77
- def test_is_parameterized():
78
+ def test_is_parameterized() -> None:
78
79
  a, b = tuple(sympy.Symbol(l) for l in 'ab')
79
80
  x, y = 0, 4
80
81
  assert not cirq.is_parameterized((x, y))
@@ -90,7 +91,7 @@ def test_is_parameterized():
90
91
  assert not cirq.is_parameterized(1j)
91
92
 
92
93
 
93
- def test_parameter_names():
94
+ def test_parameter_names() -> None:
94
95
  a, b, c = tuple(sympy.Symbol(l) for l in 'abc')
95
96
  x, y, z = 0, 4, 7
96
97
  assert cirq.parameter_names((a, b, c)) == {'a', 'b', 'c'}
@@ -105,7 +106,7 @@ def test_parameter_names():
105
106
 
106
107
 
107
108
  @pytest.mark.parametrize('resolve_fn', [cirq.resolve_parameters, cirq.resolve_parameters_once])
108
- def test_skips_empty_resolution(resolve_fn):
109
+ def test_skips_empty_resolution(resolve_fn) -> None:
109
110
  class Tester:
110
111
  def _resolve_parameters_(self, resolver, recursive):
111
112
  return 5
@@ -115,7 +116,7 @@ def test_skips_empty_resolution(resolve_fn):
115
116
  assert resolve_fn(t, {'x': 2}) == 5
116
117
 
117
118
 
118
- def test_recursive_resolve():
119
+ def test_recursive_resolve() -> None:
119
120
  a, b, c = [sympy.Symbol(l) for l in 'abc']
120
121
  resolver = cirq.ParamResolver({a: b + 3, b: c + 2, c: 1})
121
122
  assert cirq.resolve_parameters_once(a, resolver) == b + 3
@@ -12,7 +12,9 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import Any, Optional, Sequence, TypeVar, Union
15
+ from __future__ import annotations
16
+
17
+ from typing import Any, Sequence, TypeVar
16
18
 
17
19
  import numpy as np
18
20
  from typing_extensions import Protocol
@@ -79,7 +81,7 @@ def trace_distance_bound(val: Any) -> float:
79
81
  return 1.0
80
82
 
81
83
 
82
- def _strat_from_trace_distance_bound_method(val: Any) -> Optional[float]:
84
+ def _strat_from_trace_distance_bound_method(val: Any) -> float | None:
83
85
  """Attempts to use a specialized method."""
84
86
  getter = getattr(val, '_trace_distance_bound_', None)
85
87
  result = NotImplemented if getter is None else getter()
@@ -93,7 +95,7 @@ def _strat_from_trace_distance_bound_method(val: Any) -> Optional[float]:
93
95
  return NotImplemented
94
96
 
95
97
 
96
- def _strat_distance_from_unitary(val: Any) -> Optional[float]:
98
+ def _strat_distance_from_unitary(val: Any) -> float | None:
97
99
  """Attempts to compute a value's trace_distance_bound from its unitary."""
98
100
  u = unitary_protocol.unitary(val, default=None)
99
101
 
@@ -109,7 +111,7 @@ def _strat_distance_from_unitary(val: Any) -> Optional[float]:
109
111
  return trace_distance_from_angle_list(np.angle(np.linalg.eigvals(u)))
110
112
 
111
113
 
112
- def trace_distance_from_angle_list(angle_list: Union[Sequence[float], np.ndarray]) -> float:
114
+ def trace_distance_from_angle_list(angle_list: Sequence[float] | np.ndarray) -> float:
113
115
  """Given a list of arguments of the eigenvalues of a unitary matrix,
114
116
  calculates the trace distance bound of the unitary effect.
115
117
 
@@ -12,12 +12,14 @@
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 numpy as np
16
18
 
17
19
  import cirq
18
20
 
19
21
 
20
- def test_trace_distance_bound():
22
+ def test_trace_distance_bound() -> None:
21
23
  class NoMethod:
22
24
  pass
23
25
 
@@ -12,12 +12,15 @@
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
  from types import NotImplementedType
16
- from typing import Any, Optional, TypeVar, Union
18
+ from typing import Any, TypeVar
17
19
 
18
20
  import numpy as np
19
21
  from typing_extensions import Protocol
20
22
 
23
+ from cirq import linalg
21
24
  from cirq._doc import doc_private
22
25
  from cirq.protocols import qid_shape_protocol
23
26
  from cirq.protocols.apply_unitary_protocol import apply_unitaries, ApplyUnitaryArgs
@@ -37,7 +40,7 @@ class SupportsUnitary(Protocol):
37
40
  """An object that may be describable by a unitary matrix."""
38
41
 
39
42
  @doc_private
40
- def _unitary_(self) -> Union[np.ndarray, NotImplementedType]:
43
+ def _unitary_(self) -> np.ndarray | NotImplementedType:
41
44
  """A unitary matrix describing this value, e.g. the matrix of a gate.
42
45
 
43
46
  This method is used by the global `cirq.unitary` method. If this method
@@ -76,12 +79,13 @@ class SupportsUnitary(Protocol):
76
79
 
77
80
 
78
81
  def unitary(
79
- val: Any, default: Union[np.ndarray, TDefault] = RaiseTypeErrorIfNotProvided
80
- ) -> Union[np.ndarray, TDefault]:
82
+ val: Any, default: np.ndarray | TDefault = RaiseTypeErrorIfNotProvided
83
+ ) -> np.ndarray | TDefault:
81
84
  """Returns a unitary matrix describing the given value.
82
85
 
83
86
  The matrix is determined by any one of the following techniques:
84
87
 
88
+ - If the value is a numpy array, it is returned directly.
85
89
  - The value has a `_unitary_` method that returns something besides None or
86
90
  NotImplemented. The matrix is whatever the method returned.
87
91
  - The value has a `_decompose_` method that returns a list of operations,
@@ -108,7 +112,13 @@ def unitary(
108
112
  Raises:
109
113
  TypeError: `val` doesn't have a unitary effect and no default value was
110
114
  specified.
115
+ ValueError: `val` is a numpy array that is not unitary.
111
116
  """
117
+ if isinstance(val, np.ndarray):
118
+ if not linalg.is_unitary(val):
119
+ raise ValueError("The provided numpy array is not unitary.")
120
+ return val
121
+
112
122
  strats = [
113
123
  _strat_unitary_from_unitary,
114
124
  _strat_unitary_from_apply_unitary,
@@ -140,7 +150,7 @@ def unitary(
140
150
  )
141
151
 
142
152
 
143
- def _strat_unitary_from_unitary(val: Any) -> Optional[np.ndarray]:
153
+ def _strat_unitary_from_unitary(val: Any) -> np.ndarray | None:
144
154
  """Attempts to compute a value's unitary via its _unitary_ method."""
145
155
  getter = getattr(val, '_unitary_', None)
146
156
  if getter is None:
@@ -148,7 +158,7 @@ def _strat_unitary_from_unitary(val: Any) -> Optional[np.ndarray]:
148
158
  return getter()
149
159
 
150
160
 
151
- def _strat_unitary_from_apply_unitary(val: Any) -> Optional[np.ndarray]:
161
+ def _strat_unitary_from_apply_unitary(val: Any) -> np.ndarray | None:
152
162
  """Attempts to compute a value's unitary via its _apply_unitary_ method."""
153
163
  # Check for the magic method.
154
164
  method = getattr(val, '_apply_unitary_', None)
@@ -169,7 +179,7 @@ def _strat_unitary_from_apply_unitary(val: Any) -> Optional[np.ndarray]:
169
179
  return result.reshape((state_len, state_len))
170
180
 
171
181
 
172
- def _strat_unitary_from_decompose(val: Any) -> Optional[np.ndarray]:
182
+ def _strat_unitary_from_decompose(val: Any) -> np.ndarray | None:
173
183
  """Attempts to compute a value's unitary via its _decompose_ method."""
174
184
  # Check if there's a decomposition.
175
185
  operations, qubits, val_qid_shape = _try_decompose_into_operations_and_qubits(val)
@@ -11,7 +11,8 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- from typing import Optional
14
+
15
+ from __future__ import annotations
15
16
 
16
17
  import numpy as np
17
18
  import pytest
@@ -74,7 +75,7 @@ class FullyImplemented(cirq.Gate):
74
75
  def _has_unitary_(self) -> bool:
75
76
  return self.unitary_value
76
77
 
77
- def _unitary_(self) -> Optional[np.ndarray]:
78
+ def _unitary_(self) -> np.ndarray | None:
78
79
  if not self.unitary_value:
79
80
  return None
80
81
  return m1
@@ -160,6 +161,15 @@ def test_unitary():
160
161
  _ = cirq.unitary(ReturnsNotImplemented())
161
162
  assert cirq.unitary(ReturnsMatrix()) is m1
162
163
 
164
+ # Test that numpy arrays are handled directly
165
+ test_matrix = np.array([[1, 0], [0, 1]])
166
+ assert cirq.unitary(test_matrix, NotImplemented) is test_matrix
167
+
168
+ # Test that non-unitary numpy arrays raise ValueError
169
+ non_unitary_matrix = np.array([[1, 1], [0, 1]])
170
+ with pytest.raises(ValueError, match="The provided numpy array is not unitary"):
171
+ _ = cirq.unitary(non_unitary_matrix)
172
+
163
173
  assert cirq.unitary(NoMethod(), None) is None
164
174
  assert cirq.unitary(ReturnsNotImplemented(), None) is None
165
175
  assert cirq.unitary(ReturnsMatrix(), None) is m1
cirq/qis/channels.py CHANGED
@@ -11,7 +11,11 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
+
14
15
  """Tools for analyzing and manipulating quantum channels."""
16
+
17
+ from __future__ import annotations
18
+
15
19
  from typing import Sequence
16
20
 
17
21
  import numpy as np
@@ -280,7 +284,7 @@ def superoperator_to_choi(superoperator: np.ndarray) -> np.ndarray:
280
284
  return np.reshape(c, (d * d, d * d))
281
285
 
282
286
 
283
- def operation_to_choi(operation: 'protocols.SupportsKraus') -> np.ndarray:
287
+ def operation_to_choi(operation: protocols.SupportsKraus) -> np.ndarray:
284
288
  r"""Returns the unique Choi matrix associated with an operation .
285
289
 
286
290
  Choi matrix J(E) of a linear map E: L(H1) -> L(H2) which takes linear operators
@@ -302,7 +306,7 @@ def operation_to_choi(operation: 'protocols.SupportsKraus') -> np.ndarray:
302
306
  return kraus_to_choi(protocols.kraus(operation))
303
307
 
304
308
 
305
- def operation_to_superoperator(operation: 'protocols.SupportsKraus') -> np.ndarray:
309
+ def operation_to_superoperator(operation: protocols.SupportsKraus) -> np.ndarray:
306
310
  """Returns the matrix representation of an operation in standard basis.
307
311
 
308
312
  Let E: L(H1) -> L(H2) denote a linear map which takes linear operators on Hilbert space H1