cirq-core 1.4.0.dev20240529225110__py3-none-any.whl → 1.5.0__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (590) hide show
  1. cirq/__init__.py +587 -569
  2. cirq/_compat.py +9 -0
  3. cirq/_compat_test.py +11 -9
  4. cirq/_import.py +7 -8
  5. cirq/_version.py +31 -1
  6. cirq/_version_test.py +1 -1
  7. cirq/circuits/__init__.py +15 -9
  8. cirq/circuits/_block_diagram_drawer.py +1 -2
  9. cirq/circuits/_block_diagram_drawer_test.py +3 -3
  10. cirq/circuits/_box_drawing_character_data.py +0 -1
  11. cirq/circuits/_box_drawing_character_data_test.py +2 -2
  12. cirq/circuits/_bucket_priority_queue.py +0 -1
  13. cirq/circuits/_bucket_priority_queue_test.py +1 -1
  14. cirq/circuits/circuit.py +336 -234
  15. cirq/circuits/circuit_operation.py +102 -52
  16. cirq/circuits/circuit_operation_test.py +85 -4
  17. cirq/circuits/circuit_test.py +101 -32
  18. cirq/circuits/frozen_circuit.py +36 -32
  19. cirq/circuits/insert_strategy.py +10 -0
  20. cirq/circuits/insert_strategy_test.py +20 -0
  21. cirq/circuits/moment.py +79 -80
  22. cirq/circuits/moment_test.py +105 -2
  23. cirq/circuits/optimization_pass.py +15 -15
  24. cirq/circuits/optimization_pass_test.py +8 -9
  25. cirq/circuits/qasm_output.py +64 -33
  26. cirq/circuits/qasm_output_test.py +63 -2
  27. cirq/circuits/text_diagram_drawer.py +26 -56
  28. cirq/circuits/text_diagram_drawer_test.py +5 -4
  29. cirq/contrib/__init__.py +2 -2
  30. cirq/contrib/acquaintance/__init__.py +44 -29
  31. cirq/contrib/acquaintance/bipartite.py +8 -7
  32. cirq/contrib/acquaintance/bipartite_test.py +11 -1
  33. cirq/contrib/acquaintance/devices.py +5 -4
  34. cirq/contrib/acquaintance/devices_test.py +5 -1
  35. cirq/contrib/acquaintance/executor.py +18 -21
  36. cirq/contrib/acquaintance/executor_test.py +3 -2
  37. cirq/contrib/acquaintance/gates.py +36 -27
  38. cirq/contrib/acquaintance/gates_test.py +1 -1
  39. cirq/contrib/acquaintance/inspection_utils.py +10 -9
  40. cirq/contrib/acquaintance/inspection_utils_test.py +6 -1
  41. cirq/contrib/acquaintance/mutation_utils.py +10 -10
  42. cirq/contrib/acquaintance/optimizers.py +7 -6
  43. cirq/contrib/acquaintance/optimizers_test.py +1 -1
  44. cirq/contrib/acquaintance/permutation.py +22 -21
  45. cirq/contrib/acquaintance/permutation_test.py +1 -1
  46. cirq/contrib/acquaintance/shift.py +8 -6
  47. cirq/contrib/acquaintance/shift_swap_network.py +6 -4
  48. cirq/contrib/acquaintance/strategies/__init__.py +9 -3
  49. cirq/contrib/acquaintance/strategies/complete.py +4 -3
  50. cirq/contrib/acquaintance/strategies/cubic.py +5 -3
  51. cirq/contrib/acquaintance/strategies/quartic_paired.py +8 -6
  52. cirq/contrib/acquaintance/topological_sort.py +4 -2
  53. cirq/contrib/bayesian_network/__init__.py +3 -1
  54. cirq/contrib/bayesian_network/bayesian_network_gate.py +5 -3
  55. cirq/contrib/circuitdag/__init__.py +1 -1
  56. cirq/contrib/circuitdag/circuit_dag.py +24 -24
  57. cirq/contrib/circuitdag/circuit_dag_test.py +1 -1
  58. cirq/contrib/custom_simulators/custom_state_simulator.py +10 -8
  59. cirq/contrib/custom_simulators/custom_state_simulator_test.py +15 -11
  60. cirq/contrib/graph_device/__init__.py +8 -8
  61. cirq/contrib/graph_device/graph_device.py +8 -8
  62. cirq/contrib/graph_device/graph_device_test.py +0 -1
  63. cirq/contrib/graph_device/hypergraph_test.py +1 -0
  64. cirq/contrib/json.py +1 -2
  65. cirq/contrib/json_test.py +2 -2
  66. cirq/contrib/noise_models/__init__.py +5 -6
  67. cirq/contrib/noise_models/noise_models.py +8 -6
  68. cirq/contrib/paulistring/__init__.py +22 -10
  69. cirq/contrib/paulistring/clifford_optimize.py +1 -1
  70. cirq/contrib/paulistring/clifford_optimize_test.py +0 -1
  71. cirq/contrib/paulistring/clifford_target_gateset.py +15 -12
  72. cirq/contrib/paulistring/optimize.py +2 -2
  73. cirq/contrib/paulistring/optimize_test.py +0 -1
  74. cirq/contrib/paulistring/pauli_string_dag_test.py +0 -1
  75. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +379 -0
  76. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +523 -0
  77. cirq/contrib/paulistring/pauli_string_optimize.py +3 -1
  78. cirq/contrib/paulistring/pauli_string_optimize_test.py +1 -3
  79. cirq/contrib/paulistring/recombine.py +2 -2
  80. cirq/contrib/paulistring/recombine_test.py +2 -2
  81. cirq/contrib/paulistring/separate.py +3 -4
  82. cirq/contrib/qasm_import/__init__.py +2 -2
  83. cirq/contrib/qasm_import/_lexer.py +21 -26
  84. cirq/contrib/qasm_import/_lexer_test.py +90 -6
  85. cirq/contrib/qasm_import/_parser.py +238 -47
  86. cirq/contrib/qasm_import/_parser_test.py +514 -59
  87. cirq/contrib/qasm_import/qasm_test.py +1 -1
  88. cirq/contrib/qcircuit/__init__.py +6 -4
  89. cirq/contrib/qcircuit/qcircuit_diagram.py +5 -2
  90. cirq/contrib/qcircuit/qcircuit_pdf.py +1 -2
  91. cirq/{experiments/grid_parallel_two_qubit_xeb_test.py → contrib/qcircuit/qcircuit_pdf_test.py} +13 -12
  92. cirq/contrib/qcircuit/qcircuit_test.py +1 -1
  93. cirq/contrib/quantum_volume/__init__.py +7 -7
  94. cirq/contrib/quantum_volume/quantum_volume.py +6 -11
  95. cirq/contrib/quantum_volume/quantum_volume_test.py +3 -1
  96. cirq/contrib/quimb/__init__.py +16 -13
  97. cirq/contrib/quimb/density_matrix.py +1 -1
  98. cirq/contrib/quimb/mps_simulator.py +27 -28
  99. cirq/contrib/quimb/mps_simulator_test.py +5 -0
  100. cirq/contrib/quimb/state_vector.py +3 -10
  101. cirq/contrib/quirk/__init__.py +1 -1
  102. cirq/contrib/quirk/export_to_quirk.py +3 -3
  103. cirq/contrib/routing/__init__.py +12 -9
  104. cirq/contrib/routing/device.py +1 -1
  105. cirq/contrib/routing/device_test.py +1 -2
  106. cirq/contrib/routing/greedy.py +7 -5
  107. cirq/contrib/routing/greedy_test.py +5 -3
  108. cirq/contrib/routing/initialization.py +3 -1
  109. cirq/contrib/routing/initialization_test.py +1 -1
  110. cirq/contrib/routing/swap_network.py +6 -6
  111. cirq/contrib/routing/utils.py +6 -4
  112. cirq/contrib/routing/utils_test.py +1 -2
  113. cirq/{type_workarounds.py → contrib/shuffle_circuits/__init__.py} +5 -10
  114. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +250 -0
  115. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +363 -0
  116. cirq/contrib/svg/__init__.py +1 -1
  117. cirq/contrib/svg/svg.py +12 -10
  118. cirq/contrib/svg/svg_test.py +3 -2
  119. cirq/devices/__init__.py +34 -25
  120. cirq/devices/device.py +16 -12
  121. cirq/devices/device_test.py +1 -0
  122. cirq/devices/grid_device_metadata.py +16 -12
  123. cirq/devices/grid_device_metadata_test.py +2 -1
  124. cirq/devices/grid_qubit.py +31 -26
  125. cirq/devices/grid_qubit_test.py +30 -1
  126. cirq/devices/insertion_noise_model.py +6 -6
  127. cirq/devices/insertion_noise_model_test.py +1 -1
  128. cirq/devices/line_qubit.py +28 -20
  129. cirq/devices/line_qubit_test.py +26 -0
  130. cirq/devices/named_topologies.py +12 -10
  131. cirq/devices/named_topologies_test.py +5 -4
  132. cirq/devices/noise_model.py +29 -33
  133. cirq/devices/noise_properties.py +2 -2
  134. cirq/devices/noise_properties_test.py +2 -2
  135. cirq/devices/noise_utils.py +3 -3
  136. cirq/devices/superconducting_qubits_noise_properties.py +2 -2
  137. cirq/devices/superconducting_qubits_noise_properties_test.py +3 -3
  138. cirq/devices/thermal_noise_model.py +2 -1
  139. cirq/devices/unconstrained_device.py +1 -1
  140. cirq/devices/unconstrained_device_test.py +6 -0
  141. cirq/experiments/__init__.py +51 -34
  142. cirq/experiments/qubit_characterizations.py +17 -15
  143. cirq/experiments/qubit_characterizations_test.py +4 -6
  144. cirq/experiments/random_quantum_circuit_generation.py +10 -9
  145. cirq/experiments/random_quantum_circuit_generation_test.py +21 -4
  146. cirq/experiments/readout_confusion_matrix.py +73 -8
  147. cirq/experiments/readout_confusion_matrix_test.py +104 -1
  148. cirq/experiments/single_qubit_readout_calibration.py +8 -6
  149. cirq/experiments/single_qubit_readout_calibration_test.py +1 -1
  150. cirq/experiments/t1_decay_experiment.py +4 -5
  151. cirq/experiments/t1_decay_experiment_test.py +1 -2
  152. cirq/experiments/t2_decay_experiment.py +0 -1
  153. cirq/experiments/t2_decay_experiment_test.py +1 -2
  154. cirq/experiments/two_qubit_xeb.py +157 -33
  155. cirq/experiments/two_qubit_xeb_test.py +38 -22
  156. cirq/experiments/xeb_fitting.py +99 -19
  157. cirq/experiments/xeb_fitting_test.py +64 -25
  158. cirq/experiments/xeb_sampling.py +14 -18
  159. cirq/experiments/xeb_simulation.py +4 -3
  160. cirq/experiments/xeb_simulation_test.py +20 -14
  161. cirq/experiments/z_phase_calibration.py +368 -0
  162. cirq/experiments/z_phase_calibration_test.py +241 -0
  163. cirq/interop/__init__.py +4 -1
  164. cirq/interop/quirk/__init__.py +7 -4
  165. cirq/interop/quirk/cells/__init__.py +17 -6
  166. cirq/interop/quirk/cells/arithmetic_cells.py +8 -8
  167. cirq/interop/quirk/cells/arithmetic_cells_test.py +1 -1
  168. cirq/interop/quirk/cells/cell.py +6 -6
  169. cirq/interop/quirk/cells/composite_cell.py +5 -5
  170. cirq/interop/quirk/cells/composite_cell_test.py +1 -1
  171. cirq/interop/quirk/cells/control_cells.py +1 -1
  172. cirq/interop/quirk/cells/frequency_space_cells.py +2 -2
  173. cirq/interop/quirk/cells/ignored_cells.py +1 -1
  174. cirq/interop/quirk/cells/input_cells.py +1 -1
  175. cirq/interop/quirk/cells/input_cells_test.py +1 -1
  176. cirq/interop/quirk/cells/input_rotation_cells.py +1 -1
  177. cirq/interop/quirk/cells/input_rotation_cells_test.py +1 -1
  178. cirq/interop/quirk/cells/measurement_cells.py +1 -1
  179. cirq/interop/quirk/cells/parse.py +8 -7
  180. cirq/interop/quirk/cells/parse_test.py +2 -2
  181. cirq/interop/quirk/cells/single_qubit_rotation_cells.py +1 -1
  182. cirq/interop/quirk/cells/swap_cell_test.py +1 -1
  183. cirq/interop/quirk/cells/unsupported_cells.py +1 -1
  184. cirq/interop/quirk/url_to_circuit.py +7 -7
  185. cirq/interop/quirk/url_to_circuit_test.py +1 -1
  186. cirq/ion/__init__.py +4 -2
  187. cirq/json_resolver_cache.py +15 -7
  188. cirq/linalg/__init__.py +62 -51
  189. cirq/linalg/combinators.py +4 -4
  190. cirq/linalg/combinators_test.py +4 -1
  191. cirq/linalg/decompositions.py +15 -40
  192. cirq/linalg/decompositions_test.py +16 -22
  193. cirq/linalg/diagonalize.py +1 -1
  194. cirq/linalg/diagonalize_test.py +1 -1
  195. cirq/linalg/operator_spaces.py +20 -4
  196. cirq/linalg/operator_spaces_test.py +15 -2
  197. cirq/linalg/predicates.py +3 -3
  198. cirq/linalg/predicates_test.py +1 -0
  199. cirq/linalg/tolerance.py +2 -2
  200. cirq/linalg/transformations.py +30 -12
  201. cirq/linalg/transformations_test.py +13 -0
  202. cirq/neutral_atoms/__init__.py +2 -2
  203. cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +0 -1
  204. cirq/ops/__init__.py +172 -132
  205. cirq/ops/arithmetic_operation.py +2 -2
  206. cirq/ops/arithmetic_operation_test.py +2 -2
  207. cirq/ops/boolean_hamiltonian.py +3 -2
  208. cirq/ops/classically_controlled_operation.py +39 -12
  209. cirq/ops/classically_controlled_operation_test.py +147 -1
  210. cirq/ops/clifford_gate.py +38 -36
  211. cirq/ops/clifford_gate_test.py +75 -1
  212. cirq/ops/common_channels.py +16 -45
  213. cirq/ops/common_channels_test.py +10 -0
  214. cirq/ops/common_gate_families.py +1 -1
  215. cirq/ops/common_gate_families_test.py +1 -0
  216. cirq/ops/common_gates.py +48 -49
  217. cirq/ops/common_gates_test.py +18 -2
  218. cirq/ops/control_values.py +3 -3
  219. cirq/ops/control_values_test.py +2 -1
  220. cirq/ops/controlled_gate.py +36 -23
  221. cirq/ops/controlled_gate_test.py +70 -3
  222. cirq/ops/controlled_operation.py +6 -5
  223. cirq/ops/controlled_operation_test.py +7 -3
  224. cirq/ops/dense_pauli_string.py +11 -11
  225. cirq/ops/diagonal_gate.py +2 -2
  226. cirq/ops/diagonal_gate_test.py +1 -0
  227. cirq/ops/eigen_gate.py +16 -36
  228. cirq/ops/eigen_gate_test.py +60 -10
  229. cirq/ops/fourier_transform.py +1 -3
  230. cirq/ops/fourier_transform_test.py +2 -1
  231. cirq/ops/fsim_gate.py +42 -3
  232. cirq/ops/fsim_gate_test.py +21 -0
  233. cirq/ops/gate_operation.py +8 -8
  234. cirq/ops/gate_operation_test.py +4 -2
  235. cirq/ops/gateset_test.py +11 -2
  236. cirq/ops/global_phase_op.py +8 -7
  237. cirq/ops/global_phase_op_test.py +1 -1
  238. cirq/ops/greedy_qubit_manager_test.py +5 -0
  239. cirq/ops/identity.py +14 -4
  240. cirq/ops/identity_test.py +24 -0
  241. cirq/ops/kraus_channel.py +1 -0
  242. cirq/ops/kraus_channel_test.py +3 -1
  243. cirq/ops/linear_combinations.py +27 -21
  244. cirq/ops/linear_combinations_test.py +23 -4
  245. cirq/ops/matrix_gates.py +24 -8
  246. cirq/ops/measure_util.py +2 -2
  247. cirq/ops/measurement_gate.py +7 -4
  248. cirq/ops/measurement_gate_test.py +2 -1
  249. cirq/ops/mixed_unitary_channel.py +1 -0
  250. cirq/ops/mixed_unitary_channel_test.py +3 -1
  251. cirq/ops/named_qubit.py +8 -1
  252. cirq/ops/op_tree.py +3 -30
  253. cirq/ops/op_tree_test.py +4 -0
  254. cirq/ops/parallel_gate.py +2 -3
  255. cirq/ops/parallel_gate_test.py +2 -1
  256. cirq/ops/parity_gates.py +7 -8
  257. cirq/ops/parity_gates_test.py +1 -0
  258. cirq/ops/pauli_gates.py +5 -11
  259. cirq/ops/pauli_gates_test.py +1 -0
  260. cirq/ops/pauli_interaction_gate.py +11 -5
  261. cirq/ops/pauli_interaction_gate_test.py +2 -3
  262. cirq/ops/pauli_measurement_gate.py +6 -5
  263. cirq/ops/pauli_measurement_gate_test.py +1 -0
  264. cirq/ops/pauli_string.py +115 -130
  265. cirq/ops/pauli_string_phasor.py +21 -20
  266. cirq/ops/pauli_string_phasor_test.py +13 -3
  267. cirq/ops/pauli_string_raw_types.py +1 -0
  268. cirq/ops/pauli_string_test.py +192 -55
  269. cirq/ops/pauli_sum_exponential.py +3 -4
  270. cirq/ops/pauli_sum_exponential_test.py +0 -1
  271. cirq/ops/permutation_gate.py +2 -2
  272. cirq/ops/permutation_gate_test.py +1 -1
  273. cirq/ops/phased_iswap_gate.py +6 -7
  274. cirq/ops/phased_iswap_gate_test.py +21 -5
  275. cirq/ops/phased_x_gate.py +11 -25
  276. cirq/ops/phased_x_gate_test.py +19 -3
  277. cirq/ops/phased_x_z_gate.py +12 -11
  278. cirq/ops/projector.py +4 -5
  279. cirq/ops/qubit_manager.py +2 -1
  280. cirq/ops/qubit_manager_test.py +2 -1
  281. cirq/ops/qubit_order.py +1 -1
  282. cirq/ops/random_gate_channel.py +1 -1
  283. cirq/ops/random_gate_channel_test.py +0 -6
  284. cirq/ops/raw_types.py +146 -50
  285. cirq/ops/raw_types_test.py +37 -3
  286. cirq/ops/state_preparation_channel.py +2 -2
  287. cirq/ops/state_preparation_channel_test.py +2 -1
  288. cirq/ops/swap_gates.py +9 -4
  289. cirq/ops/three_qubit_gates.py +8 -8
  290. cirq/ops/three_qubit_gates_test.py +1 -0
  291. cirq/ops/two_qubit_diagonal_gate.py +4 -3
  292. cirq/ops/uniform_superposition_gate.py +4 -4
  293. cirq/ops/uniform_superposition_gate_test.py +1 -0
  294. cirq/ops/wait_gate.py +6 -8
  295. cirq/protocols/__init__.py +135 -83
  296. cirq/protocols/act_on_protocol.py +1 -1
  297. cirq/protocols/act_on_protocol_test.py +1 -1
  298. cirq/protocols/apply_channel_protocol.py +3 -3
  299. cirq/protocols/apply_mixture_protocol.py +15 -9
  300. cirq/protocols/apply_mixture_protocol_test.py +11 -0
  301. cirq/protocols/apply_unitary_protocol.py +2 -2
  302. cirq/protocols/apply_unitary_protocol_test.py +2 -1
  303. cirq/protocols/approximate_equality_protocol.py +7 -8
  304. cirq/protocols/approximate_equality_protocol_test.py +3 -1
  305. cirq/protocols/circuit_diagram_info_protocol.py +8 -6
  306. cirq/protocols/circuit_diagram_info_protocol_test.py +5 -0
  307. cirq/protocols/commutes_protocol.py +6 -6
  308. cirq/protocols/control_key_protocol.py +1 -1
  309. cirq/protocols/decompose_protocol.py +4 -5
  310. cirq/protocols/decompose_protocol_test.py +2 -1
  311. cirq/protocols/equal_up_to_global_phase_protocol.py +3 -3
  312. cirq/protocols/equal_up_to_global_phase_protocol_test.py +7 -0
  313. cirq/protocols/has_stabilizer_effect_protocol.py +5 -5
  314. cirq/protocols/has_unitary_protocol.py +1 -1
  315. cirq/protocols/has_unitary_protocol_test.py +8 -7
  316. cirq/protocols/hash_from_pickle_test.py +120 -0
  317. cirq/protocols/inverse_protocol.py +1 -1
  318. cirq/protocols/json_serialization.py +14 -1
  319. cirq/protocols/json_serialization_test.py +28 -7
  320. cirq/protocols/json_test_data/BitMaskKeyCondition.json +86 -0
  321. cirq/protocols/json_test_data/BitMaskKeyCondition.repr +7 -0
  322. cirq/protocols/json_test_data/Concat.json +19 -0
  323. cirq/protocols/json_test_data/Concat.repr +1 -0
  324. cirq/protocols/json_test_data/README.md +4 -2
  325. cirq/protocols/json_test_data/SympyCondition.json +60 -15
  326. cirq/protocols/json_test_data/SympyCondition.repr +4 -1
  327. cirq/protocols/json_test_data/_InverseCompositeGate.json +10 -0
  328. cirq/protocols/json_test_data/_InverseCompositeGate.repr +1 -0
  329. cirq/protocols/json_test_data/__init__.py +1 -1
  330. cirq/protocols/json_test_data/sympy.And.json +13 -0
  331. cirq/protocols/json_test_data/sympy.And.repr +1 -0
  332. cirq/protocols/json_test_data/sympy.Indexed.json +18 -0
  333. cirq/protocols/json_test_data/sympy.Indexed.repr +1 -0
  334. cirq/protocols/json_test_data/sympy.IndexedBase.json +9 -0
  335. cirq/protocols/json_test_data/sympy.IndexedBase.repr +1 -0
  336. cirq/protocols/json_test_data/sympy.Not.json +9 -0
  337. cirq/protocols/json_test_data/sympy.Not.repr +1 -0
  338. cirq/protocols/json_test_data/sympy.Or.json +13 -0
  339. cirq/protocols/json_test_data/sympy.Or.repr +1 -0
  340. cirq/protocols/json_test_data/sympy.Xor.json +13 -0
  341. cirq/protocols/json_test_data/sympy.Xor.repr +1 -0
  342. cirq/protocols/kraus_protocol.py +8 -8
  343. cirq/protocols/kraus_protocol_test.py +0 -1
  344. cirq/protocols/measurement_key_protocol.py +1 -1
  345. cirq/protocols/measurement_key_protocol_test.py +7 -7
  346. cirq/protocols/mixture_protocol.py +6 -4
  347. cirq/protocols/mixture_protocol_test.py +21 -13
  348. cirq/protocols/pauli_expansion_protocol.py +1 -0
  349. cirq/protocols/pow_protocol.py +1 -1
  350. cirq/protocols/qasm.py +25 -6
  351. cirq/protocols/qasm_test.py +17 -0
  352. cirq/protocols/qid_shape_protocol.py +2 -2
  353. cirq/protocols/resolve_parameters.py +2 -3
  354. cirq/protocols/resolve_parameters_test.py +2 -1
  355. cirq/protocols/trace_distance_bound.py +1 -1
  356. cirq/protocols/trace_distance_bound_test.py +1 -0
  357. cirq/protocols/unitary_protocol.py +3 -3
  358. cirq/protocols/unitary_protocol_test.py +1 -1
  359. cirq/qis/__init__.py +48 -35
  360. cirq/qis/channels_test.py +0 -9
  361. cirq/qis/clifford_tableau.py +46 -26
  362. cirq/qis/clifford_tableau_test.py +2 -1
  363. cirq/qis/entropy.py +115 -0
  364. cirq/qis/entropy_test.py +43 -0
  365. cirq/qis/measures.py +5 -4
  366. cirq/qis/measures_test.py +7 -0
  367. cirq/qis/noise_utils_test.py +4 -4
  368. cirq/qis/quantum_state_representation.py +1 -1
  369. cirq/qis/states.py +7 -7
  370. cirq/sim/__init__.py +55 -37
  371. cirq/sim/classical_simulator.py +7 -6
  372. cirq/sim/classical_simulator_test.py +3 -1
  373. cirq/sim/clifford/__init__.py +17 -9
  374. cirq/sim/clifford/clifford_simulator.py +5 -4
  375. cirq/sim/clifford/clifford_simulator_test.py +32 -9
  376. cirq/sim/clifford/clifford_tableau_simulation_state.py +1 -1
  377. cirq/sim/clifford/stabilizer_simulation_state.py +1 -1
  378. cirq/sim/clifford/stabilizer_state_ch_form.py +4 -3
  379. cirq/sim/density_matrix_simulator.py +3 -2
  380. cirq/sim/density_matrix_simulator_test.py +12 -4
  381. cirq/sim/density_matrix_utils.py +1 -1
  382. cirq/sim/mux.py +2 -2
  383. cirq/sim/simulation_state.py +4 -5
  384. cirq/sim/simulation_state_base.py +2 -2
  385. cirq/sim/simulation_state_test.py +1 -1
  386. cirq/sim/simulation_utils.py +3 -1
  387. cirq/sim/simulation_utils_test.py +2 -3
  388. cirq/sim/simulator.py +7 -6
  389. cirq/sim/simulator_base.py +5 -5
  390. cirq/sim/simulator_test.py +14 -3
  391. cirq/sim/sparse_simulator.py +4 -3
  392. cirq/sim/sparse_simulator_test.py +17 -9
  393. cirq/sim/state_vector.py +2 -2
  394. cirq/sim/state_vector_simulation_state_test.py +1 -1
  395. cirq/sim/state_vector_simulator.py +4 -4
  396. cirq/sim/state_vector_test.py +27 -32
  397. cirq/study/__init__.py +27 -21
  398. cirq/study/flatten_expressions.py +5 -6
  399. cirq/study/flatten_expressions_test.py +1 -1
  400. cirq/study/resolver.py +14 -11
  401. cirq/study/resolver_test.py +10 -1
  402. cirq/study/result.py +3 -3
  403. cirq/study/sweepable.py +15 -9
  404. cirq/study/sweepable_test.py +27 -0
  405. cirq/study/sweeps.py +65 -10
  406. cirq/study/sweeps_test.py +123 -0
  407. cirq/testing/__init__.py +86 -57
  408. cirq/testing/_compat_test_data/module_a/__init__.py +2 -2
  409. cirq/testing/_compat_test_data/module_a/sub/subsub/__init__.py +1 -1
  410. cirq/testing/circuit_compare.py +3 -4
  411. cirq/testing/circuit_compare_test.py +7 -8
  412. cirq/testing/consistent_act_on.py +3 -3
  413. cirq/testing/consistent_channels_test.py +2 -1
  414. cirq/testing/consistent_controlled_gate_op.py +3 -2
  415. cirq/testing/consistent_controlled_gate_op_test.py +2 -3
  416. cirq/testing/consistent_decomposition.py +1 -1
  417. cirq/testing/consistent_decomposition_test.py +1 -2
  418. cirq/testing/consistent_pauli_expansion_test.py +1 -1
  419. cirq/testing/consistent_phase_by.py +1 -1
  420. cirq/testing/consistent_phase_by_test.py +1 -2
  421. cirq/testing/consistent_protocols.py +11 -11
  422. cirq/testing/consistent_protocols_test.py +4 -5
  423. cirq/testing/consistent_qasm.py +8 -12
  424. cirq/testing/consistent_qasm_test.py +1 -1
  425. cirq/testing/consistent_resolve_parameters.py +2 -1
  426. cirq/testing/consistent_specified_has_unitary_test.py +1 -1
  427. cirq/testing/consistent_unitary.py +3 -1
  428. cirq/testing/consistent_unitary_test.py +3 -3
  429. cirq/testing/devices.py +1 -1
  430. cirq/testing/devices_test.py +1 -0
  431. cirq/testing/equals_tester.py +2 -4
  432. cirq/testing/equals_tester_test.py +6 -5
  433. cirq/testing/equivalent_basis_map.py +1 -0
  434. cirq/testing/equivalent_basis_map_test.py +0 -1
  435. cirq/testing/gate_features_test.py +5 -0
  436. cirq/testing/json.py +4 -4
  437. cirq/testing/lin_alg_utils_test.py +1 -1
  438. cirq/testing/order_tester.py +1 -1
  439. cirq/testing/order_tester_test.py +1 -1
  440. cirq/testing/pytest_utils.py +57 -0
  441. cirq/testing/pytest_utils_test.py +35 -0
  442. cirq/testing/random_circuit.py +2 -2
  443. cirq/testing/random_circuit_test.py +2 -2
  444. cirq/testing/routing_devices_test.py +2 -1
  445. cirq/testing/sample_circuits.py +1 -1
  446. cirq/testing/sample_gates.py +5 -4
  447. cirq/testing/sample_gates_test.py +2 -2
  448. cirq/transformers/__init__.py +101 -82
  449. cirq/transformers/align.py +12 -1
  450. cirq/transformers/align_test.py +13 -0
  451. cirq/transformers/analytical_decompositions/__init__.py +27 -24
  452. cirq/transformers/analytical_decompositions/clifford_decomposition.py +2 -1
  453. cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +1 -1
  454. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +1 -1
  455. cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
  456. cirq/transformers/analytical_decompositions/cphase_to_fsim.py +1 -1
  457. cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +1 -1
  458. cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +2 -2
  459. cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +4 -4
  460. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +99 -24
  461. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +105 -14
  462. cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +1 -1
  463. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +1 -1
  464. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +1 -0
  465. cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +3 -4
  466. cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +1 -1
  467. cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +2 -1
  468. cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -1
  469. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +5 -6
  470. cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +2 -2
  471. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +1 -1
  472. cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +1 -2
  473. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +2 -2
  474. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +2 -2
  475. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -1
  476. cirq/transformers/drop_empty_moments.py +1 -0
  477. cirq/transformers/drop_negligible_operations.py +1 -0
  478. cirq/transformers/dynamical_decoupling.py +255 -43
  479. cirq/transformers/dynamical_decoupling_test.py +730 -17
  480. cirq/transformers/eject_phased_paulis.py +29 -15
  481. cirq/transformers/eject_phased_paulis_test.py +3 -8
  482. cirq/transformers/eject_z.py +3 -2
  483. cirq/transformers/eject_z_test.py +3 -3
  484. cirq/transformers/gauge_compiling/__init__.py +25 -9
  485. cirq/transformers/gauge_compiling/cphase_gauge.py +146 -0
  486. cirq/transformers/gauge_compiling/cphase_gauge_test.py +42 -0
  487. cirq/transformers/gauge_compiling/cz_gauge.py +4 -4
  488. cirq/transformers/gauge_compiling/gauge_compiling.py +245 -6
  489. cirq/transformers/gauge_compiling/gauge_compiling_test.py +107 -2
  490. cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +39 -2
  491. cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +10 -1
  492. cirq/transformers/gauge_compiling/iswap_gauge.py +2 -2
  493. cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -2
  494. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +23 -5
  495. cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +3 -2
  496. cirq/transformers/heuristic_decompositions/__init__.py +3 -3
  497. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +2 -1
  498. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +1 -1
  499. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +4 -4
  500. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +4 -4
  501. cirq/transformers/insertion_sort.py +64 -0
  502. cirq/transformers/insertion_sort_test.py +34 -0
  503. cirq/transformers/measurement_transformers.py +14 -1
  504. cirq/transformers/measurement_transformers_test.py +35 -0
  505. cirq/transformers/merge_k_qubit_gates.py +2 -2
  506. cirq/transformers/merge_single_qubit_gates.py +1 -1
  507. cirq/transformers/merge_single_qubit_gates_test.py +1 -1
  508. cirq/transformers/noise_adding.py +115 -0
  509. cirq/transformers/noise_adding_test.py +54 -0
  510. cirq/transformers/optimize_for_target_gateset.py +1 -1
  511. cirq/transformers/optimize_for_target_gateset_test.py +3 -2
  512. cirq/transformers/qubit_management_transformers.py +1 -1
  513. cirq/transformers/randomized_measurements.py +171 -0
  514. cirq/transformers/randomized_measurements_test.py +68 -0
  515. cirq/transformers/routing/__init__.py +14 -5
  516. cirq/transformers/routing/initial_mapper.py +1 -1
  517. cirq/transformers/routing/initial_mapper_test.py +1 -0
  518. cirq/transformers/routing/line_initial_mapper.py +3 -2
  519. cirq/transformers/routing/mapping_manager.py +2 -2
  520. cirq/transformers/routing/mapping_manager_test.py +2 -2
  521. cirq/transformers/routing/route_circuit_cqc.py +3 -2
  522. cirq/transformers/routing/route_circuit_cqc_test.py +2 -1
  523. cirq/transformers/routing/visualize_routed_circuit.py +1 -0
  524. cirq/transformers/routing/visualize_routed_circuit_test.py +1 -0
  525. cirq/transformers/stratify.py +2 -2
  526. cirq/transformers/synchronize_terminal_measurements.py +2 -1
  527. cirq/transformers/target_gatesets/__init__.py +7 -5
  528. cirq/transformers/target_gatesets/compilation_target_gateset.py +16 -3
  529. cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -0
  530. cirq/transformers/target_gatesets/cz_gateset.py +5 -1
  531. cirq/transformers/target_gatesets/cz_gateset_test.py +23 -2
  532. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +1 -1
  533. cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +3 -2
  534. cirq/transformers/transformer_api.py +5 -4
  535. cirq/transformers/transformer_api_test.py +11 -3
  536. cirq/transformers/transformer_primitives.py +9 -31
  537. cirq/transformers/transformer_primitives_test.py +6 -5
  538. cirq/value/__init__.py +51 -30
  539. cirq/value/abc_alt.py +1 -2
  540. cirq/value/angle.py +2 -0
  541. cirq/value/classical_data.py +1 -0
  542. cirq/value/condition.py +149 -3
  543. cirq/value/condition_test.py +254 -0
  544. cirq/value/digits.py +1 -1
  545. cirq/value/duration.py +4 -4
  546. cirq/value/duration_test.py +2 -1
  547. cirq/value/linear_dict.py +85 -24
  548. cirq/value/linear_dict_test.py +94 -3
  549. cirq/value/measurement_key.py +9 -2
  550. cirq/value/periodic_value.py +2 -3
  551. cirq/value/periodic_value_test.py +5 -0
  552. cirq/value/probability.py +1 -0
  553. cirq/value/random_state.py +1 -1
  554. cirq/value/timestamp.py +2 -4
  555. cirq/value/timestamp_test.py +2 -1
  556. cirq/value/type_alias.py +2 -2
  557. cirq/value/value_equality_attr.py +14 -2
  558. cirq/value/value_equality_attr_test.py +1 -1
  559. cirq/vis/__init__.py +9 -6
  560. cirq/vis/density_matrix.py +1 -1
  561. cirq/vis/density_matrix_test.py +2 -5
  562. cirq/vis/heatmap.py +49 -12
  563. cirq/vis/heatmap_test.py +168 -4
  564. cirq/vis/histogram.py +1 -1
  565. cirq/vis/histogram_test.py +1 -2
  566. cirq/vis/state_histogram.py +7 -5
  567. cirq/vis/state_histogram_test.py +2 -2
  568. cirq/work/__init__.py +19 -13
  569. cirq/work/collector.py +2 -2
  570. cirq/work/observable_grouping.py +2 -2
  571. cirq/work/observable_measurement.py +3 -3
  572. cirq/work/observable_measurement_data.py +5 -2
  573. cirq/work/observable_measurement_test.py +8 -8
  574. cirq/work/observable_readout_calibration.py +2 -2
  575. cirq/work/observable_readout_calibration_test.py +2 -1
  576. cirq/work/observable_settings.py +8 -7
  577. cirq/work/observable_settings_test.py +3 -2
  578. cirq/work/pauli_sum_collector.py +1 -1
  579. cirq/work/sampler.py +8 -20
  580. cirq/work/sampler_test.py +4 -3
  581. cirq/work/zeros_sampler.py +1 -1
  582. cirq_core-1.5.0.dist-info/METADATA +125 -0
  583. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/RECORD +586 -552
  584. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/WHEEL +1 -1
  585. cirq/experiments/grid_parallel_two_qubit_xeb.py +0 -62
  586. cirq/protocols/json_test_data/GridParallelXEBMetadata.json +0 -119
  587. cirq/protocols/json_test_data/GridParallelXEBMetadata.repr +0 -1
  588. cirq_core-1.4.0.dev20240529225110.dist-info/METADATA +0 -50
  589. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/LICENSE +0 -0
  590. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/top_level.txt +0 -0
