cirq-core 1.4.0.dev20240529225110__py3-none-any.whl → 1.5.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 (590) hide show
  1. cirq/__init__.py +587 -569
  2. cirq/_compat.py +9 -0
  3. cirq/_compat_test.py +11 -9
  4. cirq/_import.py +7 -8
  5. cirq/_version.py +31 -1
  6. cirq/_version_test.py +1 -1
  7. cirq/circuits/__init__.py +15 -9
  8. cirq/circuits/_block_diagram_drawer.py +1 -2
  9. cirq/circuits/_block_diagram_drawer_test.py +3 -3
  10. cirq/circuits/_box_drawing_character_data.py +0 -1
  11. cirq/circuits/_box_drawing_character_data_test.py +2 -2
  12. cirq/circuits/_bucket_priority_queue.py +0 -1
  13. cirq/circuits/_bucket_priority_queue_test.py +1 -1
  14. cirq/circuits/circuit.py +336 -234
  15. cirq/circuits/circuit_operation.py +102 -52
  16. cirq/circuits/circuit_operation_test.py +85 -4
  17. cirq/circuits/circuit_test.py +101 -32
  18. cirq/circuits/frozen_circuit.py +36 -32
  19. cirq/circuits/insert_strategy.py +10 -0
  20. cirq/circuits/insert_strategy_test.py +20 -0
  21. cirq/circuits/moment.py +79 -80
  22. cirq/circuits/moment_test.py +105 -2
  23. cirq/circuits/optimization_pass.py +15 -15
  24. cirq/circuits/optimization_pass_test.py +8 -9
  25. cirq/circuits/qasm_output.py +64 -33
  26. cirq/circuits/qasm_output_test.py +63 -2
  27. cirq/circuits/text_diagram_drawer.py +26 -56
  28. cirq/circuits/text_diagram_drawer_test.py +5 -4
  29. cirq/contrib/__init__.py +2 -2
  30. cirq/contrib/acquaintance/__init__.py +44 -29
  31. cirq/contrib/acquaintance/bipartite.py +8 -7
  32. cirq/contrib/acquaintance/bipartite_test.py +11 -1
  33. cirq/contrib/acquaintance/devices.py +5 -4
  34. cirq/contrib/acquaintance/devices_test.py +5 -1
  35. cirq/contrib/acquaintance/executor.py +18 -21
  36. cirq/contrib/acquaintance/executor_test.py +3 -2
  37. cirq/contrib/acquaintance/gates.py +36 -27
  38. cirq/contrib/acquaintance/gates_test.py +1 -1
  39. cirq/contrib/acquaintance/inspection_utils.py +10 -9
  40. cirq/contrib/acquaintance/inspection_utils_test.py +6 -1
  41. cirq/contrib/acquaintance/mutation_utils.py +10 -10
  42. cirq/contrib/acquaintance/optimizers.py +7 -6
  43. cirq/contrib/acquaintance/optimizers_test.py +1 -1
  44. cirq/contrib/acquaintance/permutation.py +22 -21
  45. cirq/contrib/acquaintance/permutation_test.py +1 -1
  46. cirq/contrib/acquaintance/shift.py +8 -6
  47. cirq/contrib/acquaintance/shift_swap_network.py +6 -4
  48. cirq/contrib/acquaintance/strategies/__init__.py +9 -3
  49. cirq/contrib/acquaintance/strategies/complete.py +4 -3
  50. cirq/contrib/acquaintance/strategies/cubic.py +5 -3
  51. cirq/contrib/acquaintance/strategies/quartic_paired.py +8 -6
  52. cirq/contrib/acquaintance/topological_sort.py +4 -2
  53. cirq/contrib/bayesian_network/__init__.py +3 -1
  54. cirq/contrib/bayesian_network/bayesian_network_gate.py +5 -3
  55. cirq/contrib/circuitdag/__init__.py +1 -1
  56. cirq/contrib/circuitdag/circuit_dag.py +24 -24
  57. cirq/contrib/circuitdag/circuit_dag_test.py +1 -1
  58. cirq/contrib/custom_simulators/custom_state_simulator.py +10 -8
  59. cirq/contrib/custom_simulators/custom_state_simulator_test.py +15 -11
  60. cirq/contrib/graph_device/__init__.py +8 -8
  61. cirq/contrib/graph_device/graph_device.py +8 -8
  62. cirq/contrib/graph_device/graph_device_test.py +0 -1
  63. cirq/contrib/graph_device/hypergraph_test.py +1 -0
  64. cirq/contrib/json.py +1 -2
  65. cirq/contrib/json_test.py +2 -2
  66. cirq/contrib/noise_models/__init__.py +5 -6
  67. cirq/contrib/noise_models/noise_models.py +8 -6
  68. cirq/contrib/paulistring/__init__.py +22 -10
  69. cirq/contrib/paulistring/clifford_optimize.py +1 -1
  70. cirq/contrib/paulistring/clifford_optimize_test.py +0 -1
  71. cirq/contrib/paulistring/clifford_target_gateset.py +15 -12
  72. cirq/contrib/paulistring/optimize.py +2 -2
  73. cirq/contrib/paulistring/optimize_test.py +0 -1
  74. cirq/contrib/paulistring/pauli_string_dag_test.py +0 -1
  75. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +379 -0
  76. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +523 -0
  77. cirq/contrib/paulistring/pauli_string_optimize.py +3 -1
  78. cirq/contrib/paulistring/pauli_string_optimize_test.py +1 -3
  79. cirq/contrib/paulistring/recombine.py +2 -2
  80. cirq/contrib/paulistring/recombine_test.py +2 -2
  81. cirq/contrib/paulistring/separate.py +3 -4
  82. cirq/contrib/qasm_import/__init__.py +2 -2
  83. cirq/contrib/qasm_import/_lexer.py +21 -26
  84. cirq/contrib/qasm_import/_lexer_test.py +90 -6
  85. cirq/contrib/qasm_import/_parser.py +238 -47
  86. cirq/contrib/qasm_import/_parser_test.py +514 -59
  87. cirq/contrib/qasm_import/qasm_test.py +1 -1
  88. cirq/contrib/qcircuit/__init__.py +6 -4
  89. cirq/contrib/qcircuit/qcircuit_diagram.py +5 -2
  90. cirq/contrib/qcircuit/qcircuit_pdf.py +1 -2
  91. cirq/{experiments/grid_parallel_two_qubit_xeb_test.py → contrib/qcircuit/qcircuit_pdf_test.py} +13 -12
  92. cirq/contrib/qcircuit/qcircuit_test.py +1 -1
  93. cirq/contrib/quantum_volume/__init__.py +7 -7
  94. cirq/contrib/quantum_volume/quantum_volume.py +6 -11
  95. cirq/contrib/quantum_volume/quantum_volume_test.py +3 -1
  96. cirq/contrib/quimb/__init__.py +16 -13
  97. cirq/contrib/quimb/density_matrix.py +1 -1
  98. cirq/contrib/quimb/mps_simulator.py +27 -28
  99. cirq/contrib/quimb/mps_simulator_test.py +5 -0
  100. cirq/contrib/quimb/state_vector.py +3 -10
  101. cirq/contrib/quirk/__init__.py +1 -1
  102. cirq/contrib/quirk/export_to_quirk.py +3 -3
  103. cirq/contrib/routing/__init__.py +12 -9
  104. cirq/contrib/routing/device.py +1 -1
  105. cirq/contrib/routing/device_test.py +1 -2
  106. cirq/contrib/routing/greedy.py +7 -5
  107. cirq/contrib/routing/greedy_test.py +5 -3
  108. cirq/contrib/routing/initialization.py +3 -1
  109. cirq/contrib/routing/initialization_test.py +1 -1
  110. cirq/contrib/routing/swap_network.py +6 -6
  111. cirq/contrib/routing/utils.py +6 -4
  112. cirq/contrib/routing/utils_test.py +1 -2
  113. cirq/{type_workarounds.py → contrib/shuffle_circuits/__init__.py} +5 -10
  114. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +250 -0
  115. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +363 -0
  116. cirq/contrib/svg/__init__.py +1 -1
  117. cirq/contrib/svg/svg.py +12 -10
  118. cirq/contrib/svg/svg_test.py +3 -2
  119. cirq/devices/__init__.py +34 -25
  120. cirq/devices/device.py +16 -12
  121. cirq/devices/device_test.py +1 -0
  122. cirq/devices/grid_device_metadata.py +16 -12
  123. cirq/devices/grid_device_metadata_test.py +2 -1
  124. cirq/devices/grid_qubit.py +31 -26
  125. cirq/devices/grid_qubit_test.py +30 -1
  126. cirq/devices/insertion_noise_model.py +6 -6
  127. cirq/devices/insertion_noise_model_test.py +1 -1
  128. cirq/devices/line_qubit.py +28 -20
  129. cirq/devices/line_qubit_test.py +26 -0
  130. cirq/devices/named_topologies.py +12 -10
  131. cirq/devices/named_topologies_test.py +5 -4
  132. cirq/devices/noise_model.py +29 -33
  133. cirq/devices/noise_properties.py +2 -2
  134. cirq/devices/noise_properties_test.py +2 -2
  135. cirq/devices/noise_utils.py +3 -3
  136. cirq/devices/superconducting_qubits_noise_properties.py +2 -2
  137. cirq/devices/superconducting_qubits_noise_properties_test.py +3 -3
  138. cirq/devices/thermal_noise_model.py +2 -1
  139. cirq/devices/unconstrained_device.py +1 -1
  140. cirq/devices/unconstrained_device_test.py +6 -0
  141. cirq/experiments/__init__.py +51 -34
  142. cirq/experiments/qubit_characterizations.py +17 -15
  143. cirq/experiments/qubit_characterizations_test.py +4 -6
  144. cirq/experiments/random_quantum_circuit_generation.py +10 -9
  145. cirq/experiments/random_quantum_circuit_generation_test.py +21 -4
  146. cirq/experiments/readout_confusion_matrix.py +73 -8
  147. cirq/experiments/readout_confusion_matrix_test.py +104 -1
  148. cirq/experiments/single_qubit_readout_calibration.py +8 -6
  149. cirq/experiments/single_qubit_readout_calibration_test.py +1 -1
  150. cirq/experiments/t1_decay_experiment.py +4 -5
  151. cirq/experiments/t1_decay_experiment_test.py +1 -2
  152. cirq/experiments/t2_decay_experiment.py +0 -1
  153. cirq/experiments/t2_decay_experiment_test.py +1 -2
  154. cirq/experiments/two_qubit_xeb.py +157 -33
  155. cirq/experiments/two_qubit_xeb_test.py +38 -22
  156. cirq/experiments/xeb_fitting.py +99 -19
  157. cirq/experiments/xeb_fitting_test.py +64 -25
  158. cirq/experiments/xeb_sampling.py +14 -18
  159. cirq/experiments/xeb_simulation.py +4 -3
  160. cirq/experiments/xeb_simulation_test.py +20 -14
  161. cirq/experiments/z_phase_calibration.py +368 -0
  162. cirq/experiments/z_phase_calibration_test.py +241 -0
  163. cirq/interop/__init__.py +4 -1
  164. cirq/interop/quirk/__init__.py +7 -4
  165. cirq/interop/quirk/cells/__init__.py +17 -6
  166. cirq/interop/quirk/cells/arithmetic_cells.py +8 -8
  167. cirq/interop/quirk/cells/arithmetic_cells_test.py +1 -1
  168. cirq/interop/quirk/cells/cell.py +6 -6
  169. cirq/interop/quirk/cells/composite_cell.py +5 -5
  170. cirq/interop/quirk/cells/composite_cell_test.py +1 -1
  171. cirq/interop/quirk/cells/control_cells.py +1 -1
  172. cirq/interop/quirk/cells/frequency_space_cells.py +2 -2
  173. cirq/interop/quirk/cells/ignored_cells.py +1 -1
  174. cirq/interop/quirk/cells/input_cells.py +1 -1
  175. cirq/interop/quirk/cells/input_cells_test.py +1 -1
  176. cirq/interop/quirk/cells/input_rotation_cells.py +1 -1
  177. cirq/interop/quirk/cells/input_rotation_cells_test.py +1 -1
  178. cirq/interop/quirk/cells/measurement_cells.py +1 -1
  179. cirq/interop/quirk/cells/parse.py +8 -7
  180. cirq/interop/quirk/cells/parse_test.py +2 -2
  181. cirq/interop/quirk/cells/single_qubit_rotation_cells.py +1 -1
  182. cirq/interop/quirk/cells/swap_cell_test.py +1 -1
  183. cirq/interop/quirk/cells/unsupported_cells.py +1 -1
  184. cirq/interop/quirk/url_to_circuit.py +7 -7
  185. cirq/interop/quirk/url_to_circuit_test.py +1 -1
  186. cirq/ion/__init__.py +4 -2
  187. cirq/json_resolver_cache.py +15 -7
  188. cirq/linalg/__init__.py +62 -51
  189. cirq/linalg/combinators.py +4 -4
  190. cirq/linalg/combinators_test.py +4 -1
  191. cirq/linalg/decompositions.py +15 -40
  192. cirq/linalg/decompositions_test.py +16 -22
  193. cirq/linalg/diagonalize.py +1 -1
  194. cirq/linalg/diagonalize_test.py +1 -1
  195. cirq/linalg/operator_spaces.py +20 -4
  196. cirq/linalg/operator_spaces_test.py +15 -2
  197. cirq/linalg/predicates.py +3 -3
  198. cirq/linalg/predicates_test.py +1 -0
  199. cirq/linalg/tolerance.py +2 -2
  200. cirq/linalg/transformations.py +30 -12
  201. cirq/linalg/transformations_test.py +13 -0
  202. cirq/neutral_atoms/__init__.py +2 -2
  203. cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +0 -1
  204. cirq/ops/__init__.py +172 -132
  205. cirq/ops/arithmetic_operation.py +2 -2
  206. cirq/ops/arithmetic_operation_test.py +2 -2
  207. cirq/ops/boolean_hamiltonian.py +3 -2
  208. cirq/ops/classically_controlled_operation.py +39 -12
  209. cirq/ops/classically_controlled_operation_test.py +147 -1
  210. cirq/ops/clifford_gate.py +38 -36
  211. cirq/ops/clifford_gate_test.py +75 -1
  212. cirq/ops/common_channels.py +16 -45
  213. cirq/ops/common_channels_test.py +10 -0
  214. cirq/ops/common_gate_families.py +1 -1
  215. cirq/ops/common_gate_families_test.py +1 -0
  216. cirq/ops/common_gates.py +48 -49
  217. cirq/ops/common_gates_test.py +18 -2
  218. cirq/ops/control_values.py +3 -3
  219. cirq/ops/control_values_test.py +2 -1
  220. cirq/ops/controlled_gate.py +36 -23
  221. cirq/ops/controlled_gate_test.py +70 -3
  222. cirq/ops/controlled_operation.py +6 -5
  223. cirq/ops/controlled_operation_test.py +7 -3
  224. cirq/ops/dense_pauli_string.py +11 -11
  225. cirq/ops/diagonal_gate.py +2 -2
  226. cirq/ops/diagonal_gate_test.py +1 -0
  227. cirq/ops/eigen_gate.py +16 -36
  228. cirq/ops/eigen_gate_test.py +60 -10
  229. cirq/ops/fourier_transform.py +1 -3
  230. cirq/ops/fourier_transform_test.py +2 -1
  231. cirq/ops/fsim_gate.py +42 -3
  232. cirq/ops/fsim_gate_test.py +21 -0
  233. cirq/ops/gate_operation.py +8 -8
  234. cirq/ops/gate_operation_test.py +4 -2
  235. cirq/ops/gateset_test.py +11 -2
  236. cirq/ops/global_phase_op.py +8 -7
  237. cirq/ops/global_phase_op_test.py +1 -1
  238. cirq/ops/greedy_qubit_manager_test.py +5 -0
  239. cirq/ops/identity.py +14 -4
  240. cirq/ops/identity_test.py +24 -0
  241. cirq/ops/kraus_channel.py +1 -0
  242. cirq/ops/kraus_channel_test.py +3 -1
  243. cirq/ops/linear_combinations.py +27 -21
  244. cirq/ops/linear_combinations_test.py +23 -4
  245. cirq/ops/matrix_gates.py +24 -8
  246. cirq/ops/measure_util.py +2 -2
  247. cirq/ops/measurement_gate.py +7 -4
  248. cirq/ops/measurement_gate_test.py +2 -1
  249. cirq/ops/mixed_unitary_channel.py +1 -0
  250. cirq/ops/mixed_unitary_channel_test.py +3 -1
  251. cirq/ops/named_qubit.py +8 -1
  252. cirq/ops/op_tree.py +3 -30
  253. cirq/ops/op_tree_test.py +4 -0
  254. cirq/ops/parallel_gate.py +2 -3
  255. cirq/ops/parallel_gate_test.py +2 -1
  256. cirq/ops/parity_gates.py +7 -8
  257. cirq/ops/parity_gates_test.py +1 -0
  258. cirq/ops/pauli_gates.py +5 -11
  259. cirq/ops/pauli_gates_test.py +1 -0
  260. cirq/ops/pauli_interaction_gate.py +11 -5
  261. cirq/ops/pauli_interaction_gate_test.py +2 -3
  262. cirq/ops/pauli_measurement_gate.py +6 -5
  263. cirq/ops/pauli_measurement_gate_test.py +1 -0
  264. cirq/ops/pauli_string.py +115 -130
  265. cirq/ops/pauli_string_phasor.py +21 -20
  266. cirq/ops/pauli_string_phasor_test.py +13 -3
  267. cirq/ops/pauli_string_raw_types.py +1 -0
  268. cirq/ops/pauli_string_test.py +192 -55
  269. cirq/ops/pauli_sum_exponential.py +3 -4
  270. cirq/ops/pauli_sum_exponential_test.py +0 -1
  271. cirq/ops/permutation_gate.py +2 -2
  272. cirq/ops/permutation_gate_test.py +1 -1
  273. cirq/ops/phased_iswap_gate.py +6 -7
  274. cirq/ops/phased_iswap_gate_test.py +21 -5
  275. cirq/ops/phased_x_gate.py +11 -25
  276. cirq/ops/phased_x_gate_test.py +19 -3
  277. cirq/ops/phased_x_z_gate.py +12 -11
  278. cirq/ops/projector.py +4 -5
  279. cirq/ops/qubit_manager.py +2 -1
  280. cirq/ops/qubit_manager_test.py +2 -1
  281. cirq/ops/qubit_order.py +1 -1
  282. cirq/ops/random_gate_channel.py +1 -1
  283. cirq/ops/random_gate_channel_test.py +0 -6
  284. cirq/ops/raw_types.py +146 -50
  285. cirq/ops/raw_types_test.py +37 -3
  286. cirq/ops/state_preparation_channel.py +2 -2
  287. cirq/ops/state_preparation_channel_test.py +2 -1
  288. cirq/ops/swap_gates.py +9 -4
  289. cirq/ops/three_qubit_gates.py +8 -8
  290. cirq/ops/three_qubit_gates_test.py +1 -0
  291. cirq/ops/two_qubit_diagonal_gate.py +4 -3
  292. cirq/ops/uniform_superposition_gate.py +4 -4
  293. cirq/ops/uniform_superposition_gate_test.py +1 -0
  294. cirq/ops/wait_gate.py +6 -8
  295. cirq/protocols/__init__.py +135 -83
  296. cirq/protocols/act_on_protocol.py +1 -1
  297. cirq/protocols/act_on_protocol_test.py +1 -1
  298. cirq/protocols/apply_channel_protocol.py +3 -3
  299. cirq/protocols/apply_mixture_protocol.py +15 -9
  300. cirq/protocols/apply_mixture_protocol_test.py +11 -0
  301. cirq/protocols/apply_unitary_protocol.py +2 -2
  302. cirq/protocols/apply_unitary_protocol_test.py +2 -1
  303. cirq/protocols/approximate_equality_protocol.py +7 -8
  304. cirq/protocols/approximate_equality_protocol_test.py +3 -1
  305. cirq/protocols/circuit_diagram_info_protocol.py +8 -6
  306. cirq/protocols/circuit_diagram_info_protocol_test.py +5 -0
  307. cirq/protocols/commutes_protocol.py +6 -6
  308. cirq/protocols/control_key_protocol.py +1 -1
  309. cirq/protocols/decompose_protocol.py +4 -5
  310. cirq/protocols/decompose_protocol_test.py +2 -1
  311. cirq/protocols/equal_up_to_global_phase_protocol.py +3 -3
  312. cirq/protocols/equal_up_to_global_phase_protocol_test.py +7 -0
  313. cirq/protocols/has_stabilizer_effect_protocol.py +5 -5
  314. cirq/protocols/has_unitary_protocol.py +1 -1
  315. cirq/protocols/has_unitary_protocol_test.py +8 -7
  316. cirq/protocols/hash_from_pickle_test.py +120 -0
  317. cirq/protocols/inverse_protocol.py +1 -1
  318. cirq/protocols/json_serialization.py +14 -1
  319. cirq/protocols/json_serialization_test.py +28 -7
  320. cirq/protocols/json_test_data/BitMaskKeyCondition.json +86 -0
  321. cirq/protocols/json_test_data/BitMaskKeyCondition.repr +7 -0
  322. cirq/protocols/json_test_data/Concat.json +19 -0
  323. cirq/protocols/json_test_data/Concat.repr +1 -0
  324. cirq/protocols/json_test_data/README.md +4 -2
  325. cirq/protocols/json_test_data/SympyCondition.json +60 -15
  326. cirq/protocols/json_test_data/SympyCondition.repr +4 -1
  327. cirq/protocols/json_test_data/_InverseCompositeGate.json +10 -0
  328. cirq/protocols/json_test_data/_InverseCompositeGate.repr +1 -0
  329. cirq/protocols/json_test_data/__init__.py +1 -1
  330. cirq/protocols/json_test_data/sympy.And.json +13 -0
  331. cirq/protocols/json_test_data/sympy.And.repr +1 -0
  332. cirq/protocols/json_test_data/sympy.Indexed.json +18 -0
  333. cirq/protocols/json_test_data/sympy.Indexed.repr +1 -0
  334. cirq/protocols/json_test_data/sympy.IndexedBase.json +9 -0
  335. cirq/protocols/json_test_data/sympy.IndexedBase.repr +1 -0
  336. cirq/protocols/json_test_data/sympy.Not.json +9 -0
  337. cirq/protocols/json_test_data/sympy.Not.repr +1 -0
  338. cirq/protocols/json_test_data/sympy.Or.json +13 -0
  339. cirq/protocols/json_test_data/sympy.Or.repr +1 -0
  340. cirq/protocols/json_test_data/sympy.Xor.json +13 -0
  341. cirq/protocols/json_test_data/sympy.Xor.repr +1 -0
  342. cirq/protocols/kraus_protocol.py +8 -8
  343. cirq/protocols/kraus_protocol_test.py +0 -1
  344. cirq/protocols/measurement_key_protocol.py +1 -1
  345. cirq/protocols/measurement_key_protocol_test.py +7 -7
  346. cirq/protocols/mixture_protocol.py +6 -4
  347. cirq/protocols/mixture_protocol_test.py +21 -13
  348. cirq/protocols/pauli_expansion_protocol.py +1 -0
  349. cirq/protocols/pow_protocol.py +1 -1
  350. cirq/protocols/qasm.py +25 -6
  351. cirq/protocols/qasm_test.py +17 -0
  352. cirq/protocols/qid_shape_protocol.py +2 -2
  353. cirq/protocols/resolve_parameters.py +2 -3
  354. cirq/protocols/resolve_parameters_test.py +2 -1
  355. cirq/protocols/trace_distance_bound.py +1 -1
  356. cirq/protocols/trace_distance_bound_test.py +1 -0
  357. cirq/protocols/unitary_protocol.py +3 -3
  358. cirq/protocols/unitary_protocol_test.py +1 -1
  359. cirq/qis/__init__.py +48 -35
  360. cirq/qis/channels_test.py +0 -9
  361. cirq/qis/clifford_tableau.py +46 -26
  362. cirq/qis/clifford_tableau_test.py +2 -1
  363. cirq/qis/entropy.py +115 -0
  364. cirq/qis/entropy_test.py +43 -0
  365. cirq/qis/measures.py +5 -4
  366. cirq/qis/measures_test.py +7 -0
  367. cirq/qis/noise_utils_test.py +4 -4
  368. cirq/qis/quantum_state_representation.py +1 -1
  369. cirq/qis/states.py +7 -7
  370. cirq/sim/__init__.py +55 -37
  371. cirq/sim/classical_simulator.py +7 -6
  372. cirq/sim/classical_simulator_test.py +3 -1
  373. cirq/sim/clifford/__init__.py +17 -9
  374. cirq/sim/clifford/clifford_simulator.py +5 -4
  375. cirq/sim/clifford/clifford_simulator_test.py +32 -9
  376. cirq/sim/clifford/clifford_tableau_simulation_state.py +1 -1
  377. cirq/sim/clifford/stabilizer_simulation_state.py +1 -1
  378. cirq/sim/clifford/stabilizer_state_ch_form.py +4 -3
  379. cirq/sim/density_matrix_simulator.py +3 -2
  380. cirq/sim/density_matrix_simulator_test.py +12 -4
  381. cirq/sim/density_matrix_utils.py +1 -1
  382. cirq/sim/mux.py +2 -2
  383. cirq/sim/simulation_state.py +4 -5
  384. cirq/sim/simulation_state_base.py +2 -2
  385. cirq/sim/simulation_state_test.py +1 -1
  386. cirq/sim/simulation_utils.py +3 -1
  387. cirq/sim/simulation_utils_test.py +2 -3
  388. cirq/sim/simulator.py +7 -6
  389. cirq/sim/simulator_base.py +5 -5
  390. cirq/sim/simulator_test.py +14 -3
  391. cirq/sim/sparse_simulator.py +4 -3
  392. cirq/sim/sparse_simulator_test.py +17 -9
  393. cirq/sim/state_vector.py +2 -2
  394. cirq/sim/state_vector_simulation_state_test.py +1 -1
  395. cirq/sim/state_vector_simulator.py +4 -4
  396. cirq/sim/state_vector_test.py +27 -32
  397. cirq/study/__init__.py +27 -21
  398. cirq/study/flatten_expressions.py +5 -6
  399. cirq/study/flatten_expressions_test.py +1 -1
  400. cirq/study/resolver.py +14 -11
  401. cirq/study/resolver_test.py +10 -1
  402. cirq/study/result.py +3 -3
  403. cirq/study/sweepable.py +15 -9
  404. cirq/study/sweepable_test.py +27 -0
  405. cirq/study/sweeps.py +65 -10
  406. cirq/study/sweeps_test.py +123 -0
  407. cirq/testing/__init__.py +86 -57
  408. cirq/testing/_compat_test_data/module_a/__init__.py +2 -2
  409. cirq/testing/_compat_test_data/module_a/sub/subsub/__init__.py +1 -1
  410. cirq/testing/circuit_compare.py +3 -4
  411. cirq/testing/circuit_compare_test.py +7 -8
  412. cirq/testing/consistent_act_on.py +3 -3
  413. cirq/testing/consistent_channels_test.py +2 -1
  414. cirq/testing/consistent_controlled_gate_op.py +3 -2
  415. cirq/testing/consistent_controlled_gate_op_test.py +2 -3
  416. cirq/testing/consistent_decomposition.py +1 -1
  417. cirq/testing/consistent_decomposition_test.py +1 -2
  418. cirq/testing/consistent_pauli_expansion_test.py +1 -1
  419. cirq/testing/consistent_phase_by.py +1 -1
  420. cirq/testing/consistent_phase_by_test.py +1 -2
  421. cirq/testing/consistent_protocols.py +11 -11
  422. cirq/testing/consistent_protocols_test.py +4 -5
  423. cirq/testing/consistent_qasm.py +8 -12
  424. cirq/testing/consistent_qasm_test.py +1 -1
  425. cirq/testing/consistent_resolve_parameters.py +2 -1
  426. cirq/testing/consistent_specified_has_unitary_test.py +1 -1
  427. cirq/testing/consistent_unitary.py +3 -1
  428. cirq/testing/consistent_unitary_test.py +3 -3
  429. cirq/testing/devices.py +1 -1
  430. cirq/testing/devices_test.py +1 -0
  431. cirq/testing/equals_tester.py +2 -4
  432. cirq/testing/equals_tester_test.py +6 -5
  433. cirq/testing/equivalent_basis_map.py +1 -0
  434. cirq/testing/equivalent_basis_map_test.py +0 -1
  435. cirq/testing/gate_features_test.py +5 -0
  436. cirq/testing/json.py +4 -4
  437. cirq/testing/lin_alg_utils_test.py +1 -1
  438. cirq/testing/order_tester.py +1 -1
  439. cirq/testing/order_tester_test.py +1 -1
  440. cirq/testing/pytest_utils.py +57 -0
  441. cirq/testing/pytest_utils_test.py +35 -0
  442. cirq/testing/random_circuit.py +2 -2
  443. cirq/testing/random_circuit_test.py +2 -2
  444. cirq/testing/routing_devices_test.py +2 -1
  445. cirq/testing/sample_circuits.py +1 -1
  446. cirq/testing/sample_gates.py +5 -4
  447. cirq/testing/sample_gates_test.py +2 -2
  448. cirq/transformers/__init__.py +101 -82
  449. cirq/transformers/align.py +12 -1
  450. cirq/transformers/align_test.py +13 -0
  451. cirq/transformers/analytical_decompositions/__init__.py +27 -24
  452. cirq/transformers/analytical_decompositions/clifford_decomposition.py +2 -1
  453. cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +1 -1
  454. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +1 -1
  455. cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
  456. cirq/transformers/analytical_decompositions/cphase_to_fsim.py +1 -1
  457. cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +1 -1
  458. cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +2 -2
  459. cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +4 -4
  460. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +99 -24
  461. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +105 -14
  462. cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +1 -1
  463. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +1 -1
  464. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +1 -0
  465. cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +3 -4
  466. cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +1 -1
  467. cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +2 -1
  468. cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -1
  469. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +5 -6
  470. cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +2 -2
  471. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +1 -1
  472. cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +1 -2
  473. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +2 -2
  474. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +2 -2
  475. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -1
  476. cirq/transformers/drop_empty_moments.py +1 -0
  477. cirq/transformers/drop_negligible_operations.py +1 -0
  478. cirq/transformers/dynamical_decoupling.py +255 -43
  479. cirq/transformers/dynamical_decoupling_test.py +730 -17
  480. cirq/transformers/eject_phased_paulis.py +29 -15
  481. cirq/transformers/eject_phased_paulis_test.py +3 -8
  482. cirq/transformers/eject_z.py +3 -2
  483. cirq/transformers/eject_z_test.py +3 -3
  484. cirq/transformers/gauge_compiling/__init__.py +25 -9
  485. cirq/transformers/gauge_compiling/cphase_gauge.py +146 -0
  486. cirq/transformers/gauge_compiling/cphase_gauge_test.py +42 -0
  487. cirq/transformers/gauge_compiling/cz_gauge.py +4 -4
  488. cirq/transformers/gauge_compiling/gauge_compiling.py +245 -6
  489. cirq/transformers/gauge_compiling/gauge_compiling_test.py +107 -2
  490. cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +39 -2
  491. cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +10 -1
  492. cirq/transformers/gauge_compiling/iswap_gauge.py +2 -2
  493. cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -2
  494. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +23 -5
  495. cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +3 -2
  496. cirq/transformers/heuristic_decompositions/__init__.py +3 -3
  497. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +2 -1
  498. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +1 -1
  499. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +4 -4
  500. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +4 -4
  501. cirq/transformers/insertion_sort.py +64 -0
  502. cirq/transformers/insertion_sort_test.py +34 -0
  503. cirq/transformers/measurement_transformers.py +14 -1
  504. cirq/transformers/measurement_transformers_test.py +35 -0
  505. cirq/transformers/merge_k_qubit_gates.py +2 -2
  506. cirq/transformers/merge_single_qubit_gates.py +1 -1
  507. cirq/transformers/merge_single_qubit_gates_test.py +1 -1
  508. cirq/transformers/noise_adding.py +115 -0
  509. cirq/transformers/noise_adding_test.py +54 -0
  510. cirq/transformers/optimize_for_target_gateset.py +1 -1
  511. cirq/transformers/optimize_for_target_gateset_test.py +3 -2
  512. cirq/transformers/qubit_management_transformers.py +1 -1
  513. cirq/transformers/randomized_measurements.py +171 -0
  514. cirq/transformers/randomized_measurements_test.py +68 -0
  515. cirq/transformers/routing/__init__.py +14 -5
  516. cirq/transformers/routing/initial_mapper.py +1 -1
  517. cirq/transformers/routing/initial_mapper_test.py +1 -0
  518. cirq/transformers/routing/line_initial_mapper.py +3 -2
  519. cirq/transformers/routing/mapping_manager.py +2 -2
  520. cirq/transformers/routing/mapping_manager_test.py +2 -2
  521. cirq/transformers/routing/route_circuit_cqc.py +3 -2
  522. cirq/transformers/routing/route_circuit_cqc_test.py +2 -1
  523. cirq/transformers/routing/visualize_routed_circuit.py +1 -0
  524. cirq/transformers/routing/visualize_routed_circuit_test.py +1 -0
  525. cirq/transformers/stratify.py +2 -2
  526. cirq/transformers/synchronize_terminal_measurements.py +2 -1
  527. cirq/transformers/target_gatesets/__init__.py +7 -5
  528. cirq/transformers/target_gatesets/compilation_target_gateset.py +16 -3
  529. cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -0
  530. cirq/transformers/target_gatesets/cz_gateset.py +5 -1
  531. cirq/transformers/target_gatesets/cz_gateset_test.py +23 -2
  532. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +1 -1
  533. cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +3 -2
  534. cirq/transformers/transformer_api.py +5 -4
  535. cirq/transformers/transformer_api_test.py +11 -3
  536. cirq/transformers/transformer_primitives.py +9 -31
  537. cirq/transformers/transformer_primitives_test.py +6 -5
  538. cirq/value/__init__.py +51 -30
  539. cirq/value/abc_alt.py +1 -2
  540. cirq/value/angle.py +2 -0
  541. cirq/value/classical_data.py +1 -0
  542. cirq/value/condition.py +149 -3
  543. cirq/value/condition_test.py +254 -0
  544. cirq/value/digits.py +1 -1
  545. cirq/value/duration.py +4 -4
  546. cirq/value/duration_test.py +2 -1
  547. cirq/value/linear_dict.py +85 -24
  548. cirq/value/linear_dict_test.py +94 -3
  549. cirq/value/measurement_key.py +9 -2
  550. cirq/value/periodic_value.py +2 -3
  551. cirq/value/periodic_value_test.py +5 -0
  552. cirq/value/probability.py +1 -0
  553. cirq/value/random_state.py +1 -1
  554. cirq/value/timestamp.py +2 -4
  555. cirq/value/timestamp_test.py +2 -1
  556. cirq/value/type_alias.py +2 -2
  557. cirq/value/value_equality_attr.py +14 -2
  558. cirq/value/value_equality_attr_test.py +1 -1
  559. cirq/vis/__init__.py +9 -6
  560. cirq/vis/density_matrix.py +1 -1
  561. cirq/vis/density_matrix_test.py +2 -5
  562. cirq/vis/heatmap.py +49 -12
  563. cirq/vis/heatmap_test.py +168 -4
  564. cirq/vis/histogram.py +1 -1
  565. cirq/vis/histogram_test.py +1 -2
  566. cirq/vis/state_histogram.py +7 -5
  567. cirq/vis/state_histogram_test.py +2 -2
  568. cirq/work/__init__.py +19 -13
  569. cirq/work/collector.py +2 -2
  570. cirq/work/observable_grouping.py +2 -2
  571. cirq/work/observable_measurement.py +3 -3
  572. cirq/work/observable_measurement_data.py +5 -2
  573. cirq/work/observable_measurement_test.py +8 -8
  574. cirq/work/observable_readout_calibration.py +2 -2
  575. cirq/work/observable_readout_calibration_test.py +2 -1
  576. cirq/work/observable_settings.py +8 -7
  577. cirq/work/observable_settings_test.py +3 -2
  578. cirq/work/pauli_sum_collector.py +1 -1
  579. cirq/work/sampler.py +8 -20
  580. cirq/work/sampler_test.py +4 -3
  581. cirq/work/zeros_sampler.py +1 -1
  582. cirq_core-1.5.0.dist-info/METADATA +125 -0
  583. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/RECORD +586 -552
  584. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/WHEEL +1 -1
  585. cirq/experiments/grid_parallel_two_qubit_xeb.py +0 -62
  586. cirq/protocols/json_test_data/GridParallelXEBMetadata.json +0 -119
  587. cirq/protocols/json_test_data/GridParallelXEBMetadata.repr +0 -1
  588. cirq_core-1.4.0.dev20240529225110.dist-info/METADATA +0 -50
  589. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/LICENSE +0 -0
  590. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/top_level.txt +0 -0
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ import numbers
15
16
  from typing import (
16
17
  AbstractSet,
17
18
  cast,
@@ -24,20 +25,18 @@ from typing import (
24
25
  Union,
25
26
  )
26
27
 
27
- import numbers
28
-
29
28
  import sympy
30
29
 
31
- from cirq import value, protocols
30
+ from cirq import protocols, value
32
31
  from cirq._compat import proper_repr
33
32
  from cirq.ops import (
34
- raw_types,
35
33
  common_gates,
36
- gate_operation,
37
34
  dense_pauli_string as dps,
38
- pauli_string as ps,
39
- pauli_gates,
35
+ gate_operation,
40
36
  op_tree,
37
+ pauli_gates,
38
+ pauli_string as ps,
39
+ raw_types,
41
40
  )
42
41
 
43
42
  if TYPE_CHECKING:
@@ -66,8 +65,8 @@ class PauliStringPhasor(gate_operation.GateOperation):
66
65
  pauli_string: ps.PauliString,
67
66
  qubits: Optional[Sequence['cirq.Qid']] = None,
68
67
  *,
69
- exponent_neg: Union[int, float, sympy.Expr] = 1,
70
- exponent_pos: Union[int, float, sympy.Expr] = 0,
68
+ exponent_neg: 'cirq.TParamVal' = 1,
69
+ exponent_pos: 'cirq.TParamVal' = 0,
71
70
  ) -> None:
72
71
  """Initializes the operation.
73
72
 
@@ -112,12 +111,12 @@ class PauliStringPhasor(gate_operation.GateOperation):
112
111
  return cast(PauliStringPhasorGate, self._gate)
113
112
 
114
113
  @property
115
- def exponent_neg(self) -> Union[int, float, sympy.Expr]:
114
+ def exponent_neg(self) -> 'cirq.TParamVal':
116
115
  """The negative exponent."""
117
116
  return self.gate.exponent_neg
118
117
 
119
118
  @property
120
- def exponent_pos(self) -> Union[int, float, sympy.Expr]:
119
+ def exponent_pos(self) -> 'cirq.TParamVal':
121
120
  """The positive exponent."""
122
121
  return self.gate.exponent_pos
123
122
 
@@ -127,7 +126,7 @@ class PauliStringPhasor(gate_operation.GateOperation):
127
126
  return self._pauli_string
128
127
 
129
128
  @property
130
- def exponent_relative(self) -> Union[int, float, sympy.Expr]:
129
+ def exponent_relative(self) -> 'cirq.TParamVal':
131
130
  """The relative exponent between negative and positive exponents."""
132
131
  return self.gate.exponent_relative
133
132
 
@@ -189,6 +188,8 @@ class PauliStringPhasor(gate_operation.GateOperation):
189
188
  self, args: 'cirq.CircuitDiagramInfoArgs'
190
189
  ) -> 'cirq.CircuitDiagramInfo':
191
190
  qubits = self.qubits if args.known_qubits is None else args.known_qubits
191
+ if not qubits:
192
+ return NotImplemented
192
193
 
193
194
  def sym(qubit):
194
195
  if qubit in self.pauli_string:
@@ -276,8 +277,8 @@ class PauliStringPhasorGate(raw_types.Gate):
276
277
  self,
277
278
  dense_pauli_string: dps.DensePauliString,
278
279
  *,
279
- exponent_neg: Union[int, float, sympy.Expr] = 1,
280
- exponent_pos: Union[int, float, sympy.Expr] = 0,
280
+ exponent_neg: 'cirq.TParamVal' = 1,
281
+ exponent_pos: 'cirq.TParamVal' = 0,
281
282
  ) -> None:
282
283
  """Initializes the PauliStringPhasorGate.
