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
@@ -14,13 +14,14 @@
14
14
 
15
15
  """A protocol for implementing high performance mixture evolutions."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  from types import NotImplementedType
18
- from typing import Any, cast, Iterable, Optional, Tuple, TypeVar, Union
20
+ from typing import Any, cast, Iterable, TypeVar
19
21
 
20
22
  import numpy as np
21
23
  from typing_extensions import Protocol
22
24
 
23
- from cirq import linalg
24
25
  from cirq._doc import doc_private
25
26
  from cirq.protocols import qid_shape_protocol
26
27
  from cirq.protocols.apply_unitary_protocol import apply_unitary, ApplyUnitaryArgs
@@ -73,7 +74,7 @@ class ApplyMixtureArgs:
73
74
  auxiliary_buffer0: np.ndarray,
74
75
  auxiliary_buffer1: np.ndarray,
75
76
  left_axes: Iterable[int],
76
- right_axes: Optional[Iterable[int]] = None,
77
+ right_axes: Iterable[int] | None = None,
77
78
  ):
78
79
  """Args for apply mixture.
79
80
 
@@ -112,9 +113,7 @@ class SupportsApplyMixture(Protocol):
112
113
  """An object that can efficiently implement a mixture."""
113
114
 
114
115
  @doc_private
115
- def _apply_mixture_(
116
- self, args: ApplyMixtureArgs
117
- ) -> Union[np.ndarray, None, NotImplementedType]:
116
+ def _apply_mixture_(self, args: ApplyMixtureArgs) -> np.ndarray | None | NotImplementedType:
118
117
  """Efficiently applies a mixture.
119
118
 
120
119
  This method is given both the target tensor and workspace of the same
@@ -157,8 +156,8 @@ def apply_mixture(
157
156
  val: Any,
158
157
  args: ApplyMixtureArgs,
159
158
  *,
160
- default: Union[np.ndarray, TDefault] = RaiseTypeErrorIfNotProvided,
161
- ) -> Union[np.ndarray, TDefault]:
159
+ default: np.ndarray | TDefault = RaiseTypeErrorIfNotProvided,
160
+ ) -> np.ndarray | TDefault:
162
161
  """High performance evolution under a mixture of unitaries evolution.
163
162
 
164
163
  Follows the steps below to attempt to apply a mixture:
@@ -273,7 +272,7 @@ def apply_mixture(
273
272
  )
274
273
 
275
274
 
276
- def _validate_input(val: Any, args: 'ApplyMixtureArgs') -> Tuple[Any, 'ApplyMixtureArgs', bool]:
275
+ def _validate_input(val: Any, args: ApplyMixtureArgs) -> tuple[Any, ApplyMixtureArgs, bool]:
277
276
  """Validate args input and determine if we are operating on a
278
277
  density matrix or a state vector.
279
278
  """
