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
@@ -13,55 +13,70 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Tools for creating and using acquaintance strategies."""
16
+ from cirq.contrib.acquaintance.bipartite import (
17
+ BipartiteGraphType as BipartiteGraphType,
18
+ BipartiteSwapNetworkGate as BipartiteSwapNetworkGate,
19
+ )
16
20
 
17
- from cirq.contrib.acquaintance.bipartite import BipartiteGraphType, BipartiteSwapNetworkGate
18
-
19
- from cirq.contrib.acquaintance.devices import get_acquaintance_size, UnconstrainedAcquaintanceDevice
21
+ from cirq.contrib.acquaintance.devices import (
22
+ get_acquaintance_size as get_acquaintance_size,
23
+ UnconstrainedAcquaintanceDevice as UnconstrainedAcquaintanceDevice,
24
+ )
20
25
 
21
26
  from cirq.contrib.acquaintance.executor import (
22
- AcquaintanceOperation,
23
- GreedyExecutionStrategy,
24
- StrategyExecutorTransformer,
27
+ AcquaintanceOperation as AcquaintanceOperation,
28
+ GreedyExecutionStrategy as GreedyExecutionStrategy,
29
+ StrategyExecutorTransformer as StrategyExecutorTransformer,
25
30
  )
26
31
 
27
- from cirq.contrib.acquaintance.gates import acquaint, AcquaintanceOpportunityGate, SwapNetworkGate
32
+ from cirq.contrib.acquaintance.gates import (
33
+ acquaint as acquaint,
34
+ AcquaintanceOpportunityGate as AcquaintanceOpportunityGate,
35
+ SwapNetworkGate as SwapNetworkGate,
36
+ )
28
37
 
29
- from cirq.contrib.acquaintance.inspection_utils import get_logical_acquaintance_opportunities
38
+ from cirq.contrib.acquaintance.inspection_utils import (
39
+ get_logical_acquaintance_opportunities as get_logical_acquaintance_opportunities,
40
+ )
30
41
 
31
42
  from cirq.contrib.acquaintance.mutation_utils import (
32
- expose_acquaintance_gates,
33
- rectify_acquaintance_strategy,
34
- replace_acquaintance_with_swap_network,
43
+ expose_acquaintance_gates as expose_acquaintance_gates,
44
+ rectify_acquaintance_strategy as rectify_acquaintance_strategy,
45
+ replace_acquaintance_with_swap_network as replace_acquaintance_with_swap_network,
35
46
  )
36
47
 
37
- from cirq.contrib.acquaintance.optimizers import remove_redundant_acquaintance_opportunities
48
+ from cirq.contrib.acquaintance.optimizers import (
49
+ remove_redundant_acquaintance_opportunities as remove_redundant_acquaintance_opportunities,
50
+ )
38
51
 
39
52
  from cirq.contrib.acquaintance.permutation import (
40
- LinearPermutationGate,
41
- PermutationGate,
42
- SwapPermutationGate,
43
- update_mapping,
44
- get_logical_operations,
45
- display_mapping,
46
- return_to_initial_mapping,
47
- uses_consistent_swap_gate,
48
- EXPAND_PERMUTATION_GATES,
49
- DECOMPOSE_PERMUTATION_GATES,
53
+ LinearPermutationGate as LinearPermutationGate,
54
+ PermutationGate as PermutationGate,
55
+ SwapPermutationGate as SwapPermutationGate,
56
+ update_mapping as update_mapping,
57
+ get_logical_operations as get_logical_operations,
58
+ display_mapping as display_mapping,
59
+ return_to_initial_mapping as return_to_initial_mapping,
60
+ uses_consistent_swap_gate as uses_consistent_swap_gate,
61
+ EXPAND_PERMUTATION_GATES as EXPAND_PERMUTATION_GATES,
62
+ DECOMPOSE_PERMUTATION_GATES as DECOMPOSE_PERMUTATION_GATES,
50
63
  )
51
64
 
52
- from cirq.contrib.acquaintance.shift import CircularShiftGate
65
+ from cirq.contrib.acquaintance.shift import CircularShiftGate as CircularShiftGate
53
66
 
54
- from cirq.contrib.acquaintance.shift_swap_network import ShiftSwapNetworkGate
67
+ from cirq.contrib.acquaintance.shift_swap_network import (
68
+ ShiftSwapNetworkGate as ShiftSwapNetworkGate,
69
+ )
55
70
 
56
71
  from cirq.contrib.acquaintance.strategies import (
57
- complete_acquaintance_strategy,
58
- cubic_acquaintance_strategy,
59
- quartic_paired_acquaintance_strategy,
72
+ complete_acquaintance_strategy as complete_acquaintance_strategy,
73
+ cubic_acquaintance_strategy as cubic_acquaintance_strategy,
74
+ quartic_paired_acquaintance_strategy as quartic_paired_acquaintance_strategy,
60
75
  )
61
76
 
62
77
  from cirq.contrib.acquaintance.topological_sort import (
63
- is_topologically_sorted,
64
- random_topological_sort,
78
+ is_topologically_sorted as is_topologically_sorted,
79
+ random_topological_sort as random_topological_sort,
65
80
  )
66
81
 
67
82
  from cirq.contrib.acquaintance import testing
@@ -12,12 +12,13 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import enum
16
18
  import itertools
17
- from typing import Dict, Sequence, Tuple, Union, TYPE_CHECKING
19
+ from typing import Dict, Iterator, Sequence, Tuple, TYPE_CHECKING, Union
18
20
 
19
21
  from cirq import ops
20
-
21
22
  from cirq.contrib.acquaintance.gates import acquaint
22
23
  from cirq.contrib.acquaintance.permutation import PermutationGate, SwapPermutationGate
23
24
 
@@ -63,7 +64,7 @@ class BipartiteSwapNetworkGate(PermutationGate):
63
64
  self,
64
65
  subgraph: Union[str, BipartiteGraphType],
65
66
  part_size: int,
66
- swap_gate: 'cirq.Gate' = ops.SWAP,
67
+ swap_gate: cirq.Gate = ops.SWAP,
67
68
  ) -> None:
68
69
  super().__init__(2 * part_size, swap_gate)
69
70
  self.part_size = part_size
@@ -72,7 +73,7 @@ class BipartiteSwapNetworkGate(PermutationGate):
72
73
  )
73
74
  self.swap_gate = swap_gate
74
75
 
75
- def decompose_complete(self, qubits: Sequence['cirq.Qid']) -> 'cirq.OP_TREE':
76
+ def decompose_complete(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
76
77
  swap_gate = SwapPermutationGate(self.swap_gate)
77
78
  if self.part_size == 1:
78
79
  yield acquaint(*qubits)
@@ -87,7 +88,7 @@ class BipartiteSwapNetworkGate(PermutationGate):
87
88
  yield acquaint(*qubits[x : x + 2])
88
89
  yield swap_gate(*qubits[x : x + 2])
89
90
 
90
- def decompose_matching(self, qubits: Sequence['cirq.Qid']) -> 'cirq.OP_TREE':
91
+ def decompose_matching(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
91
92
  swap_gate = SwapPermutationGate(self.swap_gate)
92
93
  for k in range(-self.part_size + 1, self.part_size):
93
94
  for x in range(abs(k), 2 * self.part_size - abs(k), 2):
@@ -96,7 +97,7 @@ class BipartiteSwapNetworkGate(PermutationGate):
96
97
  else:
97
98
  yield acquaint(*qubits[x : x + 2])
98
99
 
99
- def _decompose_(self, qubits: Sequence['cirq.Qid']) -> 'cirq.OP_TREE':
100
+ def _decompose_(self, qubits: Sequence[cirq.Qid]) -> cirq.OP_TREE:
100
101
  if len(qubits) != 2 * self.part_size:
101
102
  raise ValueError('len(qubits) != 2 * self.part_size')
102
103
  if self.subgraph == BipartiteGraphType.COMPLETE:
@@ -123,7 +124,7 @@ class BipartiteSwapNetworkGate(PermutationGate):
123
124
  return dict(enumerate(range(2 * self.part_size)))
124
125
  raise NotImplementedError(str(self.subgraph) + 'not implemented')
125
126
 
126
- def _circuit_diagram_info_(self, args: 'cirq.CircuitDiagramInfoArgs') -> Tuple[str, ...]:
127
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> Tuple[str, ...]:
127
128
  qubit_count = 2 * self.part_size
128
129
  if args.known_qubit_count not in (None, qubit_count):
129
130
  raise ValueError('args.known_qubit_count not in (None, 2 * self.part_size)')
@@ -19,7 +19,6 @@ import pytest
19
19
  import cirq
20
20
  import cirq.contrib.acquaintance as cca
21
21
 
22
-
23
22
  circuit_diagrams = {
24
23
  (
25
24
  'undecomposed',
@@ -340,3 +339,14 @@ def test_decomposition_permutation_consistency(part_size, subgraph):
340
339
  cca.update_mapping(mapping, gate._decompose_(qubits))
341
340
  permutation = gate.permutation()
342
341
  assert {qubits[i]: j for i, j in permutation.items()} == mapping
342
+
343
+
344
+ def test_bad_number_of_qubits():
345
+ gate = cca.BipartiteSwapNetworkGate(cca.BipartiteGraphType.COMPLETE, 6)
346
+ qubits = cirq.LineQubit.range(6)
347
+ mapping = {q: i for i, q in enumerate(qubits)}
348
+ with pytest.raises(ValueError, match='len'):
349
+ cca.update_mapping(mapping, gate._decompose_(qubits))
350
+ gate.part_size = 5
351
+ with pytest.raises(ValueError, match='qubit_count'):
352
+ gate.permutation()
@@ -12,15 +12,16 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import Union, TYPE_CHECKING
15
+ from __future__ import annotations
16
16
 
17
17
  import abc
18
+ from typing import TYPE_CHECKING, Union
18
19
 
19
20
  from cirq import circuits, devices, ops
20
- from cirq.contrib.acquaintance.gates import AcquaintanceOpportunityGate, SwapNetworkGate
21
21
  from cirq.contrib.acquaintance.bipartite import BipartiteSwapNetworkGate
22
- from cirq.contrib.acquaintance.shift_swap_network import ShiftSwapNetworkGate
22
+ from cirq.contrib.acquaintance.gates import AcquaintanceOpportunityGate, SwapNetworkGate
23
23
  from cirq.contrib.acquaintance.permutation import PermutationGate
24
+ from cirq.contrib.acquaintance.shift_swap_network import ShiftSwapNetworkGate
24
25
 
25
26
  if TYPE_CHECKING:
26
27
  import cirq
@@ -31,7 +32,7 @@ class AcquaintanceDevice(devices.Device, metaclass=abc.ABCMeta):
31
32
 
32
33
  gate_types = (AcquaintanceOpportunityGate, PermutationGate)
33
34
 
34
- def validate_operation(self, operation: 'cirq.Operation') -> None:
35
+ def validate_operation(self, operation: cirq.Operation) -> None:
35
36
  if not (
36
37
  isinstance(operation, ops.GateOperation) and isinstance(operation.gate, self.gate_types)
37
38
  ):
@@ -15,7 +15,6 @@
15
15
  import pytest
16
16
 
17
17
  import cirq
18
-
19
18
  import cirq.contrib.acquaintance as cca
20
19
 
21
20
 
@@ -28,3 +27,8 @@ def test_acquaintance_device():
28
27
  swap_network = cca.SwapNetworkGate((1, 2, 1))
29
28
  cca.UnconstrainedAcquaintanceDevice.validate_operation(cca.acquaint(*qubits[:2]))
30
29
  cca.UnconstrainedAcquaintanceDevice.validate_operation(swap_network(*qubits))
30
+
31
+
32
+ def test_not_operation():
33
+ with pytest.raises(TypeError):
34
+ _ = cca.get_acquaintance_size(cirq.LineQubit(1))
@@ -12,22 +12,22 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import DefaultDict, Dict, Sequence, TYPE_CHECKING, Optional
15
+ from __future__ import annotations
16
16
 
17
17
  import abc
18
18
  from collections import defaultdict
19
+ from typing import DefaultDict, Dict, Iterator, Optional, Sequence, TYPE_CHECKING
19
20
 
20
21
  from cirq import circuits, devices, ops, protocols, transformers
21
-
22
22
  from cirq.contrib.acquaintance.gates import AcquaintanceOpportunityGate
23
+ from cirq.contrib.acquaintance.mutation_utils import expose_acquaintance_gates
23
24
  from cirq.contrib.acquaintance.permutation import (
24
- PermutationGate,
25
+ LogicalGates,
25
26
  LogicalIndex,
26
27
  LogicalIndexSequence,
27
- LogicalGates,
28
28
  LogicalMapping,
29
+ PermutationGate,
29
30
  )
30
- from cirq.contrib.acquaintance.mutation_utils import expose_acquaintance_gates
31
31
 
32
32
  if TYPE_CHECKING:
33
33
  import cirq
@@ -44,7 +44,7 @@ class ExecutionStrategy(metaclass=abc.ABCMeta):
44
44
 
45
45
  @property
46
46
  @abc.abstractmethod
47
- def device(self) -> 'cirq.Device':
47
+ def device(self) -> cirq.Device:
48
48
  """The device for which the executed acquaintance strategy should be