283
284
 
@@ -307,17 +308,17 @@ class PauliStringPhasorGate(raw_types.Gate):
307
308
  self._exponent_pos = value.canonicalize_half_turns(exponent_pos)
308
309
 
309
310
  @property
310
- def exponent_relative(self) -> Union[int, float, sympy.Expr]:
311
+ def exponent_relative(self) -> 'cirq.TParamVal':
311
312
  """The relative exponent between negative and positive exponents."""
312
313
  return value.canonicalize_half_turns(self.exponent_neg - self.exponent_pos)
313
314
 
314
315
  @property
315
- def exponent_neg(self) -> Union[int, float, sympy.Expr]:
316
+ def exponent_neg(self) -> 'cirq.TParamVal':
316
317
  """The negative exponent."""
317
318
  return self._exponent_neg
318
319
 
319
320
  @property
320
- def exponent_pos(self) -> Union[int, float, sympy.Expr]:
321
+ def exponent_pos(self) -> 'cirq.TParamVal':
321
322
  """The positive exponent."""
322
323
  return self._exponent_pos
323
324
 
@@ -351,7 +352,7 @@ class PauliStringPhasorGate(raw_types.Gate):
351
352
  """Returns operations to convert the qubits to the computational basis."""
352
353
  return self.dense_pauli_string.on(*qubits).to_z_basis_ops()