@@ -12,26 +12,59 @@
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, Union
15
+ from typing import Sequence, Tuple, Union
16
+
17
+ import numpy as np
18
+ import pytest
19
+
16
20
  import cirq
17
21
  from cirq import add_dynamical_decoupling
18
- import pytest
22
+
23
+
24
+ def assert_sim_eq(circuit1: 'cirq.AbstractCircuit', circuit2: 'cirq.AbstractCircuit'):
25
+ # Simulate 2 circuits and compare final states.
26
+ sampler = cirq.Simulator(dtype=np.complex128)
27
+ psi0 = sampler.simulate(cirq.drop_terminal_measurements(circuit1)).final_state_vector
28
+ psi1 = sampler.simulate(cirq.drop_terminal_measurements(circuit2)).final_state_vector
29
+
30
+ assert np.isclose(np.abs(np.vdot(psi0, psi1)) ** 2, 1.0)
19
31
 
20
32
 
21
33
  def assert_dd(
22
- input_circuit: cirq.Circuit,
23
- expected_circuit: cirq.Circuit,
24
- schema: Union[str, Sequence['cirq.Gate']],
34
+ input_circuit: 'cirq.AbstractCircuit',
35
+ expected_circuit: Union[str, 'cirq.AbstractCircuit'],
36
+ schema: Union[str, Tuple['cirq.Gate', ...]] = 'DEFAULT',
37
+ single_qubit_gate_moments_only: bool = True,
25
38
  ):