49
49
  valid.
50
50
  """
@@ -56,8 +56,8 @@ class ExecutionStrategy(metaclass=abc.ABCMeta):
56
56
 
57
57
  @abc.abstractmethod
58
58
  def get_operations(
59
- self, indices: Sequence[LogicalIndex], qubits: Sequence['cirq.Qid']
60
- ) -> 'cirq.OP_TREE':
59
+ self, indices: Sequence[LogicalIndex], qubits: Sequence[cirq.Qid]
60
+ ) -> cirq.OP_TREE:
61
61
  """Gets the logical operations to apply to qubits."""
62
62
 
63
63
  def __call__(self, *args, **kwargs):
@@ -75,6 +75,7 @@ class ExecutionStrategy(metaclass=abc.ABCMeta):
75
75
  strategy = StrategyExecutorTransformer(self)
76
76
  final_circuit = strategy(input_circuit, **kwargs)
77
77
  input_circuit._moments = final_circuit._moments
78
+ input_circuit._placement_cache = final_circuit._placement_cache
78
79
  return strategy.mapping
79
80
 
80
81
 
@@ -98,13 +99,13 @@ class StrategyExecutorTransformer:
98
99
  self._mapping = execution_strategy.initial_mapping.copy()
99
100
 
100
101
  def __call__(
101
- self, circuit: circuits.AbstractCircuit, context: Optional['cirq.TransformerContext'] = None
102
+ self, circuit: circuits.AbstractCircuit, context: Optional[cirq.TransformerContext] = None
102
103
  ) -> circuits.Circuit:
103
104
  """Executes an acquaintance strategy using cirq.map_operations_and_unroll and