353
354
 
354
- def _decompose_(self, qubits: Sequence['cirq.Qid']) -> 'cirq.OP_TREE':
355
+ def _decompose_(self, qubits: Sequence['cirq.Qid']) -> Iterator['cirq.OP_TREE']:
355
356
  if len(self.dense_pauli_string) <= 0:
356
357
  return
357
358
  any_qubit = qubits[0]
@@ -390,14 +391,14 @@ class PauliStringPhasorGate(raw_types.Gate):
390
391
  ) -> 'PauliStringPhasorGate':
391
392
  exponent_neg = resolver.value_of(self.exponent_neg, recursive)
392
393
  exponent_pos = resolver.value_of(self.exponent_pos, recursive)
393
- if isinstance(exponent_neg, (complex, numbers.Complex)):
394
+ if isinstance(exponent_neg, numbers.Complex):
394
395
  if isinstance(exponent_neg, numbers.Real):
395
396
  exponent_neg = float(exponent_neg)
396
397
  else:
397
398
  raise ValueError(
398
399
  f'PauliStringPhasorGate does not support complex exponent {exponent_neg}'
399
400
  )
400
- if isinstance(exponent_pos, (complex, numbers.Complex)):
401
+ if isinstance(exponent_pos, numbers.Complex):
401
402
  if isinstance(exponent_pos, numbers.Real):