26
- updated_circuit = add_dynamical_decoupling(input_circuit, schema=schema)
27
- cirq.testing.assert_same_circuits(updated_circuit, expected_circuit)
39
+ transformed_circuit = add_dynamical_decoupling(
40
+ input_circuit, schema=schema, single_qubit_gate_moments_only=single_qubit_gate_moments_only
41
+ ).freeze()
42
+ if isinstance(expected_circuit, str):
43
+ cirq.testing.assert_has_diagram(transformed_circuit, expected_circuit)
44
+ else:
45
+ cirq.testing.assert_same_circuits(transformed_circuit, expected_circuit)
46
+ cirq.testing.assert_circuits_have_same_unitary_given_final_permutation(
47
+ cirq.drop_terminal_measurements(input_circuit),
48
+ cirq.drop_terminal_measurements(transformed_circuit),
49
+ {q: q for q in input_circuit.all_qubits()},
50
+ )
51
+ assert_sim_eq(input_circuit, transformed_circuit)
28
52
 
29
53
 
30
- def test_no_insert_due_to_no_consecutive_moments():
54
+ def test_no_insertion():
55
+ """Test case diagrams.
56
+ Input:
57
+ a: ───H───@───────
58
+
59
+ b: ───────X───H───
60
+ Output:
61
+ a: ───H───@───────
62
+
63
+ b: ───────X───H───
64
+ """
31
65
  a = cirq.NamedQubit('a')
