cirq-core 1.5.0.dev20250409222543__py3-none-any.whl → 1.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cirq-core might be problematic. Click here for more details.

Files changed (732) hide show
  1. cirq/__init__.py +16 -17
  2. cirq/_compat.py +21 -20
  3. cirq/_compat_test.py +14 -34
  4. cirq/_doc.py +4 -2
  5. cirq/_import.py +8 -6
  6. cirq/_import_test.py +4 -2
  7. cirq/_version.py +6 -6
  8. cirq/_version_test.py +2 -2
  9. cirq/circuits/_block_diagram_drawer.py +11 -10
  10. cirq/circuits/_block_diagram_drawer_test.py +8 -6
  11. cirq/circuits/_box_drawing_character_data.py +8 -8
  12. cirq/circuits/_box_drawing_character_data_test.py +3 -1
  13. cirq/circuits/_bucket_priority_queue.py +9 -7
  14. cirq/circuits/_bucket_priority_queue_test.py +22 -20
  15. cirq/circuits/circuit.py +248 -172
  16. cirq/circuits/circuit_operation.py +73 -83
  17. cirq/circuits/circuit_operation_test.py +128 -90
  18. cirq/circuits/circuit_test.py +211 -151
  19. cirq/circuits/frozen_circuit.py +23 -60
  20. cirq/circuits/frozen_circuit_test.py +31 -8
  21. cirq/circuits/insert_strategy.py +7 -5
  22. cirq/circuits/insert_strategy_test.py +4 -2
  23. cirq/circuits/moment.py +88 -40
  24. cirq/circuits/moment_test.py +128 -51
  25. cirq/circuits/optimization_pass.py +5 -5
  26. cirq/circuits/optimization_pass_test.py +10 -10
  27. cirq/circuits/qasm_output.py +11 -11
  28. cirq/circuits/qasm_output_test.py +25 -22
  29. cirq/circuits/text_diagram_drawer.py +23 -38
  30. cirq/circuits/text_diagram_drawer_test.py +19 -17
  31. cirq/conftest.py +4 -3
  32. cirq/contrib/__init__.py +4 -4
  33. cirq/contrib/acquaintance/__init__.py +1 -1
  34. cirq/contrib/acquaintance/bipartite.py +5 -8
  35. cirq/contrib/acquaintance/bipartite_test.py +18 -13
  36. cirq/contrib/acquaintance/devices.py +2 -2
  37. cirq/contrib/acquaintance/devices_test.py +5 -3
  38. cirq/contrib/acquaintance/executor.py +5 -5
  39. cirq/contrib/acquaintance/executor_test.py +13 -9
  40. cirq/contrib/acquaintance/gates.py +18 -28
  41. cirq/contrib/acquaintance/gates_test.py +24 -20
  42. cirq/contrib/acquaintance/inspection_utils.py +8 -4
  43. cirq/contrib/acquaintance/inspection_utils_test.py +4 -2
  44. cirq/contrib/acquaintance/mutation_utils.py +4 -4
  45. cirq/contrib/acquaintance/mutation_utils_test.py +4 -2
  46. cirq/contrib/acquaintance/optimizers.py +4 -4
  47. cirq/contrib/acquaintance/optimizers_test.py +4 -1
  48. cirq/contrib/acquaintance/permutation.py +15 -27
  49. cirq/contrib/acquaintance/permutation_test.py +26 -17
  50. cirq/contrib/acquaintance/shift.py +4 -4
  51. cirq/contrib/acquaintance/shift_swap_network.py +4 -4
  52. cirq/contrib/acquaintance/shift_swap_network_test.py +9 -6
  53. cirq/contrib/acquaintance/shift_test.py +8 -6
  54. cirq/contrib/acquaintance/strategies/cubic.py +2 -2
  55. cirq/contrib/acquaintance/strategies/cubic_test.py +4 -2
  56. cirq/contrib/acquaintance/strategies/quartic_paired.py +6 -6
  57. cirq/contrib/acquaintance/strategies/quartic_paired_test.py +10 -6
  58. cirq/contrib/acquaintance/testing.py +2 -0
  59. cirq/contrib/acquaintance/topological_sort.py +2 -2
  60. cirq/contrib/acquaintance/topological_sort_test.py +3 -1
  61. cirq/contrib/bayesian_network/bayesian_network_gate.py +9 -10
  62. cirq/contrib/bayesian_network/bayesian_network_gate_test.py +14 -9
  63. cirq/contrib/circuitdag/circuit_dag.py +4 -4
  64. cirq/contrib/circuitdag/circuit_dag_test.py +17 -15
  65. cirq/contrib/custom_simulators/custom_state_simulator.py +5 -5
  66. cirq/contrib/custom_simulators/custom_state_simulator_test.py +22 -17
  67. cirq/contrib/graph_device/graph_device.py +12 -11
  68. cirq/contrib/graph_device/graph_device_test.py +18 -14
  69. cirq/contrib/graph_device/hypergraph.py +16 -14
  70. cirq/contrib/graph_device/hypergraph_test.py +13 -11
  71. cirq/contrib/graph_device/uniform_graph_device.py +6 -4
  72. cirq/contrib/graph_device/uniform_graph_device_test.py +11 -3
  73. cirq/contrib/hacks/disable_validation.py +6 -1
  74. cirq/contrib/hacks/disable_validation_test.py +3 -1
  75. cirq/contrib/json.py +31 -5
  76. cirq/contrib/json_test.py +6 -3
  77. cirq/contrib/json_test_data/DampedReadoutNoiseModel.json +12 -0
  78. cirq/contrib/json_test_data/DampedReadoutNoiseModel.repr +4 -0
  79. cirq/contrib/json_test_data/DepolarizingNoiseModel.json +12 -0
  80. cirq/contrib/json_test_data/DepolarizingNoiseModel.repr +4 -0
  81. cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.json +6 -0
  82. cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.repr +1 -0
  83. cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.json +5 -0
  84. cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.repr +1 -0
  85. cirq/contrib/json_test_data/ReadoutNoiseModel.json +12 -0
  86. cirq/contrib/json_test_data/ReadoutNoiseModel.repr +4 -0
  87. cirq/contrib/json_test_data/__init__.py +17 -0
  88. cirq/contrib/json_test_data/spec.py +32 -0
  89. cirq/contrib/noise_models/noise_models.py +119 -5
  90. cirq/contrib/noise_models/noise_models_test.py +37 -9
  91. cirq/contrib/paulistring/clifford_optimize.py +6 -4
  92. cirq/contrib/paulistring/clifford_optimize_test.py +6 -5
  93. cirq/contrib/paulistring/clifford_target_gateset.py +10 -10
  94. cirq/contrib/paulistring/clifford_target_gateset_test.py +13 -11
  95. cirq/contrib/paulistring/optimize.py +2 -0
  96. cirq/contrib/paulistring/optimize_test.py +4 -3
  97. cirq/contrib/paulistring/pauli_string_dag.py +2 -0
  98. cirq/contrib/paulistring/pauli_string_dag_test.py +3 -1
  99. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +255 -120
  100. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +398 -19
  101. cirq/contrib/paulistring/pauli_string_optimize.py +7 -1
  102. cirq/contrib/paulistring/pauli_string_optimize_test.py +5 -3
  103. cirq/contrib/paulistring/recombine.py +6 -4
  104. cirq/contrib/paulistring/recombine_test.py +3 -1
  105. cirq/contrib/paulistring/separate.py +9 -6
  106. cirq/contrib/paulistring/separate_test.py +3 -1
  107. cirq/contrib/qasm_import/_lexer.py +3 -2
  108. cirq/contrib/qasm_import/_lexer_test.py +49 -13
  109. cirq/contrib/qasm_import/_parser.py +547 -83
  110. cirq/contrib/qasm_import/_parser_test.py +988 -97
  111. cirq/contrib/qasm_import/exception.py +2 -0
  112. cirq/contrib/qasm_import/qasm.py +8 -2
  113. cirq/contrib/qasm_import/qasm_test.py +7 -4
  114. cirq/contrib/qcircuit/qcircuit_diagram_info.py +5 -5
  115. cirq/contrib/qcircuit/qcircuit_diagram_info_test.py +4 -1
  116. cirq/contrib/qcircuit/qcircuit_pdf.py +7 -3
  117. cirq/contrib/qcircuit/qcircuit_pdf_test.py +3 -1
  118. cirq/contrib/qcircuit/qcircuit_test.py +10 -8
  119. cirq/contrib/quantum_volume/quantum_volume.py +31 -27
  120. cirq/contrib/quantum_volume/quantum_volume_test.py +19 -16
  121. cirq/contrib/quimb/density_matrix.py +15 -14
  122. cirq/contrib/quimb/density_matrix_test.py +10 -7
  123. cirq/contrib/quimb/grid_circuits.py +5 -2
  124. cirq/contrib/quimb/grid_circuits_test.py +3 -0
  125. cirq/contrib/quimb/mps_simulator.py +20 -20
  126. cirq/contrib/quimb/mps_simulator_test.py +3 -0
  127. cirq/contrib/quimb/state_vector.py +12 -11
  128. cirq/contrib/quimb/state_vector_test.py +3 -0
  129. cirq/contrib/quirk/export_to_quirk.py +5 -3
  130. cirq/contrib/quirk/export_to_quirk_test.py +18 -16
  131. cirq/contrib/quirk/linearize_circuit.py +2 -0
  132. cirq/contrib/quirk/quirk_gate.py +18 -17
  133. cirq/contrib/routing/device.py +5 -3
  134. cirq/contrib/routing/device_test.py +2 -0
  135. cirq/contrib/routing/greedy.py +10 -21
  136. cirq/contrib/routing/greedy_test.py +4 -2
  137. cirq/contrib/routing/initialization.py +2 -2
  138. cirq/contrib/routing/initialization_test.py +5 -3
  139. cirq/contrib/routing/router.py +9 -5
  140. cirq/contrib/routing/router_test.py +2 -0
  141. cirq/contrib/routing/swap_network.py +3 -3
  142. cirq/contrib/routing/swap_network_test.py +3 -1
  143. cirq/contrib/routing/utils.py +2 -2
  144. cirq/contrib/routing/utils_test.py +3 -0
  145. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +15 -9
  146. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +3 -0
  147. cirq/contrib/svg/svg.py +3 -3
  148. cirq/contrib/svg/svg_test.py +8 -5
  149. cirq/devices/device.py +4 -4
  150. cirq/devices/device_test.py +7 -4
  151. cirq/devices/grid_device_metadata.py +10 -10
  152. cirq/devices/grid_device_metadata_test.py +3 -0
  153. cirq/devices/grid_qubit.py +29 -21
  154. cirq/devices/grid_qubit_test.py +3 -0
  155. cirq/devices/insertion_noise_model.py +7 -7
  156. cirq/devices/insertion_noise_model_test.py +7 -5
  157. cirq/devices/line_qubit.py +13 -13
  158. cirq/devices/line_qubit_test.py +2 -0
  159. cirq/devices/named_topologies.py +18 -29
  160. cirq/devices/named_topologies_test.py +13 -10
  161. cirq/devices/noise_model.py +3 -3
  162. cirq/devices/noise_model_test.py +19 -15
  163. cirq/devices/noise_properties.py +15 -6
  164. cirq/devices/noise_properties_test.py +34 -3
  165. cirq/devices/noise_utils.py +11 -9
  166. cirq/devices/noise_utils_test.py +2 -0
  167. cirq/devices/superconducting_qubits_noise_properties.py +23 -22
  168. cirq/devices/superconducting_qubits_noise_properties_test.py +6 -6
  169. cirq/devices/thermal_noise_model.py +107 -37
  170. cirq/devices/thermal_noise_model_test.py +21 -0
  171. cirq/devices/unconstrained_device.py +5 -3
  172. cirq/devices/unconstrained_device_test.py +2 -0
  173. cirq/experiments/__init__.py +4 -2
  174. cirq/experiments/benchmarking/__init__.py +17 -0
  175. cirq/experiments/benchmarking/parallel_xeb.py +677 -0
  176. cirq/experiments/benchmarking/parallel_xeb_test.py +447 -0
  177. cirq/experiments/fidelity_estimation.py +14 -8
  178. cirq/experiments/fidelity_estimation_test.py +3 -0
  179. cirq/experiments/n_qubit_tomography.py +17 -16
  180. cirq/experiments/n_qubit_tomography_test.py +8 -5
  181. cirq/experiments/purity_estimation.py +2 -0
  182. cirq/experiments/purity_estimation_test.py +2 -0
  183. cirq/experiments/qubit_characterizations.py +207 -103
  184. cirq/experiments/qubit_characterizations_test.py +40 -12
  185. cirq/experiments/random_quantum_circuit_generation.py +56 -70
  186. cirq/experiments/random_quantum_circuit_generation_test.py +11 -8
  187. cirq/experiments/readout_confusion_matrix.py +24 -22
  188. cirq/experiments/readout_confusion_matrix_test.py +2 -0
  189. cirq/experiments/single_qubit_readout_calibration.py +30 -15
  190. cirq/experiments/single_qubit_readout_calibration_test.py +5 -2
  191. cirq/experiments/t1_decay_experiment.py +9 -7
  192. cirq/experiments/t1_decay_experiment_test.py +13 -11
  193. cirq/experiments/t2_decay_experiment.py +16 -13
  194. cirq/experiments/t2_decay_experiment_test.py +2 -0
  195. cirq/experiments/two_qubit_xeb.py +64 -57
  196. cirq/experiments/two_qubit_xeb_test.py +10 -6
  197. cirq/experiments/xeb_fitting.py +39 -35
  198. cirq/experiments/xeb_sampling.py +37 -44
  199. cirq/experiments/xeb_sampling_test.py +3 -0
  200. cirq/experiments/xeb_simulation.py +14 -10
  201. cirq/experiments/xeb_simulation_test.py +5 -5
  202. cirq/experiments/z_phase_calibration.py +32 -29
  203. cirq/experiments/z_phase_calibration_test.py +3 -4
  204. cirq/interop/quirk/cells/__init__.py +1 -1
  205. cirq/interop/quirk/cells/all_cells.py +7 -2
  206. cirq/interop/quirk/cells/arithmetic_cells.py +29 -41
  207. cirq/interop/quirk/cells/arithmetic_cells_test.py +17 -14
  208. cirq/interop/quirk/cells/cell.py +19 -28
  209. cirq/interop/quirk/cells/cell_test.py +3 -0
  210. cirq/interop/quirk/cells/composite_cell.py +13 -28
  211. cirq/interop/quirk/cells/composite_cell_test.py +2 -0
  212. cirq/interop/quirk/cells/control_cells.py +15 -15
  213. cirq/interop/quirk/cells/control_cells_test.py +7 -5
  214. cirq/interop/quirk/cells/frequency_space_cells.py +4 -3
  215. cirq/interop/quirk/cells/frequency_space_cells_test.py +3 -1
  216. cirq/interop/quirk/cells/ignored_cells.py +3 -0
  217. cirq/interop/quirk/cells/ignored_cells_test.py +3 -1
  218. cirq/interop/quirk/cells/input_cells.py +7 -5
  219. cirq/interop/quirk/cells/input_cells_test.py +7 -5
  220. cirq/interop/quirk/cells/input_rotation_cells.py +15 -13
  221. cirq/interop/quirk/cells/input_rotation_cells_test.py +9 -7
  222. cirq/interop/quirk/cells/measurement_cells.py +5 -2
  223. cirq/interop/quirk/cells/measurement_cells_test.py +3 -1
  224. cirq/interop/quirk/cells/parse.py +22 -23
  225. cirq/interop/quirk/cells/parse_test.py +12 -10
  226. cirq/interop/quirk/cells/qubit_permutation_cells.py +5 -3
  227. cirq/interop/quirk/cells/qubit_permutation_cells_test.py +9 -7
  228. cirq/interop/quirk/cells/scalar_cells.py +4 -1
  229. cirq/interop/quirk/cells/scalar_cells_test.py +3 -1
  230. cirq/interop/quirk/cells/single_qubit_rotation_cells.py +5 -2
  231. cirq/interop/quirk/cells/single_qubit_rotation_cells_test.py +5 -3
  232. cirq/interop/quirk/cells/swap_cell.py +8 -6
  233. cirq/interop/quirk/cells/swap_cell_test.py +6 -4
  234. cirq/interop/quirk/cells/testing.py +6 -6
  235. cirq/interop/quirk/cells/testing_test.py +8 -6
  236. cirq/interop/quirk/cells/unsupported_cells.py +3 -0
  237. cirq/interop/quirk/cells/unsupported_cells_test.py +4 -2
  238. cirq/interop/quirk/url_to_circuit.py +23 -36
  239. cirq/interop/quirk/url_to_circuit_test.py +4 -1
  240. cirq/json_resolver_cache.py +14 -12
  241. cirq/linalg/__init__.py +4 -6
  242. cirq/linalg/combinators.py +7 -5
  243. cirq/linalg/combinators_test.py +10 -7
  244. cirq/linalg/decompositions.py +24 -35
  245. cirq/linalg/decompositions_test.py +3 -1
  246. cirq/linalg/diagonalize.py +6 -4
  247. cirq/linalg/diagonalize_test.py +15 -14
  248. cirq/linalg/operator_spaces.py +14 -14
  249. cirq/linalg/operator_spaces_test.py +13 -11
  250. cirq/linalg/predicates.py +18 -9
  251. cirq/linalg/predicates_test.py +5 -0
  252. cirq/linalg/tolerance.py +6 -3
  253. cirq/linalg/tolerance_test.py +6 -4
  254. cirq/linalg/transformations.py +23 -20
  255. cirq/linalg/transformations_test.py +73 -43
  256. cirq/neutral_atoms/convert_to_neutral_atom_gates.py +9 -3
  257. cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +3 -1
  258. cirq/neutral_atoms/neutral_atom_devices.py +2 -0
  259. cirq/ops/__init__.py +2 -0
  260. cirq/ops/arithmetic_operation.py +21 -21
  261. cirq/ops/arithmetic_operation_test.py +7 -8
  262. cirq/ops/boolean_hamiltonian.py +23 -22
  263. cirq/ops/boolean_hamiltonian_test.py +12 -9
  264. cirq/ops/classically_controlled_operation.py +31 -36
  265. cirq/ops/classically_controlled_operation_test.py +121 -117
  266. cirq/ops/clifford_gate.py +98 -81
  267. cirq/ops/clifford_gate_test.py +72 -57
  268. cirq/ops/common_channels.py +44 -44
  269. cirq/ops/common_channels_test.py +83 -81
  270. cirq/ops/common_gate_families.py +9 -7
  271. cirq/ops/common_gate_families_test.py +11 -7
  272. cirq/ops/common_gates.py +164 -183
  273. cirq/ops/common_gates_test.py +135 -95
  274. cirq/ops/control_values.py +23 -26
  275. cirq/ops/control_values_test.py +22 -20
  276. cirq/ops/controlled_gate.py +64 -112
  277. cirq/ops/controlled_gate_test.py +130 -35
  278. cirq/ops/controlled_operation.py +24 -35
  279. cirq/ops/controlled_operation_test.py +8 -6
  280. cirq/ops/dense_pauli_string.py +38 -49
  281. cirq/ops/dense_pauli_string_test.py +4 -2
  282. cirq/ops/diagonal_gate.py +18 -31
  283. cirq/ops/diagonal_gate_test.py +13 -13
  284. cirq/ops/eigen_gate.py +29 -29
  285. cirq/ops/eigen_gate_test.py +45 -28
  286. cirq/ops/fourier_transform.py +14 -20
  287. cirq/ops/fourier_transform_test.py +15 -12
  288. cirq/ops/fsim_gate.py +43 -42
  289. cirq/ops/fsim_gate_test.py +29 -29
  290. cirq/ops/gate_features.py +2 -0
  291. cirq/ops/gate_features_test.py +5 -3
  292. cirq/ops/gate_operation.py +43 -65
  293. cirq/ops/gate_operation_test.py +46 -42
  294. cirq/ops/gateset.py +28 -40
  295. cirq/ops/gateset_test.py +4 -2
  296. cirq/ops/global_phase_op.py +45 -20
  297. cirq/ops/global_phase_op_test.py +44 -20
  298. cirq/ops/greedy_qubit_manager.py +10 -8
  299. cirq/ops/greedy_qubit_manager_test.py +5 -3
  300. cirq/ops/identity.py +14 -12
  301. cirq/ops/identity_test.py +24 -20
  302. cirq/ops/kraus_channel.py +11 -8
  303. cirq/ops/kraus_channel_test.py +14 -11
  304. cirq/ops/linear_combinations.py +65 -77
  305. cirq/ops/linear_combinations_test.py +14 -9
  306. cirq/ops/matrix_gates.py +21 -18
  307. cirq/ops/matrix_gates_test.py +16 -0
  308. cirq/ops/measure_util.py +15 -20
  309. cirq/ops/measure_util_test.py +2 -0
  310. cirq/ops/measurement_gate.py +26 -37
  311. cirq/ops/measurement_gate_test.py +2 -0
  312. cirq/ops/mixed_unitary_channel.py +12 -9
  313. cirq/ops/mixed_unitary_channel_test.py +14 -11
  314. cirq/ops/named_qubit.py +16 -13
  315. cirq/ops/named_qubit_test.py +15 -13
  316. cirq/ops/op_tree.py +9 -7
  317. cirq/ops/op_tree_test.py +22 -19
  318. cirq/ops/parallel_gate.py +15 -17
  319. cirq/ops/parallel_gate_test.py +18 -16
  320. cirq/ops/parity_gates.py +23 -25
  321. cirq/ops/parity_gates_test.py +36 -32
  322. cirq/ops/pauli_gates.py +22 -21
  323. cirq/ops/pauli_gates_test.py +29 -20
  324. cirq/ops/pauli_interaction_gate.py +15 -19
  325. cirq/ops/pauli_interaction_gate_test.py +10 -8
  326. cirq/ops/pauli_measurement_gate.py +23 -35
  327. cirq/ops/pauli_measurement_gate_test.py +2 -0
  328. cirq/ops/pauli_string.py +92 -120
  329. cirq/ops/pauli_string_phasor.py +52 -45
  330. cirq/ops/pauli_string_phasor_test.py +4 -5
  331. cirq/ops/pauli_string_raw_types.py +9 -7
  332. cirq/ops/pauli_string_raw_types_test.py +2 -0
  333. cirq/ops/pauli_string_test.py +31 -154
  334. cirq/ops/pauli_sum_exponential.py +12 -12
  335. cirq/ops/pauli_sum_exponential_test.py +12 -10
  336. cirq/ops/permutation_gate.py +8 -6
  337. cirq/ops/permutation_gate_test.py +10 -8
  338. cirq/ops/phased_iswap_gate.py +16 -16
  339. cirq/ops/phased_iswap_gate_test.py +17 -15
  340. cirq/ops/phased_x_gate.py +16 -17
  341. cirq/ops/phased_x_gate_test.py +18 -16
  342. cirq/ops/phased_x_z_gate.py +24 -22
  343. cirq/ops/phased_x_z_gate_test.py +17 -11
  344. cirq/ops/projector.py +16 -11
  345. cirq/ops/projector_test.py +19 -16
  346. cirq/ops/qid_util.py +7 -5
  347. cirq/ops/qid_util_test.py +2 -0
  348. cirq/ops/qubit_manager.py +11 -9
  349. cirq/ops/qubit_manager_test.py +6 -4
  350. cirq/ops/qubit_order.py +11 -14
  351. cirq/ops/qubit_order_or_list.py +4 -2
  352. cirq/ops/qubit_order_test.py +12 -10
  353. cirq/ops/random_gate_channel.py +12 -10
  354. cirq/ops/random_gate_channel_test.py +14 -11
  355. cirq/ops/raw_types.py +109 -129
  356. cirq/ops/raw_types_test.py +63 -57
  357. cirq/ops/state_preparation_channel.py +7 -7
  358. cirq/ops/state_preparation_channel_test.py +11 -9
  359. cirq/ops/swap_gates.py +13 -15
  360. cirq/ops/swap_gates_test.py +19 -17
  361. cirq/ops/tags.py +5 -3
  362. cirq/ops/tags_test.py +4 -2
  363. cirq/ops/three_qubit_gates.py +43 -76
  364. cirq/ops/three_qubit_gates_test.py +19 -17
  365. cirq/ops/two_qubit_diagonal_gate.py +13 -13
  366. cirq/ops/two_qubit_diagonal_gate_test.py +10 -8
  367. cirq/ops/uniform_superposition_gate.py +5 -3
  368. cirq/ops/uniform_superposition_gate_test.py +5 -3
  369. cirq/ops/wait_gate.py +17 -14
  370. cirq/ops/wait_gate_test.py +9 -6
  371. cirq/protocols/__init__.py +0 -3
  372. cirq/protocols/act_on_protocol.py +8 -6
  373. cirq/protocols/act_on_protocol_test.py +15 -12
  374. cirq/protocols/apply_channel_protocol.py +10 -14
  375. cirq/protocols/apply_channel_protocol_test.py +2 -0
  376. cirq/protocols/apply_mixture_protocol.py +13 -42
  377. cirq/protocols/apply_mixture_protocol_test.py +7 -5
  378. cirq/protocols/apply_unitary_protocol.py +39 -34
  379. cirq/protocols/apply_unitary_protocol_test.py +4 -1
  380. cirq/protocols/approximate_equality_protocol.py +2 -0
  381. cirq/protocols/approximate_equality_protocol_test.py +2 -0
  382. cirq/protocols/circuit_diagram_info_protocol.py +58 -42
  383. cirq/protocols/circuit_diagram_info_protocol_test.py +70 -12
  384. cirq/protocols/commutes_protocol.py +8 -7
  385. cirq/protocols/commutes_protocol_test.py +2 -0
  386. cirq/protocols/control_key_protocol.py +6 -4
  387. cirq/protocols/control_key_protocol_test.py +3 -1
  388. cirq/protocols/decompose_protocol.py +49 -48
  389. cirq/protocols/decompose_protocol_test.py +27 -16
  390. cirq/protocols/equal_up_to_global_phase_protocol.py +2 -0
  391. cirq/protocols/equal_up_to_global_phase_protocol_test.py +9 -6
  392. cirq/protocols/has_stabilizer_effect_protocol.py +7 -5
  393. cirq/protocols/has_stabilizer_effect_protocol_test.py +7 -5
  394. cirq/protocols/has_unitary_protocol.py +10 -6
  395. cirq/protocols/has_unitary_protocol_test.py +13 -8
  396. cirq/protocols/hash_from_pickle_test.py +2 -11
  397. cirq/protocols/inverse_protocol.py +13 -16
  398. cirq/protocols/inverse_protocol_test.py +5 -3
  399. cirq/protocols/json_serialization.py +35 -54
  400. cirq/protocols/json_serialization_test.py +14 -21
  401. cirq/protocols/json_test_data/CXSWAP.json +46 -0
  402. cirq/protocols/json_test_data/CXSWAP.repr +13 -0
  403. cirq/protocols/json_test_data/CZSWAP.json +46 -0
  404. cirq/protocols/json_test_data/CZSWAP.repr +13 -0
  405. cirq/protocols/json_test_data/CircuitOperation.json +6 -3
  406. cirq/protocols/json_test_data/CircuitOperation.repr_inward +4 -2
  407. cirq/protocols/json_test_data/Moment.json +24 -1
  408. cirq/protocols/json_test_data/Moment.repr +6 -1
  409. cirq/protocols/json_test_data/ThermalNoiseModel.json +32 -0
  410. cirq/protocols/json_test_data/ThermalNoiseModel.repr +1 -0
  411. cirq/protocols/json_test_data/spec.py +6 -2
  412. cirq/protocols/kraus_protocol.py +47 -7
  413. cirq/protocols/kraus_protocol_test.py +86 -12
  414. cirq/protocols/measurement_key_protocol.py +15 -16
  415. cirq/protocols/measurement_key_protocol_test.py +13 -11
  416. cirq/protocols/mixture_protocol.py +7 -5
  417. cirq/protocols/mixture_protocol_test.py +4 -2
  418. cirq/protocols/mul_protocol.py +2 -3
  419. cirq/protocols/mul_protocol_test.py +2 -0
  420. cirq/protocols/pauli_expansion_protocol.py +6 -3
  421. cirq/protocols/pauli_expansion_protocol_test.py +5 -3
  422. cirq/protocols/phase_protocol.py +2 -0
  423. cirq/protocols/phase_protocol_test.py +3 -1
  424. cirq/protocols/pow_protocol.py +11 -16
  425. cirq/protocols/pow_protocol_test.py +2 -0
  426. cirq/protocols/qasm.py +14 -20
  427. cirq/protocols/qasm_test.py +6 -3
  428. cirq/protocols/qid_shape_protocol.py +8 -8
  429. cirq/protocols/qid_shape_protocol_test.py +3 -1
  430. cirq/protocols/resolve_parameters.py +5 -3
  431. cirq/protocols/resolve_parameters_test.py +8 -7
  432. cirq/protocols/trace_distance_bound.py +6 -4
  433. cirq/protocols/trace_distance_bound_test.py +3 -1
  434. cirq/protocols/unitary_protocol.py +17 -7
  435. cirq/protocols/unitary_protocol_test.py +12 -2
  436. cirq/qis/channels.py +6 -2
  437. cirq/qis/channels_test.py +20 -16
  438. cirq/qis/clifford_tableau.py +21 -19
  439. cirq/qis/clifford_tableau_test.py +2 -2
  440. cirq/qis/entropy.py +14 -3
  441. cirq/qis/entropy_test.py +3 -1
  442. cirq/qis/measures.py +13 -13
  443. cirq/qis/measures_test.py +20 -14
  444. cirq/qis/noise_utils.py +2 -0
  445. cirq/qis/noise_utils_test.py +9 -7
  446. cirq/qis/quantum_state_representation.py +7 -8
  447. cirq/qis/states.py +58 -56
  448. cirq/qis/states_test.py +2 -0
  449. cirq/sim/classical_simulator.py +23 -22
  450. cirq/sim/classical_simulator_test.py +2 -0
  451. cirq/sim/clifford/clifford_simulator.py +23 -21
  452. cirq/sim/clifford/clifford_simulator_test.py +7 -4
  453. cirq/sim/clifford/clifford_tableau_simulation_state.py +10 -7
  454. cirq/sim/clifford/clifford_tableau_simulation_state_test.py +5 -5
  455. cirq/sim/clifford/stabilizer_ch_form_simulation_state.py +8 -6
  456. cirq/sim/clifford/stabilizer_ch_form_simulation_state_test.py +8 -6
  457. cirq/sim/clifford/stabilizer_sampler.py +9 -7
  458. cirq/sim/clifford/stabilizer_sampler_test.py +4 -2
  459. cirq/sim/clifford/stabilizer_simulation_state.py +14 -13
  460. cirq/sim/clifford/stabilizer_simulation_state_test.py +6 -4
  461. cirq/sim/clifford/stabilizer_state_ch_form.py +13 -11
  462. cirq/sim/clifford/stabilizer_state_ch_form_test.py +4 -2
  463. cirq/sim/density_matrix_simulation_state.py +26 -27
  464. cirq/sim/density_matrix_simulation_state_test.py +10 -8
  465. cirq/sim/density_matrix_simulator.py +30 -28
  466. cirq/sim/density_matrix_simulator_test.py +48 -48
  467. cirq/sim/density_matrix_utils.py +13 -11
  468. cirq/sim/density_matrix_utils_test.py +38 -36
  469. cirq/sim/mux.py +33 -31
  470. cirq/sim/mux_test.py +3 -0
  471. cirq/sim/simulation_product_state.py +15 -15
  472. cirq/sim/simulation_product_state_test.py +29 -26
  473. cirq/sim/simulation_state.py +29 -38
  474. cirq/sim/simulation_state_base.py +21 -32
  475. cirq/sim/simulation_state_test.py +15 -13
  476. cirq/sim/simulation_utils.py +5 -2
  477. cirq/sim/simulation_utils_test.py +5 -2
  478. cirq/sim/simulator.py +90 -106
  479. cirq/sim/simulator_base.py +33 -45
  480. cirq/sim/simulator_base_test.py +20 -15
  481. cirq/sim/simulator_test.py +23 -14
  482. cirq/sim/sparse_simulator.py +19 -17
  483. cirq/sim/sparse_simulator_test.py +41 -40
  484. cirq/sim/state_vector.py +15 -12
  485. cirq/sim/state_vector_simulation_state.py +31 -31
  486. cirq/sim/state_vector_simulation_state_test.py +16 -14
  487. cirq/sim/state_vector_simulator.py +17 -14
  488. cirq/sim/state_vector_simulator_test.py +2 -0
  489. cirq/sim/state_vector_test.py +6 -3
  490. cirq/study/flatten_expressions.py +16 -15
  491. cirq/study/flatten_expressions_test.py +13 -11
  492. cirq/study/resolver.py +18 -17
  493. cirq/study/resolver_test.py +22 -20
  494. cirq/study/result.py +17 -27
  495. cirq/study/result_test.py +2 -0
  496. cirq/study/sweepable.py +12 -10
  497. cirq/study/sweepable_test.py +3 -0
  498. cirq/study/sweeps.py +42 -61
  499. cirq/study/sweeps_test.py +33 -0
  500. cirq/testing/__init__.py +7 -11
  501. cirq/testing/_compat_test_data/module_a/__init__.py +1 -0
  502. cirq/testing/_compat_test_data/module_a/module_b/__init__.py +1 -0
  503. cirq/testing/_compat_test_data/module_a/sub/__init__.py +1 -0
  504. cirq/testing/circuit_compare.py +8 -17
  505. cirq/testing/circuit_compare_test.py +2 -0
  506. cirq/testing/consistent_act_on.py +13 -11
  507. cirq/testing/consistent_act_on_test.py +5 -3
  508. cirq/testing/consistent_channels.py +2 -0
  509. cirq/testing/consistent_channels_test.py +10 -8
  510. cirq/testing/consistent_controlled_gate_op.py +5 -5
  511. cirq/testing/consistent_controlled_gate_op_test.py +18 -18
  512. cirq/testing/consistent_decomposition.py +2 -2
  513. cirq/testing/consistent_decomposition_test.py +4 -2
  514. cirq/testing/consistent_pauli_expansion.py +2 -0
  515. cirq/testing/consistent_pauli_expansion_test.py +3 -1
  516. cirq/testing/consistent_phase_by.py +2 -0
  517. cirq/testing/consistent_phase_by_test.py +3 -1
  518. cirq/testing/consistent_protocols.py +14 -20
  519. cirq/testing/consistent_protocols_test.py +13 -11
  520. cirq/testing/consistent_qasm.py +6 -4
  521. cirq/testing/consistent_qasm_test.py +7 -7
  522. cirq/testing/consistent_resolve_parameters.py +2 -0
  523. cirq/testing/consistent_specified_has_unitary.py +2 -2
  524. cirq/testing/consistent_specified_has_unitary_test.py +6 -4
  525. cirq/testing/consistent_unitary.py +1 -0
  526. cirq/testing/consistent_unitary_test.py +4 -2
  527. cirq/testing/deprecation.py +5 -2
  528. cirq/testing/deprecation_test.py +5 -2
  529. cirq/testing/devices.py +7 -4
  530. cirq/testing/devices_test.py +7 -4
  531. cirq/testing/equals_tester.py +4 -2
  532. cirq/testing/equals_tester_test.py +21 -17
  533. cirq/testing/equivalent_basis_map.py +6 -4
  534. cirq/testing/equivalent_basis_map_test.py +6 -4
  535. cirq/testing/equivalent_repr_eval.py +6 -4
  536. cirq/testing/equivalent_repr_eval_test.py +5 -3
  537. cirq/testing/gate_features.py +2 -0
  538. cirq/testing/gate_features_test.py +7 -5
  539. cirq/testing/json.py +19 -15
  540. cirq/testing/json_test.py +5 -3
  541. cirq/testing/lin_alg_utils.py +10 -11
  542. cirq/testing/lin_alg_utils_test.py +14 -12
  543. cirq/testing/logs.py +7 -6
  544. cirq/testing/logs_test.py +9 -7
  545. cirq/testing/no_identifier_qubit.py +4 -2
  546. cirq/testing/no_identifier_qubit_test.py +5 -3
  547. cirq/testing/op_tree.py +2 -0
  548. cirq/testing/op_tree_test.py +4 -1
  549. cirq/testing/order_tester.py +2 -0
  550. cirq/testing/order_tester_test.py +8 -6
  551. cirq/testing/pytest_utils.py +2 -0
  552. cirq/testing/pytest_utils_test.py +4 -2
  553. cirq/testing/random_circuit.py +21 -20
  554. cirq/testing/random_circuit_test.py +12 -9
  555. cirq/testing/repr_pretty_tester.py +1 -0
  556. cirq/testing/repr_pretty_tester_test.py +5 -3
  557. cirq/testing/routing_devices.py +4 -1
  558. cirq/testing/routing_devices_test.py +9 -6
  559. cirq/testing/sample_circuits.py +4 -1
  560. cirq/testing/sample_circuits_test.py +3 -1
  561. cirq/testing/sample_gates.py +3 -0
  562. cirq/testing/sample_gates_test.py +5 -2
  563. cirq/transformers/__init__.py +11 -4
  564. cirq/transformers/align.py +9 -7
  565. cirq/transformers/align_test.py +2 -0
  566. cirq/transformers/analytical_decompositions/__init__.py +3 -6
  567. cirq/transformers/analytical_decompositions/clifford_decomposition.py +18 -16
  568. cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +2 -0
  569. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +19 -16
  570. cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
  571. cirq/transformers/analytical_decompositions/cphase_to_fsim.py +11 -9
  572. cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +5 -3
  573. cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +5 -3
  574. cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +5 -3
  575. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +141 -44
  576. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +35 -1
  577. cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +8 -7
  578. cirq/transformers/analytical_decompositions/single_qubit_decompositions_test.py +2 -0
  579. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +7 -4
  580. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +3 -0
  581. cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +11 -19
  582. cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +8 -33
  583. cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +9 -11
  584. cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -0
  585. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +91 -27
  586. cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +36 -7
  587. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +20 -21
  588. cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +8 -6
  589. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +13 -15
  590. cirq/transformers/analytical_decompositions/two_qubit_to_ms_test.py +3 -1
  591. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +39 -41
  592. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -0
  593. cirq/transformers/drop_empty_moments.py +5 -3
  594. cirq/transformers/drop_empty_moments_test.py +4 -2
  595. cirq/transformers/drop_negligible_operations.py +7 -5
  596. cirq/transformers/drop_negligible_operations_test.py +2 -0
  597. cirq/transformers/dynamical_decoupling.py +49 -42
  598. cirq/transformers/dynamical_decoupling_test.py +223 -205
  599. cirq/transformers/eject_phased_paulis.py +28 -26
  600. cirq/transformers/eject_phased_paulis_test.py +12 -9
  601. cirq/transformers/eject_z.py +12 -12
  602. cirq/transformers/eject_z_test.py +2 -2
  603. cirq/transformers/expand_composite.py +6 -4
  604. cirq/transformers/expand_composite_test.py +3 -1
  605. cirq/transformers/gauge_compiling/__init__.py +3 -1
  606. cirq/transformers/gauge_compiling/cphase_gauge.py +2 -0
  607. cirq/transformers/gauge_compiling/cphase_gauge_test.py +2 -0
  608. cirq/transformers/gauge_compiling/cz_gauge.py +2 -0
  609. cirq/transformers/gauge_compiling/cz_gauge_test.py +1 -0
  610. cirq/transformers/gauge_compiling/gauge_compiling.py +45 -41
  611. cirq/transformers/gauge_compiling/gauge_compiling_test.py +2 -0
  612. cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +1 -0
  613. cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +5 -1
  614. cirq/transformers/gauge_compiling/iswap_gauge.py +2 -0
  615. cirq/transformers/gauge_compiling/iswap_gauge_test.py +1 -0
  616. cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -0
  617. cirq/transformers/gauge_compiling/spin_inversion_gauge_test.py +2 -0
  618. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +7 -6
  619. cirq/transformers/gauge_compiling/sqrt_cz_gauge_test.py +2 -0
  620. cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +2 -0
  621. cirq/transformers/gauge_compiling/sqrt_iswap_gauge_test.py +2 -0
  622. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +6 -3
  623. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +3 -0
  624. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +12 -9
  625. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +9 -7
  626. cirq/transformers/insertion_sort.py +8 -6
  627. cirq/transformers/insertion_sort_test.py +3 -1
  628. cirq/transformers/measurement_transformers.py +29 -29
  629. cirq/transformers/measurement_transformers_test.py +2 -0
  630. cirq/transformers/merge_k_qubit_gates.py +12 -10
  631. cirq/transformers/merge_k_qubit_gates_test.py +18 -18
  632. cirq/transformers/merge_single_qubit_gates.py +197 -20
  633. cirq/transformers/merge_single_qubit_gates_test.py +177 -5
  634. cirq/transformers/noise_adding.py +5 -3
  635. cirq/transformers/noise_adding_test.py +2 -0
  636. cirq/transformers/optimize_for_target_gateset.py +19 -17
  637. cirq/transformers/optimize_for_target_gateset_test.py +11 -8
  638. cirq/transformers/qubit_management_transformers.py +13 -11
  639. cirq/transformers/qubit_management_transformers_test.py +5 -3
  640. cirq/transformers/randomized_measurements.py +16 -14
  641. cirq/transformers/randomized_measurements_test.py +10 -4
  642. cirq/transformers/routing/initial_mapper.py +6 -4
  643. cirq/transformers/routing/initial_mapper_test.py +2 -0
  644. cirq/transformers/routing/line_initial_mapper.py +16 -14
  645. cirq/transformers/routing/line_initial_mapper_test.py +9 -7
  646. cirq/transformers/routing/mapping_manager.py +10 -10
  647. cirq/transformers/routing/mapping_manager_test.py +2 -0
  648. cirq/transformers/routing/route_circuit_cqc.py +33 -31
  649. cirq/transformers/routing/route_circuit_cqc_test.py +15 -13
  650. cirq/transformers/routing/visualize_routed_circuit.py +8 -7
  651. cirq/transformers/routing/visualize_routed_circuit_test.py +4 -2
  652. cirq/transformers/stratify.py +17 -15
  653. cirq/transformers/stratify_test.py +3 -0
  654. cirq/transformers/symbolize.py +103 -0
  655. cirq/transformers/symbolize_test.py +62 -0
  656. cirq/transformers/synchronize_terminal_measurements.py +10 -10
  657. cirq/transformers/synchronize_terminal_measurements_test.py +12 -10
  658. cirq/transformers/tag_transformers.py +97 -0
  659. cirq/transformers/tag_transformers_test.py +103 -0
  660. cirq/transformers/target_gatesets/compilation_target_gateset.py +21 -19
  661. cirq/transformers/target_gatesets/compilation_target_gateset_test.py +20 -16
  662. cirq/transformers/target_gatesets/cz_gateset.py +7 -5
  663. cirq/transformers/target_gatesets/cz_gateset_test.py +21 -19
  664. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +9 -7
  665. cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +25 -25
  666. cirq/transformers/transformer_api.py +34 -47
  667. cirq/transformers/transformer_api_test.py +9 -8
  668. cirq/transformers/transformer_primitives.py +39 -49
  669. cirq/transformers/transformer_primitives_test.py +10 -17
  670. cirq/value/abc_alt.py +6 -4
  671. cirq/value/abc_alt_test.py +5 -3
  672. cirq/value/angle.py +11 -12
  673. cirq/value/angle_test.py +5 -3
  674. cirq/value/classical_data.py +27 -27
  675. cirq/value/classical_data_test.py +11 -8
  676. cirq/value/condition.py +26 -24
  677. cirq/value/condition_test.py +2 -0
  678. cirq/value/digits.py +14 -11
  679. cirq/value/digits_test.py +2 -0
  680. cirq/value/duration.py +23 -20
  681. cirq/value/duration_test.py +2 -0
  682. cirq/value/linear_dict.py +25 -30
  683. cirq/value/linear_dict_test.py +10 -8
  684. cirq/value/measurement_key.py +12 -12
  685. cirq/value/measurement_key_test.py +2 -0
  686. cirq/value/periodic_value.py +4 -4
  687. cirq/value/periodic_value_test.py +11 -7
  688. cirq/value/probability.py +3 -1
  689. cirq/value/probability_test.py +4 -2
  690. cirq/value/product_state.py +15 -13
  691. cirq/value/product_state_test.py +4 -1
  692. cirq/value/random_state.py +2 -0
  693. cirq/value/random_state_test.py +5 -3
  694. cirq/value/timestamp.py +11 -7
  695. cirq/value/timestamp_test.py +14 -12
  696. cirq/value/type_alias.py +4 -4
  697. cirq/value/value_equality_attr.py +8 -9
  698. cirq/value/value_equality_attr_test.py +14 -11
  699. cirq/vis/density_matrix.py +3 -3
  700. cirq/vis/density_matrix_test.py +20 -17
  701. cirq/vis/heatmap.py +24 -37
  702. cirq/vis/heatmap_test.py +3 -0
  703. cirq/vis/histogram.py +9 -6
  704. cirq/vis/histogram_test.py +5 -2
  705. cirq/vis/state_histogram.py +10 -8
  706. cirq/vis/state_histogram_test.py +7 -5
  707. cirq/vis/vis_utils.py +4 -1
  708. cirq/vis/vis_utils_test.py +4 -1
  709. cirq/work/collector.py +12 -18
  710. cirq/work/collector_test.py +15 -10
  711. cirq/work/observable_grouping.py +6 -7
  712. cirq/work/observable_grouping_test.py +10 -9
  713. cirq/work/observable_measurement.py +47 -45
  714. cirq/work/observable_measurement_data.py +22 -17
  715. cirq/work/observable_measurement_data_test.py +4 -1
  716. cirq/work/observable_measurement_test.py +48 -29
  717. cirq/work/observable_readout_calibration.py +5 -2
  718. cirq/work/observable_readout_calibration_test.py +5 -2
  719. cirq/work/observable_settings.py +13 -22
  720. cirq/work/observable_settings_test.py +9 -7
  721. cirq/work/pauli_sum_collector.py +12 -10
  722. cirq/work/pauli_sum_collector_test.py +9 -9
  723. cirq/work/sampler.py +42 -43
  724. cirq/work/sampler_test.py +31 -24
  725. cirq/work/zeros_sampler.py +6 -4
  726. cirq/work/zeros_sampler_test.py +7 -5
  727. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/METADATA +7 -8
  728. cirq_core-1.6.0.dist-info/RECORD +1241 -0
  729. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/WHEEL +1 -1
  730. cirq_core-1.5.0.dev20250409222543.dist-info/RECORD +0 -1216
  731. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/licenses/LICENSE +0 -0
  732. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/top_level.txt +0 -0