402
403
  exponent_pos = float(exponent_pos)
403
404
  else:
@@ -13,8 +13,9 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import itertools
16
- import pytest
16
+
17
17
  import numpy as np
18
+ import pytest
18
19
  import sympy
19
20
 
20
21
  import cirq
@@ -163,8 +164,10 @@ def test_pass_operations_over():
163
164
  ps_after = cirq.PauliString({q0: cirq.Z, q1: cirq.Y}, -1)
164
165
  before = cirq.PauliStringPhasor(ps_before, exponent_neg=0.1)
165
166
  after = cirq.PauliStringPhasor(ps_after, exponent_neg=0.1)
166
- assert before.pass_operations_over([op]) == after
167
- assert after.pass_operations_over([op], after_to_before=True) == before
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
+ )
168
171
 
169
172
 
170
173
  def test_extrapolate_effect():
@@ -422,6 +425,13 @@ q2: ────────────────────[Z]───[X]^
422
425
  )
423
426
 
424
427
 
428
+ def test_empty_phasor_diagram():
429
+ q = cirq.LineQubit(0)
430
+ op = cirq.PauliSumExponential(cirq.I(q))
431
+ circuit = cirq.Circuit(op)
432
+ cirq.testing.assert_has_diagram(circuit, ' (I)**-0.6366197723675815')
433
+
434
+
425
435
  def test_repr():
426
436
  q0, q1, q2 = _make_qubits(3)