@@ -303,8 +302,8 @@ def _validate_input(val: Any, args: 'ApplyMixtureArgs') -> Tuple[Any, 'ApplyMixt
303
302
 
304
303
 
305
304
  def _apply_unitary_strat(
306
- val: Any, args: 'ApplyMixtureArgs', is_density_matrix: bool
307
- ) -> Optional[np.ndarray]:
305
+ val: Any, args: ApplyMixtureArgs, is_density_matrix: bool
306
+ ) -> np.ndarray | None:
308
307
  """Attempt to use `apply_unitary` and return the result.
309
308
 
310
309
  If `val` does not support `apply_unitary` returns None.
@@ -325,42 +324,16 @@ def _apply_unitary_strat(
325
324
  right_args = ApplyUnitaryArgs(
326
325
  target_tensor=np.conjugate(left_result),
327
326
  available_buffer=args.auxiliary_buffer0,
328
- axes=cast(Tuple[int], args.right_axes),
327
+ axes=cast(tuple[int], args.right_axes),
329
328
  )
330
329
  right_result = apply_unitary(val, right_args)
331
330
  np.conjugate(right_result, out=right_result)
332
331
  return right_result
333
332
 
334
333
 
335
- def _apply_unitary_from_matrix_strat(
336
- val: np.ndarray, args: 'ApplyMixtureArgs', is_density_matrix: bool
337
- ) -> Optional[np.ndarray]:
338
- """Used to enact mixture tuples that are given as (probability, np.ndarray)
339
-
340
- If `val` does not support `apply_unitary` returns None.
341
- """
342
- qid_shape = tuple(args.target_tensor.shape[i] for i in args.left_axes)
343
- matrix_tensor = np.reshape(val.astype(args.target_tensor.dtype), qid_shape * 2)
344
- linalg.targeted_left_multiply(
345
- matrix_tensor, args.target_tensor, args.left_axes, out=args.auxiliary_buffer0
346
- )
347
-
348
- if not is_density_matrix:
349
- return args.auxiliary_buffer0
350
- # No need to transpose as we are acting on the tensor
351
- # representation of matrix, so transpose is done for us.
352
- linalg.targeted_left_multiply(
353
- np.conjugate(matrix_tensor),
354
- args.auxiliary_buffer0,
355
- cast(Tuple[int], args.right_axes),
356
- out=args.target_tensor,
357
- )
358
- return args.target_tensor
359
-
360
-
361
334
  def _apply_mixture_from_mixture_strat(
362
- val: Any, args: 'ApplyMixtureArgs', is_density_matrix: bool
363
- ) -> Optional[np.ndarray]:
335
+ val: Any, args: ApplyMixtureArgs, is_density_matrix: bool
336
+ ) -> np.ndarray | None:
364
337
  """Attempt to use unitary matrices in _mixture_ and return the result."""
365
338
  method = getattr(val, '_mixture_', None)
366
339
  if method is None:
@@ -373,8 +346,6 @@ def _apply_mixture_from_mixture_strat(
373
346
  for prob, op in prob_mix:
374
347
  np.copyto(dst=args.target_tensor, src=args.auxiliary_buffer1)
375
348
  right_result = _apply_unitary_strat(op, args, is_density_matrix)
376
- if right_result is None:
377
- right_result = _apply_unitary_from_matrix_strat(op, args, is_density_matrix)
378
349
 
379
350
  args.out_buffer += prob * right_result
380
351
 
@@ -11,7 +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
- from typing import Any, cast, Iterable, Optional, Tuple
14
+ from __future__ import annotations
15
+
16
+ from typing import Any, cast, Iterable
15
17
 
16
18
  import numpy as np
17
19
  import pytest
@@ -31,9 +33,9 @@ def assert_apply_mixture_returns(
31
33
  val: Any,
32
34
  rho: np.ndarray,
33
35
  left_axes: Iterable[int],
34
- right_axes: Optional[Iterable[int]],
36
+ right_axes: Iterable[int] | None,
35
37
  assert_result_is_out_buf: bool = False,
36
- expected_result: Optional[np.ndarray] = None,
38
+ expected_result: np.ndarray | None = None,
37
39
  ):
38
40
  out_buf, buf0, buf1 = make_buffers(rho.shape, rho.dtype)
39
41
  result = cirq.apply_mixture(
@@ -94,8 +96,8 @@ def test_apply_mixture_simple():
94
96
  def _apply_mixture_(self, args: cirq.ApplyMixtureArgs):
95
97
  zero_left = cirq.slice_for_qubits_equal_to(args.left_axes, 0)
96
98
  one_left = cirq.slice_for_qubits_equal_to(args.left_axes, 1)
97
- zero_right = cirq.slice_for_qubits_equal_to(cast(Tuple[int], args.right_axes), 0)
98
- one_right = cirq.slice_for_qubits_equal_to(cast(Tuple[int], args.right_axes), 1)
99
+ zero_right = cirq.slice_for_qubits_equal_to(cast(tuple[int], args.right_axes), 0)
100
+ one_right = cirq.slice_for_qubits_equal_to(cast(tuple[int], args.right_axes), 1)
99
101
  args.out_buffer[:] = 0
100
102
  np.copyto(dst=args.auxiliary_buffer0, src=args.target_tensor)
101
103
  for kraus_op in [np.sqrt(0.5) * np.eye(2, dtype=np.complex128), np.sqrt(0.5) * x]:
@@ -14,9 +14,11 @@
14
14
 
15
15
  """A protocol for implementing high performance unitary left-multiplies."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  import warnings