@@ -12,23 +12,13 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- import numbers
16
- from typing import (
17
- AbstractSet,
18
- cast,
19
- Dict,
20
- Iterable,
21
- Iterator,
22
- Optional,
23
- Sequence,
24
- TYPE_CHECKING,
25
- Union,
26
- )
15
+ from __future__ import annotations
27
16
 
28
- import sympy
17
+ import numbers
18
+ from typing import AbstractSet, cast, Iterable, Iterator, Sequence, TYPE_CHECKING
29
19
 
30
20
  from cirq import protocols, value
31
- from cirq._compat import proper_repr
21
+ from cirq._compat import deprecated, proper_repr
32
22
  from cirq.ops import (
33
23
  common_gates,
34
24
  dense_pauli_string as dps,
@@ -40,6 +30,8 @@ from cirq.ops import (
40
30
  )
41
31
 
42
32
  if TYPE_CHECKING:
33
+ import sympy
34
+
43
35
  import cirq
44
36
 
45
37
 
@@ -63,10 +55,10 @@ class PauliStringPhasor(gate_operation.GateOperation):
63
55
  def __init__(
64
56
  self,
65
57
  pauli_string: ps.PauliString,
66
- qubits: Optional[Sequence['cirq.Qid']] = None,
58
+ qubits: Sequence[cirq.Qid] | None = None,
67
59
  *,
68
- exponent_neg: 'cirq.TParamVal' = 1,
69
- exponent_pos: 'cirq.TParamVal' = 0,
60
+ exponent_neg: cirq.TParamVal = 1,
61
+ exponent_pos: cirq.TParamVal = 0,
70
62
  ) -> None:
71
63
  """Initializes the operation.
72
64
 
@@ -106,34 +98,34 @@ class PauliStringPhasor(gate_operation.GateOperation):
106
98
  self._pauli_string = gate.dense_pauli_string.on(*self.qubits)
107
99
 
108
100
  @property
109
- def gate(self) -> 'cirq.PauliStringPhasorGate':
101
+ def gate(self) -> cirq.PauliStringPhasorGate:
110
102
  """The gate applied by the operation."""
111
103
  return cast(PauliStringPhasorGate, self._gate)
112
104
 
113
105
  @property
114
- def exponent_neg(self) -> 'cirq.TParamVal':
106
+ def exponent_neg(self) -> cirq.TParamVal:
115
107
  """The negative exponent."""
116
108
  return self.gate.exponent_neg
117
109
 
118
110
  @property
119
- def exponent_pos(self) -> 'cirq.TParamVal':
111
+ def exponent_pos(self) -> cirq.TParamVal:
120
112
  """The positive exponent."""
121
113
  return self.gate.exponent_pos
122
114
 
123
115
  @property
124
- def pauli_string(self) -> 'cirq.PauliString':
116
+ def pauli_string(self) -> cirq.PauliString:
125
117
  """The underlying pauli string."""
126
118
  return self._pauli_string
127
119
 
128
120
  @property
129
- def exponent_relative(self) -> 'cirq.TParamVal':
121
+ def exponent_relative(self) -> cirq.TParamVal:
130
122
  """The relative exponent between negative and positive exponents."""
131
123
  return self.gate.exponent_relative
132
124
 
133
125
  def _value_equality_values_(self):
134
126
  return (self.pauli_string, self.qubits, self.exponent_neg, self.exponent_pos)
135
127
 
136
- def equal_up_to_global_phase(self, other: 'PauliStringPhasor') -> bool:
128
+ def equal_up_to_global_phase(self, other: PauliStringPhasor) -> bool:
137
129
  """Checks equality of two PauliStringPhasors, up to global phase."""
138
130
  if isinstance(other, PauliStringPhasor):
139
131
  return (
@@ -143,7 +135,7 @@ class PauliStringPhasor(gate_operation.GateOperation):
143
135
  )
144
136
  return False
145
137
 
146
- def map_qubits(self, qubit_map: Dict[raw_types.Qid, raw_types.Qid]) -> 'PauliStringPhasor':
138
+ def map_qubits(self, qubit_map: dict[raw_types.Qid, raw_types.Qid]) -> PauliStringPhasor:
147
139
  """Maps the qubits inside the PauliStringPhasor.
148
140
 
149
141
  Args:
@@ -168,13 +160,13 @@ class PauliStringPhasor(gate_operation.GateOperation):
168
160
  exponent_pos=self.exponent_pos,
169
161
  )