104
105
  mutates initial mapping.
105
106
 
106
107
  Args:
107
- circuit: 'cirq.Circuit' input circuit to transform.
108
+ circuit: `cirq.Circuit` input circuit to transform.
108
109
  context: `cirq.TransformerContext` storing common configurable
109
110
  options for transformers.
110
111
 
@@ -127,7 +128,7 @@ class StrategyExecutorTransformer:
127
128
  def mapping(self) -> LogicalMapping:
128
129
  return self._mapping
129
130
 
130
- def _map_func(self, op: 'cirq.Operation', index) -> 'cirq.OP_TREE':
131
+ def _map_func(self, op: cirq.Operation, index) -> cirq.OP_TREE:
131
132
  if isinstance(op.gate, AcquaintanceOpportunityGate):
132
133
  logical_indices = tuple(self._mapping[q] for q in op.qubits)
133
134
  logical_operations = self.execution_strategy.get_operations(logical_indices, op.qubits)
@@ -151,17 +152,13 @@ class AcquaintanceOperation(ops.GateOperation):
151
152
  logical indices on a particular set of physical qubits.
152
153
  """
153
154
 
154
- def __init__(
155
- self, qubits: Sequence['cirq.Qid'], logical_indices: Sequence[LogicalIndex]
156
- ) -> None:
155
+ def __init__(self, qubits: Sequence[cirq.Qid], logical_indices: Sequence[LogicalIndex]) -> None:
157
156
  if len(logical_indices) != len(qubits):
158
157
  raise ValueError('len(logical_indices) != len(qubits)')
159
158
  super().__init__(AcquaintanceOpportunityGate(num_qubits=len(qubits)), qubits)
160
159
  self.logical_indices: LogicalIndexSequence = logical_indices
161
160
 
162
- def _circuit_diagram_info_(
163
- self, args: 'cirq.CircuitDiagramInfoArgs'
164
- ) -> 'cirq.CircuitDiagramInfo':
161
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
165
162
  wire_symbols = tuple(f'({i})' for i in self.logical_indices)
166
163
  return protocols.CircuitDiagramInfo(wire_symbols=wire_symbols)
167
164
 
@@ -177,7 +174,7 @@ class GreedyExecutionStrategy(ExecutionStrategy):
177
174
  self,
178
175
  gates: LogicalGates,
179
176
  initial_mapping: LogicalMapping,
180
- device: Optional['cirq.Device'] = None,
177
+ device: Optional[cirq.Device] = None,
181
178
  ) -> None:
182
179
  """Inits GreedyExecutionStrategy.