32
66
  b = cirq.NamedQubit('b')
33
67
 
34
- # No insertion as there is no room for a dd sequence.
35
68
  assert_dd(
36
69
  input_circuit=cirq.Circuit(
37
70
  cirq.Moment(cirq.H(a)), cirq.Moment(cirq.CNOT(a, b)), cirq.Moment(cirq.H(b))
@@ -40,6 +73,7 @@ def test_no_insert_due_to_no_consecutive_moments():
40
73
  cirq.Moment(cirq.H(a)), cirq.Moment(cirq.CNOT(a, b)), cirq.Moment(cirq.H(b))
41
74
  ),
42
75
  schema='XX_PAIR',
76
+ single_qubit_gate_moments_only=False,
43
77
  )
44
78
 
45
79
 
@@ -53,6 +87,14 @@ def test_no_insert_due_to_no_consecutive_moments():
53
87
  ],
54
88
  )
55
89
  def test_insert_provided_schema(schema: str, inserted_gates: Sequence['cirq.Gate']):
90
+ """Test case diagrams.
91
+ Input:
92
+ a: ───H───@───────────M───
93
+
94
+ b: ───────X───@───@───M───
95
+ │ │
96
+ c: ───────────X───X───M───
97
+ """
56
98
  a = cirq.NamedQubit('a')