170
162
 
171
- def can_merge_with(self, op: 'PauliStringPhasor') -> bool:
163
+ def can_merge_with(self, op: PauliStringPhasor) -> bool:
172
164
  """Checks whether the underlying PauliStrings can be merged."""
173
165
  return (
174
166
  self.pauli_string.equal_up_to_coefficient(op.pauli_string) and self.qubits == op.qubits
175
167
  )
176
168
 
177
- def merged_with(self, op: 'PauliStringPhasor') -> 'PauliStringPhasor':
169
+ def merged_with(self, op: PauliStringPhasor) -> PauliStringPhasor:
178
170
  """Merges two PauliStringPhasors."""
179
171
  if not self.can_merge_with(op):
180
172
  raise ValueError(f'Cannot merge operations: {self}, {op}')
@@ -184,9 +176,7 @@ class PauliStringPhasor(gate_operation.GateOperation):
184
176
  self.pauli_string, qubits=self.qubits, exponent_pos=pp, exponent_neg=pn
185
177
  )
186
178
 
187
- def _circuit_diagram_info_(
188
- self, args: 'cirq.CircuitDiagramInfoArgs'
189
- ) -> 'cirq.CircuitDiagramInfo':
179
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
190
180
  qubits = self.qubits if args.known_qubits is None else args.known_qubits