183
180
 
@@ -203,12 +200,12 @@ class GreedyExecutionStrategy(ExecutionStrategy):
203
200
  return self._initial_mapping
204
201
 
205
202
  @property
206
- def device(self) -> 'cirq.Device':
203
+ def device(self) -> cirq.Device:
207
204
  return self._device
208
205
 
209
206
  def get_operations(
210
- self, indices: Sequence[LogicalIndex], qubits: Sequence['cirq.Qid']
211
- ) -> 'cirq.OP_TREE':
207
+ self, indices: Sequence[LogicalIndex], qubits: Sequence[cirq.Qid]
208
+ ) -> Iterator[cirq.OP_TREE]:
212
209
  index_set = frozenset(indices)
213
210
  if index_set in self.index_set_to_gates:
214
211
  gates = self.index_set_to_gates.pop(index_set)
@@ -14,14 +14,14 @@
14
14
 
15
15
  from itertools import combinations
16
16
  from string import ascii_lowercase
17
- from typing import Sequence, Dict, Tuple
17
+ from typing import Dict, Sequence, Tuple
18
18
 
19
19
  import numpy as np
20
20
  import pytest
21
21
 
22
22
  import cirq
23
- import cirq.testing as ct
24
23
  import cirq.contrib.acquaintance as cca