57
99
  b = cirq.NamedQubit('b')
58
100
  c = cirq.NamedQubit('c')
@@ -62,21 +104,35 @@ def test_insert_provided_schema(schema: str, inserted_gates: Sequence['cirq.Gate
62
104
  cirq.Moment(cirq.CNOT(a, b)),
63
105
  cirq.Moment(cirq.CNOT(b, c)),
64
106
  cirq.Moment(cirq.CNOT(b, c)),
65
- cirq.Moment(cirq.measure_each(a, b, c)),
107
+ cirq.Moment([cirq.M(qubit) for qubit in [a, b, c]]),
66
108
  )
67
109
  expected_circuit = cirq.Circuit(
68
110
  cirq.Moment(cirq.H(a)),
69
111
  cirq.Moment(cirq.CNOT(a, b)),
70
112
  cirq.Moment(cirq.CNOT(b, c), inserted_gates[0](a)),
71
113
  cirq.Moment(cirq.CNOT(b, c), inserted_gates[1](a)),
72
- cirq.Moment(cirq.measure_each(a, b, c)),
114
+ cirq.Moment([cirq.M(qubit) for qubit in [a, b, c]]),
73
115
  )
74
116
 
75
117
  # Insert one dynamical decoupling sequence in idle moments.
76
- assert_dd(input_circuit, expected_circuit, schema=schema)
118
+ assert_dd(input_circuit, expected_circuit, schema=schema, single_qubit_gate_moments_only=False)
77
119
 
78
120
 
79
121
  def test_insert_by_customized_dd_sequence():
122
+ """Test case diagrams.
123
+ Input:
124
+ a: ───H───@───────────────────H───
125
+
126
+ b: ───────X───@───@───@───@───H───
127
+ │ │ │ │
128
+ c: ───────────X───X───X───X───H───
129
+ Output:
130
+ a: ───H───@───X───X───Y───Y───H───
131
+
132
+ b: ───────X───@───@───@───@───H───
133
+ │ │ │ │
134
+ c: ───────────X───X───X───X───H───
135
+ """
80
136
  a = cirq.NamedQubit('a')
81
137
  b = cirq.NamedQubit('b')
82
138
  c = cirq.NamedQubit('c')
@@ -89,7 +145,7 @@ def test_insert_by_customized_dd_sequence():
89
145
  cirq.Moment(cirq.CNOT(b, c)),
90
146
  cirq.Moment(cirq.CNOT(b, c)),
91
147
  cirq.Moment(cirq.CNOT(b, c)),
92
- cirq.Moment(cirq.measure_each(a, b, c)),
148
+ cirq.Moment([cirq.H(qubit) for qubit in [a, b, c]]),
93
149
  ),
94
150
  expected_circuit=cirq.Circuit(
95
151
  cirq.Moment(cirq.H(a)),
@@ -98,9 +154,84 @@ def test_insert_by_customized_dd_sequence():
98
154
  cirq.Moment(cirq.CNOT(b, c), cirq.X(a)),
99
155
  cirq.Moment(cirq.CNOT(b, c), cirq.Y(a)),
100
156
  cirq.Moment(cirq.CNOT(b, c), cirq.Y(a)),
101
- cirq.Moment(cirq.measure_each(a, b, c)),
157
+ cirq.Moment([cirq.H(qubit) for qubit in [a, b, c]]),
102
158
  ),
103
159
  schema=[cirq.X, cirq.X, cirq.Y, cirq.Y],
160
+ single_qubit_gate_moments_only=False,
161
+ )
162
+
163
+
164
+ @pytest.mark.parametrize('single_qubit_gate_moments_only', [True, False])
165
+ def test_pull_through_h_gate_case1(single_qubit_gate_moments_only: bool):
166
+ """Test case diagrams.
167
+ Input:
168
+ a: ───H───────H───────@───
169
+
170
+ b: ───H───H───H───H───X───
171
+ Output:
172
+ a: ───H───X───H───X───@───Y───
173
+
174
+ b: ───H───H───H───H───X───X───
175
+ """
176
+ a = cirq.NamedQubit('a')
177
+ b = cirq.NamedQubit('b')
178
+
179
+ assert_dd(
180
+ input_circuit=cirq.Circuit(
181
+ cirq.Moment(cirq.H(a), cirq.H(b)),
182
+ cirq.Moment(cirq.H(b)),
183
+ cirq.Moment(cirq.H(a), cirq.H(b)),
184
+ cirq.Moment(cirq.H(b)),
185
+ cirq.Moment(cirq.CNOT(a, b)),
186
+ ),
187
+ expected_circuit=cirq.Circuit(
188
+ cirq.Moment(cirq.H(a), cirq.H(b)),
189
+ cirq.Moment(cirq.H(b), cirq.X(a)),
190
+ cirq.Moment(cirq.H(a), cirq.H(b)),
191
+ cirq.Moment(cirq.H(b), cirq.X(a)),
192
+ cirq.Moment(cirq.CNOT(a, b)),
193
+ cirq.Moment(cirq.Y(a), cirq.X(b)),
194
+ ),
195
+ schema="XX_PAIR",
196
+ single_qubit_gate_moments_only=single_qubit_gate_moments_only,
197
+ )
198
+
199
+
200
+ @pytest.mark.parametrize('single_qubit_gate_moments_only', [True, False])
201
+ def test_pull_through_h_gate_case2(single_qubit_gate_moments_only: bool):
202
+ """Test case diagrams.
203
+ Input:
204
+ a: ───H───────H───────H───
205
+
206
+ b: ───H───H───H───H───H───
207
+ Output:
208
+ a: ───H───X───H───X───PhXZ(a=0.5,x=0.5,z=1)───
209
+
210
+ b: ───H───H───H───H───H───────────────────────
211
+ """
212
+ a = cirq.NamedQubit('a')
213
+ b = cirq.NamedQubit('b')
214
+
215
+ assert_dd(
216
+ input_circuit=cirq.Circuit(
217
+ cirq.Moment(cirq.H(a), cirq.H(b)),
218
+ cirq.Moment(cirq.H(b)),
219
+ cirq.Moment(cirq.H(a), cirq.H(b)),
220
+ cirq.Moment(cirq.H(b)),
221
+ cirq.Moment(cirq.H(a), cirq.H(b)),
222
+ ),
223
+ expected_circuit=cirq.Circuit(
224
+ cirq.Moment(cirq.H(a), cirq.H(b)),
225
+ cirq.Moment(cirq.H(b), cirq.X(a)),
226
+ cirq.Moment(cirq.H(a), cirq.H(b)),
227
+ cirq.Moment(cirq.H(b), cirq.X(a)),
228
+ cirq.Moment(
229
+ cirq.PhasedXZGate(axis_phase_exponent=0.5, x_exponent=0.5, z_exponent=1).on(a),
230
+ cirq.H(b),
231
+ ),
232
+ ),
233
+ schema="XX_PAIR",
234
+ single_qubit_gate_moments_only=single_qubit_gate_moments_only,
104
235
  )
105
236
 
106
237
 
@@ -110,14 +241,596 @@ def test_insert_by_customized_dd_sequence():
110
241
  ('INVALID_SCHEMA', 'Invalid schema name.'),
111
242
  ([cirq.X], 'Invalid dynamical decoupling sequence. Expect more than one gates.'),
112
243
  (
113
- [cirq.X, cirq.H],
244
+ [cirq.X, cirq.Y],
114
245
  'Invalid dynamical decoupling sequence. Expect sequence production equals identity'
115
246
  ' up to a global phase, got',
116
247
  ),
248
+ (
249
+ [cirq.H, cirq.H],
250
+ 'Dynamical decoupling sequence should only contain gates that are essentially'
251
+ ' Pauli gates.',
252
+ ),
117
253
  ],
118
254
  )
119
- def test_invalid_dd_schema(schema: Union[str, Sequence['cirq.Gate']], error_msg_regex):
255
+ def test_invalid_dd_schema(schema: Union[str, Tuple['cirq.Gate', ...]], error_msg_regex):
120
256
  a = cirq.NamedQubit('a')
121
257
  input_circuit = cirq.Circuit(cirq.H(a))
122
258
  with pytest.raises(ValueError, match=error_msg_regex):