18
- from types import NotImplementedType
19
- from typing import Any, cast, Iterable, Optional, Sequence, Tuple, TYPE_CHECKING, TypeVar, Union
20
+ from types import EllipsisType, NotImplementedType
21
+ from typing import Any, cast, Iterable, Sequence, TYPE_CHECKING, TypeVar
20
22
 
21
23
  import numpy as np
22
24
  from typing_extensions import Protocol
@@ -73,7 +75,7 @@ class ApplyUnitaryArgs:
73
75
  target_tensor: np.ndarray,
74
76
  available_buffer: np.ndarray,
75
77
  axes: Iterable[int],
76
- subspaces: Optional[Sequence[Tuple[int, ...]]] = None,
78
+ subspaces: Sequence[tuple[int, ...]] | None = None,
77
79
  ):
78
80
  """Inits ApplyUnitaryArgs.
79
81
 
@@ -111,8 +113,8 @@ class ApplyUnitaryArgs:
111
113
 
112
114
  @staticmethod
113
115
  def default(
114
- num_qubits: Optional[int] = None, *, qid_shape: Optional[Tuple[int, ...]] = None
115
- ) -> 'ApplyUnitaryArgs':
116
+ num_qubits: int | None = None, *, qid_shape: tuple[int, ...] | None = None
117
+ ) -> ApplyUnitaryArgs:
116
118
  """A default instance starting in state |0⟩.
117
119
 
118
120
  Specify exactly one argument.
@@ -130,15 +132,15 @@ class ApplyUnitaryArgs:
130
132
  raise TypeError('Specify exactly one of num_qubits or qid_shape.')
131
133
  if num_qubits is not None:
132
134
  qid_shape = (2,) * num_qubits
133
- qid_shape = cast(Tuple[int, ...], qid_shape) # Satisfy mypy
135
+ qid_shape = cast(tuple[int, ...], qid_shape) # Satisfy mypy
134
136
  num_qubits = len(qid_shape)
135
137
  state = qis.one_hot(index=(0,) * num_qubits, shape=qid_shape, dtype=np.complex128)
136
138
  return ApplyUnitaryArgs(state, np.empty_like(state), range(num_qubits))
137
139
 
138
140
  @classmethod
139
141
  def for_unitary(
140
- cls, num_qubits: Optional[int] = None, *, qid_shape: Optional[Tuple[int, ...]] = None
141
- ) -> 'ApplyUnitaryArgs':
142
+ cls, num_qubits: int | None = None, *, qid_shape: tuple[int, ...] | None = None
143
+ ) -> ApplyUnitaryArgs:
142
144
  """A default instance corresponding to an identity matrix.
143
145
 
144
146
  Specify exactly one argument.
@@ -157,12 +159,12 @@ class ApplyUnitaryArgs:
157
159
  raise TypeError('Specify exactly one of num_qubits or qid_shape.')
158
160
  if num_qubits is not None:
159
161
  qid_shape = (2,) * num_qubits
160
- qid_shape = cast(Tuple[int, ...], qid_shape) # Satisfy mypy
162
+ qid_shape = cast(tuple[int, ...], qid_shape) # Satisfy mypy
161
163
  num_qubits = len(qid_shape)
162
164
  state = qis.eye_tensor(qid_shape, dtype=np.complex128)
163
165
  return ApplyUnitaryArgs(state, np.empty_like(state), range(num_qubits))
164
166
 
165
- def with_axes_transposed_to_start(self) -> 'ApplyUnitaryArgs':
167
+ def with_axes_transposed_to_start(self) -> ApplyUnitaryArgs:
166
168
  """Returns a transposed view of the same arguments.
167
169
 
168
170
  Returns:
@@ -180,8 +182,8 @@ class ApplyUnitaryArgs:
180
182
  return ApplyUnitaryArgs(target_tensor, available_buffer, range(len(self.axes)))
181
183
 
182
184
  def _for_operation_with_qid_shape(
183
- self, indices: Iterable[int], slices: Tuple[Union[int, slice], ...]
184
- ) -> 'ApplyUnitaryArgs':
185
+ self, indices: Iterable[int], slices: tuple[int | slice, ...]
186
+ ) -> ApplyUnitaryArgs:
185
187
  """Creates a sliced and transposed view of `self` appropriate for an
186
188
  operation with shape `qid_shape` on qubits with the given indices.
187
189
 
@@ -213,7 +215,7 @@ class ApplyUnitaryArgs:
213
215
 
214
216
  def subspace_index(
215
217
  self, little_endian_bits_int: int = 0, *, big_endian_bits_int: int = 0
216
- ) -> Tuple[Union[slice, int, 'ellipsis'], ...]:
218
+ ) -> tuple[slice | int | EllipsisType, ...]:
217
219
  """An index for the subspace where the target axes equal a value.
218
220
 
219
221
  Args:
@@ -258,9 +260,7 @@ class SupportsConsistentApplyUnitary(Protocol):
258
260
  """An object that can be efficiently left-multiplied into tensors."""
259
261
 
260
262
  @doc_private
261
- def _apply_unitary_(
262
- self, args: ApplyUnitaryArgs
263
- ) -> Union[np.ndarray, None, NotImplementedType]:
263
+ def _apply_unitary_(self, args: ApplyUnitaryArgs) -> np.ndarray | None | NotImplementedType:
264
264
  """Left-multiplies a unitary effect onto a tensor with good performance.
265
265
 
266
266
  This method is given both the target tensor and workspace of the same
@@ -306,10 +306,10 @@ class SupportsConsistentApplyUnitary(Protocol):
306
306
  def apply_unitary(
307
307
  unitary_value: Any,
308
308
  args: ApplyUnitaryArgs,
309
- default: Union[np.ndarray, TDefault] = RaiseTypeErrorIfNotProvided,
309
+ default: np.ndarray | TDefault = RaiseTypeErrorIfNotProvided,
310
310
  *,
311
311
  allow_decompose: bool = True,
312
- ) -> Union[np.ndarray, TDefault]:
312
+ ) -> np.ndarray | TDefault:
313
313
  """High performance left-multiplication of a unitary effect onto a tensor.
314
314
 
315
315
  Applies the unitary effect of `unitary_value` to the tensor specified in
@@ -420,7 +420,7 @@ def apply_unitary(
420
420
 
421
421
  def _strat_apply_unitary_from_apply_unitary(
422
422
  unitary_value: Any, args: ApplyUnitaryArgs
423
- ) -> Optional[np.ndarray]:
423
+ ) -> np.ndarray | None:
424
424
  # Check for magic method.
425
425
  func = getattr(unitary_value, '_apply_unitary_', None)
426
426
  if func is None:
@@ -468,21 +468,26 @@ def _apply_unitary_from_matrix(matrix: np.ndarray, unitary_value: Any, args: App
468
468
 
469
469
  def _strat_apply_unitary_from_unitary(
470
470
  unitary_value: Any, args: ApplyUnitaryArgs
471
- ) -> Optional[np.ndarray]:
472
- # Check for magic method.
473
- method = getattr(unitary_value, '_unitary_', None)
474
- if method is None:
475
- return NotImplemented
471
+ ) -> np.ndarray | None:
472
+ if isinstance(unitary_value, np.ndarray):
473
+ matrix = unitary_value
474
+ if not linalg.is_unitary(matrix):
475
+ return None
476
+ else:
477
+ # Check for magic method.
478
+ method = getattr(unitary_value, '_unitary_', None)
479
+ if method is None:
480
+ return NotImplemented
476
481
 
477
- # Attempt to get the unitary matrix.
478
- matrix = method()
479
- if matrix is NotImplemented or matrix is None:
480
- return matrix
482
+ # Attempt to get the unitary matrix.
483
+ matrix = method()
484
+ if matrix is NotImplemented or matrix is None:
485
+ return matrix
481
486
 
482
487
  return _apply_unitary_from_matrix(matrix, unitary_value, args)
483
488
 
484
489
 
485
- def _strat_apply_unitary_from_decompose(val: Any, args: ApplyUnitaryArgs) -> Optional[np.ndarray]:
490
+ def _strat_apply_unitary_from_decompose(val: Any, args: ApplyUnitaryArgs) -> np.ndarray | None:
486
491
  operations, qubits, _ = _try_decompose_into_operations_and_qubits(val)
487
492
  if operations is None:
488
493
  return NotImplemented
@@ -506,10 +511,10 @@ def _strat_apply_unitary_from_decompose(val: Any, args: ApplyUnitaryArgs) -> Opt
506
511
 
507
512
  def apply_unitaries(
508
513
  unitary_values: Iterable[Any],
509
- qubits: Sequence['cirq.Qid'],
510
- args: Optional[ApplyUnitaryArgs] = None,
514
+ qubits: Sequence[cirq.Qid],
515
+ args: ApplyUnitaryArgs | None = None,
511
516
  default: Any = RaiseTypeErrorIfNotProvided,
512
- ) -> Optional[np.ndarray]:
517
+ ) -> np.ndarray | None:
513
518
  """Apply a series of unitaries onto a state tensor.
514
519
 
515
520
  Uses `cirq.apply_unitary` on each of the unitary values, to apply them to
@@ -589,7 +594,7 @@ def apply_unitaries(
589
594
 
590
595
 
591
596
  def _incorporate_result_into_target(
592
- args: 'ApplyUnitaryArgs', sub_args: 'ApplyUnitaryArgs', sub_result: np.ndarray
597
+ args: ApplyUnitaryArgs, sub_args: ApplyUnitaryArgs, sub_result: np.ndarray
593
598
  ):
594
599
  """Takes the result of calling `_apply_unitary_` on `sub_args` and
595
600
  copies it back into `args.target_tensor` or `args.available_buffer` as