24
+ import cirq.testing as ct
25
25
 
26
26
 
27
27
  class ExampleGate(cirq.Gate):
@@ -48,6 +48,7 @@ def test_executor_explicit():
48
48
  }
49
49
  initial_mapping = {q: i for i, q in enumerate(sorted(qubits))}
50
50
  execution_strategy = cca.GreedyExecutionStrategy(gates, initial_mapping)
51
+ assert execution_strategy.device == cirq.UNCONSTRAINED_DEVICE
51
52
 
52
53
  with pytest.raises(ValueError):
53
54
  executor = cca.StrategyExecutorTransformer(None)
@@ -12,33 +12,42 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import functools
16
18
  import itertools
17
19
  import math
18
20
  import operator
19
- from typing import Dict, Iterable, List, NamedTuple, Optional, Sequence, Tuple, TYPE_CHECKING
21
+ from typing import (
22
+ Dict,
23
+ Iterable,
24
+ Iterator,
25
+ List,
26
+ NamedTuple,
27
+ Optional,
28
+ Sequence,
29
+ Tuple,
30
+ TYPE_CHECKING,
31
+ )
20
32
 
21
33
  from cirq import ops, protocols, value
22
-
23
- from cirq.contrib.acquaintance.shift import CircularShiftGate
24
34
  from cirq.contrib.acquaintance.permutation import (
35
+ LinearPermutationGate,
25
36
  PermutationGate,
26
37
  SwapPermutationGate,
27
- LinearPermutationGate,
28
38
  )