123
- add_dynamical_decoupling(input_circuit, schema=schema)
259
+ add_dynamical_decoupling(input_circuit, schema=schema, single_qubit_gate_moments_only=False)
260
+
261
+
262
+ def test_single_qubit_gate_moments_only_no_updates_succeeds():
263
+ qubits = cirq.LineQubit.range(9)
264
+ input_circuit = cirq.Circuit(
265
+ cirq.Moment([cirq.H(qubits[i]) for i in [3, 4, 5]]),
266
+ cirq.Moment(cirq.CZ(*qubits[4:6])),
267
+ cirq.Moment(cirq.CZ(*qubits[3:5])),
268
+ cirq.Moment([cirq.H(qubits[i]) for i in [2, 3, 5, 6]]),
269
+ cirq.Moment(cirq.CZ(*qubits[2:4]), cirq.CNOT(*qubits[5:7])),
270
+ cirq.Moment([cirq.H(qubits[i]) for i in [1, 2, 6, 7]]),
271
+ cirq.Moment(cirq.CZ(*qubits[1:3]), cirq.CNOT(*qubits[6:8])),
272
+ cirq.Moment([cirq.H(qubits[i]) for i in [0, 1, 7, 8]]),
273
+ cirq.Moment(cirq.CZ(*qubits[0:2]), cirq.CNOT(*qubits[7:])),
274
+ )
275
+ add_dynamical_decoupling(input_circuit, schema='X_XINV', single_qubit_gate_moments_only=True)
276
+
277
+
278
+ def test_scattered_circuit():
279
+ """Test case diagrams.
280
+ Input:
281
+ 0: ───────────────────────────────H───@───H───
282
+
283
+ 1: ───────────────────────H───@───H───@───H───
284
+
285
+ 2: ───────────────H───@───H───@───────────H───
286
+
287
+ 3: ───H───────@───H───@───────────────────H───
288
+
289
+ 4: ───H───@───@───────────────────────────H───
290
+
291
+ 5: ───H───@───────H───@───────────────────H───
292
+
293
+ 6: ───────────────H───@───H───@───────────H───
294
+
295
+ 7: ───────────────────────H───@───H───@───H───
296
+
297
+ 8: ───────────────────────────────H───@───H───
298
+
299
+ Output (single_qubit_gate_moment_only_on):
300
+ 0: ───────────────────────────────H───@───H────────────────────────
301
+
302
+ 1: ───────────────────────H───@───H───@───H────────────────────────
303
+
304
+ 2: ───────────────H───@───H───@───X───────PhXZ(a=-0.5,x=0.5,z=0)───
305
+
306
+ 3: ───H───────@───H───@───X───────Y───────PhXZ(a=0.5,x=0.5,z=0)────
307
+
308
+ 4: ───H───@───@───X───────Y───────X───────PhXZ(a=0.5,x=0.5,z=-1)───
309
+
310
+ 5: ───H───@───────H───@───X───────Y───────PhXZ(a=0.5,x=0.5,z=0)────
311
+
312
+ 6: ───────────────H───@───H───@───X───────PhXZ(a=-0.5,x=0.5,z=0)───
313
+
314
+ 7: ───────────────────────H───@───H───@───H────────────────────────
315
+
316
+ 8: ───────────────────────────────H───@───H────────────────────────
317
+
318
+ Output (single_qubit_gate_moment_only_off):
319
+ 0: ───────────────────────────────H───@───H───────────────────────
320
+
321
+ 1: ───────────────────────H───@───H───@───H───────────────────────
322
+
323
+ 2: ───────────────H───@───H───@───X───Y───PhXZ(a=0.5,x=0.5,z=0)───
324
+
325
+ 3: ───H───X───@───H───@───Y───X───Y───X───PhXZ(a=0.5,x=0.5,z=0)───
326
+
327
+ 4: ───H───@───@───X───Y───X───Y───X───Y───H───────────────────────
328
+
329
+ 5: ───H───@───X───H───@───Y───X───Y───X───PhXZ(a=0.5,x=0.5,z=0)───
330
+
331
+ 6: ───────────────H───@───H───@───X───Y───PhXZ(a=0.5,x=0.5,z=0)───
332
+
333
+ 7: ───────────────────────H───@───H───@───H───────────────────────
334
+
335
+ 8: ───────────────────────────────H───@───H───────────────────────
336
+ """
337
+ qubits = cirq.LineQubit.range(9)
338
+ input_circuit = cirq.Circuit(
339
+ cirq.Moment([cirq.H(qubits[i]) for i in [3, 4, 5]]),
340
+ cirq.Moment(cirq.CZ(*qubits[4:6])),
341
+ cirq.Moment(cirq.CZ(*qubits[3:5])),
342
+ cirq.Moment([cirq.H(qubits[i]) for i in [2, 3, 5, 6]]),
343
+ cirq.Moment(cirq.CZ(*qubits[2:4]), cirq.CZ(*qubits[5:7])),
344
+ cirq.Moment([cirq.H(qubits[i]) for i in [1, 2, 6, 7]]),
345
+ cirq.Moment(cirq.CZ(*qubits[1:3]), cirq.CZ(*qubits[6:8])),
346
+ cirq.Moment([cirq.H(qubits[i]) for i in [0, 1, 7, 8]]),
347
+ cirq.Moment(cirq.CZ(*qubits[0:2]), cirq.CZ(*qubits[7:])),
348
+ cirq.Moment([cirq.H(q) for q in qubits]),
349
+ )
350
+ expected_circuit_single_qubit_gate_on = cirq.Circuit(
351
+ cirq.Moment([cirq.H(qubits[i]) for i in [3, 4, 5]]),
352
+ cirq.Moment(cirq.CZ(*qubits[4:6])),
353
+ cirq.Moment(cirq.CZ(*qubits[3:5])),
354
+ cirq.Moment([cirq.H(qubits[i]) for i in [2, 3, 5, 6]] + [cirq.X(qubits[4])]),
355
+ cirq.Moment(cirq.CZ(*qubits[2:4]), cirq.CZ(*qubits[5:7])),
356
+ cirq.Moment(
357
+ [cirq.H(qubits[i]) for i in [1, 2, 6, 7]]
358
+ + [cirq.X(qubits[i]) for i in [3, 5]]
359
+ + [cirq.Y(qubits[4])]
360
+ ),
361
+ cirq.Moment(cirq.CZ(*qubits[1:3]), cirq.CZ(*qubits[6:8])),
362
+ cirq.Moment(
363
+ [cirq.H(qubits[i]) for i in [0, 1, 7, 8]]
364
+ + [cirq.X(qubits[i]) for i in [2, 4, 6]]
365
+ + [cirq.Y(qubits[i]) for i in [3, 5]]
366
+ ),
367
+ cirq.Moment(cirq.CZ(*qubits[0:2]), cirq.CZ(*qubits[7:])),
368
+ cirq.Moment(
369
+ [cirq.H(qubits[i]) for i in [0, 1, 7, 8]]
370
+ + [
371
+ cirq.PhasedXZGate(axis_phase_exponent=-0.5, x_exponent=0.5, z_exponent=0).on(
372
+ qubits[2]
373
+ ),
374
+ cirq.PhasedXZGate(axis_phase_exponent=0.5, x_exponent=0.5, z_exponent=0).on(
375
+ qubits[3]
376
+ ),
377
+ cirq.PhasedXZGate(axis_phase_exponent=0.5, x_exponent=0.5, z_exponent=-1).on(
378
+ qubits[4]
379
+ ),
380
+ cirq.PhasedXZGate(axis_phase_exponent=0.5, x_exponent=0.5, z_exponent=0).on(
381
+ qubits[5]
382
+ ),
383
+ cirq.PhasedXZGate(axis_phase_exponent=-0.5, x_exponent=0.5, z_exponent=0).on(
384
+ qubits[6]
385
+ ),
386
+ ]
387
+ ),
388
+ )
389
+ expected_circuit_single_qubit_gates_off = cirq.Circuit(
390
+ cirq.Moment([cirq.H(qubits[i]) for i in [3, 4, 5]]),
391
+ cirq.Moment(cirq.CZ(*qubits[4:6]), cirq.X(qubits[3])),
392
+ cirq.Moment(cirq.CZ(*qubits[3:5]), cirq.X(qubits[5])),
393
+ cirq.Moment([cirq.H(qubits[i]) for i in [2, 3, 5, 6]] + [cirq.X(qubits[i]) for i in [4]]),
394
+ cirq.Moment(cirq.CZ(*qubits[2:4]), cirq.CZ(*qubits[5:7]), cirq.Y(qubits[4])),
395
+ cirq.Moment(
396
+ [cirq.H(qubits[i]) for i in [1, 2, 6, 7]]
397
+ + [cirq.Y(qubits[i]) for i in [3, 5]]
398
+ + [cirq.X(qubits[4])]
399
+ ),
400
+ cirq.Moment(
401
+ [cirq.CZ(*qubits[1:3]), cirq.CZ(*qubits[6:8])]
402
+ + [cirq.X(qubits[i]) for i in [3, 5]]
403
+ + [cirq.Y(qubits[4])]
404
+ ),
405
+ cirq.Moment(
406
+ [cirq.H(qubits[i]) for i in [0, 1, 7, 8]]
407
+ + [cirq.X(qubits[i]) for i in [2, 4, 6]]
408
+ + [cirq.Y(qubits[i]) for i in [3, 5]]
409
+ ),
410
+ cirq.Moment(
411
+ [cirq.CZ(*qubits[0:2]), cirq.CZ(*qubits[7:])]
412
+ + [cirq.X(qubits[i]) for i in [3, 5]]
413
+ + [cirq.Y(qubits[i]) for i in [2, 4, 6]]
414
+ ),
415
+ cirq.Moment(
416
+ [cirq.H(qubits[i]) for i in [0, 1, 4, 7, 8]]
417
+ + [
418
+ cirq.PhasedXZGate(axis_phase_exponent=0.5, x_exponent=0.5, z_exponent=0).on(
419
+ qubits[i]
420
+ )
421
+ for i in [2, 3, 5, 6]
422
+ ]
423
+ ),
424
+ )
425
+ assert_dd(
426
+ input_circuit,
427
+ expected_circuit_single_qubit_gate_on,
428
+ schema='DEFAULT',
429
+ single_qubit_gate_moments_only=True,
430
+ )
431
+ assert_dd(
432
+ input_circuit,
433
+ expected_circuit_single_qubit_gates_off,
434
+ schema='DEFAULT',
435
+ single_qubit_gate_moments_only=False,
436
+ )
437
+
438
+
439
+ def test_scattered_circuit2():
440
+ """Test case diagrams.
441
+ Input:
442
+ 0: ───────────────────@───
443
+
444
+ 1: ───────────────@───@───
445
+
446
+ 2: ───────────@───@───────
447
+
448
+ 3: ───────@───@───────────
449
+
450
+ 4: ───@───@───────────────
451
+
452
+ 5: ───@───────@───────────
453
+
454
+ 6: ───────────@───@───────
455
+
456
+ 7: ───────────────@───@───
457
+
458
+ 8: ───────────────────@───
459
+ Output:
460
+ 0: ───────────────────@───
461
+
462
+ 1: ───────────────@───@───
463
+
464
+ 2: ───────────@───@───────
465
+
466
+ 3: ───────@───@───────────
467
+
468
+ 4: ───@───@───────────────
469
+
470
+ 5: ───@───X───@───X───────
471
+
472
+ 6: ───────────@───@───Z───
473
+
474
+ 7: ───────────────@───@───
475
+
476
+ 8: ───────────────────@───
477
+ """
478
+ qubits = cirq.LineQubit.range(9)
479
+ assert_dd(
480
+ input_circuit=cirq.Circuit(
481
+ cirq.Moment(cirq.CZ(*qubits[4:6])),
482
+ cirq.Moment(cirq.CZ(*qubits[3:5])),
483
+ cirq.Moment(cirq.CZ(*qubits[2:4]), cirq.CZ(*qubits[5:7])),
484
+ cirq.Moment(cirq.CZ(*qubits[1:3]), cirq.CZ(*qubits[6:8])),
485
+ cirq.Moment(cirq.CZ(*qubits[0:2]), cirq.CZ(*qubits[7:])),
486
+ ),
487
+ expected_circuit=cirq.Circuit(
488
+ cirq.Moment(cirq.CZ(*qubits[4:6])),
489
+ cirq.Moment(cirq.CZ(*qubits[3:5]), cirq.X(qubits[5])),
490
+ cirq.Moment(cirq.CZ(*qubits[2:4]), cirq.CZ(*qubits[5:7])),
491
+ cirq.Moment(cirq.CZ(*qubits[1:3]), cirq.CZ(*qubits[6:8]), cirq.X(qubits[5])),
492
+ cirq.Moment(cirq.CZ(*qubits[0:2]), cirq.CZ(*qubits[7:]), cirq.Z(qubits[6])),
493
+ ),
494
+ schema="XX_PAIR",
495
+ single_qubit_gate_moments_only=False,
496
+ )
497
+
498
+
499
+ def test_pull_through_chain():
500
+ """Test case diagrams.
501
+ Input:
502
+ 0: ───X───────×───────────X───
503
+
504
+ 1: ───────Y───×───×───────X───
505
+
506
+ 2: ───────────────×───×───X───
507
+
508
+ 3: ───────────────────×───X───
509
+ Output:
510
+ 0: ───X───X───×───X───X───X───
511
+
512
+ 1: ───────Y───×───×───X───I───
513
+
514
+ 2: ───────────────×───×───X───
515
+
516
+ 3: ───────────────────×───I───
517
+ """
518
+ qubits = cirq.LineQubit.range(4)
519
+ assert_dd(
520
+ input_circuit=cirq.Circuit(
521
+ cirq.Moment(cirq.X(qubits[0])),
522
+ cirq.Moment(cirq.Y(qubits[1])),
523
+ cirq.Moment(cirq.SWAP(*qubits[0:2])),
524
+ cirq.Moment(cirq.SWAP(*qubits[1:3])),
525
+ cirq.Moment(cirq.SWAP(*qubits[2:4])),
526
+ cirq.Moment([cirq.X(qubits[i]) for i in range(4)]),
527
+ ),
528
+ expected_circuit=cirq.Circuit(
529
+ cirq.Moment(cirq.X(qubits[0])),
530
+ cirq.Moment(cirq.Y(qubits[1]), cirq.X(qubits[0])),
531
+ cirq.Moment(cirq.SWAP(*qubits[0:2])),
532
+ cirq.Moment([cirq.SWAP(*qubits[1:3])] + [cirq.X(qubits[0])]),
533
+ cirq.Moment([cirq.SWAP(*qubits[2:4])] + [cirq.X(qubits[0]), cirq.X(qubits[1])]),
534
+ cirq.Moment(cirq.X(qubits[0]), cirq.I(qubits[1]), cirq.X(qubits[2]), cirq.I(qubits[3])),
535
+ ),
536
+ schema='XX_PAIR',
537
+ single_qubit_gate_moments_only=False,
538
+ )
539
+
540
+
541
+ def test_multiple_clifford_pieces_case1():
542
+ """Test case diagrams.
543
+ Input:
544
+ a: ───H───────H───────@───────────H───────H───
545
+
546
+ b: ───H───H───H───H───@^0.5───H───H───H───H───
547
+ Output:
548
+ a: ───H───X───H───PhXZ(a=0.5,x=0,z=-1)───@───────X───H───X───PhXZ(a=0.5,x=0.5,z=-1)───
549
+
550
+ b: ───H───H───H───H──────────────────────@^0.5───H───H───H───H────────────────────────
551
+ """
552
+ a = cirq.NamedQubit('a')
553
+ b = cirq.NamedQubit('b')
554
+ assert_dd(
555
+ input_circuit=cirq.Circuit(
556
+ cirq.Moment(cirq.H(a), cirq.H(b)),
557
+ cirq.Moment(cirq.H(b)),
558
+ cirq.Moment(cirq.H(a), cirq.H(b)),
559
+ cirq.Moment(cirq.H(b)),
560
+ cirq.Moment(cirq.CZPowGate(exponent=0.5).on(a, b)),
561
+ cirq.Moment(cirq.H(b)),
562
+ cirq.Moment(cirq.H(a), cirq.H(b)),
563
+ cirq.Moment(cirq.H(b)),
564
+ cirq.Moment(cirq.H(a), cirq.H(b)),
565
+ ),
566
+ expected_circuit=cirq.Circuit(
567
+ cirq.Moment(cirq.H(a), cirq.H(b)),
568
+ cirq.Moment(cirq.H(b), cirq.X(a)),
569
+ cirq.Moment(cirq.H(a), cirq.H(b)),
570
+ cirq.Moment(
571
+ cirq.H(b),
572
+ cirq.PhasedXZGate(axis_phase_exponent=0.5, x_exponent=0, z_exponent=-1).on(a),
573
+ ),
574
+ cirq.Moment(cirq.CZPowGate(exponent=0.5).on(a, b)),
575
+ cirq.Moment(cirq.H(b), cirq.X(a)),
576
+ cirq.Moment(cirq.H(a), cirq.H(b)),
577
+ cirq.Moment(cirq.H(b), cirq.X(a)),
578
+ cirq.Moment(
579
+ cirq.H(b),
580
+ cirq.PhasedXZGate(axis_phase_exponent=0.5, x_exponent=0.5, z_exponent=-1).on(a),
581
+ ),
582
+ ),
583
+ schema="XX_PAIR",
584
+ )
585
+
586
+
587
+ def test_multiple_clifford_pieces_case2():
588
+ """Test case diagrams.
589
+ Input:
590
+ a: ───@───PhXZ(a=0.3,x=0.2,z=0)───PhXZ(a=0.3,x=0.2,z=0)───PhXZ(a=0.3,x=0.2,z=0)───@───
591
+ │ │
592
+ b: ───@───────────────────────────────────────────────────────────────────────────@───
593
+ Output:
594
+ a: ───@───PhXZ(a=0.3,x=0.2,z=0)───PhXZ(a=0.3,x=0.2,z=0)───PhXZ(a=0.3,x=0.2,z=0)───@───Z───
595
+ │ │
596
+ b: ───@───X───────────────────────X───────────────────────X───────────────────────@───X───
597
+ """
598
+ a = cirq.NamedQubit('a')
599
+ b = cirq.NamedQubit('b')
600
+ phased_xz_gate = cirq.PhasedXZGate(axis_phase_exponent=0.3, x_exponent=0.2, z_exponent=0)
601
+
602
+ assert_dd(
603
+ input_circuit=cirq.Circuit(
604
+ cirq.Moment(cirq.CZ(a, b)),
605
+ cirq.Moment(phased_xz_gate.on(a)),
606
+ cirq.Moment(phased_xz_gate.on(a)),
607
+ cirq.Moment(phased_xz_gate.on(a)),
608
+ cirq.Moment(cirq.CZ(a, b)),
609
+ ),
610
+ expected_circuit=cirq.Circuit(
611
+ cirq.Moment(cirq.CZ(a, b)),
612
+ cirq.Moment(phased_xz_gate.on(a), cirq.X(b)),
613
+ cirq.Moment(phased_xz_gate.on(a), cirq.X(b)),
614
+ cirq.Moment(phased_xz_gate.on(a), cirq.X(b)),
615
+ cirq.Moment(cirq.CZ(a, b)),
616
+ cirq.Moment(cirq.Z(a), cirq.X(b)),
617
+ ),
618
+ schema='XX_PAIR',
619
+ single_qubit_gate_moments_only=False,
620
+ )
621
+
622
+
623
+ def test_insert_new_moment():
624
+ """Test case diagrams.
625
+ Input:
626
+ a: ───H───────H───@───@───────
627
+ │ │
628
+ b: ───H───H───H───X───@^0.5───
629
+
630
+ c: ───H───────────────H───────
631
+ Output:
632
+ a: ───H───X───H───@───Z───@────────────────────────
633
+ │ │
634
+ b: ───H───H───H───X───────@^0.5────────────────────
635
+
636
+ c: ───H───X───X───────X───PhXZ(a=-0.5,x=0.5,z=0)───
637
+ """
638
+ a = cirq.NamedQubit('a')
639
+ b = cirq.NamedQubit('b')
640
+ c = cirq.NamedQubit('c')
641
+ assert_dd(
642
+ input_circuit=cirq.Circuit(
643
+ cirq.Moment(cirq.H(a), cirq.H(b), cirq.H(c)),
644
+ cirq.Moment(cirq.H(b)),
645
+ cirq.Moment(cirq.H(b), cirq.H(a)),
646
+ cirq.Moment(cirq.CNOT(a, b)),
647
+ cirq.Moment(cirq.CZPowGate(exponent=0.5).on(a, b), cirq.H(c)),
648
+ ),
649
+ expected_circuit=cirq.Circuit(
650
+ cirq.Moment(cirq.H(a), cirq.H(b), cirq.H(c)),
651
+ cirq.Moment(cirq.H(b), cirq.X(a), cirq.X(c)),
652
+ cirq.Moment(cirq.H(a), cirq.H(b), cirq.X(c)),
653
+ cirq.Moment(cirq.CNOT(a, b)),
654
+ cirq.Moment(cirq.Z(a), cirq.X(c)),
655
+ cirq.Moment(
656
+ cirq.CZPowGate(exponent=0.5).on(a, b),
657
+ cirq.PhasedXZGate(axis_phase_exponent=-0.5, x_exponent=0.5, z_exponent=0).on(c),
658
+ ),
659
+ ),
660
+ schema="XX_PAIR",
661
+ )
662
+
663
+
664
+ def test_with_non_clifford_measurements():
665
+ """Test case diagrams.
666
+ Input:
667
+ 0: ───────────H───@───H───M───
668
+
669
+ 1: ───H───@───────@───────M───
670
+
671
+ 2: ───H───@───H───@───────M───
672
+
673
+ 3: ───────────H───@───H───M───
674
+ Output:
675
+ 0: ───────────H───@───PhXZ(a=0.5,x=0.5,z=0)───M───
676
+
677
+ 1: ───H───@───X───@───X───────────────────────M───
678
+
679
+ 2: ───H───@───H───@───I───────────────────────M───
680
+
681
+ 3: ───────────H───@───H───────────────────────M───
682
+ """
683
+ qubits = cirq.LineQubit.range(4)
684
+ assert_dd(
685
+ input_circuit=cirq.Circuit(
686
+ cirq.Moment([cirq.H(qubits[i]) for i in [1, 2]]),
687
+ cirq.Moment(cirq.CZ(*qubits[1:3])),
688
+ cirq.Moment([cirq.H(qubits[i]) for i in [0, 2, 3]]),
689
+ cirq.Moment(cirq.CZ(*qubits[0:2]), cirq.CZ(*qubits[2:])),
690
+ cirq.Moment([cirq.H(qubits[i]) for i in [0, 3]]),
691
+ cirq.Moment([cirq.M(qubits[i]) for i in [0, 1, 2, 3]]),
692
+ ),
693
+ expected_circuit=cirq.Circuit(
694
+ cirq.Moment([cirq.H(qubits[i]) for i in [1, 2]]),
695
+ cirq.Moment(cirq.CZ(*qubits[1:3])),
696
+ cirq.Moment([cirq.H(qubits[i]) for i in [0, 2, 3]] + [cirq.X(qubits[1])]),
697
+ cirq.Moment(cirq.CZ(*qubits[0:2]), cirq.CZ(*qubits[2:])),
698
+ cirq.Moment(
699
+ cirq.H(qubits[3]),
700
+ cirq.I(qubits[2]),
701
+ cirq.X(qubits[1]),
702
+ cirq.PhasedXZGate(axis_phase_exponent=0.5, x_exponent=0.5, z_exponent=0).on(
703
+ qubits[0]
704
+ ),
705
+ ),
706
+ cirq.Moment([cirq.M(qubits[i]) for i in [0, 1, 2, 3]]),
707
+ ),
708
+ schema="XX_PAIR",
709
+ single_qubit_gate_moments_only=True,
710
+ )
711
+
712
+
713
+ def test_cross_clifford_pieces_filling_merge():
714
+ # pylint: disable=line-too-long
715
+ """Test case diagrams.
716
+ Input:
717
+ 0: ─────────────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=0.2,x=0.2,z=0.1)───H───
718
+ │ │
719
+ 1: ─────────────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=0.2,x=0.2,z=0.1)───H───
720
+
721
+ 2: ───PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────────H───
722
+ │ │ │
723
+ 3: ─────────────────────────────┼───PhXZ(a=0.2,x=0.2,z=0.1)───@───────────────────────────────────────────────────@─────────────────────────────H───
724
+
725
+ 4: ─────────────────────────────┼─────────────────────────────@─────────────────────────────────────────────────────────────────────────────────H───
726
+ │ │
727
+ 5: ───PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=0.2,x=0.2,z=0.1)───H───
728
+
729
+ 6: ───────────────────────────────────────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)─────────────────────────────@───PhXZ(a=0.2,x=0.2,z=0.1)───H───
730
+ Output:
731
+
732
+ 0: ─────────────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=0.2,x=0.2,z=0.1)─────H────────────────────────
733
+ │ │
734
+ 1: ─────────────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=0.2,x=0.2,z=0.1)─────H────────────────────────
735
+
736
+ 2: ───PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@───X───────────────────────────PhXZ(a=0.5,x=0.5,z=-1)───
737
+ │ │ │
738
+ 3: ─────────────────────────────┼───PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────X─────────────────────────@───Y───────────────────────────PhXZ(a=0.5,x=0.5,z=0)────
739
+
740
+ 4: ─────────────────────────────┼─────────────────────────────@─────────────────────────X─────────────────────────────Y───────────────────────────PhXZ(a=0.5,x=0.5,z=0)────
741
+ │ │
742
+ 5: ───PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=-0.8,x=0.2,z=-0.9)───H────────────────────────
743
+
744
+ 6: ───────────────────────────────────────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───X─────────────────────────@───PhXZ(a=0.8,x=0.8,z=0.5)─────H────────────────────────
745
+ """
746
+ # pylint: enable
747
+ qubits = cirq.LineQubit.range(7)
748
+ phased_xz_gate = cirq.PhasedXZGate(axis_phase_exponent=0.2, x_exponent=0.2, z_exponent=0.1)
749
+ assert_dd(
750
+ input_circuit=cirq.Circuit(
751
+ cirq.Moment([phased_xz_gate.on(qubits[i]) for i in [2, 5]]),
752
+ cirq.Moment(cirq.CZ(qubits[2], qubits[5])),
753
+ cirq.Moment([phased_xz_gate.on(qubits[i]) for i in [0, 1, 2, 3, 5]]),
754
+ cirq.Moment(
755
+ [cirq.CZ(qubits[i0], qubits[i1]) for i0, i1 in [(0, 1), (2, 3), (4, 5)]]
756
+ + [phased_xz_gate.on(qubits[6])]
757
+ ),
758
+ cirq.Moment([phased_xz_gate.on(qubits[i]) for i in [0, 1, 2, 5]]),
759
+ cirq.Moment([cirq.CZ(qubits[i0], qubits[i1]) for i0, i1 in [(0, 1), (2, 3), (5, 6)]]),
760
+ cirq.Moment([phased_xz_gate.on(qubits[i]) for i in [0, 1, 5, 6]]),
761
+ cirq.Moment([cirq.H.on(q) for q in qubits]),
762
+ ),
763
+ expected_circuit="""
764
+ 0: ─────────────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=0.2,x=0.2,z=0.1)─────H────────────────────────
765
+ │ │
766
+ 1: ─────────────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=0.2,x=0.2,z=0.1)─────H────────────────────────
767
+
768
+ 2: ───PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@───X───────────────────────────PhXZ(a=0.5,x=0.5,z=-1)───
769
+ │ │ │
770
+ 3: ─────────────────────────────┼───PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────X─────────────────────────@───Y───────────────────────────PhXZ(a=0.5,x=0.5,z=0)────
771
+
772
+ 4: ─────────────────────────────┼─────────────────────────────@─────────────────────────X─────────────────────────────Y───────────────────────────PhXZ(a=0.5,x=0.5,z=0)────
773
+ │ │
774
+ 5: ───PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───@───PhXZ(a=-0.8,x=0.2,z=-0.9)───H────────────────────────
775
+
776
+ 6: ───────────────────────────────────────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───X─────────────────────────@───PhXZ(a=0.8,x=0.8,z=0.5)─────H────────────────────────
777
+ """,
778
+ )
779
+
780
+
781
+ def test_pull_through_phxz_gate_case1():
782
+ """Test case diagrams.
783
+ Input:
784
+ a: ───H───────PhXZ(a=0.25,x=-1,z=0)───────@───
785
+
786
+ b: ───H───H───H───────────────────────H───X───
787
+ Output: expected circuit diagram below.
788
+ """
789
+ a = cirq.NamedQubit('a')
790
+ b = cirq.NamedQubit('b')
791
+
792
+ phxz = cirq.PhasedXZGate(axis_phase_exponent=0.25, x_exponent=-1, z_exponent=0)
793
+ assert_dd(
794
+ input_circuit=cirq.Circuit(
795
+ cirq.Moment(cirq.H(a), cirq.H(b)),
796
+ cirq.Moment(cirq.H(b)),
797
+ cirq.Moment(phxz(a), cirq.H(b)),
798
+ cirq.Moment(cirq.H(b)),
799
+ cirq.Moment(cirq.CNOT(a, b)),
800
+ ),
801
+ expected_circuit="""
802
+ a: ───H───X───PhXZ(a=0.25,x=-1,z=0)───X───@───Z───
803
+
804
+ b: ───H───H───H───────────────────────H───X───────
805
+ """,
806
+ schema="XX_PAIR",
807
+ )
808
+
809
+
810
+ def test_pull_through_phxz_gate_case2():
811
+ """Test case diagrams.
812
+ Input:
813
+ a: ───H───────PhXZ(a=0.2,x=-1,z=0)───────@───
814
+
815
+ b: ───H───H───H───────────────────────H───X───
816
+ Output: expected circuit diagram below.
817
+ """
818
+ a = cirq.NamedQubit('a')
819
+ b = cirq.NamedQubit('b')
820
+
821
+ phxz = cirq.PhasedXZGate(axis_phase_exponent=0.2, x_exponent=-1, z_exponent=0)
822
+ assert_dd(
823
+ input_circuit=cirq.Circuit(
824
+ cirq.Moment(cirq.H(a), cirq.H(b)),
825
+ cirq.Moment(cirq.H(b)),
826
+ cirq.Moment(phxz(a), cirq.H(b)),
827
+ cirq.Moment(cirq.H(b)),
828
+ cirq.Moment(cirq.CNOT(a, b)),
829
+ ),
830
+ expected_circuit="""
831
+ a: ───H───X───PhXZ(a=0.1,x=0,z=0.4)───X───@───X───
832
+
833
+ b: ───H───H───H───────────────────────H───X───X───
834
+ """,
835
+ schema="XX_PAIR",
836
+ )