191
181
  if not qubits:
192
182
  return NotImplemented
@@ -199,9 +189,21 @@ class PauliStringPhasor(gate_operation.GateOperation):
199
189
  syms = tuple(sym(qubit) for qubit in qubits)
200
190
  return protocols.CircuitDiagramInfo(wire_symbols=syms, exponent=self.exponent_relative)
201
191
 
192
+ def conjugated_by(self, clifford: cirq.OP_TREE) -> PauliStringPhasor:
193
+ r"""Returns the Pauli string conjugated by a clifford operation.
194
+
195
+ The PauliStringPhasor $P$ conjugated by the Clifford operation $C$ is
196
+ $C^\dagger P C$.
197
+ """
198
+ new_pauli_string: ps.PauliString = self.pauli_string.conjugated_by(clifford)
199
+ pp = self.exponent_pos
200
+ pn = self.exponent_neg
201
+ return PauliStringPhasor(new_pauli_string, exponent_pos=pp, exponent_neg=pn)
202
+
203
+ @deprecated(deadline="v2.0", fix="Use conjuagetd_by() instead.")
202
204
  def pass_operations_over(
203
205
  self, ops: Iterable[raw_types.Operation], after_to_before: bool = False
204
- ) -> 'PauliStringPhasor':
206
+ ) -> PauliStringPhasor: # pragma: no cover
205
207
  """Determines how the Pauli phasor changes when conjugated by Cliffords.
206
208
 
207
209
  The output and input pauli phasors are related by a circuit equivalence.
@@ -228,7 +230,12 @@ class PauliStringPhasor(gate_operation.GateOperation):
228
230
  pauli string, instead of before (and so are moving in the
229
231
  opposite direction).
230
232
  """