39
+ from cirq.contrib.acquaintance.shift import CircularShiftGate
29
40
 
30
41
  if TYPE_CHECKING:
31
42
  import cirq
32
43
 
33
44
 
34
45
  def operations_to_part_lens(
35
- qubit_order: Sequence['cirq.Qid'], op_tree: 'cirq.OP_TREE'
46
+ qubit_order: Sequence[cirq.Qid], op_tree: cirq.OP_TREE
36
47
  ) -> Tuple[int, ...]:
37
48
  qubit_sort_key = functools.partial(operator.indexOf, qubit_order)
38
49
  op_parts = [tuple(sorted(op.qubits, key=qubit_sort_key)) for op in ops.flatten_op_tree(op_tree)]
39
- singletons: List[Tuple['cirq.Qid', ...]] = [
40
- (q,) for q in set(qubit_order).difference(*op_parts)
41
- ]
50
+ singletons: List[Tuple[cirq.Qid, ...]] = [(q,) for q in set(qubit_order).difference(*op_parts)]
42
51
  part_sort_key = lambda p: min(qubit_sort_key(q) for q in p)
43
52
  parts = tuple(tuple(part) for part in sorted(singletons + op_parts, key=part_sort_key))
44
53
 
@@ -62,7 +71,7 @@ class AcquaintanceOpportunityGate(ops.Gate, ops.InterchangeableQubitsGate):
62
71
  f'num_qubits={self.num_qubits()!r})'
63
72
  )
64
73
 
65
- def _circuit_diagram_info_(self, args: 'cirq.CircuitDiagramInfoArgs') -> Iterable[str]:
74
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> Iterable[str]:
66
75
  wire_symbol = '█' if args.use_unicode_characters else 'Acq'
67
76
  wire_symbols = (wire_symbol,) * self.num_qubits()
68
77
  return wire_symbols
@@ -71,7 +80,7 @@ class AcquaintanceOpportunityGate(ops.Gate, ops.InterchangeableQubitsGate):
71
80
  return self._num_qubits
72
81
 
73
82
 
74
- def acquaint(*qubits) -> 'cirq.Operation':
83
+ def acquaint(*qubits) -> cirq.Operation:
75
84
  return AcquaintanceOpportunityGate(len(qubits)).on(*qubits)
76
85
 
77
86
 
@@ -87,14 +96,14 @@ Layers = NamedTuple(
87
96
  )
88
97
 
89
98
 
90
- def new_layers(**kwargs: List['cirq.Operation']) -> Layers:
99
+ def new_layers(**kwargs: List[cirq.Operation]) -> Layers:
91
100
  return Layers._make(kwargs.get(field, []) for field in Layers._fields)
92
101
 
93
102
 
94
103
  def acquaint_insides(
95
- swap_gate: 'cirq.Gate',
96
- acquaintance_gate: 'cirq.Operation',
97
- qubits: Sequence['cirq.Qid'],
104
+ swap_gate: cirq.Gate,
105
+ acquaintance_gate: cirq.Operation,
106
+ qubits: Sequence[cirq.Qid],
98
107
  before: bool,
99
108
  layers: Layers,
100
109
  mapping: Dict[ops.Qid, int],
@@ -144,10 +153,10 @@ def _get_max_reach(size: int, round_up: bool = True) -> int:
144
153
 
145
154
 
146
155
  def acquaint_and_shift(
147
- parts: Tuple[List['cirq.Qid'], List['cirq.Qid']],
156
+ parts: Tuple[List[cirq.Qid], List[cirq.Qid]],
148
157
  layers: Layers,
149
158
  acquaintance_size: Optional[int],
150
- swap_gate: 'cirq.Gate',
159
+ swap_gate: cirq.Gate,
151
160
  mapping: Dict[ops.Qid, int],
152
161
  ):
153
162
  """Acquaints and shifts a pair of lists of qubits. The first part is
@@ -268,7 +277,7 @@ class SwapNetworkGate(PermutationGate):
268
277
  self,
269
278
  part_lens: Sequence[int],
270
279
  acquaintance_size: Optional[int] = 0,
271
- swap_gate: 'cirq.Gate' = ops.SWAP,
280
+ swap_gate: cirq.Gate = ops.SWAP,
272
281
  ) -> None:
273
282
  super().__init__(sum(part_lens), swap_gate)
274
283
  if len(part_lens) < 2:
@@ -276,7 +285,7 @@ class SwapNetworkGate(PermutationGate):
276
285
  self.part_lens = tuple(part_lens)
277
286
  self.acquaintance_size = acquaintance_size
278
287
 
279
- def _decompose_(self, qubits: Sequence['cirq.Qid']) -> 'cirq.OP_TREE':
288
+ def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
280
289
  qubit_to_position = {q: i for i, q in enumerate(qubits)}
281
290
  mapping = dict(qubit_to_position)
282
291
  parts = []
@@ -306,10 +315,12 @@ class SwapNetworkGate(PermutationGate):
306
315
  parts_qubits = list(left_part + right_part)
307
316
  parts[i] = parts_qubits[: len(right_part)]
308
317
  parts[i + 1] = parts_qubits[len(right_part) :]
309
- layers.prior_interstitial.sort(key=op_sort_key)
318
+ if op_sort_key is not None:
319
+ layers.prior_interstitial.sort(key=op_sort_key)
310
320
  for l in ('prior_interstitial', 'pre', 'intra', 'post'):
311
321
  yield getattr(layers, l)
312
- layers.posterior_interstitial.sort(key=op_sort_key)
322
+ if op_sort_key is not None:
323
+ layers.posterior_interstitial.sort(key=op_sort_key)
313
324
  yield layers.posterior_interstitial
314
325
 
315
326
  assert list(
@@ -322,9 +333,7 @@ class SwapNetworkGate(PermutationGate):
322
333
  if final_gate:
323
334
  yield final_gate(*qubits)
324
335
 
325
- def _circuit_diagram_info_(
326
- self, args: 'cirq.CircuitDiagramInfoArgs'
327
- ) -> 'cirq.CircuitDiagramInfo':
336
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
328
337
  wire_symbol = '×' if args.use_unicode_characters else 'swap'
329
338
  wire_symbols = tuple(
330
339
  wire_symbol + f'({part_index},{qubit_index})'
@@ -335,11 +344,11 @@ class SwapNetworkGate(PermutationGate):
335
344
 
336
345
  @staticmethod
337
346
  def from_operations(
338
- qubit_order: Sequence['cirq.Qid'],
339
- operations: Sequence['cirq.Operation'],
347
+ qubit_order: Sequence[cirq.Qid],
348
+ operations: Sequence[cirq.Operation],
340
349
  acquaintance_size: Optional[int] = 0,
341
- swap_gate: 'cirq.Gate' = ops.SWAP,
342
- ) -> 'SwapNetworkGate':
350
+ swap_gate: cirq.Gate = ops.SWAP,
351
+ ) -> SwapNetworkGate:
343
352
  part_sizes = operations_to_part_lens(qubit_order, operations)
344
353
  return SwapNetworkGate(part_sizes, acquaintance_size, swap_gate)
345
354
 
@@ -21,8 +21,8 @@ import numpy
21
21
  import pytest
22
22
 
23
23
  import cirq
24
- import cirq.testing as ct
25
24
  import cirq.contrib.acquaintance as cca
25
+ import cirq.testing as ct
26
26
 
27
27
 
28
28
  def test_acquaintance_gate_repr():
@@ -12,17 +12,18 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import FrozenSet, Sequence, Set, TYPE_CHECKING
15
+ from __future__ import annotations
16
16
 
17
- from cirq import devices
17
+ from typing import FrozenSet, Iterator, Sequence, Set, TYPE_CHECKING
18
18
 
19
+ from cirq import devices
20
+ from cirq.contrib import circuitdag
19
21
  from cirq.contrib.acquaintance.executor import AcquaintanceOperation, ExecutionStrategy
20
22
  from cirq.contrib.acquaintance.mutation_utils import expose_acquaintance_gates
21
- from cirq.contrib.acquaintance.permutation import LogicalIndex, LogicalMapping
22
- from cirq.contrib import circuitdag
23
23
 
24
24
  if TYPE_CHECKING:
25
25
  import cirq
26
+ from cirq.contrib.acquaintance.permutation import LogicalIndex, LogicalMapping
26
27
 
27
28
 
28
29
  class LogicalAnnotator(ExecutionStrategy):
@@ -41,16 +42,16 @@ class LogicalAnnotator(ExecutionStrategy):
41
42
  return self._initial_mapping
42
43
 
43
44
  @property
44
- def device(self) -> 'cirq.Device':
45
+ def device(self) -> cirq.Device:
45
46
  return devices.UNCONSTRAINED_DEVICE
46
47
 
47
48
  def get_operations(
48
- self, indices: Sequence[LogicalIndex], qubits: Sequence['cirq.Qid']
49
- ) -> 'cirq.OP_TREE':
49
+ self, indices: Sequence[LogicalIndex], qubits: Sequence[cirq.Qid]
50
+ ) -> Iterator[cirq.OP_TREE]:
50
51
  yield AcquaintanceOperation(qubits, indices)
51
52
 
52
53
 
53
- def get_acquaintance_dag(strategy: 'cirq.Circuit', initial_mapping: LogicalMapping):
54
+ def get_acquaintance_dag(strategy: cirq.Circuit, initial_mapping: LogicalMapping):
54
55
  strategy = strategy.copy()
55
56
  expose_acquaintance_gates(strategy)
56
57
  LogicalAnnotator(initial_mapping)(strategy)
@@ -64,7 +65,7 @@ def get_acquaintance_dag(strategy: 'cirq.Circuit', initial_mapping: LogicalMappi
64
65
 
65
66
 
66
67
  def get_logical_acquaintance_opportunities(
67
- strategy: 'cirq.Circuit', initial_mapping: LogicalMapping
68
+ strategy: cirq.Circuit, initial_mapping: LogicalMapping
68
69
  ) -> Set[FrozenSet[LogicalIndex]]:
69
70
  acquaintance_dag = get_acquaintance_dag(strategy, initial_mapping)
70
71
  logical_acquaintance_opportunities = set()
@@ -12,12 +12,13 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from itertools import product, combinations
15
+ from itertools import combinations, product
16
16
 
17
17
  import pytest
18
18
 
19
19
  import cirq
20
20
  import cirq.contrib.acquaintance as cca
21
+ import cirq.contrib.acquaintance.inspection_utils as inspection_utils
21
22
 
22
23
 
23
24
  @pytest.mark.parametrize('n_qubits, acquaintance_size', product(range(2, 6), range(2, 5)))
@@ -27,3 +28,7 @@ def test_get_logical_acquaintance_opportunities(n_qubits, acquaintance_size):
27
28
  initial_mapping = {q: i for i, q in enumerate(qubits)}
28
29
  opps = cca.get_logical_acquaintance_opportunities(acquaintance_strategy, initial_mapping)
29
30
  assert opps == set(frozenset(s) for s in combinations(range(n_qubits), acquaintance_size))
31
+
32
+
33
+ def test_device():
34
+ assert inspection_utils.LogicalAnnotator({}).device == cirq.UNCONSTRAINED_DEVICE