427
437
  cirq.testing.assert_equivalent_repr(
@@ -14,6 +14,7 @@
14
14
 
15
15
  import abc
16
16
  from typing import Any, Dict, Sequence, Tuple, TYPE_CHECKING
17
+
17
18
  from typing_extensions import Self
18
19
 
19
20
  from cirq import protocols
@@ -57,6 +57,56 @@ def _small_sample_qubit_pauli_maps():
57
57
  yield {qubits[0]: cirq.Z, qubits[1]: cirq.X, qubits[2]: cirq.Y}
58
58
 
59
59
 
60
+ def assert_conjugation(
61
+ input_ps: cirq.PauliString,
62
+ op: cirq.Operation,
63
+ expected: cirq.PauliString | None = None,
64
+ force_checking_unitary=True,
65
+ ):
66
+ """Verifies that conjugating `input_ps` by `op` results in `expected`.
67
+
68
+ Also ensures that the unitary representation of the Pauli string is
69
+ preserved under the conjugation.
70
+ """
71
+
72
+ def _ps_on_qubits(ps: cirq.PauliString, qubits: tuple[cirq.Qid, ...]):
73
+ """Extracts a sub-PauliString from a given PauliString, restricted to
74
+ a specified subset of qubits.
75
+ """
76
+ pauli_map = {}
77
+ for q, pauli in ps.items():
78
+ if q in qubits:
79
+ pauli_map[q] = pauli
80
+ return cirq.PauliString(qubit_pauli_map=pauli_map, coefficient=ps.coefficient)
81
+
82
+ conjugation = input_ps.conjugated_by(op)
83
+ if expected is None or force_checking_unitary:
84
+ # Compares the unitary of the conjugation result and the expected unitary.
85
+ clifford = cirq.CliffordGate.from_op_list([op], op.qubits)
86
+ actual_unitary = cirq.unitary(_ps_on_qubits(conjugation, op.qubits).dense(op.qubits))
87
+ c = cirq.unitary(clifford)
88
+ expected_unitary = (
89
+ np.conj(c.T) @ cirq.unitary(_ps_on_qubits(input_ps, op.qubits).dense(op.qubits)) @ c
90
+ )
91
+ assert np.allclose(actual_unitary, expected_unitary, atol=1e-8)
92
+ if expected is not None:
93
+ assert conjugation == expected
94
+
95
+
96
+ def assert_conjugation_multi_ops(
97
+ input_ps: cirq.PauliString, ops: list[cirq.Operation], expected: cirq.PauliString | None = None
98
+ ):
99
+ conjugation = input_ps.conjugated_by(ops)
100
+ if expected is not None:
101
+ assert conjugation == expected
102
+ # conj_by(op_{n-1}).conj_by(op_{n-1}).....conj_by(op_0)
103
+ conj_in_order = input_ps
104
+ for op in ops[::-1]:
105
+ assert_conjugation(conj_in_order, op)
106
+ conj_in_order = conj_in_order.conjugated_by(op)
107
+ assert conjugation == conj_in_order
108
+
109
+
60
110
  def test_eq_ne_hash():
61
111
  q0, q1, q2 = _make_qubits(3)
62
112
  eq = cirq.testing.EqualsTester()
@@ -211,6 +261,29 @@ def test_list_op_constructor_matches_mapping(pauli):
211
261
  assert cirq.PauliString([op]) == cirq.PauliString({q0: pauli})
212
262
 
213
263
 
264
+ @pytest.mark.parametrize('pauli1', (cirq.X, cirq.Y, cirq.Z))
265
+ @pytest.mark.parametrize('pauli2', (cirq.X, cirq.Y, cirq.Z))
266
+ def test_exponent_mul_consistency(pauli1, pauli2):
267
+ a, b = cirq.LineQubit.range(2)
268
+ op_a, op_b = pauli1(a), pauli2(b)
269
+
270
+ assert op_a * op_a * op_a == op_a
271
+ assert op_a * op_a**2 == op_a
272
+ assert op_a**2 * op_a == op_a
273
+ assert op_b * op_a * op_a == op_b
274
+ assert op_b * op_a**2 == op_b
275
+ assert op_a**2 * op_b == op_b
276
+ assert op_a * op_a * op_a * op_a == cirq.PauliString()
277
+ assert op_a * op_a**3 == cirq.PauliString()
278
+ assert op_b * op_a * op_a * op_a == op_b * op_a
279
+ assert op_b * op_a**3 == op_b * op_a
280
+
281
+ op_a, op_b = pauli1(a), pauli2(a)
282
+
283
+ assert op_a * op_b**3 == op_a * op_b * op_b * op_b
284
+ assert op_b**3 * op_a == op_b * op_b * op_b * op_a
285
+
286
+
214
287
  def test_constructor_flexibility():
215
288
  a, b = cirq.LineQubit.range(2)
216
289
  with pytest.raises(TypeError, match='cirq.PAULI_STRING_LIKE'):
@@ -574,6 +647,8 @@ def test_numpy_ufunc():
574
647
  _ = np.exp(cirq.PauliString())
575
648
  x = np.exp(1j * np.pi * cirq.PauliString())
576
649
  assert x is not None
650
+ x = np.int64(2) * cirq.PauliString()
651
+ assert x == 2 * cirq.PauliString()
577
652
 
578
653
 
579
654
  def test_map_qubits():
@@ -700,26 +775,31 @@ def test_pass_operations_over_double(shift: int, t_or_f1: bool, t_or_f2: bool, n
700
775
  op0 = cirq.PauliInteractionGate(Z, t_or_f1, X, t_or_f2)(q0, q1)
701
776
  ps_before = cirq.PauliString(qubit_pauli_map={q0: Z, q2: Y}, coefficient=sign)
702
777
  ps_after = cirq.PauliString(qubit_pauli_map={q0: Z, q2: Y}, coefficient=sign)
778
+ assert_conjugation(ps_before, op0, ps_after, True)
703
779
  _assert_pass_over([op0], ps_before, ps_after)
704
780
 
705
781
  op0 = cirq.PauliInteractionGate(Y, t_or_f1, X, t_or_f2)(q0, q1)
706
782
  ps_before = cirq.PauliString({q0: Z, q2: Y}, sign)
707
- ps_after = cirq.PauliString({q0: Z, q2: Y, q1: X}, 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)
708
785
  _assert_pass_over([op0], ps_before, ps_after)
709
786
 
710
787
  op0 = cirq.PauliInteractionGate(Z, t_or_f1, X, t_or_f2)(q0, q1)
711
788
  ps_before = cirq.PauliString({q0: Z, q1: Y}, sign)
712
- ps_after = cirq.PauliString({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)
713
791
  _assert_pass_over([op0], ps_before, ps_after)
714
792
 
715
793
  op0 = cirq.PauliInteractionGate(Y, t_or_f1, X, t_or_f2)(q0, q1)
716
794
  ps_before = cirq.PauliString({q0: Z, q1: Y}, sign)
717
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)
718
797
  _assert_pass_over([op0], ps_before, ps_after)
719
798
 
720
799
  op0 = cirq.PauliInteractionGate(X, t_or_f1, X, t_or_f2)(q0, q1)
721
800
  ps_before = cirq.PauliString({q0: Z, q1: Y}, sign)
722
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)
723
803
  _assert_pass_over([op0], ps_before, ps_after)
724
804
 
725
805
 
@@ -733,7 +813,9 @@ def test_pass_operations_over_cz():
733
813
 
734
814
  def test_pass_operations_over_no_common_qubits():
735
815
  class ExampleGate(cirq.testing.SingleQubitGate):
736
- pass
816
+
817
+ def _decompose_(self, qubits):
818
+ return cirq.X(qubits[0])
737
819
 
738
820
  q0, q1 = _make_qubits(2)
739
821
  op0 = ExampleGate()(q1)
@@ -745,7 +827,11 @@ def test_pass_operations_over_no_common_qubits():
745
827
  def test_pass_unsupported_operations_over():
746
828
  (q0,) = _make_qubits(1)
747
829
  pauli_string = cirq.PauliString({q0: cirq.X})
748
- with pytest.raises(TypeError, match='not a known Clifford'):
830
+ with pytest.raises(
831
+ ValueError,
832
+ match='Clifford Gate can only be constructed from the operations'
833
+ ' that has stabilizer effect.',
834
+ ):
749
835
  pauli_string.pass_operations_over([cirq.T(q0)])
750
836
 
751
837
 
@@ -1356,13 +1442,24 @@ def test_pauli_string_expectation_from_state_vector_mixed_state_linearity():
1356
1442
  def test_conjugated_by_normal_gates():
1357
1443
  a = cirq.LineQubit(0)
1358
1444
 
1359
- assert cirq.X(a).conjugated_by(cirq.H(a)) == cirq.Z(a)
1360
- assert cirq.Y(a).conjugated_by(cirq.H(a)) == -cirq.Y(a)
1361
- assert cirq.Z(a).conjugated_by(cirq.H(a)) == cirq.X(a)
1445
+ assert_conjugation(cirq.X(a), cirq.H(a), cirq.Z(a))
1446
+ assert_conjugation(cirq.Y(a), cirq.H(a), -cirq.Y(a))
1447
+ assert_conjugation(cirq.Z(a), cirq.H(a), cirq.X(a))
1448
+
1449
+ assert_conjugation(cirq.X(a), cirq.S(a), -cirq.Y(a))
1450
+ assert_conjugation(cirq.Y(a), cirq.S(a), cirq.X(a))
1451
+ assert_conjugation(cirq.Z(a), cirq.S(a), cirq.Z(a))
1452
+
1453
+ clifford_op = cirq.PhasedXZGate(axis_phase_exponent=0.25, x_exponent=-1, z_exponent=0).on(a)
1454
+ assert_conjugation(cirq.X(a), clifford_op, cirq.Y(a))
1455
+ assert_conjugation(cirq.Y(a), clifford_op, cirq.X(a))
1456
+ assert_conjugation(cirq.Z(a), clifford_op, -cirq.Z(a))
1457
+
1362
1458
 
1363
- assert cirq.X(a).conjugated_by(cirq.S(a)) == -cirq.Y(a)
1364
- assert cirq.Y(a).conjugated_by(cirq.S(a)) == cirq.X(a)
1365
- assert cirq.Z(a).conjugated_by(cirq.S(a)) == cirq.Z(a)
1459
+ def test_conjugated_by_op_gate_of_clifford_gate_type():
1460
+ a = cirq.LineQubit(0)
1461
+
1462
+ assert_conjugation(cirq.X(a), cirq.CliffordGate.from_op_list([cirq.H(a)], [a]).on(a), cirq.Z(a))
1366
1463
 
1367
1464
 
1368
1465
  def test_dense():
@@ -1405,16 +1502,25 @@ def test_conjugated_by_incorrectly_powered_cliffords():
1405
1502
  cirq.ZZ(a, b),
1406
1503
  ]