231
- new_pauli_string = self.pauli_string.pass_operations_over(ops, after_to_before)
233
+ new_pauli_string: ps.PauliString = ps.PauliString()
234
+ if after_to_before:
235
+ new_pauli_string = self.pauli_string.after(ops)
236
+ else:
237
+ all_ops = list(op_tree.flatten_to_ops(ops))
238
+ new_pauli_string = self.pauli_string.before(all_ops[::-1])
232
239
  pp = self.exponent_pos
233
240
  pn = self.exponent_neg
234
241
  return PauliStringPhasor(new_pauli_string, exponent_pos=pp, exponent_neg=pn)
@@ -277,8 +284,8 @@ class PauliStringPhasorGate(raw_types.Gate):
277
284
  self,
278
285
  dense_pauli_string: dps.DensePauliString,
279
286
  *,
280
- exponent_neg: 'cirq.TParamVal' = 1,
281
- exponent_pos: 'cirq.TParamVal' = 0,
287
+ exponent_neg: cirq.TParamVal = 1,
288
+ exponent_pos: cirq.TParamVal = 0,
282
289
  ) -> None:
283
290
  """Initializes the PauliStringPhasorGate.
284
291
 
@@ -308,29 +315,29 @@ class PauliStringPhasorGate(raw_types.Gate):
308
315
  self._exponent_pos = value.canonicalize_half_turns(exponent_pos)
309
316
 
310
317
  @property
311
- def exponent_relative(self) -> 'cirq.TParamVal':
318
+ def exponent_relative(self) -> cirq.TParamVal:
312
319
  """The relative exponent between negative and positive exponents."""
313
320
  return value.canonicalize_half_turns(self.exponent_neg - self.exponent_pos)
314
321
 
315
322
  @property
316
- def exponent_neg(self) -> 'cirq.TParamVal':
323
+ def exponent_neg(self) -> cirq.TParamVal:
317
324
  """The negative exponent."""
318
325
  return self._exponent_neg
319
326
 
320
327
  @property
321
- def exponent_pos(self) -> 'cirq.TParamVal':
328
+ def exponent_pos(self) -> cirq.TParamVal:
322
329
  """The positive exponent."""
323
330
  return self._exponent_pos
324
331
 
325
332
  @property
326
- def dense_pauli_string(self) -> 'cirq.DensePauliString':
333
+ def dense_pauli_string(self) -> cirq.DensePauliString:
327
334
  """The underlying DensePauliString."""
328
335
  return self._dense_pauli_string
329
336
 
330
337
  def _value_equality_values_(self):
331
338
  return (self.dense_pauli_string, self.exponent_neg, self.exponent_pos)
332
339
 
333
- def equal_up_to_global_phase(self, other: 'cirq.PauliStringPhasorGate') -> bool:
340
+ def equal_up_to_global_phase(self, other: cirq.PauliStringPhasorGate) -> bool:
334
341
  """Checks equality of two PauliStringPhasors, up to global phase."""
335
342
  if isinstance(other, PauliStringPhasorGate):
336
343
  rel1 = self.exponent_relative
@@ -338,7 +345,7 @@ class PauliStringPhasorGate(raw_types.Gate):
338
345
  return rel1 == rel2 and self.dense_pauli_string == other.dense_pauli_string
339
346
  return False
340
347
 
341
- def __pow__(self, exponent: Union[float, sympy.Symbol]) -> 'PauliStringPhasorGate':
348
+ def __pow__(self, exponent: float | sympy.Symbol) -> PauliStringPhasorGate:
342
349
  pn = protocols.mul(self.exponent_neg, exponent, None)
343
350
  pp = protocols.mul(self.exponent_pos, exponent, None)
344
351
  if pn is None or pp is None:
@@ -348,11 +355,11 @@ class PauliStringPhasorGate(raw_types.Gate):
348
355
  def _has_unitary_(self) -> bool:
349
356
  return not self._is_parameterized_()
350
357
 
351
- def _to_z_basis_ops(self, qubits: Sequence['cirq.Qid']) -> Iterator[raw_types.Operation]:
358
+ def _to_z_basis_ops(self, qubits: Sequence[cirq.Qid]) -> Iterator[raw_types.Operation]:
352
359
  """Returns operations to convert the qubits to the computational basis."""
353
360
  return self.dense_pauli_string.on(*qubits).to_z_basis_ops()
354
361
 
355
- def _decompose_(self, qubits: Sequence['cirq.Qid']) -> Iterator['cirq.OP_TREE']:
362
+ def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
356
363
  if len(self.dense_pauli_string) <= 0:
357
364
  return
358
365
  any_qubit = qubits[0]
@@ -387,8 +394,8 @@ class PauliStringPhasorGate(raw_types.Gate):
387
394
  )
388
395
 
389
396
  def _resolve_parameters_(
390
- self, resolver: 'cirq.ParamResolver', recursive: bool
391
- ) -> 'PauliStringPhasorGate':
397
+ self, resolver: cirq.ParamResolver, recursive: bool
398
+ ) -> PauliStringPhasorGate:
392
399
  exponent_neg = resolver.value_of(self.exponent_neg, recursive)
393
400
  exponent_pos = resolver.value_of(self.exponent_pos, recursive)
394
401
  if isinstance(exponent_neg, numbers.Complex):
@@ -427,7 +434,7 @@ class PauliStringPhasorGate(raw_types.Gate):
427
434
  """The number of qubits for the gate."""
428
435
  return len(self.dense_pauli_string)
429
436
 
430
- def on(self, *qubits: 'cirq.Qid') -> 'cirq.PauliStringPhasor':
437
+ def on(self, *qubits: cirq.Qid) -> cirq.PauliStringPhasor:
431
438
  """Creates a PauliStringPhasor on the qubits."""
432
439
  return PauliStringPhasor(
433
440
  self.dense_pauli_string.on(*qubits),
@@ -443,7 +450,7 @@ class PauliStringPhasorGate(raw_types.Gate):
443
450
 
444
451
 
445
452
  def xor_nonlocal_decompose(
446
- qubits: Iterable[raw_types.Qid], onto_qubit: 'cirq.Qid'
453
+ qubits: Iterable[raw_types.Qid], onto_qubit: cirq.Qid
447
454
  ) -> Iterable[raw_types.Operation]:
448
455
  """Decomposition ignores connectivity."""
449
456
  for qubit in qubits:
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import itertools
16
18
 
17
19
  import numpy as np
@@ -155,7 +157,7 @@ def test_consistent():
155
157
  cirq.testing.assert_implements_consistent_protocols(p)
156
158
 
157
159
 
158
- def test_pass_operations_over():
160
+ def test_conjugated_by():
159
161
  q0, q1 = _make_qubits(2)
160
162
  op = cirq.SingleQubitCliffordGate.from_double_map(
161
163
  {cirq.Z: (cirq.X, False), cirq.X: (cirq.Z, False)}
@@ -164,10 +166,7 @@ def test_pass_operations_over():
164
166
  ps_after = cirq.PauliString({q0: cirq.Z, q1: cirq.Y}, -1)
165
167
  before = cirq.PauliStringPhasor(ps_before, exponent_neg=0.1)
166
168
  after = cirq.PauliStringPhasor(ps_after, exponent_neg=0.1)
167
- assert before.pass_operations_over([op]).pauli_string == after.pauli_string
168
- assert (
169
- after.pass_operations_over([op], after_to_before=True).pauli_string == before.pauli_string
170
- )
169
+ assert before.conjugated_by(op).pauli_string == after.pauli_string
171
170
 
172
171
 
173
172
  def test_extrapolate_effect():
@@ -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
  import abc
16
- from typing import Any, Dict, Sequence, Tuple, TYPE_CHECKING
18
+ from typing import Any, Sequence, TYPE_CHECKING
17
19
 
18
20
  from typing_extensions import Self
19
21
 
@@ -29,19 +31,19 @@ class PauliStringGateOperation(raw_types.Operation, metaclass=abc.ABCMeta):
29
31
  self._pauli_string = pauli_string
30
32
 
31
33
  @property
32
- def pauli_string(self) -> 'cirq.PauliString':
34
+ def pauli_string(self) -> cirq.PauliString:
33
35
  return self._pauli_string
34
36
 
35
37
  def validate_args(self, qubits: Sequence[raw_types.Qid]) -> None:
36
38
  if len(qubits) != len(self.pauli_string):
37
39
  raise ValueError('Incorrect number of qubits for gate')
38
40
 
39
- def with_qubits(self, *new_qubits: 'cirq.Qid') -> Self:
41
+ def with_qubits(self, *new_qubits: cirq.Qid) -> Self:
40
42
  self.validate_args(new_qubits)
41
43
  return self.map_qubits(dict(zip(self.pauli_string.qubits, new_qubits)))
42
44
 
43
45
  @abc.abstractmethod
44
- def map_qubits(self, qubit_map: Dict[raw_types.Qid, raw_types.Qid]) -> Self:
46
+ def map_qubits(self, qubit_map: dict[raw_types.Qid, raw_types.Qid]) -> Self:
45
47
  """Return an equivalent operation on new qubits with its Pauli string
