cirq-core 1.4.1__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 +1 -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.1.dist-info → cirq_core-1.5.0.dist-info}/RECORD +586 -552
  584. {cirq_core-1.4.1.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.1.dist-info/METADATA +0 -45
  589. {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/LICENSE +0 -0
  590. {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/top_level.txt +0 -0
cirq/ops/raw_types.py CHANGED
@@ -16,11 +16,12 @@
16
16
 
17
17
  import abc
18
18
  import functools
19
+ from types import NotImplementedType
19
20
  from typing import (
20
- cast,
21
21
  AbstractSet,
22
22
  Any,
23
23
  Callable,
24
+ cast,
24
25
  Collection,
25
26
  Dict,
26
27
  FrozenSet,
@@ -34,15 +35,14 @@ from typing import (
34
35
  TYPE_CHECKING,
35
36
  Union,
36
37
  )
37
- from typing_extensions import Self
38
38
 
39
39
  import numpy as np
40
40
  import sympy
41
+ from typing_extensions import Self
41
42
 
42
43
  from cirq import protocols, value
44
+ from cirq._compat import __cirq_debug__, _method_cache_name, cached_method
43
45
  from cirq._import import LazyLoader
44
- from cirq._compat import __cirq_debug__, cached_method
45
- from cirq.type_workarounds import NotImplementedType
46
46
  from cirq.ops import control_values as cv
47
47
 
48
48
  # Lazy imports to break circular dependencies.
@@ -115,6 +115,15 @@ class Qid(metaclass=abc.ABCMeta):
115
115
  def __hash__(self) -> int:
116
116
  return hash((Qid, self._comparison_key()))
117
117
 
118
+ def __getstate__(self) -> Dict[str, Any]:
119
+ # clear cached hash value when pickling, see #6674
120
+ state = self.__dict__
121
+ hash_attr = _method_cache_name(self.__hash__)
122
+ if hash_attr in state:
123
+ state = state.copy()
124
+ del state[hash_attr]
125
+ return state
126
+
118
127
  def __eq__(self, other):
119
128
  if not isinstance(other, Qid):
120
129
  return NotImplemented
@@ -297,7 +306,7 @@ class Gate(metaclass=value.ABCMetaImplementAnyOneOf):
297
306
  return operations
298
307
 
299
308
  def wrap_in_linear_combination(
300
- self, coefficient: Union[complex, float, int] = 1
309
+ self, coefficient: 'cirq.TParamValComplex' = 1
301
310
  ) -> 'cirq.LinearCombinationOfGates':
302
311
  """Returns a LinearCombinationOfGates with this gate.
303
312
 
@@ -328,13 +337,13 @@ class Gate(metaclass=value.ABCMetaImplementAnyOneOf):
328
337
  def __neg__(self) -> 'cirq.LinearCombinationOfGates':
329
338
  return self.wrap_in_linear_combination(coefficient=-1)
330
339
 
331
- def __mul__(self, other: Union[complex, float, int]) -> 'cirq.LinearCombinationOfGates':
340
+ def __mul__(self, other: complex) -> 'cirq.LinearCombinationOfGates':
332
341
  return self.wrap_in_linear_combination(coefficient=other)
333
342
 
334
- def __rmul__(self, other: Union[complex, float, int]) -> 'cirq.LinearCombinationOfGates':
343
+ def __rmul__(self, other: complex) -> 'cirq.LinearCombinationOfGates':
335
344
  return self.wrap_in_linear_combination(coefficient=other)
336
345
 
337
- def __truediv__(self, other: Union[complex, float, int]) -> 'cirq.LinearCombinationOfGates':
346
+ def __truediv__(self, other: complex) -> 'cirq.LinearCombinationOfGates':
338
347
  return self.wrap_in_linear_combination(coefficient=1 / other)
339
348
 
340
349
  def __pow__(self, power):
@@ -455,6 +464,18 @@ class Gate(metaclass=value.ABCMetaImplementAnyOneOf):
455
464
  """
456
465
  raise NotImplementedError
457
466
 
467
+ def _equal_up_to_global_phase_(
468
+ self, other: Any, atol: float = 1e-8
469
+ ) -> Union[NotImplementedType, bool]:
470
+ """Default fallback for gates that do not implement this protocol."""
471
+ try:
472
+ return protocols.equal_up_to_global_phase(
473
+ protocols.unitary(self), protocols.unitary(other), atol=atol
474
+ )
475
+ except TypeError:
476
+ # Gate has no unitary protocol
477
+ return NotImplemented
478
+
458
479
  def _commutes_on_qids_(
459
480
  self, qids: 'Sequence[cirq.Qid]', other: Any, *, atol: float = 1e-8
460
481
  ) -> Union[bool, NotImplementedType, None]:
@@ -545,6 +566,9 @@ class Operation(metaclass=abc.ABCMeta):
545
566
  resulting operation to be eventually serialized into JSON, you should
546
567
  also restrict the operation to be JSON serializable.
547
568
 
569
+ Please note that tags should be instantiated if classes are
570
+ used. Raw types are not allowed.
571
+
548
572
  Args:
549
573
  *new_tags: The tags to wrap this operation in.
550
574
  """
@@ -557,6 +581,26 @@ class Operation(metaclass=abc.ABCMeta):
557
581
  ) -> Self:
558
582
  """Returns the same operation, but with different qubits.
559
583
 
584
+ This function will return a new operation with the same gate but
585
+ with qubits mapped according to the argument.
586
+
587
+ For example, the following will translate LineQubits to GridQubits
588
+ using a grid with 4 columns:
589
+
590
+ >>> op = cirq.CZ(cirq.LineQubit(5), cirq.LineQubit(9))
591
+ >>> op.transform_qubits(lambda q: cirq.GridQubit(q.x // 4, q.x % 4))
592
+ cirq.CZ(cirq.GridQubit(1, 1), cirq.GridQubit(2, 1))
593
+
594
+ This can also be used with a dictionary that has a mapping, such
595
+ as the following which maps named qubits to line qubits:
596
+
597
+ >>> a = cirq.NamedQubit('alice')
598
+ >>> b = cirq.NamedQubit('bob')
599
+ >>> d = {a: cirq.LineQubit(4), b: cirq.LineQubit(5)}
600
+ >>> op = cirq.CNOT(a, b)
601
+ >>> op.transform_qubits(d)
602
+ cirq.CNOT(cirq.LineQubit(4), cirq.LineQubit(5))
603
+
560
604
  Args:
561
605
  qubit_map: A function or a dict mapping each current qubit into a desired
562
606
  new qubit.
@@ -571,7 +615,7 @@ class Operation(metaclass=abc.ABCMeta):
571
615
  if callable(qubit_map):
572
616
  transform = qubit_map
573
617
  elif isinstance(qubit_map, dict):
574
- transform = lambda q: qubit_map.get(q, q) # type: ignore
618
+ transform = lambda q: qubit_map.get(q, q)
575
619
  else:
576
620
  raise TypeError('qubit_map must be a function or dict mapping qubits to qubits.')
577
621
  return self.with_qubits(*(transform(q) for q in self.qubits))
@@ -644,41 +688,7 @@ class Operation(metaclass=abc.ABCMeta):
644
688
  """Determine if this Operation commutes with the object"""
645
689
  if not isinstance(other, Operation):
646
690
  return NotImplemented
647
-
648
- self_keys = protocols.measurement_key_objs(self)
649
- other_keys = protocols.measurement_key_objs(other)
650
- if (
651
- not self_keys.isdisjoint(other_keys)
652
- or not protocols.control_keys(self).isdisjoint(other_keys)
653
- or not protocols.control_keys(other).isdisjoint(self_keys)
654
- ):
655
- return False
656
-
657
- if hasattr(other, 'qubits') and set(self.qubits).isdisjoint(other.qubits):
658
- return True
659
-
660
- from cirq import circuits
661
-
662
- # Remove the classical controls to validate the quantum commutativity. This can be done
663
- # because during execution, the two operations will either both be run, in which case they
664
- # behave like the suboperations, so if the suboperations commute then these commute. Or
665
- # one of them is cold in which case it behaves like the identity, which always commutes.
666
- self_raw = self.without_classical_controls()
667
- other_raw = other.without_classical_controls()
668
- circuit12 = circuits.Circuit(self_raw, other_raw)
669
- circuit21 = circuits.Circuit(other_raw, self_raw)
670
-
671
- # Don't create gigantic matrices.
672
- shape = protocols.qid_shape_protocol.qid_shape(circuit12)
673
- if np.prod(shape, dtype=np.int64) > 2**10:
674
- return NotImplemented # pragma: no cover
675
-
676
- m12 = protocols.unitary_protocol.unitary(circuit12, default=None)
677
- m21 = protocols.unitary_protocol.unitary(circuit21, default=None)
678
- if m12 is None or m21 is None:
679
- return NotImplemented
680
-
681
- return np.allclose(m12, m21, atol=atol)
691
+ return _operations_commutes_impl([self], [other], atol=atol)
682
692
 
683
693
  @property
684
694
  def classical_controls(self) -> FrozenSet['cirq.Condition']:
@@ -750,7 +760,8 @@ class TaggedOperation(Operation):
750
760
  Tags added can be of any type, but they should be Hashable in order
751
761
  to allow equality checking. If you wish to serialize operations into
752
762
  JSON, you should restrict yourself to only use objects that have a JSON
753
- serialization.
763
+ serialization. Tags cannot be raw types and should be instantiated
764
+ if classes are used.
754
765
 
755
766
  See `Operation.with_tags()` for more information on intended usage.
756
767
  """
@@ -758,6 +769,8 @@ class TaggedOperation(Operation):
758
769
  def __init__(self, sub_operation: 'cirq.Operation', *tags: Hashable):
759
770
  self._sub_operation = sub_operation
760
771
  self._tags = tuple(tags)
772
+ if any(isinstance(tag, type) for tag in tags):
773
+ raise ValueError('Tags cannot be types. Did you forget to instantiate the tag type?')
761
774
 
762
775
  @property
763
776
  def sub_operation(self) -> 'cirq.Operation':
@@ -807,6 +820,9 @@ class TaggedOperation(Operation):
807
820
  Overloads Operation.with_tags to create a new TaggedOperation
808
821
  that has the tags of this operation combined with the new_tags
809
822
  specified as the parameter.
823
+
824
+ Please note that tags should be instantiated if classes are
825
+ used. Raw types are not allowed.
810
826
  """
811
827
  if not new_tags:
812
828
  return self
@@ -870,7 +886,7 @@ class TaggedOperation(Operation):
870
886
  def _has_kraus_(self) -> bool:
871
887
  return protocols.has_kraus(self.sub_operation)
872
888
 
873
- def _kraus_(self) -> Union[Tuple[np.ndarray], NotImplementedType]:
889
+ def _kraus_(self) -> Union[Tuple[np.ndarray, ...], NotImplementedType]:
874
890
  return protocols.kraus(self.sub_operation, NotImplemented)
875
891
 
876
892
  @cached_method
@@ -886,7 +902,7 @@ class TaggedOperation(Operation):
886
902
  sub = getattr(self.sub_operation, "_is_measurement_", None)
887
903
  if sub is not None:
888
904
  return sub()
889
- return NotImplemented
905
+ return NotImplemented # pragma: no cover
890
906
 
891
907
  @cached_method
892
908
  def _is_parameterized_(self) -> bool:
@@ -930,7 +946,9 @@ class TaggedOperation(Operation):
930
946
  return protocols.trace_distance_bound(self.sub_operation)
931
947
 
932
948
  def _phase_by_(self, phase_turns: float, qubit_index: int) -> 'cirq.Operation':
933
- return protocols.phase_by(self.sub_operation, phase_turns, qubit_index)
949
+ return protocols.phase_by(
950
+ self.sub_operation, phase_turns, qubit_index, default=NotImplemented
951
+ )
934
952
 
935
953
  def __pow__(self, exponent: Any) -> 'cirq.Operation':
936
954
  return self.sub_operation**exponent
@@ -945,7 +963,7 @@ class TaggedOperation(Operation):
945
963
  return protocols.qasm(self.sub_operation, args=args, default=None)
946
964
 
947
965
  def _equal_up_to_global_phase_(
948
- self, other: Any, atol: Union[int, float] = 1e-8
966
+ self, other: Any, atol: float = 1e-8
949
967
  ) -> Union[NotImplementedType, bool]:
950
968
  return protocols.equal_up_to_global_phase(self.sub_operation, other, atol=atol)
951
969
 
@@ -996,7 +1014,7 @@ class _InverseCompositeGate(Gate):
996
1014
  )
997
1015
 
998
1016
  def _has_unitary_(self):
999
- from cirq import protocols, devices
1017
+ from cirq import devices, protocols
1000
1018
 
1001
1019
  qubits = devices.LineQid.for_gate(self)
1002
1020
  return all(
@@ -1035,6 +1053,9 @@ class _InverseCompositeGate(Gate):
1035
1053
  def __str__(self) -> str:
1036
1054
  return f'{self._original!s}†'
1037
1055
 
1056
+ def _json_dict_(self) -> Dict[str, Any]:
1057
+ return {'original': self._original}
1058
+
1038
1059
 
1039
1060
  def _validate_qid_shape(val: Any, qubits: Sequence['cirq.Qid']) -> None:
1040
1061
  """Helper function to validate qubits for gates and operations.
@@ -1057,3 +1078,78 @@ def _validate_qid_shape(val: Any, qubits: Sequence['cirq.Qid']) -> None:
1057
1078
  raise ValueError(
1058
1079
  f'Duplicate qids for <{val!r}>. Expected unique qids but got <{qubits!r}>.'
1059
1080
  )
1081
+
1082
+
1083
+ def _operations_commutes_impl(
1084
+ ops1: Collection[Operation], ops2: Collection[Operation], *, atol: float
1085
+ ) -> Union[bool, NotImplementedType]:
1086
+ """Determine if two collections of non-overlapping Operations commute.
1087
+
1088
+ This function implements the commutes protocol for the Operation and Moment classes
1089
+ and is not intended for other use.
1090
+
1091
+ Args:
1092
+ ops1: The first collection of operations. It is assumed each operation
1093
+ acts on different qubits, i.e., the operations can form a Moment.
1094
+ ops2: The second collection of operations to be checked for commutation
1095
+ with `ops1`. It is assumed each operation acts on different qubits,
1096
+ i.e., the operations can form a Moment.
1097
+ atol: Absolute error tolerance. If all entries in ops1@ops2 - ops2@ops1
1098
+ have a magnitude less than this tolerance, ops1 and ops2 are considered
1099
+ to commute.
1100
+
1101
+ Returns:
1102
+ True: `ops1` and `ops2` commute (or approximately commute).
1103
+ False: `ops1` and `ops2` do not commute.
1104
+ NotImplemented: The commutativity cannot be determined here.
1105
+ """
1106
+ ops1_keys = frozenset(k for op in ops1 for k in protocols.measurement_key_objs(op))
1107
+ ops2_keys = frozenset(k for op in ops2 for k in protocols.measurement_key_objs(op))
1108
+ ops1_control_keys = frozenset(k for op in ops1 for k in protocols.control_keys(op))
1109
+ ops2_control_keys = frozenset(k for op in ops2 for k in protocols.control_keys(op))
1110
+ if (
1111
+ not ops1_keys.isdisjoint(ops2_keys)
1112
+ or not ops1_control_keys.isdisjoint(ops2_keys)
1113
+ or not ops2_control_keys.isdisjoint(ops1_keys)
1114
+ ):
1115
+ return False
1116
+
1117
+ ops1_qubits = frozenset().union(*(op.qubits for op in ops1))
1118
+ ops2_qubits = frozenset().union(*(op.qubits for op in ops2))
1119
+ if ops1_qubits.isdisjoint(ops2_qubits):
1120
+ return True
1121
+
1122
+ from cirq import circuits
1123
+
1124
+ # Remove the classical controls to validate the quantum commutativity. This can be done
1125
+ # because during execution, the two operations will either both be run, in which case they
1126
+ # behave like the suboperations, so if the suboperations commute then these commute. Or
1127
+ # one of them is cold in which case it behaves like the identity, which always commutes.
1128
+ shared_qubits = ops1_qubits.intersection(ops2_qubits)
1129
+ ops1_raw = [
1130
+ op.without_classical_controls() for op in ops1 if not shared_qubits.isdisjoint(op.qubits)
1131
+ ]
1132
+ ops2_raw = [
1133
+ op.without_classical_controls() for op in ops2 if not shared_qubits.isdisjoint(op.qubits)
1134
+ ]
1135
+ moment1 = circuits.Moment(ops1_raw)
1136
+ moment2 = circuits.Moment(ops2_raw)
1137
+
1138
+ # shortcut if we have equal moments
1139
+ if moment1 == moment2:
1140
+ return True
1141
+
1142
+ circuit12 = circuits.Circuit(moment1, moment2)
1143
+ circuit21 = circuits.Circuit(moment2, moment1)
1144
+
1145
+ # Don't create gigantic matrices.
1146
+ shape = protocols.qid_shape_protocol.qid_shape(circuit12)
1147
+ if np.prod(shape, dtype=np.int64) > 2**10:
1148
+ return NotImplemented # pragma: no cover
1149
+
1150
+ m12 = protocols.unitary_protocol.unitary(circuit12, default=None)
1151
+ m21 = protocols.unitary_protocol.unitary(circuit21, default=None)
1152
+ if m12 is None or m21 is None:
1153
+ return NotImplemented
1154
+
1155
+ return np.allclose(m12, m21, atol=atol)
@@ -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
- from typing import AbstractSet, Iterator, Any
15
+ from typing import AbstractSet, Any, Iterator
16
16
 
17
- import pytest
18
17
  import numpy as np
18
+ import pytest
19
19
  import sympy
20
20
 
21
21
  import cirq
@@ -77,6 +77,13 @@ def test_wrapped_qid():
77
77
  'dimension': 3,
78
78
  }
79
79
 
80
+ assert not ValidQubit('zz') == 4
81
+ assert ValidQubit('zz') != 4
82
+ assert ValidQubit('zz') > ValidQubit('aa')
83
+ assert ValidQubit('zz') <= ValidQubit('zz')
84
+ assert ValidQubit('zz') >= ValidQubit('zz')
85
+ assert ValidQubit('zz') >= ValidQubit('aa')
86
+
80
87
 
81
88
  def test_qid_dimension():
82
89
  assert ValidQubit('a').dimension == 2
@@ -210,6 +217,21 @@ def test_default_validation_and_inverse():
210
217
  cirq.testing.assert_implements_consistent_protocols(i, local_vals={'TestGate': TestGate})
211
218
 
212
219
 
220
+ def test_default_no_qubits():
221
+ class TestOp(cirq.Operation):
222
+ def with_qubits(self, *new_qubits):
223
+ raise NotImplementedError()
224
+
225
+ @property
226
+ def qubits(self):
227
+ pass
228
+
229
+ op = TestOp()
230
+ assert op.controlled_by(*[]) is op
231
+ op = TestOp().with_tags("abc")
232
+ assert op.classical_controls == frozenset()
233
+
234
+
213
235
  def test_default_inverse():
214
236
  class TestGate(cirq.Gate):
215
237
  def _num_qubits_(self):
@@ -258,6 +280,7 @@ def test_default_qudit_inverse():
258
280
  (cirq.CZ * 1, cirq.CZ / 1),
259
281
  (-cirq.CSWAP * 1j, cirq.CSWAP / 1j),
260
282
  (cirq.TOFFOLI * 0.5, cirq.TOFFOLI / 2),
283
+ (-cirq.X * sympy.Symbol('s'), -sympy.Symbol('s') * cirq.X),
261
284
  ),
262
285
  )
263
286
  def test_gate_algebra(expression, expected_result):
@@ -356,7 +379,7 @@ def test_gate_shape_protocol():
356
379
  def test_operation_shape():
357
380
  class FixedQids(cirq.Operation):
358
381
  def with_qubits(self, *new_qids):
359
- raise NotImplementedError # pragma: no cover
382
+ raise NotImplementedError
360
383
 
361
384
  class QubitOp(FixedQids):
362
385
  @property
@@ -458,6 +481,12 @@ def test_tagged_operation():
458
481
  assert op.with_qubits(q2).qubits == (q2,)
459
482
  assert not cirq.is_measurement(op)
460
483
 
484
+ # Tags can't be types
485
+ # This is to prevent typos of cirq.X(q1).with_tags(TagType)
486
+ # when you meant cirq.X(q1).with_tags(TagType())
487
+ with pytest.raises(ValueError, match="cannot be types"):
488
+ _ = cirq.X(q1).with_tags(cirq.Circuit)
489
+
461
490
 
462
491
  def test_with_tags_returns_same_instance_if_possible():
463
492
  untagged = cirq.X(cirq.GridQubit(1, 1))
@@ -652,6 +681,9 @@ def test_tagged_operation_forwards_protocols():
652
681
  assert isinstance(controlled_y, cirq.Operation)
653
682
  assert not isinstance(controlled_y, cirq.TaggedOperation)
654
683
  classically_controlled_y = tagged_y.with_classical_controls("a")
684
+ assert classically_controlled_y.classical_controls == frozenset(
685
+ {cirq.KeyCondition(cirq.MeasurementKey(name='a'))}
686
+ )
655
687
  assert classically_controlled_y == y.with_classical_controls("a")
656
688
  assert isinstance(classically_controlled_y, cirq.Operation)
657
689
  assert not isinstance(classically_controlled_y, cirq.TaggedOperation)
@@ -662,6 +694,8 @@ def test_tagged_operation_forwards_protocols():
662
694
  assert cirq.commutes(tagged_x, clifford_x)
663
695
  assert cirq.commutes(clifford_x, tagged_x)
664
696
  assert cirq.commutes(tagged_x, tagged_x)
697
+ assert cirq.phase_by(clifford_x, 0.125, 0, default=None) is None
698
+ assert cirq.phase_by(tagged_x, 0.125, 0, default=None) is None
665
699
 
666
700
  assert cirq.trace_distance_bound(y**0.001) == cirq.trace_distance_bound(
667
701
  (y**0.001).with_tags(tag)
@@ -14,13 +14,13 @@
14
14
 
15
15
  """Quantum gates to prepare a given target state."""
16
16
 
17
- from typing import Any, Dict, Tuple, Iterable, TYPE_CHECKING
17
+ from typing import Any, Dict, Iterable, Tuple, TYPE_CHECKING
18
18
 
19
19
  import numpy as np
20
20
 
21
21
  from cirq import protocols
22
- from cirq.ops import raw_types
23
22
  from cirq._compat import proper_repr
23
+ from cirq.ops import raw_types
24
24
 
25
25
  if TYPE_CHECKING:
26
26
  import cirq
@@ -13,9 +13,10 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import numpy as np
16
- import cirq
17
16
  import pytest
18
17
 
18
+ import cirq
19
+
19
20
 
20
21
  @pytest.mark.parametrize(
21
22
  'state',
cirq/ops/swap_gates.py CHANGED
@@ -25,7 +25,7 @@ raised to a power (i.e. SQRT_ISWAP_INV=cirq.ISWAP**-0.5). See the definition in
25
25
  EigenGate.
26
26
  """
27
27
 
28
- from typing import Optional, Tuple, TYPE_CHECKING, List
28
+ from typing import cast, List, Optional, Tuple, TYPE_CHECKING
29
29
 
30
30
  import numpy as np
31
31
  import sympy
@@ -33,7 +33,7 @@ import sympy
33
33
  from cirq import protocols, value
34
34
  from cirq._compat import proper_repr
35
35
  from cirq._doc import document
36
- from cirq.ops import common_gates, gate_features, eigen_gate
36
+ from cirq.ops import common_gates, eigen_gate, gate_features
37
37
 
38
38
  if TYPE_CHECKING:
39
39
  import cirq
@@ -148,7 +148,7 @@ class SwapPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate)
148
148
  def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optional[str]:
149
149
  if self._exponent != 1:
150
150
  return None # Don't have an equivalent gate in QASM
151
- args.validate_version('2.0')
151
+ args.validate_version('2.0', '3.0')
152
152
  return args.format('swap {0},{1};\n', qubits[0], qubits[1])
153
153
 
154
154
  def __str__(self) -> str:
@@ -219,6 +219,11 @@ class ISwapPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate
219
219
  ]
220
220
  # yapf: enable
221
221
 
222
+ def _has_stabilizer_effect_(self) -> Optional[bool]:
223
+ if self._is_parameterized_():
224
+ return None
225
+ return self.exponent % 1 == 0
226
+
222
227
  def _decompose_(self, qubits):
223
228
  a, b = qubits
224
229
 
@@ -294,7 +299,7 @@ class ISwapPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate
294
299
  def riswap(rads: value.TParamVal) -> ISwapPowGate:
295
300
  """Returns gate with matrix exp(+i angle_rads (X⊗X + Y⊗Y) / 2)."""
296
301
  pi = sympy.pi if protocols.is_parameterized(rads) else np.pi
297
- return ISwapPowGate() ** (2 * rads / pi)
302
+ return cast(ISwapPowGate, ISwapPowGate() ** (2 * rads / pi))
298
303
 
299
304
 
300
305
  SWAP = SwapPowGate()
@@ -19,6 +19,7 @@ from typing import (
19
19
  Any,
20
20
  Collection,
21
21
  Dict,
22
+ Iterator,
22
23
  List,
23
24
  Optional,
24
25
  Sequence,
@@ -35,15 +36,14 @@ from cirq._compat import proper_repr
35
36
  from cirq._doc import document
36
37
  from cirq.ops import (
37
38
  common_gates,
39
+ control_values as cv,
38
40
  controlled_gate,
39
41
  eigen_gate,
40
42
  gate_features,
43
+ global_phase_op,
41
44
  pauli_gates,
42
45
  raw_types,
43
46
  swap_gates,
44
- raw_types,
45
- control_values as cv,
46
- global_phase_op,
47
47
  )
48
48
 
49
49
  if TYPE_CHECKING:
@@ -163,7 +163,7 @@ class CCZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
163
163
  if self._exponent != 1:
164
164
  return None
165
165
 
166
- args.validate_version('2.0')
166
+ args.validate_version('2.0', '3.0')
167
167
  lines = [
168
168
  args.format('h {0};\n', qubits[2]),
169
169
  args.format('ccx {0},{1},{2};\n', qubits[0], qubits[1], qubits[2]),
@@ -482,7 +482,7 @@ class CCXPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
482
482
  if self._exponent != 1:
483
483
  return None
484
484
 
485
- args.validate_version('2.0')
485
+ args.validate_version('2.0', '3.0')
486
486
  return args.format('ccx {0},{1},{2};\n', qubits[0], qubits[1], qubits[2])
487
487
 
488
488
  def __repr__(self) -> str:
@@ -573,7 +573,7 @@ class CSwapGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
573
573
 
574
574
  def _decompose_inside_control(
575
575
  self, target1: 'cirq.Qid', control: 'cirq.Qid', target2: 'cirq.Qid'
576
- ) -> 'cirq.OP_TREE':
576
+ ) -> Iterator['cirq.OP_TREE']:
577
577
  """A decomposition assuming the control separates the targets.
578
578
 
579
579
  target1: ─@─X───────T──────@────────@─────────X───@─────X^-0.5─
@@ -617,7 +617,7 @@ class CSwapGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
617
617
 
618
618
  def _decompose_outside_control(
619
619
  self, control: 'cirq.Qid', near_target: 'cirq.Qid', far_target: 'cirq.Qid'
620
- ) -> 'cirq.OP_TREE':
620
+ ) -> Iterator['cirq.OP_TREE']:
621
621
  """A decomposition assuming one of the targets is in the middle.
622
622
 
623
623
  control: ───T──────@────────@───@────────────@────────────────
@@ -660,7 +660,7 @@ class CSwapGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
660
660
  return protocols.CircuitDiagramInfo(('@', '×', '×'))
661
661
 
662
662
  def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optional[str]:
663
- args.validate_version('2.0')
663
+ args.validate_version('2.0', '3.0')
664
664
  return args.format('cswap {0},{1},{2};\n', qubits[0], qubits[1], qubits[2])
665
665
 
666
666
  def _value_equality_values_(self):
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import itertools
16
+
16
17
  import numpy as np
17
18
  import pytest
18
19
  import sympy
@@ -18,13 +18,14 @@ The gate is used to create a 4x4 matrix with the diagonal elements
18
18
  passed as a list.
19
19
  """
20
20
 
21
- from typing import AbstractSet, Any, Dict, Tuple, Optional, Sequence, TYPE_CHECKING
21
+ from typing import AbstractSet, Any, Dict, Iterator, Optional, Sequence, Tuple, TYPE_CHECKING
22
+
22
23
  import numpy as np
23
24
  import sympy
24
25
 
25
26
  from cirq import protocols, value
26
27
  from cirq._compat import proper_repr
27
- from cirq.ops import raw_types, common_gates
28
+ from cirq.ops import common_gates, raw_types
28
29
 
29
30
  if TYPE_CHECKING:
30
31
  import cirq
@@ -93,7 +94,7 @@ class TwoQubitDiagonalGate(raw_types.Gate):
93
94
  return None
94
95
  return np.diag([np.exp(1j * angle) for angle in self._diag_angles_radians])
95
96
 
96
- def _decompose_(self, qubits: Sequence['cirq.Qid']) -> 'cirq.OP_TREE':
97
+ def _decompose_(self, qubits: Sequence['cirq.Qid']) -> Iterator['cirq.OP_TREE']:
97
98
  x0, x1, x2, x3 = self._diag_angles_radians
98
99
  q0, q1 = qubits
99
100
  yield common_gates.ZPowGate(exponent=x2 / np.pi).on(q0)
@@ -12,13 +12,13 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import Sequence, Any, Dict, TYPE_CHECKING
15
+ from typing import Any, Dict, Iterator, Sequence, TYPE_CHECKING
16
16
 
17
17
  import numpy as np
18
+
19
+ from cirq.ops import raw_types
18
20
  from cirq.ops.common_gates import H, ry
19
21
  from cirq.ops.pauli_gates import X
20
- from cirq.ops import raw_types
21
-
22
22
 
23
23
  if TYPE_CHECKING:
24
24
  import cirq
@@ -58,7 +58,7 @@ class UniformSuperpositionGate(raw_types.Gate):
58
58
  self._m_value = m_value
59
59
  self._num_qubits = num_qubits
60
60
 
61
- def _decompose_(self, qubits: Sequence["cirq.Qid"]) -> "cirq.OP_TREE":
61
+ def _decompose_(self, qubits: Sequence["cirq.Qid"]) -> Iterator["cirq.OP_TREE"]:
62
62
  """Decomposes the gate into a sequence of standard gates.
63
63
  Implements the construction from https://arxiv.org/pdf/2306.11747.
64
64
  """
@@ -14,6 +14,7 @@
14
14
 
15
15
  import numpy as np
16
16
  import pytest
17
+
17
18
  import cirq
18
19
 
19
20
 
cirq/ops/wait_gate.py CHANGED
@@ -11,11 +11,9 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- from typing import AbstractSet, Any, Dict, Optional, Tuple, TYPE_CHECKING, Union
14
+ from typing import AbstractSet, Any, Dict, Optional, Tuple, TYPE_CHECKING
15
15
 
16
- import sympy
17
-
18
- from cirq import value, protocols
16
+ from cirq import protocols, value
19
17
  from cirq.ops import raw_types
20
18
 
21
19
  if TYPE_CHECKING:
@@ -136,10 +134,10 @@ class WaitGate(raw_types.Gate):
136
134
  def wait(
137
135
  *target: 'cirq.Qid',
138
136
  duration: 'cirq.DURATION_LIKE' = None,
139
- picos: Union[int, float, sympy.Expr] = 0,
140
- nanos: Union[int, float, sympy.Expr] = 0,
141
- micros: Union[int, float, sympy.Expr] = 0,
142
- millis: Union[int, float, sympy.Expr] = 0,
137
+ picos: 'cirq.TParamVal' = 0,
138
+ nanos: 'cirq.TParamVal' = 0,
139
+ micros: 'cirq.TParamVal' = 0,
140
+ millis: 'cirq.TParamVal' = 0,
143
141
  ) -> raw_types.Operation:
144
142
  """Creates a WaitGate applied to all the given qubits.
145
143