1407
1504
  for c in cliffords:
1408
- with pytest.raises(TypeError, match='not a known Clifford'):
1505
+ with pytest.raises(
1506
+ ValueError,
1507
+ match='Clifford Gate can only be constructed from the operations'
1508
+ ' that has stabilizer effect.',
1509
+ ):
1409
1510
  _ = p.conjugated_by(c**0.1)
1410
- with pytest.raises(TypeError, match='not a known Clifford'):
1511
+ with pytest.raises(
1512
+ ValueError,
1513
+ match='Clifford Gate can only be constructed from the operations'
1514
+ ' that has stabilizer effect.',
1515
+ ):
1411
1516
  _ = p.conjugated_by(c ** sympy.Symbol('t'))
1412
1517
 
1413
1518
 
1414
1519
  def test_conjugated_by_global_phase():
1520
+ """Global phase gate preserves PauliString."""
1415
1521
  a = cirq.LineQubit(0)
1416
- assert cirq.X(a).conjugated_by(cirq.global_phase_operation(1j)) == cirq.X(a)
1417
- assert cirq.Z(a).conjugated_by(cirq.global_phase_operation(np.exp(1.1j))) == cirq.Z(a)
1522
+ assert_conjugation(cirq.X(a), cirq.global_phase_operation(1j), cirq.X(a))
1523
+ assert_conjugation(cirq.X(a), cirq.global_phase_operation(np.exp(1.1j)), cirq.X(a))
1418
1524
 
1419
1525
  class DecomposeGlobal(cirq.Gate):
1420
1526
  def num_qubits(self):
@@ -1423,7 +1529,7 @@ def test_conjugated_by_global_phase():
1423
1529
  def _decompose_(self, qubits):
1424
1530
  yield cirq.global_phase_operation(1j)
1425
1531
 
1426
- assert cirq.X(a).conjugated_by(DecomposeGlobal().on(a)) == cirq.X(a)
1532
+ assert_conjugation(cirq.X(a), DecomposeGlobal().on(a), cirq.X(a))
1427
1533
 
1428
1534
 
1429
1535
  def test_conjugated_by_composite_with_disjoint_sub_gates():
@@ -1436,8 +1542,10 @@ def test_conjugated_by_composite_with_disjoint_sub_gates():
1436
1542
  def _decompose_(self, qubits):
1437
1543
  yield cirq.H(qubits[1])
1438
1544
 
1439
- assert cirq.X(a).conjugated_by(DecomposeDisjoint().on(a, b)) == cirq.X(a)
1440
- assert cirq.X(a).pass_operations_over([DecomposeDisjoint().on(a, b)]) == cirq.X(a)
1545
+ for g1 in [cirq.X, cirq.Y]:
1546
+ for g2 in [cirq.X, cirq.Y]:
1547
+ ps = g1(a) * g2(b)
1548
+ assert ps.conjugated_by(DecomposeDisjoint().on(a, b)) == ps.conjugated_by(cirq.H(b))
1441
1549
 
1442
1550
 
1443
1551
  def test_conjugated_by_clifford_composite():
@@ -1452,16 +1560,16 @@ def test_conjugated_by_clifford_composite():
1452
1560
  yield cirq.SWAP(qubits[2], qubits[3])
1453
1561
 
1454
1562
  a, b, c, d = cirq.LineQubit.range(4)
1455
- p = cirq.X(a) * cirq.Z(b)
1563
+ ps = cirq.X(a) * cirq.Z(b)
1456
1564
  u = UnknownGate()
1457
- assert p.conjugated_by(u(a, b, c, d)) == cirq.Z(a) * cirq.X(b)
1565
+ assert_conjugation(ps, u(a, b, c, d), cirq.Z(a) * cirq.X(b))
1458
1566
 
1459
1567
 
1460
1568
  def test_conjugated_by_move_into_uninvolved():
1461
1569
  a, b, c, d = cirq.LineQubit.range(4)
1462
- p = cirq.X(a) * cirq.Z(b)
1463
- assert p.conjugated_by([cirq.SWAP(c, d), cirq.SWAP(b, c)]) == cirq.X(a) * cirq.Z(d)
1464
- assert p.conjugated_by([cirq.SWAP(b, c), cirq.SWAP(c, d)]) == cirq.X(a) * cirq.Z(c)
1570
+ ps = cirq.X(a) * cirq.Z(b)
1571
+ assert_conjugation_multi_ops(ps, [cirq.SWAP(c, d), cirq.SWAP(b, c)], cirq.X(a) * cirq.Z(d))
1572
+ assert_conjugation_multi_ops(ps, [cirq.SWAP(b, c), cirq.SWAP(c, d)], cirq.X(a) * cirq.Z(c))
1465
1573
 
1466
1574
 
1467
1575
  def test_conjugated_by_common_single_qubit_gates():
@@ -1483,21 +1591,13 @@ def test_conjugated_by_common_single_qubit_gates():
1483
1591
  single_qubit_gates = [g**i for i in range(4) for g in base_single_qubit_gates]
1484
1592
  for p in [cirq.X, cirq.Y, cirq.Z]:
1485
1593
  for g in single_qubit_gates:
1486
- assert p.on(a).conjugated_by(g.on(b)) == p.on(a)
1487
-
1488
- actual = cirq.unitary(p.on(a).conjugated_by(g.on(a)))
1489
- u = cirq.unitary(g)
1490
- expected = np.conj(u.T) @ cirq.unitary(p) @ u
1491
- assert cirq.allclose_up_to_global_phase(actual, expected, atol=1e-8)
1594
+ # pauli gate on a, clifford on b: pauli gate preserves.
1595
+ assert_conjugation(p(a), g(b), p(a))
1596
+ # pauli gate on a, clifford on a: check conjugation in matrices.
1597
+ assert_conjugation(p(a), g(a))
1492
1598
 
1493
1599
 
1494
1600
  def test_conjugated_by_common_two_qubit_gates():
1495
- class OrderSensitiveGate(cirq.Gate):
1496
- def num_qubits(self):
1497
- return 2
1498
-
1499
- def _decompose_(self, qubits):
1500
- return [cirq.Y(qubits[0]) ** -0.5, cirq.CNOT(*qubits)]
1501
1601
 
1502
1602
  a, b, c, d = cirq.LineQubit.range(4)
1503
1603
  two_qubit_gates = [
@@ -1516,34 +1616,25 @@ def test_conjugated_by_common_two_qubit_gates():
1516
1616
  cirq.YY**-0.5,
1517
1617
  cirq.ZZ**-0.5,
1518
1618
  ]
1519
- two_qubit_gates.extend([OrderSensitiveGate()])
1520
1619
  for p1 in [cirq.I, cirq.X, cirq.Y, cirq.Z]:
1521
1620
  for p2 in [cirq.I, cirq.X, cirq.Y, cirq.Z]:
1522
1621
  pd = cirq.DensePauliString([p1, p2])
1523
- p = pd.sparse()
1622
+ p = pd.sparse([a, b])
1524
1623
  for g in two_qubit_gates:
1525
- assert p.conjugated_by(g.on(c, d)) == p
1526
-
1527
- actual = cirq.unitary(p.conjugated_by(g.on(a, b)).dense([a, b]))
1528
- u = cirq.unitary(g)
1529
- expected = np.conj(u.T) @ cirq.unitary(pd) @ u
1530
- np.testing.assert_allclose(actual, expected, atol=1e-8)
1624
+ # pauli_string on (a,b), clifford on (c,d): pauli_string preserves.
1625
+ assert_conjugation(p, g(c, d), p)
1626
+ # pauli_string on (a,b), clifford on (a,b): compare unitaries of
1627
+ # the conjugated_by and actual matrix conjugation.
1628
+ assert_conjugation(p, g.on(a, b))
1531
1629
 
1532
1630
 
1533
1631
  def test_conjugated_by_ordering():
1534
- class OrderSensitiveGate(cirq.Gate):
1535
- def num_qubits(self):
1536
- return 2
1537
-
1538
- def _decompose_(self, qubits):
1539
- return [cirq.Y(qubits[0]) ** -0.5, cirq.CNOT(*qubits)]
1540
-
1632
+ """Tests .conjugated_by([op1, op2]) == .conjugated_by(op2).conjugated_by(op1)"""
1541
1633
  a, b = cirq.LineQubit.range(2)
1542
1634
  inp = cirq.Z(b)
1543
- out1 = inp.conjugated_by(OrderSensitiveGate().on(a, b))
1544
- out2 = inp.conjugated_by([cirq.H(a), cirq.CNOT(a, b)])
1545
- out3 = inp.conjugated_by(cirq.CNOT(a, b)).conjugated_by(cirq.H(a))
1546
- assert out1 == out2 == out3 == cirq.X(a) * cirq.Z(b)
1635
+ out1 = inp.conjugated_by([cirq.H(a), cirq.CNOT(a, b)])
1636
+ out2 = inp.conjugated_by(cirq.CNOT(a, b)).conjugated_by(cirq.H(a))
1637
+ assert out1 == out2 == cirq.X(a) * cirq.Z(b)
1547
1638
 
1548
1639
 
1549
1640
  def test_pass_operations_over_ordering():
@@ -1556,7 +1647,7 @@ def test_pass_operations_over_ordering():
1556
1647
 
1557
1648
  a, b = cirq.LineQubit.range(2)
1558
1649
  inp = cirq.Z(b)
1559
- out1 = inp.pass_operations_over([OrderSensitiveGate().on(a, b)])
1650
+ out1 = inp.pass_operations_over(OrderSensitiveGate().on(a, b))
1560
1651
  out2 = inp.pass_operations_over([cirq.CNOT(a, b), cirq.Y(a) ** -0.5])
1561
1652
  out3 = inp.pass_operations_over([cirq.CNOT(a, b)]).pass_operations_over([cirq.Y(a) ** -0.5])
1562
1653
  assert out1 == out2 == out3 == cirq.X(a) * cirq.Z(b)
@@ -1572,7 +1663,7 @@ def test_pass_operations_over_ordering_reversed():
1572
1663
 
1573
1664
  a, b = cirq.LineQubit.range(2)
1574
1665
  inp = cirq.X(a) * cirq.Z(b)
1575
- out1 = inp.pass_operations_over([OrderSensitiveGate().on(a, b)], after_to_before=True)
1666
+ out1 = inp.pass_operations_over(OrderSensitiveGate().on(a, b), after_to_before=True)
1576
1667
  out2 = inp.pass_operations_over([cirq.Y(a) ** -0.5, cirq.CNOT(a, b)], after_to_before=True)
1577
1668
  out3 = inp.pass_operations_over([cirq.Y(a) ** -0.5], after_to_before=True).pass_operations_over(
1578
1669
  [cirq.CNOT(a, b)], after_to_before=True
@@ -1798,6 +1889,48 @@ def test_mutable_pauli_string_inplace_conjugate_by():
1798
1889
  p2 = p.inplace_after(cirq.S(a))
1799
1890
  assert p2 is p and p == cirq.X(a)
1800
1891
 
1892
+ # After sqrt-X and back.
1893
+ p2 = p.inplace_before(cirq.X(a) ** 0.5)
1894
+ assert p2 is p and p == cirq.X(a)
1895
+ p2 = p.inplace_after(cirq.X(a) ** 0.5)
1896
+ assert p2 is p and p == cirq.X(a)
1897
+
1898
+ # After sqrt-Y and back.
1899
+ p2 = p.inplace_before(cirq.Y(a) ** 0.5)
1900
+ assert p2 is p and p == cirq.Z(a)
1901
+ p2 = p.inplace_after(cirq.Y(a) ** 0.5)
1902
+ assert p2 is p and p == cirq.X(a)
1903
+
1904
+ # After inv-sqrt-Y and back.
1905
+ p2 = p.inplace_before(cirq.Y(a) ** 1.5)
1906
+ assert p2 is p and p == -cirq.Z(a)
1907
+ p2 = p.inplace_after(cirq.Y(a) ** 1.5)
1908
+ assert p2 is p and p == cirq.X(a)
1909
+
1910
+ # After X**0 and back.
1911
+ p2 = p.inplace_before(cirq.X(a) ** 0)
1912
+ assert p2 is p and p == cirq.X(a)
1913
+ p2 = p.inplace_after(cirq.X(a) ** 0)
1914
+ assert p2 is p and p == cirq.X(a)
1915
+
1916
+ # After Y**0 and back.
1917
+ p2 = p.inplace_before(cirq.Y(a) ** 0)
1918
+ assert p2 is p and p == cirq.X(a)
1919
+ p2 = p.inplace_after(cirq.Y(a) ** 0)
1920
+ assert p2 is p and p == cirq.X(a)
1921
+
1922
+ # After Z**0 and back.
1923
+ p2 = p.inplace_before(cirq.Z(a) ** 0)
1924
+ assert p2 is p and p == cirq.X(a)
1925
+ p2 = p.inplace_after(cirq.Z(a) ** 0)
1926
+ assert p2 is p and p == cirq.X(a)
1927
+
1928
+ # After H**0 and back.
1929
+ p2 = p.inplace_before(cirq.H(a) ** 0)
1930
+ assert p2 is p and p == cirq.X(a)
1931
+ p2 = p.inplace_after(cirq.H(a) ** 0)
1932
+ assert p2 is p and p == cirq.X(a)
1933
+
1801
1934
  # After inverse S and back.
1802
1935
  p2 = p.inplace_after(cirq.S(a) ** -1)
1803
1936
  assert p2 is p and p == -cirq.Y(a)
@@ -1809,6 +1942,10 @@ def test_mutable_pauli_string_inplace_conjugate_by():
1809
1942
  assert p2 is p and p == cirq.X(a)
1810
1943
 
1811
1944
  # Two qubit operation.
1945
+ p2 = p.inplace_after(cirq.CX(a, b) ** 0)
1946
+ assert p2 is p and p == cirq.X(a)
1947
+ p2 = p.inplace_after(cirq.CZ(a, b) ** 0)
1948
+ assert p2 is p and p == cirq.X(a)
1812
1949
  p2 = p.inplace_after(cirq.CZ(a, b))
1813
1950
  assert p2 is p and p == cirq.X(a) * cirq.Z(b)
1814
1951
  p2 = p.inplace_after(cirq.CZ(a, c))
@@ -11,12 +11,11 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- from typing import Any, Iterator, Tuple, Union, TYPE_CHECKING
14
+ from typing import Any, Iterator, Tuple, TYPE_CHECKING
15
15
 
16
16
  import numpy as np
17
- import sympy
18
17
 
19
- from cirq import linalg, protocols, value, _compat
18
+ from cirq import _compat, linalg, protocols, value
20
19
  from cirq.ops import linear_combinations, pauli_string_phasor
21
20
 
22
21
  if TYPE_CHECKING:
@@ -45,7 +44,7 @@ class PauliSumExponential:
45
44
  def __init__(
46
45
  self,
47
46
  pauli_sum_like: 'cirq.PauliSumLike',
48
- exponent: Union[int, float, sympy.Expr] = 1,
47
+ exponent: 'cirq.TParamVal' = 1,
49
48
  atol: float = 1e-8,
50
49
  ):
51
50
  pauli_sum = linear_combinations.PauliSum.wrap(pauli_sum_like)
@@ -14,7 +14,6 @@
14
14
 
15
15
  import numpy as np
16
16
  import pytest
17
-
18
17
  import sympy
19
18
 
20
19
  import cirq
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import Any, Dict, Sequence, Tuple, TYPE_CHECKING
15
+ from typing import Any, Dict, Iterator, Sequence, Tuple, TYPE_CHECKING
16
16
 
17
17
  from cirq import protocols, value
18
18
  from cirq.ops import raw_types, swap_gates
@@ -73,7 +73,7 @@ class QubitPermutationGate(raw_types.Gate):
73
73
  def _has_unitary_(self):
74
74
  return True
75
75
 
76
- def _decompose_(self, qubits: Sequence['cirq.Qid']) -> 'cirq.OP_TREE':
76
+ def _decompose_(self, qubits: Sequence['cirq.Qid']) -> Iterator['cirq.OP_TREE']:
77
77
  permutation = [p for p in self.permutation]
78
78
 
79
79
  for i in range(len(permutation)):
@@ -12,10 +12,10 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ import numpy as np
15
16
  import pytest
16
17
 
17
18
  import cirq
18
- import numpy as np
19
19
  from cirq.ops import QubitPermutationGate
20
20
 
21
21