46
48
  mapped to new qubits.
47
49
 
@@ -49,12 +51,12 @@ class PauliStringGateOperation(raw_types.Operation, metaclass=abc.ABCMeta):
49
51
  """
50
52
 
51
53
  @property
52
- def qubits(self) -> Tuple[raw_types.Qid, ...]:
54
+ def qubits(self) -> tuple[raw_types.Qid, ...]:
53
55
  return tuple(self.pauli_string)
54
56
 
55
57
  def _pauli_string_diagram_info(
56
- self, args: 'protocols.CircuitDiagramInfoArgs', exponent: Any = 1
57
- ) -> 'cirq.CircuitDiagramInfo':
58
+ self, args: protocols.CircuitDiagramInfoArgs, exponent: Any = 1
59
+ ) -> cirq.CircuitDiagramInfo:
58
60
  qubits = self.qubits if args.known_qubits is None else args.known_qubits
59
61
  syms = tuple(f'[{self.pauli_string[qubit]}]' for qubit in qubits)
60
62
  return protocols.CircuitDiagramInfo(wire_symbols=syms, exponent=exponent)
@@ -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
@@ -12,9 +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
  import itertools
16
18
  import math
17
- from typing import List
18
19
 
19
20
  import numpy as np
20
21
  import pytest
@@ -336,9 +337,7 @@ def test_get(qubit_pauli_map):
336
337
  assert qubit_pauli_map.get(key) == pauli_string.get(key)
337
338
  assert qubit_pauli_map.get(other) is None
338
339
  assert pauli_string.get(other) is None
339
- # pylint: disable=too-many-function-args
340
340
  assert qubit_pauli_map.get(other, 5) == pauli_string.get(other, 5) == 5
341
- # pylint: enable=too-many-function-args
342
341
 
343
342
 
344
343
  @pytest.mark.parametrize('qubit_pauli_map', _sample_qubit_pauli_maps())
@@ -723,118 +722,6 @@ def test_to_z_basis_ops_product_state():
723
722
  )
724
723
 
725
724
 
726
- def _assert_pass_over(ops: List[cirq.Operation], before: cirq.PauliString, after: cirq.PauliString):
727
- assert before.pass_operations_over(ops[::-1]) == after
728
- assert after.pass_operations_over(ops, after_to_before=True) == before
729
-
730
-
731
- @pytest.mark.parametrize('shift,sign', itertools.product(range(3), (-1, +1)))
732
- def test_pass_operations_over_single(shift: int, sign: int):
733
- q0, q1 = _make_qubits(2)
734
- X, Y, Z = (cirq.Pauli.by_relative_index(pauli, shift) for pauli in (cirq.X, cirq.Y, cirq.Z))
735
-
736
- op0 = cirq.SingleQubitCliffordGate.from_pauli(Y)(q1)
737
- ps_before: cirq.PauliString[cirq.Qid] = cirq.PauliString({q0: X}, sign)
738
- ps_after = ps_before
739
- _assert_pass_over([op0], ps_before, ps_after)
740
-
741
- op0 = cirq.SingleQubitCliffordGate.from_pauli(X)(q0)
742
- op1 = cirq.SingleQubitCliffordGate.from_pauli(Y)(q1)
743
- ps_before = cirq.PauliString({q0: X, q1: Y}, sign)
744
- ps_after = ps_before
745
- _assert_pass_over([op0, op1], ps_before, ps_after)
746
-
747
- op0 = cirq.SingleQubitCliffordGate.from_double_map({Z: (X, False), X: (Z, False)})(q0)
748
- ps_before = cirq.PauliString({q0: X, q1: Y}, sign)
749
- ps_after = cirq.PauliString({q0: Z, q1: Y}, sign)
750
- _assert_pass_over([op0], ps_before, ps_after)
751
-
752
- op1 = cirq.SingleQubitCliffordGate.from_pauli(X)(q1)
753
- ps_before = cirq.PauliString({q0: X, q1: Y}, sign)
754
- ps_after = -ps_before
755
- _assert_pass_over([op1], ps_before, ps_after)
756
-
757
- ps_after = cirq.PauliString({q0: Z, q1: Y}, -sign)
758
- _assert_pass_over([op0, op1], ps_before, ps_after)
759
-
760
- op0 = cirq.SingleQubitCliffordGate.from_pauli(Z, True)(q0)
761
- op1 = cirq.SingleQubitCliffordGate.from_pauli(X, True)(q0)
762
- ps_before = cirq.PauliString({q0: X}, sign)
763
- ps_after = cirq.PauliString({q0: Y}, -sign)
764
- _assert_pass_over([op0, op1], ps_before, ps_after)
765
-
766
-
767
- @pytest.mark.parametrize(
768
- 'shift,t_or_f1, t_or_f2,neg', itertools.product(range(3), *((True, False),) * 3)
769
- )
770
- def test_pass_operations_over_double(shift: int, t_or_f1: bool, t_or_f2: bool, neg: bool):
771
- sign = -1 if neg else +1
772
- q0, q1, q2 = _make_qubits(3)
773
- X, Y, Z = (cirq.Pauli.by_relative_index(pauli, shift) for pauli in (cirq.X, cirq.Y, cirq.Z))
774
-
775
- op0 = cirq.PauliInteractionGate(Z, t_or_f1, X, t_or_f2)(q0, q1)
776
- ps_before = cirq.PauliString(qubit_pauli_map={q0: Z, q2: Y}, coefficient=sign)
777
- ps_after = cirq.PauliString(qubit_pauli_map={q0: Z, q2: Y}, coefficient=sign)
778
- assert_conjugation(ps_before, op0, ps_after, True)
779
- _assert_pass_over([op0], ps_before, ps_after)
780
-
781
- op0 = cirq.PauliInteractionGate(Y, t_or_f1, X, t_or_f2)(q0, q1)
782
- ps_before = cirq.PauliString({q0: Z, q2: Y}, sign)
783
- ps_after = cirq.PauliString({q0: Z, q2: Y, q1: X}, -sign if t_or_f2 else sign)
784
- assert_conjugation(ps_before, op0, ps_after, True)
785
- _assert_pass_over([op0], ps_before, ps_after)
786
-
787
- op0 = cirq.PauliInteractionGate(Z, t_or_f1, X, t_or_f2)(q0, q1)
788
- ps_before = cirq.PauliString({q0: Z, q1: Y}, sign)
789
- ps_after = cirq.PauliString({q1: Y}, -sign if t_or_f1 else sign)
790
- assert_conjugation(ps_before, op0, ps_after, True)
791
- _assert_pass_over([op0], ps_before, ps_after)
792
-
793
- op0 = cirq.PauliInteractionGate(Y, t_or_f1, X, t_or_f2)(q0, q1)
794
- ps_before = cirq.PauliString({q0: Z, q1: Y}, sign)
795
- ps_after = cirq.PauliString({q0: X, q1: Z}, -1 if neg ^ t_or_f1 ^ t_or_f2 else +1)
796
- assert_conjugation(ps_before, op0, ps_after, True)
797
- _assert_pass_over([op0], ps_before, ps_after)
798
-
799
- op0 = cirq.PauliInteractionGate(X, t_or_f1, X, t_or_f2)(q0, q1)
800
- ps_before = cirq.PauliString({q0: Z, q1: Y}, sign)
801
- ps_after = cirq.PauliString({q0: Y, q1: Z}, +1 if neg ^ t_or_f1 ^ t_or_f2 else -1)
802
- assert_conjugation(ps_before, op0, ps_after, True)
803
- _assert_pass_over([op0], ps_before, ps_after)
804
-
805
-
806
- def test_pass_operations_over_cz():
807
- q0, q1 = _make_qubits(2)
808
- op0 = cirq.CZ(q0, q1)
809
- ps_before = cirq.PauliString({q0: cirq.Z, q1: cirq.Y})
810
- ps_after = cirq.PauliString({q1: cirq.Y})
811
- _assert_pass_over([op0], ps_before, ps_after)
812
-
813
-
814
- def test_pass_operations_over_no_common_qubits():
815
- class ExampleGate(cirq.testing.SingleQubitGate):
816
-
817
- def _decompose_(self, qubits):
818
- return cirq.X(qubits[0])
819
-
820
- q0, q1 = _make_qubits(2)
821
- op0 = ExampleGate()(q1)
822
- ps_before = cirq.PauliString({q0: cirq.Z})
823
- ps_after = cirq.PauliString({q0: cirq.Z})
824
- _assert_pass_over([op0], ps_before, ps_after)
825
-
826
-
827
- def test_pass_unsupported_operations_over():
828
- (q0,) = _make_qubits(1)
829
- pauli_string = cirq.PauliString({q0: cirq.X})
830
- with pytest.raises(
831
- ValueError,
832
- match='Clifford Gate can only be constructed from the operations'
833
- ' that has stabilizer effect.',
834
- ):
835
- pauli_string.pass_operations_over([cirq.T(q0)])
836
-
837
-
838
725
  def test_with_qubits():
839
726
  old_qubits = cirq.LineQubit.range(9)
840
727
  new_qubits = cirq.LineQubit.range(9, 18)
@@ -1637,40 +1524,6 @@ def test_conjugated_by_ordering():
1637
1524
  assert out1 == out2 == cirq.X(a) * cirq.Z(b)
1638
1525
 
1639
1526
 
1640
- def test_pass_operations_over_ordering():
1641
- class OrderSensitiveGate(cirq.Gate):
1642
- def num_qubits(self):
1643
- return 2
1644
-
1645
- def _decompose_(self, qubits):
1646
- return [cirq.Y(qubits[0]) ** -0.5, cirq.CNOT(*qubits)]
1647
-
1648
- a, b = cirq.LineQubit.range(2)
1649
- inp = cirq.Z(b)
1650
- out1 = inp.pass_operations_over(OrderSensitiveGate().on(a, b))
1651
- out2 = inp.pass_operations_over([cirq.CNOT(a, b), cirq.Y(a) ** -0.5])
1652
- out3 = inp.pass_operations_over([cirq.CNOT(a, b)]).pass_operations_over([cirq.Y(a) ** -0.5])
1653
- assert out1 == out2 == out3 == cirq.X(a) * cirq.Z(b)
1654
-
1655
-
1656
- def test_pass_operations_over_ordering_reversed():
1657
- class OrderSensitiveGate(cirq.Gate):
1658
- def num_qubits(self):
1659
- return 2
1660
-
1661
- def _decompose_(self, qubits):
1662
- return [cirq.Y(qubits[0]) ** -0.5, cirq.CNOT(*qubits)]
1663
-
1664
- a, b = cirq.LineQubit.range(2)
1665
- inp = cirq.X(a) * cirq.Z(b)
1666
- out1 = inp.pass_operations_over(OrderSensitiveGate().on(a, b), after_to_before=True)
1667
- out2 = inp.pass_operations_over([cirq.Y(a) ** -0.5, cirq.CNOT(a, b)], after_to_before=True)
1668
- out3 = inp.pass_operations_over([cirq.Y(a) ** -0.5], after_to_before=True).pass_operations_over(
1669
- [cirq.CNOT(a, b)], after_to_before=True
1670
- )
1671
- assert out1 == out2 == out3 == cirq.Z(b)
1672
-
1673
-
1674
1527
  def test_pretty_print():
1675
1528
  a, b, c = cirq.LineQubit.range(3)
1676
1529
  result = cirq.PauliString({a: 'x', b: 'y', c: 'z'})
@@ -1693,7 +1546,6 @@ def test_pretty_print():
1693
1546
  assert p.text_pretty == 'cirq.PauliString(...)'
1694
1547
 
1695
1548
 
1696
- # pylint: disable=line-too-long
1697
1549
  def test_circuit_diagram_info():
1698
1550
  a, b, c = cirq.LineQubit.range(3)
1699
1551
 
@@ -1714,13 +1566,10 @@ def test_circuit_diagram_info():
1714
1566
  1: ───────────────────────────────────────┼─────────────────Y─────────────────PauliString(-iY)───Y───────────────────────────────
1715
1567
 
1716
1568
  2: ───────────────────────────────────────Z──────────────────────────────────────────────────────────────────────────────────────
1717
- """,
1569
+ """, # noqa: E501
1718
1570
  )
1719
1571
 
1720
1572
 
1721
- # pylint: enable=line-too-long
1722
-
1723
-
1724
1573
  def test_mutable_pauli_string_init_raises():
1725
1574
  q = cirq.LineQubit.range(3)
1726
1575
  with pytest.raises(ValueError, match='must be between 1 and 3'):
@@ -2137,3 +1986,31 @@ def test_resolve(resolve_fn):
2137
1986
  pst = cirq.PauliString({q: 'x'}, coefficient=t)
2138
1987
  ps1 = cirq.PauliString({q: 'x'}, coefficient=1j)
2139
1988
  assert resolve_fn(pst, {'t': 1j}) == ps1
1989
+
1990
+
1991
+ @pytest.mark.parametrize(
1992
+ 'gate1,gate2',
1993
+ [
1994
+ (cirq.I, cirq.I),
1995
+ (cirq.I, cirq.X),
1996
+ (cirq.I, cirq.Y),
1997
+ (cirq.I, cirq.Z),
1998
+ (cirq.X, cirq.I),
1999
+ (cirq.Y, cirq.I),
2000
+ (cirq.Z, cirq.I),
2001
+ ],
2002
+ ids=str,
2003
+ )
2004
+ def test_pauli_ops_identity_gate_operation(gate1: cirq.Pauli, gate2: cirq.Pauli) -> None:
2005
+ # TODO: Issue #7280 - Support addition and subtraction of identity gate operations.
2006
+ if gate1 == gate2 == cirq.I:
2007
+ pytest.skip('Not yet implemented per #7280')
2008
+ q = cirq.LineQubit(0)
2009
+ pauli1, pauli2 = gate1.on(q), gate2.on(q)
2010
+ unitary1, unitary2 = cirq.unitary(gate1), cirq.unitary(gate2)
2011
+ addition = pauli1 + pauli2
2012
+ assert isinstance(addition, cirq.PauliSum)
2013
+ assert np.array_equal(addition.matrix(), unitary1 + unitary2)
2014
+ subtraction = pauli1 - pauli2
2015
+ assert isinstance(subtraction, cirq.PauliSum)
2016
+ assert np.array_equal(subtraction.matrix(), unitary1 - unitary2)
@@ -11,7 +11,10 @@
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, Iterator, Tuple, TYPE_CHECKING
14
+
15
+ from __future__ import annotations
16
+
17
+ from typing import Any, Iterator, TYPE_CHECKING
15
18
 
16
19
  import numpy as np
17
20
 
@@ -22,7 +25,7 @@ if TYPE_CHECKING:
22
25
  import cirq
23
26
 
24
27
 
25
- def _all_pauli_strings_commute(pauli_sum: 'cirq.PauliSum') -> bool:
28
+ def _all_pauli_strings_commute(pauli_sum: cirq.PauliSum) -> bool:
26
29
  for x in pauli_sum:
27
30
  for y in pauli_sum:
28
31
  if not protocols.commutes(x, y):
@@ -42,10 +45,7 @@ class PauliSumExponential:
42
45
  """