@@ -645,7 +650,7 @@ def _incorporate_result_into_target(
645
650
  return args.target_tensor
646
651
 
647
652
 
648
- def _to_slice(subspace_def: Tuple[int, ...]):
653
+ def _to_slice(subspace_def: tuple[int, ...]):
649
654
  if len(subspace_def) < 1:
650
655
  raise ValueError(f'Subspace {subspace_def} has zero dimensions.')
651
656
 
@@ -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 numpy as np
16
18
  import pytest
17
19
 
@@ -54,12 +56,13 @@ def test_apply_unitary_presence_absence():
54
56
  args.target_tensor[one] *= -1
55
57
  return args.target_tensor
56
58
 
57
- fails = [NoUnitaryEffect(), HasApplyReturnsNotImplemented()]
59
+ fails = [NoUnitaryEffect(), HasApplyReturnsNotImplemented(), m * 2]
58
60
  passes = [
59
61
  HasUnitary(),
60
62
  HasApplyReturnsNotImplementedButHasUnitary(),
61
63
  HasApplyOutputInBuffer(),
62
64
  HasApplyMutateInline(),
65
+ m,
63
66
  ]
64
67
 
65
68
  def make_input():
@@ -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 decimal import Decimal
17
19
  from fractions import Fraction
@@ -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
  from decimal import Decimal
16
18
  from fractions import Fraction
17
19
  from numbers import Number
@@ -12,20 +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 re
16
18
  from fractions import Fraction
17
- from typing import (
18
- Any,
19
- Dict,
20
- Iterable,
21
- List,
22
- Optional,
23
- overload,
24
- Sequence,
25
- TYPE_CHECKING,
26
- TypeVar,
27
- Union,
28
- )
19
+ from typing import Any, Iterable, overload, Sequence, TYPE_CHECKING, TypeVar, Union
29
20
 
30
21
  import numpy as np
31
22
  import sympy
@@ -50,7 +41,7 @@ class CircuitDiagramInfo:
50
41
  wire_symbols: Iterable[str],
51
42
  exponent: Any = 1,
52
43
  connected: bool = True,
53
- exponent_qubit_index: Optional[int] = None,
44
+ exponent_qubit_index: int | None = None,
54
45
  auto_exponent_parens: bool = True,
55
46
  ) -> None:
56
47
  """Inits CircuitDiagramInfo.
@@ -104,8 +95,8 @@ class CircuitDiagramInfo:
104
95
  )
105
96
 
106
97
  def _wire_symbols_including_formatted_exponent(
107
- self, args: 'cirq.CircuitDiagramInfoArgs', *, preferred_exponent_index: Optional[int] = None
108
- ) -> List[str]:
98
+ self, args: cirq.CircuitDiagramInfoArgs, *, preferred_exponent_index: int | None = None
99
+ ) -> list[str]:
109
100
  result = list(self.wire_symbols)
110
101
  exponent = self._formatted_exponent(args)
111
102
  if exponent is not None:
@@ -122,7 +113,7 @@ class CircuitDiagramInfo:
122
113
  result[k] += f"^{exponent}"
123
114
  return result
124
115
 
125
- def _formatted_exponent(self, args: 'cirq.CircuitDiagramInfoArgs') -> Optional[str]:
116
+ def _formatted_exponent(self, args: cirq.CircuitDiagramInfoArgs) -> str | None:
126
117
  if protocols.is_parameterized(self.exponent):
127
118
  name = str(self.exponent)
128
119
  return f'({name})' if _is_exposed_formula(name) else name
@@ -190,21 +181,24 @@ class CircuitDiagramInfoArgs:
190
181
  precision: The number of digits after the decimal to show for numbers in
191
182
  the text diagram. None means use full precision.
192
183
  label_map: The map from label entities to diagram positions.
193
- include_tags: Whether to print tags from TaggedOperations.
184
+ include_tags: If ``True`` all tags from ``TaggedOperations`` will be
185
+ printed. If ``False`` no tags will be printed. Alternatively a
186
+ collection of tag classes can be provided. In this case only tags
187
+ whose type is contained in the collection will be shown.
194
188
  transpose: Whether the circuit is to be drawn with time from left to
195
189
  right (transpose is False), or from top to bottom.
196
190
  """
197
191
 
198
- UNINFORMED_DEFAULT: 'CircuitDiagramInfoArgs'
192
+ UNINFORMED_DEFAULT: CircuitDiagramInfoArgs
199
193
 
200
194
  def __init__(
201
195
  self,
202
- known_qubits: Optional[Iterable['cirq.Qid']],
203
- known_qubit_count: Optional[int],
196
+ known_qubits: Iterable[cirq.Qid] | None,
197
+ known_qubit_count: int | None,
204
198
  use_unicode_characters: bool,
205
- precision: Optional[int],
206
- label_map: Optional[Dict['cirq.LabelEntity', int]],
207
- include_tags: bool = True,
199
+ precision: int | None,
200
+ label_map: dict[LabelEntity, int] | None,
201
+ include_tags: bool | Iterable[type] = True,
208
202
  transpose: bool = False,
209
203
  ) -> None:
210
204
  self.known_qubits = None if known_qubits is None else tuple(known_qubits)
@@ -212,7 +206,11 @@ class CircuitDiagramInfoArgs:
212
206
  self.use_unicode_characters = use_unicode_characters
213
207
  self.precision = precision
214
208
  self.label_map = label_map
215
- self.include_tags = include_tags
209
+ self.include_tags: bool | frozenset[type]
210
+ if isinstance(include_tags, bool):
211
+ self.include_tags = include_tags
212
+ else:
213
+ self.include_tags = frozenset(include_tags)
216
214
  self.transpose = transpose
217
215
 
218
216
  def _value_equality_values_(self) -> Any:
@@ -226,7 +224,11 @@ class CircuitDiagramInfoArgs:
226
224
  if self.label_map is None
227
225
  else tuple(sorted(self.label_map.items(), key=lambda e: e[0]))
228
226
  ),
229
- self.include_tags,
227
+ (
228
+ self.include_tags
229
+ if isinstance(self.include_tags, bool)
230
+ else tuple(sorted(self.include_tags, key=lambda c: c.__name__))
231
+ ),
230
232
  self.transpose,
231
233
  )
232
234
 
@@ -238,11 +240,28 @@ class CircuitDiagramInfoArgs:
238
240
  f'use_unicode_characters={self.use_unicode_characters!r}, '
239
241
  f'precision={self.precision!r}, '
240
242
  f'label_map={self.label_map!r}, '
241
- f'include_tags={self.include_tags!r}, '
243
+ f'include_tags={self._include_tags_repr()}, '
242
244
  f'transpose={self.transpose!r})'
243
245
  )
244
246
 
245
- def format_real(self, val: Union[sympy.Basic, int, float]) -> str:
247
+ def _include_tags_repr(self) -> str:
248
+ if isinstance(self.include_tags, bool):
249
+ return repr(self.include_tags)
250
+ items = []
251
+ for cls in self.include_tags:
252
+ if cls.__module__ == 'builtins':
253
+ items.append(cls.__qualname__)
254
+ else:
255
+ items.append(f"{cls.__module__}.{cls.__qualname__}")
256
+ joined = ', '.join(items)
257
+ return f'frozenset({{{joined}}})'
258
+
259
+ def tags_to_include(self, tags: Iterable[Any]) -> list[Any]:
260
+ if isinstance(self.include_tags, bool):
261
+ return list(tags) if self.include_tags else []
262
+ return [t for t in tags if any(isinstance(t, cls) for cls in self.include_tags)]
263
+
264
+ def format_real(self, val: sympy.Basic | int | float) -> str:
246
265
  if isinstance(val, sympy.Basic):
247
266
  return str(val)
248
267
  if val == int(val):
@@ -251,7 +270,7 @@ class CircuitDiagramInfoArgs:
251
270
  return str(val)
252
271
  return f'{float(val):.{self.precision}}'
253
272
 
254
- def format_complex(self, val: Union[sympy.Basic, int, float, 'cirq.TParamValComplex']) -> str:
273
+ def format_complex(self, val: sympy.Basic | int | float | cirq.TParamValComplex) -> str:
255
274
  if isinstance(val, sympy.Basic):
256
275
  return str(val)
257
276
  c = complex(val)
@@ -263,7 +282,7 @@ class CircuitDiagramInfoArgs:
263
282
  imag_str = '' if abs_imag == 1 else self.format_real(abs_imag)
264
283
  return f'{self.format_real(c.real)}{joiner}{imag_str}i'
265
284
 
266
- def format_radians(self, radians: Union[sympy.Basic, int, float]) -> str:
285
+ def format_radians(self, radians: sympy.Basic | int | float) -> str:
267
286
  """Returns angle in radians as a human-readable string."""
268
287
  if protocols.is_parameterized(radians):
269
288
  return str(radians)
@@ -288,6 +307,7 @@ class CircuitDiagramInfoArgs:
288
307
  use_unicode_characters=self.use_unicode_characters,
289
308
  precision=self.precision,
290
309
  label_map=self.label_map,
310
+ include_tags=self.include_tags,
291
311
  transpose=self.transpose,
292
312
  )
293
313
 
@@ -314,7 +334,7 @@ class SupportsCircuitDiagramInfo(Protocol):
314
334
  @doc_private
315
335
  def _circuit_diagram_info_(
316
336
  self, args: CircuitDiagramInfoArgs
317
- ) -> Union[str, Iterable[str], CircuitDiagramInfo]:
337
+ ) -> str | Iterable[str] | CircuitDiagramInfo:
318
338
  """Describes how to draw an operation in a circuit diagram.
319
339
 
320
340
  This method is used by the global `cirq.diagram_info` method. If this
@@ -336,10 +356,10 @@ RaiseTypeErrorIfNotProvided = CircuitDiagramInfo(())
336
356
 
337
357
 
338
358
  def _op_info_with_fallback(
339
- op: 'cirq.Operation', args: 'cirq.CircuitDiagramInfoArgs'
340
- ) -> 'cirq.CircuitDiagramInfo':
359
+ op: cirq.Operation, args: cirq.CircuitDiagramInfoArgs
360
+ ) -> cirq.CircuitDiagramInfo:
341
361
  info = protocols.circuit_diagram_info(op, args, None)
342
- rows: List[LabelEntity] = list(op.qubits)
362
+ rows: list[LabelEntity] = list(op.qubits)
343
363
  if args.label_map is not None:
344
364
  rows += protocols.measurement_keys_touched(op) & args.label_map.keys()
345
365
  if info is not None and info.wire_symbols:
@@ -366,28 +386,27 @@ def _op_info_with_fallback(
366
386
  return protocols.CircuitDiagramInfo(wire_symbols=symbols)
367
387
 
368
388
 
369
- # pylint: disable=function-redefined
370
389
  @overload
371
390
  def circuit_diagram_info(
372
- val: Any, args: Optional[CircuitDiagramInfoArgs] = None
391
+ val: Any, args: CircuitDiagramInfoArgs | None = None
373
392
  ) -> CircuitDiagramInfo:
374
393
  pass
375
394
 
376
395
 
377
396
  @overload
378
397
  def circuit_diagram_info(
379
- val: Any, args: Optional[CircuitDiagramInfoArgs], default: TDefault
380
- ) -> Union[CircuitDiagramInfo, TDefault]:
398
+ val: Any, args: CircuitDiagramInfoArgs | None, default: TDefault
399
+ ) -> CircuitDiagramInfo | TDefault:
381
400
  pass
382
401
 
383
402
 
384
403
  @overload
385
- def circuit_diagram_info(val: Any, *, default: TDefault) -> Union[CircuitDiagramInfo, TDefault]:
404
+ def circuit_diagram_info(val: Any, *, default: TDefault) -> CircuitDiagramInfo | TDefault:
386
405
  pass
387
406
 
388
407
 
389
408
  def circuit_diagram_info(
390
- val: Any, args: Optional[CircuitDiagramInfoArgs] = None, default=RaiseTypeErrorIfNotProvided
409
+ val: Any, args: CircuitDiagramInfoArgs | None = None, default=RaiseTypeErrorIfNotProvided
391
410
  ):
392
411
  """Requests information on drawing an operation in a circuit diagram.
393
412
 
@@ -438,6 +457,3 @@ def circuit_diagram_info(
438
457
  f"object of type '{type(val)}' does have a _circuit_diagram_info_ "
439
458
  "method, but it returned NotImplemented."
440
459
  )
441
-
442
-
443
- # pylint: enable=function-redefined