43
46
 
44
47
  def __init__(
45
- self,
46
- pauli_sum_like: 'cirq.PauliSumLike',
47
- exponent: 'cirq.TParamVal' = 1,
48
- atol: float = 1e-8,
48
+ self, pauli_sum_like: cirq.PauliSumLike, exponent: cirq.TParamVal = 1, atol: float = 1e-8
49
49
  ):
50
50
  pauli_sum = linear_combinations.PauliSum.wrap(pauli_sum_like)
51
51
  if not _all_pauli_strings_commute(pauli_sum):
@@ -68,13 +68,13 @@ class PauliSumExponential:
68
68
  self._pauli_sum = pauli_sum
69
69
 
70
70
  @property
71
- def qubits(self) -> Tuple['cirq.Qid', ...]:
71
+ def qubits(self) -> tuple[cirq.Qid, ...]:
72
72
  return self._pauli_sum.qubits
73
73
 
74
74
  def _value_equality_values_(self) -> Any:
75
75
  return (self._pauli_sum, self._exponent)
76
76
 
77
- def with_qubits(self, *new_qubits: 'cirq.Qid') -> 'PauliSumExponential':
77
+ def with_qubits(self, *new_qubits: cirq.Qid) -> PauliSumExponential:
78
78
  return PauliSumExponential(self._pauli_sum.with_qubits(*new_qubits), self._exponent)
79
79
 
80
80
  @_compat.cached_method
@@ -82,14 +82,14 @@ class PauliSumExponential:
82
82
  return protocols.is_parameterized(self._exponent)
83
83
 
84
84
  def _resolve_parameters_(
85
- self, resolver: 'cirq.ParamResolver', recursive: bool
86
- ) -> 'PauliSumExponential':
85
+ self, resolver: cirq.ParamResolver, recursive: bool
86
+ ) -> PauliSumExponential:
87
87
  return PauliSumExponential(
88
88
  self._pauli_sum,
89
89
  exponent=protocols.resolve_parameters(self._exponent, resolver, recursive),
90
90
  )
91
91
 
92
- def __iter__(self) -> Iterator['cirq.PauliStringPhasor']:
92
+ def __iter__(self) -> Iterator[cirq.PauliStringPhasor]:
93
93
  for pauli_string in self._pauli_sum:
94
94
  theta = pauli_string.coefficient * self._multiplier
95
95
  theta *= self._exponent / np.pi
@@ -119,7 +119,7 @@ class PauliSumExponential:
119
119
  def _unitary_(self) -> np.ndarray:
120
120
  return self.matrix()
121
121
 
122
- def __pow__(self, exponent: int) -> 'PauliSumExponential':
122
+ def __pow__(self, exponent: int) -> PauliSumExponential:
123
123
  return PauliSumExponential(self._pauli_sum, self._exponent * exponent)
124
124
 
125
125
  def __repr__(self) -> str: