cirq-core 1.7.0.dev20250825174419__py3-none-any.whl → 1.7.0.dev20251203004401__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.
Files changed (426) hide show
  1. cirq/__init__.py +1 -0
  2. cirq/_compat.py +3 -2
  3. cirq/_compat_test.py +16 -15
  4. cirq/_doc.py +4 -3
  5. cirq/_import.py +2 -1
  6. cirq/_version.py +1 -1
  7. cirq/_version_test.py +1 -1
  8. cirq/circuits/_bucket_priority_queue.py +2 -1
  9. cirq/circuits/circuit.py +19 -17
  10. cirq/circuits/circuit_operation.py +2 -1
  11. cirq/circuits/circuit_operation_test.py +19 -0
  12. cirq/circuits/circuit_test.py +31 -12
  13. cirq/circuits/frozen_circuit.py +3 -2
  14. cirq/circuits/moment.py +3 -15
  15. cirq/circuits/optimization_pass.py +2 -1
  16. cirq/circuits/qasm_output.py +39 -10
  17. cirq/circuits/qasm_output_test.py +51 -2
  18. cirq/circuits/text_diagram_drawer.py +2 -1
  19. cirq/contrib/acquaintance/bipartite.py +2 -1
  20. cirq/contrib/acquaintance/devices.py +1 -1
  21. cirq/contrib/acquaintance/executor.py +4 -5
  22. cirq/contrib/acquaintance/executor_test.py +2 -1
  23. cirq/contrib/acquaintance/gates.py +2 -1
  24. cirq/contrib/acquaintance/gates_test.py +1 -1
  25. cirq/contrib/acquaintance/inspection_utils.py +2 -1
  26. cirq/contrib/acquaintance/mutation_utils.py +2 -1
  27. cirq/contrib/acquaintance/optimizers.py +2 -1
  28. cirq/contrib/acquaintance/permutation.py +2 -1
  29. cirq/contrib/acquaintance/permutation_test.py +1 -1
  30. cirq/contrib/acquaintance/shift.py +2 -1
  31. cirq/contrib/acquaintance/shift_swap_network.py +2 -1
  32. cirq/contrib/acquaintance/strategies/complete.py +3 -2
  33. cirq/contrib/acquaintance/strategies/cubic.py +2 -1
  34. cirq/contrib/acquaintance/strategies/quartic_paired.py +2 -1
  35. cirq/contrib/acquaintance/strategies/quartic_paired_test.py +1 -1
  36. cirq/contrib/acquaintance/testing.py +2 -1
  37. cirq/contrib/acquaintance/topological_sort.py +2 -1
  38. cirq/contrib/bayesian_network/bayesian_network_gate.py +3 -2
  39. cirq/contrib/circuitdag/circuit_dag.py +4 -2
  40. cirq/contrib/custom_simulators/custom_state_simulator.py +2 -1
  41. cirq/contrib/custom_simulators/custom_state_simulator_test.py +1 -1
  42. cirq/contrib/graph_device/graph_device.py +2 -1
  43. cirq/contrib/graph_device/graph_device_test.py +2 -1
  44. cirq/contrib/graph_device/hypergraph.py +2 -1
  45. cirq/contrib/graph_device/uniform_graph_device.py +2 -1
  46. cirq/contrib/json.py +14 -2
  47. cirq/contrib/json_test_data/BayesianNetworkGate.json +10 -0
  48. cirq/contrib/json_test_data/BayesianNetworkGate.repr +3 -0
  49. cirq/contrib/json_test_data/QuantumVolumeResult.json +169 -0
  50. cirq/contrib/json_test_data/QuantumVolumeResult.repr +22 -0
  51. cirq/contrib/json_test_data/SwapPermutationGate.json +3 -0
  52. cirq/contrib/json_test_data/SwapPermutationGate.repr +1 -0
  53. cirq/contrib/json_test_data/spec.py +0 -2
  54. cirq/contrib/noise_models/noise_models.py +2 -1
  55. cirq/contrib/paulistring/clifford_optimize.py +20 -2
  56. cirq/contrib/paulistring/optimize.py +1 -1
  57. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +146 -35
  58. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +81 -178
  59. cirq/contrib/paulistring/recombine.py +5 -2
  60. cirq/contrib/paulistring/separate.py +1 -1
  61. cirq/contrib/qasm_import/_lexer.py +6 -1
  62. cirq/contrib/qasm_import/_lexer_test.py +1 -1
  63. cirq/contrib/qasm_import/_parser.py +24 -8
  64. cirq/contrib/qasm_import/_parser_test.py +44 -6
  65. cirq/contrib/qcircuit/qcircuit_pdf_test.py +6 -9
  66. cirq/contrib/quantikz/__init__.py +21 -0
  67. cirq/contrib/quantikz/circuit_to_latex_quantikz.py +680 -0
  68. cirq/contrib/quantikz/circuit_to_latex_quantikz_test.py +253 -0
  69. cirq/contrib/quantikz/circuit_to_latex_render.py +424 -0
  70. cirq/contrib/quantikz/circuit_to_latex_render_test.py +44 -0
  71. cirq/contrib/quantum_volume/quantum_volume.py +2 -1
  72. cirq/contrib/quimb/density_matrix.py +1 -1
  73. cirq/contrib/quimb/grid_circuits.py +2 -1
  74. cirq/contrib/quimb/grid_circuits_test.py +1 -1
  75. cirq/contrib/quimb/mps_simulator.py +4 -3
  76. cirq/contrib/quimb/state_vector.py +2 -1
  77. cirq/contrib/quirk/export_to_quirk.py +2 -1
  78. cirq/contrib/quirk/linearize_circuit.py +1 -1
  79. cirq/contrib/quirk/quirk_gate.py +2 -1
  80. cirq/contrib/routing/device.py +1 -1
  81. cirq/contrib/routing/greedy.py +2 -1
  82. cirq/contrib/routing/initialization.py +2 -1
  83. cirq/contrib/routing/router.py +2 -1
  84. cirq/contrib/routing/swap_network.py +2 -1
  85. cirq/contrib/routing/utils.py +2 -1
  86. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +7 -5
  87. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +6 -6
  88. cirq/devices/device.py +2 -1
  89. cirq/devices/grid_device_metadata.py +2 -1
  90. cirq/devices/grid_qubit.py +7 -6
  91. cirq/devices/insertion_noise_model.py +2 -1
  92. cirq/devices/line_qubit.py +2 -1
  93. cirq/devices/named_topologies.py +2 -1
  94. cirq/devices/noise_model.py +2 -1
  95. cirq/devices/noise_model_test.py +1 -1
  96. cirq/devices/noise_properties.py +2 -1
  97. cirq/devices/superconducting_qubits_noise_properties_test.py +2 -1
  98. cirq/devices/thermal_noise_model.py +2 -1
  99. cirq/experiments/__init__.py +2 -0
  100. cirq/experiments/benchmarking/parallel_xeb.py +2 -1
  101. cirq/experiments/benchmarking/parallel_xeb_test.py +1 -1
  102. cirq/experiments/fidelity_estimation.py +2 -1
  103. cirq/experiments/fidelity_estimation_test.py +1 -1
  104. cirq/experiments/ghz_2d.py +150 -0
  105. cirq/experiments/ghz_2d_test.py +155 -0
  106. cirq/experiments/n_qubit_tomography.py +2 -1
  107. cirq/experiments/n_qubit_tomography_test.py +1 -1
  108. cirq/experiments/purity_estimation.py +1 -1
  109. cirq/experiments/qubit_characterizations.py +33 -4
  110. cirq/experiments/qubit_characterizations_test.py +16 -0
  111. cirq/experiments/random_quantum_circuit_generation.py +2 -1
  112. cirq/experiments/random_quantum_circuit_generation_test.py +2 -1
  113. cirq/experiments/readout_confusion_matrix.py +2 -1
  114. cirq/experiments/readout_confusion_matrix_test.py +1 -1
  115. cirq/experiments/single_qubit_readout_calibration.py +2 -1
  116. cirq/experiments/single_qubit_readout_calibration_test.py +1 -1
  117. cirq/experiments/t1_decay_experiment.py +2 -1
  118. cirq/experiments/two_qubit_xeb.py +2 -1
  119. cirq/experiments/two_qubit_xeb_test.py +1 -1
  120. cirq/experiments/xeb_fitting.py +2 -1
  121. cirq/experiments/xeb_fitting_test.py +1 -1
  122. cirq/experiments/xeb_sampling.py +5 -3
  123. cirq/experiments/xeb_sampling_test.py +1 -1
  124. cirq/experiments/xeb_simulation.py +2 -1
  125. cirq/experiments/xeb_simulation_test.py +2 -1
  126. cirq/experiments/z_phase_calibration.py +2 -1
  127. cirq/experiments/z_phase_calibration_test.py +18 -3
  128. cirq/interop/quirk/cells/__init__.py +1 -2
  129. cirq/interop/quirk/cells/all_cells.py +2 -1
  130. cirq/interop/quirk/cells/arithmetic_cells.py +2 -1
  131. cirq/interop/quirk/cells/cell.py +2 -1
  132. cirq/interop/quirk/cells/composite_cell.py +2 -1
  133. cirq/interop/quirk/cells/composite_cell_test.py +1 -1
  134. cirq/interop/quirk/cells/control_cells.py +2 -1
  135. cirq/interop/quirk/cells/frequency_space_cells.py +1 -1
  136. cirq/interop/quirk/cells/ignored_cells.py +1 -1
  137. cirq/interop/quirk/cells/input_cells.py +2 -1
  138. cirq/interop/quirk/cells/input_rotation_cells.py +2 -1
  139. cirq/interop/quirk/cells/measurement_cells.py +2 -1
  140. cirq/interop/quirk/cells/parse.py +2 -11
  141. cirq/interop/quirk/cells/qubit_permutation_cells.py +2 -1
  142. cirq/interop/quirk/cells/scalar_cells.py +2 -1
  143. cirq/interop/quirk/cells/single_qubit_rotation_cells.py +2 -1
  144. cirq/interop/quirk/cells/swap_cell.py +2 -1
  145. cirq/interop/quirk/cells/unsupported_cells.py +1 -1
  146. cirq/interop/quirk/url_to_circuit.py +2 -1
  147. cirq/json_resolver_cache.py +0 -2
  148. cirq/linalg/decompositions.py +6 -2
  149. cirq/linalg/decompositions_test.py +1 -0
  150. cirq/linalg/diagonalize.py +1 -1
  151. cirq/linalg/predicates.py +2 -1
  152. cirq/linalg/tolerance.py +2 -1
  153. cirq/linalg/transformations.py +3 -2
  154. cirq/ops/arithmetic_operation.py +4 -3
  155. cirq/ops/arithmetic_operation_test.py +1 -1
  156. cirq/ops/boolean_hamiltonian.py +4 -3
  157. cirq/ops/classically_controlled_operation.py +11 -11
  158. cirq/ops/classically_controlled_operation_test.py +26 -2
  159. cirq/ops/clifford_gate.py +3 -2
  160. cirq/ops/clifford_gate_test.py +1 -2
  161. cirq/ops/common_channels.py +2 -1
  162. cirq/ops/common_gates.py +3 -2
  163. cirq/ops/control_values.py +2 -1
  164. cirq/ops/controlled_gate.py +3 -2
  165. cirq/ops/controlled_gate_test.py +2 -1
  166. cirq/ops/controlled_operation.py +3 -2
  167. cirq/ops/controlled_operation_test.py +2 -1
  168. cirq/ops/dense_pauli_string.py +44 -81
  169. cirq/ops/dense_pauli_string_test.py +21 -0
  170. cirq/ops/diagonal_gate.py +3 -2
  171. cirq/ops/eigen_gate.py +9 -7
  172. cirq/ops/fourier_transform.py +3 -2
  173. cirq/ops/fourier_transform_test.py +2 -4
  174. cirq/ops/fsim_gate.py +3 -2
  175. cirq/ops/gate_operation.py +23 -12
  176. cirq/ops/gateset.py +22 -2
  177. cirq/ops/global_phase_op.py +3 -2
  178. cirq/ops/greedy_qubit_manager.py +2 -1
  179. cirq/ops/identity.py +2 -1
  180. cirq/ops/kraus_channel.py +2 -1
  181. cirq/ops/linear_combinations.py +12 -17
  182. cirq/ops/linear_combinations_test.py +23 -1
  183. cirq/ops/matrix_gates.py +2 -1
  184. cirq/ops/measure_util.py +8 -6
  185. cirq/ops/measurement_gate.py +2 -1
  186. cirq/ops/mixed_unitary_channel.py +2 -1
  187. cirq/ops/named_qubit.py +2 -2
  188. cirq/ops/op_tree.py +2 -1
  189. cirq/ops/parallel_gate.py +3 -2
  190. cirq/ops/parity_gates.py +2 -1
  191. cirq/ops/parity_gates_test.py +35 -0
  192. cirq/ops/pauli_interaction_gate.py +2 -1
  193. cirq/ops/pauli_measurement_gate.py +2 -1
  194. cirq/ops/pauli_string.py +37 -57
  195. cirq/ops/pauli_string_phasor.py +6 -5
  196. cirq/ops/pauli_string_raw_types.py +2 -1
  197. cirq/ops/pauli_string_test.py +49 -6
  198. cirq/ops/pauli_sum_exponential.py +2 -1
  199. cirq/ops/permutation_gate.py +2 -1
  200. cirq/ops/phased_iswap_gate.py +3 -2
  201. cirq/ops/phased_x_gate.py +5 -4
  202. cirq/ops/phased_x_z_gate.py +12 -5
  203. cirq/ops/projector.py +2 -1
  204. cirq/ops/qubit_manager.py +2 -1
  205. cirq/ops/qubit_order.py +2 -1
  206. cirq/ops/qubit_order_or_list.py +1 -1
  207. cirq/ops/random_gate_channel.py +3 -2
  208. cirq/ops/raw_types.py +33 -16
  209. cirq/ops/raw_types_test.py +4 -3
  210. cirq/ops/state_preparation_channel.py +2 -1
  211. cirq/ops/three_qubit_gates.py +3 -2
  212. cirq/ops/two_qubit_diagonal_gate.py +3 -2
  213. cirq/ops/uniform_superposition_gate.py +2 -1
  214. cirq/ops/wait_gate.py +10 -4
  215. cirq/protocols/act_on_protocol.py +2 -1
  216. cirq/protocols/act_on_protocol_test.py +2 -1
  217. cirq/protocols/apply_channel_protocol.py +2 -1
  218. cirq/protocols/apply_mixture_protocol.py +2 -1
  219. cirq/protocols/apply_mixture_protocol_test.py +2 -1
  220. cirq/protocols/apply_unitary_protocol.py +2 -1
  221. cirq/protocols/apply_unitary_protocol_test.py +2 -0
  222. cirq/protocols/approximate_equality_protocol.py +2 -1
  223. cirq/protocols/circuit_diagram_info_protocol.py +2 -1
  224. cirq/protocols/control_key_protocol.py +7 -0
  225. cirq/protocols/decompose_protocol.py +2 -12
  226. cirq/protocols/has_stabilizer_effect_protocol.py +1 -1
  227. cirq/protocols/has_stabilizer_effect_protocol_test.py +11 -9
  228. cirq/protocols/has_unitary_protocol_test.py +3 -3
  229. cirq/protocols/hash_from_pickle_test.py +2 -2
  230. cirq/protocols/inverse_protocol.py +2 -1
  231. cirq/protocols/json_serialization.py +5 -4
  232. cirq/protocols/json_serialization_test.py +31 -31
  233. cirq/protocols/kraus_protocol.py +4 -3
  234. cirq/protocols/kraus_protocol_test.py +7 -7
  235. cirq/protocols/measurement_key_protocol.py +32 -8
  236. cirq/protocols/mixture_protocol.py +3 -2
  237. cirq/protocols/mixture_protocol_test.py +7 -7
  238. cirq/protocols/mul_protocol_test.py +4 -4
  239. cirq/protocols/phase_protocol.py +13 -4
  240. cirq/protocols/pow_protocol.py +2 -1
  241. cirq/protocols/pow_protocol_test.py +5 -5
  242. cirq/protocols/qasm.py +2 -1
  243. cirq/protocols/qid_shape_protocol.py +2 -1
  244. cirq/protocols/resolve_parameters.py +17 -15
  245. cirq/protocols/trace_distance_bound.py +2 -1
  246. cirq/protocols/unitary_protocol.py +21 -21
  247. cirq/protocols/unitary_protocol_test.py +31 -19
  248. cirq/qis/channels.py +1 -1
  249. cirq/qis/channels_test.py +1 -1
  250. cirq/qis/clifford_tableau.py +16 -15
  251. cirq/qis/clifford_tableau_test.py +17 -17
  252. cirq/qis/entropy.py +3 -3
  253. cirq/qis/entropy_test.py +1 -1
  254. cirq/qis/quantum_state_representation.py +2 -1
  255. cirq/qis/states.py +7 -2
  256. cirq/qis/states_test.py +54 -54
  257. cirq/sim/classical_simulator.py +25 -14
  258. cirq/sim/classical_simulator_test.py +85 -30
  259. cirq/sim/clifford/clifford_simulator.py +7 -6
  260. cirq/sim/clifford/clifford_simulator_test.py +51 -50
  261. cirq/sim/clifford/clifford_tableau_simulation_state.py +2 -1
  262. cirq/sim/clifford/stabilizer_ch_form_simulation_state.py +2 -1
  263. cirq/sim/clifford/stabilizer_sampler.py +1 -1
  264. cirq/sim/clifford/stabilizer_simulation_state.py +2 -1
  265. cirq/sim/clifford/stabilizer_state_ch_form.py +16 -15
  266. cirq/sim/clifford/stabilizer_state_ch_form_test.py +0 -1
  267. cirq/sim/density_matrix_simulation_state.py +7 -6
  268. cirq/sim/density_matrix_simulator.py +3 -2
  269. cirq/sim/density_matrix_simulator_test.py +94 -84
  270. cirq/sim/density_matrix_utils.py +2 -1
  271. cirq/sim/density_matrix_utils_test.py +1 -1
  272. cirq/sim/mux.py +35 -8
  273. cirq/sim/mux_test.py +39 -26
  274. cirq/sim/simulation_product_state.py +2 -1
  275. cirq/sim/simulation_product_state_test.py +8 -7
  276. cirq/sim/simulation_state.py +6 -5
  277. cirq/sim/simulation_state_base.py +3 -2
  278. cirq/sim/simulation_state_test.py +7 -6
  279. cirq/sim/simulation_utils.py +2 -1
  280. cirq/sim/simulator.py +4 -3
  281. cirq/sim/simulator_base.py +2 -1
  282. cirq/sim/simulator_base_test.py +51 -36
  283. cirq/sim/simulator_test.py +41 -36
  284. cirq/sim/sparse_simulator.py +3 -2
  285. cirq/sim/sparse_simulator_test.py +92 -82
  286. cirq/sim/state_vector.py +5 -6
  287. cirq/sim/state_vector_simulation_state.py +10 -9
  288. cirq/sim/state_vector_simulator.py +2 -1
  289. cirq/sim/state_vector_simulator_test.py +9 -9
  290. cirq/sim/state_vector_test.py +40 -39
  291. cirq/study/__init__.py +1 -0
  292. cirq/study/flatten_expressions.py +2 -1
  293. cirq/study/resolver.py +31 -18
  294. cirq/study/resolver_test.py +1 -1
  295. cirq/study/result.py +2 -1
  296. cirq/study/result_test.py +20 -20
  297. cirq/study/sweepable.py +2 -1
  298. cirq/study/sweepable_test.py +20 -20
  299. cirq/study/sweeps.py +26 -1
  300. cirq/study/sweeps_test.py +67 -43
  301. cirq/testing/_compat_test_data/__init__.py +3 -3
  302. cirq/testing/circuit_compare.py +2 -1
  303. cirq/testing/circuit_compare_test.py +16 -14
  304. cirq/testing/consistent_act_on_test.py +1 -1
  305. cirq/testing/consistent_channels.py +2 -2
  306. cirq/testing/consistent_controlled_gate_op.py +2 -2
  307. cirq/testing/consistent_controlled_gate_op_test.py +2 -1
  308. cirq/testing/consistent_decomposition.py +4 -2
  309. cirq/testing/consistent_phase_by.py +1 -1
  310. cirq/testing/consistent_protocols.py +2 -1
  311. cirq/testing/consistent_protocols_test.py +3 -3
  312. cirq/testing/consistent_qasm.py +4 -3
  313. cirq/testing/consistent_qasm_test.py +3 -3
  314. cirq/testing/consistent_resolve_parameters.py +1 -1
  315. cirq/testing/consistent_unitary.py +1 -1
  316. cirq/testing/consistent_unitary_test.py +1 -1
  317. cirq/testing/deprecation.py +1 -1
  318. cirq/testing/devices.py +3 -2
  319. cirq/testing/equals_tester.py +4 -3
  320. cirq/testing/equivalent_basis_map.py +4 -2
  321. cirq/testing/json.py +3 -2
  322. cirq/testing/lin_alg_utils.py +1 -1
  323. cirq/testing/logs.py +1 -1
  324. cirq/testing/op_tree.py +1 -1
  325. cirq/testing/order_tester.py +2 -2
  326. cirq/testing/pytest_utils.py +2 -1
  327. cirq/testing/random_circuit.py +2 -1
  328. cirq/testing/random_circuit_test.py +2 -1
  329. cirq/testing/repr_pretty_tester.py +3 -3
  330. cirq/transformers/__init__.py +1 -0
  331. cirq/transformers/_connected_component.py +231 -0
  332. cirq/transformers/_connected_component_test.py +200 -0
  333. cirq/transformers/align_test.py +13 -13
  334. cirq/transformers/analytical_decompositions/clifford_decomposition.py +8 -7
  335. cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +5 -5
  336. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +11 -10
  337. cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +6 -6
  338. cirq/transformers/analytical_decompositions/cphase_to_fsim.py +3 -2
  339. cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +11 -10
  340. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +8 -7
  341. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +17 -20
  342. cirq/transformers/analytical_decompositions/single_qubit_decompositions_test.py +33 -27
  343. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +1 -1
  344. cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +1 -1
  345. cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +12 -11
  346. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +5 -2
  347. cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +3 -3
  348. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +2 -1
  349. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +2 -1
  350. cirq/transformers/analytical_decompositions/two_qubit_to_ms_test.py +2 -2
  351. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +2 -1
  352. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +32 -30
  353. cirq/transformers/drop_negligible_operations_test.py +7 -7
  354. cirq/transformers/dynamical_decoupling.py +185 -112
  355. cirq/transformers/dynamical_decoupling_test.py +195 -201
  356. cirq/transformers/eject_phased_paulis.py +2 -1
  357. cirq/transformers/eject_phased_paulis_test.py +3 -2
  358. cirq/transformers/eject_z.py +5 -3
  359. cirq/transformers/eject_z_test.py +23 -25
  360. cirq/transformers/expand_composite.py +3 -2
  361. cirq/transformers/expand_composite_test.py +14 -14
  362. cirq/transformers/gauge_compiling/__init__.py +13 -0
  363. cirq/transformers/gauge_compiling/gauge_compiling.py +3 -2
  364. cirq/transformers/gauge_compiling/gauge_compiling_test.py +14 -12
  365. cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +3 -3
  366. cirq/transformers/gauge_compiling/idle_moments_gauge.py +225 -0
  367. cirq/transformers/gauge_compiling/idle_moments_gauge_test.py +193 -0
  368. cirq/transformers/gauge_compiling/multi_moment_cphase_gauge.py +242 -0
  369. cirq/transformers/gauge_compiling/multi_moment_cphase_gauge_test.py +243 -0
  370. cirq/transformers/gauge_compiling/multi_moment_gauge_compiling.py +151 -0
  371. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +2 -1
  372. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +1 -1
  373. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +6 -6
  374. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +3 -2
  375. cirq/transformers/measurement_transformers.py +2 -1
  376. cirq/transformers/measurement_transformers_test.py +45 -39
  377. cirq/transformers/merge_k_qubit_gates.py +2 -1
  378. cirq/transformers/merge_k_qubit_gates_test.py +1 -1
  379. cirq/transformers/merge_single_qubit_gates.py +9 -5
  380. cirq/transformers/merge_single_qubit_gates_test.py +22 -22
  381. cirq/transformers/noise_adding_test.py +2 -2
  382. cirq/transformers/optimize_for_target_gateset.py +2 -1
  383. cirq/transformers/optimize_for_target_gateset_test.py +11 -9
  384. cirq/transformers/qubit_management_transformers_test.py +6 -2
  385. cirq/transformers/routing/mapping_manager.py +2 -1
  386. cirq/transformers/routing/route_circuit_cqc.py +2 -1
  387. cirq/transformers/stratify.py +2 -1
  388. cirq/transformers/symbolize.py +2 -1
  389. cirq/transformers/tag_transformers.py +2 -1
  390. cirq/transformers/target_gatesets/compilation_target_gateset.py +2 -1
  391. cirq/transformers/target_gatesets/cz_gateset.py +2 -1
  392. cirq/transformers/target_gatesets/cz_gateset_test.py +1 -1
  393. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +2 -1
  394. cirq/transformers/transformer_api.py +2 -1
  395. cirq/transformers/transformer_primitives.py +271 -145
  396. cirq/transformers/transformer_primitives_test.py +185 -1
  397. cirq/value/abc_alt.py +2 -1
  398. cirq/value/classical_data.py +2 -1
  399. cirq/value/condition.py +2 -1
  400. cirq/value/digits.py +9 -2
  401. cirq/value/duration.py +6 -5
  402. cirq/value/linear_dict.py +4 -9
  403. cirq/value/measurement_key.py +2 -1
  404. cirq/value/periodic_value.py +3 -2
  405. cirq/value/product_state.py +2 -1
  406. cirq/value/value_equality_attr.py +2 -1
  407. cirq/vis/density_matrix.py +1 -1
  408. cirq/vis/heatmap.py +2 -1
  409. cirq/vis/histogram.py +2 -1
  410. cirq/vis/state_histogram.py +2 -1
  411. cirq/work/collector.py +2 -1
  412. cirq/work/observable_grouping.py +2 -1
  413. cirq/work/observable_measurement.py +2 -1
  414. cirq/work/observable_measurement_data.py +2 -1
  415. cirq/work/observable_measurement_test.py +1 -1
  416. cirq/work/observable_readout_calibration.py +2 -1
  417. cirq/work/observable_readout_calibration_test.py +1 -1
  418. cirq/work/observable_settings.py +2 -1
  419. cirq/work/sampler.py +2 -1
  420. cirq/work/sampler_test.py +1 -1
  421. {cirq_core-1.7.0.dev20250825174419.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/METADATA +5 -6
  422. {cirq_core-1.7.0.dev20250825174419.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/RECORD +425 -406
  423. cirq/contrib/json_test.py +0 -33
  424. {cirq_core-1.7.0.dev20250825174419.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/WHEEL +0 -0
  425. {cirq_core-1.7.0.dev20250825174419.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/licenses/LICENSE +0 -0
  426. {cirq_core-1.7.0.dev20250825174419.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/top_level.txt +0 -0
@@ -14,16 +14,18 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Sequence
17
+ from collections.abc import Sequence
18
+ from unittest import mock
18
19
 
19
20
  import numpy as np
20
21
  import pytest
21
22
 
22
23
  import cirq
23
24
  from cirq import add_dynamical_decoupling, CNOT, CZ, CZPowGate, H, X, Y, Z
25
+ from cirq.transformers.dynamical_decoupling import _CellType, _Grid
24
26
 
25
27
 
26
- def assert_sim_eq(circuit1: cirq.AbstractCircuit, circuit2: cirq.AbstractCircuit):
28
+ def assert_sim_eq(circuit1: cirq.AbstractCircuit, circuit2: cirq.AbstractCircuit) -> None:
27
29
  # Simulate 2 circuits and compare final states.
28
30
  sampler = cirq.Simulator(dtype=np.complex128)
29
31
  psi0 = sampler.simulate(cirq.drop_terminal_measurements(circuit1)).final_state_vector
@@ -37,7 +39,7 @@ def assert_dd(
37
39
  expected_circuit: str | cirq.AbstractCircuit,
38
40
  schema: str | tuple[cirq.Gate, ...] = 'DEFAULT',
39
41
  single_qubit_gate_moments_only: bool = True,
40
- ):
42
+ ) -> None:
41
43
  transformed_circuit = add_dynamical_decoupling(
42
44
  input_circuit, schema=schema, single_qubit_gate_moments_only=single_qubit_gate_moments_only
43
45
  ).freeze()
@@ -53,7 +55,7 @@ def assert_dd(
53
55
  assert_sim_eq(input_circuit, transformed_circuit)
54
56
 
55
57
 
56
- def test_no_insertion():
58
+ def test_no_insertion() -> None:
57
59
  """Test case diagrams.
58
60
  Input:
59
61
  a: ───H───@───────
@@ -81,7 +83,7 @@ def test_no_insertion():
81
83
  'schema,inserted_gates',
82
84
  [('XX_PAIR', (X, X)), ('X_XINV', (X, X**-1)), ('YY_PAIR', (Y, Y)), ('Y_YINV', (Y, Y**-1))],
83
85
  )
84
- def test_insert_provided_schema(schema: str, inserted_gates: Sequence[cirq.Gate]):
86
+ def test_insert_provided_schema(schema: str, inserted_gates: Sequence[cirq.Gate]) -> None:
85
87
  """Test case diagrams.
86
88
  Input:
87
89
  a: ───H───@───────────M───
@@ -113,7 +115,7 @@ def test_insert_provided_schema(schema: str, inserted_gates: Sequence[cirq.Gate]
113
115
  assert_dd(input_circuit, expected_circuit, schema=schema, single_qubit_gate_moments_only=False)
114
116
 
115
117
 
116
- def test_insert_by_customized_dd_sequence():
118
+ def test_insert_by_customized_dd_sequence() -> None:
117
119
  """Test case diagrams.
118
120
  Input:
119
121
  a: ───H───@───────────────────H───
@@ -151,22 +153,18 @@ def test_insert_by_customized_dd_sequence():
151
153
  cirq.Moment(CNOT(b, c), Y(a)),
152
154
  cirq.Moment([H(qubit) for qubit in [a, b, c]]),
153
155
  ),
154
- schema=[X, X, Y, Y],
156
+ schema=(X, X, Y, Y),
155
157
  single_qubit_gate_moments_only=False,
156
158
  )
157
159
 
158
160
 
159
161
  @pytest.mark.parametrize('single_qubit_gate_moments_only', [True, False])
160
- def test_pull_through_h_gate_case1(single_qubit_gate_moments_only: bool):
162
+ def test_pull_through_h_gate_case1(single_qubit_gate_moments_only: bool) -> None:
161
163
  """Test case diagrams.
162
164
  Input:
163
165
  a: ───H───────H───────@───
164
166
 
165
167
  b: ───H───H───H───H───X───
166
- Output:
167
- a: ───H───X───H───X───@───Y───
168
-
169
- b: ───H───H───H───H───X───X───
170
168
  """
171
169
  a = cirq.NamedQubit('a')
172
170
  b = cirq.NamedQubit('b')
@@ -179,30 +177,23 @@ def test_pull_through_h_gate_case1(single_qubit_gate_moments_only: bool):
179
177
  cirq.Moment(H(b)),
180
178
  cirq.Moment(CNOT(a, b)),
181
179
  ),
182
- expected_circuit=cirq.Circuit(
183
- cirq.Moment(H(a), H(b)),
184
- cirq.Moment(H(b), X(a)),
185
- cirq.Moment(H(a), H(b)),
186
- cirq.Moment(H(b), X(a)),
187
- cirq.Moment(CNOT(a, b)),
188
- cirq.Moment(Y(a), X(b)),
189
- ),
180
+ expected_circuit="""
181
+ a: ───H───X───H───PhXZ(a=-0.5,x=0,z=-1)───@───
182
+
183
+ b: ───H───H───H───H───────────────────────X───
184
+ """,
190
185
  schema="XX_PAIR",
191
186
  single_qubit_gate_moments_only=single_qubit_gate_moments_only,
192
187
  )
193
188
 
194
189
 
195
190
  @pytest.mark.parametrize('single_qubit_gate_moments_only', [True, False])
196
- def test_pull_through_h_gate_case2(single_qubit_gate_moments_only: bool):
191
+ def test_pull_through_h_gate_case2(single_qubit_gate_moments_only: bool) -> None:
197
192
  """Test case diagrams.
198
193
  Input:
199
194
  a: ───H───────H───────H───
200
195
 
201
196
  b: ───H───H───H───H───H───
202
- Output:
203
- a: ───H───X───H───X───PhXZ(a=0.5,x=0.5,z=1)───
204
-
205
- b: ───H───H───H───H───H───────────────────────
206
197
  """
207
198
  a = cirq.NamedQubit('a')
208
199
  b = cirq.NamedQubit('b')
@@ -215,15 +206,11 @@ def test_pull_through_h_gate_case2(single_qubit_gate_moments_only: bool):
215
206
  cirq.Moment(H(b)),
216
207
  cirq.Moment(H(a), H(b)),
217
208
  ),
218
- expected_circuit=cirq.Circuit(
219
- cirq.Moment(H(a), H(b)),
220
- cirq.Moment(H(b), X(a)),
221
- cirq.Moment(H(a), H(b)),
222
- cirq.Moment(H(b), X(a)),
223
- cirq.Moment(
224
- cirq.PhasedXZGate(axis_phase_exponent=0.5, x_exponent=0.5, z_exponent=1).on(a), H(b)
225
- ),
226
- ),
209
+ expected_circuit="""
210
+ a: ───H───X───H───X───PhXZ(a=0.5,x=0.5,z=-1)───
211
+
212
+ b: ───H───H───H───H───H────────────────────────
213
+ """,
227
214
  schema="XX_PAIR",
228
215
  single_qubit_gate_moments_only=single_qubit_gate_moments_only,
229
216
  )
@@ -246,14 +233,14 @@ def test_pull_through_h_gate_case2(single_qubit_gate_moments_only: bool):
246
233
  ),
247
234
  ],
248
235
  )
249
- def test_invalid_dd_schema(schema: str | tuple[cirq.Gate, ...], error_msg_regex):
236
+ def test_invalid_dd_schema(schema: str | tuple[cirq.Gate, ...], error_msg_regex) -> None:
250
237
  a = cirq.NamedQubit('a')
251
238
  input_circuit = cirq.Circuit(H(a))
252
239
  with pytest.raises(ValueError, match=error_msg_regex):
253
240
  add_dynamical_decoupling(input_circuit, schema=schema, single_qubit_gate_moments_only=False)
254
241
 
255
242
 
256
- def test_single_qubit_gate_moments_only_no_updates_succeeds():
243
+ def test_single_qubit_gate_moments_only_no_updates_succeeds() -> None:
257
244
  qubits = cirq.LineQubit.range(9)
258
245
  input_circuit = cirq.Circuit(
259
246
  cirq.Moment([H(qubits[i]) for i in [3, 4, 5]]),
@@ -269,7 +256,7 @@ def test_single_qubit_gate_moments_only_no_updates_succeeds():
269
256
  add_dynamical_decoupling(input_circuit, schema='X_XINV', single_qubit_gate_moments_only=True)
270
257
 
271
258
 
272
- def test_scattered_circuit():
259
+ def test_scattered_circuit() -> None:
273
260
  """Test case diagrams.
274
261
  Input:
275
262
  0: ───────────────────────────────H───@───H───
@@ -424,7 +411,7 @@ def test_scattered_circuit():
424
411
  )
425
412
 
426
413
 
427
- def test_scattered_circuit2():
414
+ def test_scattered_circuit2() -> None:
428
415
  """Test case diagrams.
429
416
  Input:
430
417
  0: ───────────────────@───
@@ -444,24 +431,6 @@ def test_scattered_circuit2():
444
431
  7: ───────────────@───@───
445
432
 
446
433
  8: ───────────────────@───
447
- Output:
448
- 0: ───────────────────@───
449
-
450
- 1: ───────────────@───@───
451
-
452
- 2: ───────────@───@───────
453
-
454
- 3: ───────@───@───────────
455
-
456
- 4: ───@───@───────────────
457
-
458
- 5: ───@───X───@───X───────
459
-
460
- 6: ───────────@───@───Z───
461
-
462
- 7: ───────────────@───@───
463
-
464
- 8: ───────────────────@───
465
434
  """
466
435
  qubits = cirq.LineQubit.range(9)
467
436
  assert_dd(
@@ -472,19 +441,31 @@ def test_scattered_circuit2():
472
441
  cirq.Moment(CZ(*qubits[1:3]), CZ(*qubits[6:8])),
473
442
  cirq.Moment(CZ(*qubits[0:2]), CZ(*qubits[7:])),
474
443
  ),
475
- expected_circuit=cirq.Circuit(
476
- cirq.Moment(CZ(*qubits[4:6])),
477
- cirq.Moment(CZ(*qubits[3:5]), X(qubits[5])),
478
- cirq.Moment(CZ(*qubits[2:4]), CZ(*qubits[5:7])),
479
- cirq.Moment(CZ(*qubits[1:3]), CZ(*qubits[6:8]), X(qubits[5])),
480
- cirq.Moment(CZ(*qubits[0:2]), CZ(*qubits[7:]), Z(qubits[6])),
481
- ),
444
+ expected_circuit="""
445
+ 0: ───────────────────@───
446
+
447
+ 1: ───────────────@───@───
448
+
449
+ 2: ───────────@───@───────
450
+
451
+ 3: ───────@───@───────────
452
+
453
+ 4: ───@───@───────────────
454
+
455
+ 5: ───@───I───@───────────
456
+
457
+ 6: ───────────@───@───────
458
+
459
+ 7: ───────────────@───@───
460
+
461
+ 8: ───────────────────@───
462
+ """,
482
463
  schema="XX_PAIR",
483
464
  single_qubit_gate_moments_only=False,
484
465
  )
485
466
 
486
467
 
487
- def test_pull_through_chain():
468
+ def test_pull_through_chain() -> None:
488
469
  """Test case diagrams.
489
470
  Input:
490
471
  0: ───X───────×───────────X───
@@ -494,14 +475,6 @@ def test_pull_through_chain():
494
475
  2: ───────────────×───×───X───
495
476
 
496
477
  3: ───────────────────×───X───
497
- Output:
498
- 0: ───X───X───×───X───X───X───
499
-
500
- 1: ───────Y───×───×───X───I───
501
-
502
- 2: ───────────────×───×───X───
503
-
504
- 3: ───────────────────×───I───
505
478
  """
506
479
  qubits = cirq.LineQubit.range(4)
507
480
  assert_dd(
@@ -513,29 +486,26 @@ def test_pull_through_chain():
513
486
  cirq.Moment(cirq.SWAP(*qubits[2:4])),
514
487
  cirq.Moment([X(qubits[i]) for i in range(4)]),
515
488
  ),
516
- expected_circuit=cirq.Circuit(
517
- cirq.Moment(X(qubits[0])),
518
- cirq.Moment(Y(qubits[1]), X(qubits[0])),
519
- cirq.Moment(cirq.SWAP(*qubits[0:2])),
520
- cirq.Moment([cirq.SWAP(*qubits[1:3])] + [X(qubits[0])]),
521
- cirq.Moment([cirq.SWAP(*qubits[2:4])] + [X(qubits[0]), X(qubits[1])]),
522
- cirq.Moment(X(qubits[0]), cirq.I(qubits[1]), X(qubits[2]), cirq.I(qubits[3])),
523
- ),
489
+ expected_circuit="""
490
+ 0: ───X───X───×───X───X───X───
491
+
492
+ 1: ───────Y───×───×───X───I───
493
+
494
+ 2: ───────────────×───×───X───
495
+
496
+ 3: ───────────────────×───I───
497
+ """,
524
498
  schema='XX_PAIR',
525
499
  single_qubit_gate_moments_only=False,
526
500
  )
527
501
 
528
502
 
529
- def test_multiple_clifford_pieces_case1():
503
+ def test_multiple_clifford_pieces_case1() -> None:
530
504
  """Test case diagrams.
531
505
  Input:
532
506
  a: ───H───────H───────@───────────H───────H───
533
507
 
534
508
  b: ───H───H───H───H───@^0.5───H───H───H───H───
535
- Output:
536
- a: ───H───X───H───X───Y───@───────X───H───X───PhXZ(a=0.5,x=0.5,z=-1)───
537
-
538
- b: ───H───H───H───H───────@^0.5───H───H───H───H────────────────────────
539
509
  """
540
510
  a = cirq.NamedQubit('a')
541
511
  b = cirq.NamedQubit('b')
@@ -552,24 +522,20 @@ def test_multiple_clifford_pieces_case1():
552
522
  cirq.Moment(H(a), H(b)),
553
523
  ),
554
524
  expected_circuit="""
555
- a: ───H───X───H───X───Y───@───────X───H───X───PhXZ(a=0.5,x=0.5,z=-1)───
556
-
557
- b: ───H───H───H───H───────@^0.5───H───H───H───H────────────────────────
525
+ a: ───H───X───H───PhXZ(a=-0.5,x=0,z=-1)───@───────X───H───X───PhXZ(a=0.5,x=0.5,z=-1)───
526
+
527
+ b: ───H───H───H───H───────────────────────@^0.5───H───H───H───H────────────────────────
558
528
  """,
559
529
  schema="XX_PAIR",
560
530
  )
561
531
 
562
532
 
563
- def test_multiple_clifford_pieces_case2():
533
+ def test_multiple_clifford_pieces_case2() -> None:
564
534
  """Test case diagrams.
565
535
  Input:
566
536
  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)───@───
567
537
  │ │
568
538
  b: ───@───────────────────────────────────────────────────────────────────────────@───
569
- Output:
570
- 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───
571
- │ │
572
- b: ───@───X───────────────────────X───────────────────────X───────────────────────@───X───
573
539
  """
574
540
  a = cirq.NamedQubit('a')
575
541
  b = cirq.NamedQubit('b')
@@ -583,20 +549,17 @@ def test_multiple_clifford_pieces_case2():
583
549
  cirq.Moment(phased_xz_gate.on(a)),
584
550
  cirq.Moment(CZ(a, b)),
585
551
  ),
586
- expected_circuit=cirq.Circuit(
587
- cirq.Moment(CZ(a, b)),
588
- cirq.Moment(phased_xz_gate.on(a), X(b)),
589
- cirq.Moment(phased_xz_gate.on(a), X(b)),
590
- cirq.Moment(phased_xz_gate.on(a), X(b)),
591
- cirq.Moment(CZ(a, b)),
592
- cirq.Moment(Z(a), X(b)),
593
- ),
552
+ expected_circuit="""
553
+ 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)───@───
554
+ │ │
555
+ b: ───@───X───────────────────────X───────────────────────I───────────────────────@───
556
+ """,
594
557
  schema='XX_PAIR',
595
558
  single_qubit_gate_moments_only=False,
596
559
  )
597
560
 
598
561
 
599
- def test_insert_new_moment():
562
+ def test_absorb_remaining_dd_sequence() -> None:
600
563
  """Test case diagrams.
601
564
  Input:
602
565
  a: ───H───────H───@───@───────
@@ -604,12 +567,6 @@ def test_insert_new_moment():
604
567
  b: ───H───H───H───X───@^0.5───
605
568
 
606
569
  c: ───H───────────────H───────
607
- Output:
608
- a: ───H───X───H───@───Z───@────────────────────────
609
- │ │
610
- b: ───H───H───H───X───────@^0.5────────────────────
611
-
612
- c: ───H───X───X───────X───PhXZ(a=-0.5,x=0.5,z=0)───
613
570
  """
614
571
  a = cirq.NamedQubit('a')
615
572
  b = cirq.NamedQubit('b')
@@ -622,22 +579,18 @@ def test_insert_new_moment():
622
579
  cirq.Moment(CNOT(a, b)),
623
580
  cirq.Moment(CZPowGate(exponent=0.5).on(a, b), H(c)),
624
581
  ),
625
- expected_circuit=cirq.Circuit(
626
- cirq.Moment(H(a), H(b), H(c)),
627
- cirq.Moment(H(b), X(a), X(c)),
628
- cirq.Moment(H(a), H(b), X(c)),
629
- cirq.Moment(CNOT(a, b)),
630
- cirq.Moment(Z(a), X(c)),
631
- cirq.Moment(
632
- CZPowGate(exponent=0.5).on(a, b),
633
- cirq.PhasedXZGate(axis_phase_exponent=-0.5, x_exponent=0.5, z_exponent=0).on(c),
634
- ),
635
- ),
582
+ expected_circuit="""
583
+ a: ───H───X───PhXZ(a=-0.5,x=0.5,z=0)───@───@───────
584
+ │ │
585
+ b: ───H───H───H────────────────────────X───@^0.5───
586
+
587
+ c: ───H───X───X────────────────────────────H───────
588
+ """,
636
589
  schema="XX_PAIR",
637
590
  )
638
591
 
639
592
 
640
- def test_with_non_clifford_measurements():
593
+ def test_with_non_clifford_measurements() -> None:
641
594
  """Test case diagrams.
642
595
  Input:
643
596
  0: ───────────H───@───H───M───
@@ -659,20 +612,20 @@ def test_with_non_clifford_measurements():
659
612
  cirq.Moment([cirq.M(qubits[i]) for i in [0, 1, 2, 3]]),
660
613
  ),
661
614
  expected_circuit="""
662
- 0: ───────────H───@───H───X───M───
615
+ 0: ───────────H───@───PhXZ(a=0.5,x=0.5,z=0)───M───
663
616
 
664
- 1: ───H───@───X───@───X───────M───
617
+ 1: ───H───@───X───@───X───────────────────────M───
665
618
 
666
- 2: ───H───@───H───@───X───X───M───
619
+ 2: ───H───@───H───@───I───────────────────────M───
667
620
 
668
- 3: ───────────H───@───H───────M───
621
+ 3: ───────────H───@───H───────────────────────M───
669
622
  """,
670
623
  schema="XX_PAIR",
671
624
  single_qubit_gate_moments_only=True,
672
625
  )
673
626
 
674
627
 
675
- def test_cross_clifford_pieces_filling_merge():
628
+ def test_cross_clifford_pieces_filling_merge() -> None:
676
629
  """Test case diagrams.
677
630
  Input:
678
631
  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───
@@ -688,21 +641,6 @@ def test_cross_clifford_pieces_filling_merge():
688
641
  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───
689
642
 
690
643
  6: ───────────────────────────────────────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)─────────────────────────────@───PhXZ(a=0.2,x=0.2,z=0.1)───H───
691
- Output:
692
-
693
- 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────────────────────────
694
- │ │
695
- 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────────────────────────
696
-
697
- 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)───
698
- │ │ │
699
- 3: ─────────────────────────────┼───PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────X─────────────────────────@───Y───────────────────────────PhXZ(a=0.5,x=0.5,z=0)────
700
-
701
- 4: ─────────────────────────────┼─────────────────────────────@─────────────────────────X─────────────────────────────Y───────────────────────────PhXZ(a=0.5,x=0.5,z=0)────
702
- │ │
703
- 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────────────────────────
704
-
705
- 6: ───────────────────────────────────────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───X─────────────────────────@───PhXZ(a=0.8,x=0.8,z=0.5)─────H────────────────────────
706
644
  """ # noqa: E501
707
645
  qubits = cirq.LineQubit.range(7)
708
646
  phased_xz_gate = cirq.PhasedXZGate(axis_phase_exponent=0.2, x_exponent=0.2, z_exponent=0.1)
@@ -721,30 +659,31 @@ def test_cross_clifford_pieces_filling_merge():
721
659
  cirq.Moment([H.on(q) for q in qubits]),
722
660
  ),
723
661
  expected_circuit="""
724
- 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────────────────────────
662
+ 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────────────────────────
725
663
  │ │
726
- 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────────────────────────
664
+ 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────────────────────────
727
665
 
728
- 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)───
666
+ 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)───
729
667
  │ │ │
730
- 3: ─────────────────────────────┼───PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────X─────────────────────────@───Y───────────────────────────PhXZ(a=0.5,x=0.5,z=0)────
668
+ 3: ─────────────────────────────┼───PhXZ(a=0.2,x=0.2,z=0.1)───@─────────────────────────X─────────────────────────@───Y─────────────────────────PhXZ(a=0.5,x=0.5,z=0)────
731
669
 
732
- 4: ─────────────────────────────┼─────────────────────────────@─────────────────────────X─────────────────────────────Y───────────────────────────PhXZ(a=0.5,x=0.5,z=0)────
670
+ 4: ─────────────────────────────┼─────────────────────────────@─────────────────────────X─────────────────────────────Y─────────────────────────PhXZ(a=0.5,x=0.5,z=0)────
733
671
  │ │
734
- 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────────────────────────
672
+ 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────────────────────────
735
673
 
736
- 6: ───────────────────────────────────────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───X─────────────────────────@───PhXZ(a=0.8,x=0.8,z=0.5)─────H────────────────────────
674
+ 6: ───────────────────────────────────────────────────────────PhXZ(a=0.2,x=0.2,z=0.1)───I─────────────────────────@───PhXZ(a=0.2,x=0.2,z=0.1)───H────────────────────────
737
675
  """, # noqa: E501
738
676
  )
739
677
 
740
678
 
741
- def test_pull_through_phxz_gate_case1():
679
+ def test_pull_through_phxz_gate_case1() -> None:
742
680
  """Test case diagrams.
743
- Input:
681
+
682
+ Input:
744
683
  a: ───H───────PhXZ(a=0.25,x=-1,z=0)───────@───
745
684
 
746
685
  b: ───H───H───H───────────────────────H───X───
747
- Output: expected circuit diagram below.
686
+ Output: expected circuit diagram below.
748
687
  """
749
688
  a = cirq.NamedQubit('a')
750
689
  b = cirq.NamedQubit('b')
@@ -759,21 +698,22 @@ def test_pull_through_phxz_gate_case1():
759
698
  cirq.Moment(CNOT(a, b)),
760
699
  ),
761
700
  expected_circuit="""
762
- a: ───H───X───PhXZ(a=0.25,x=-1,z=0)───X───@───Z───
763
-
764
- b: ───H───H───H───────────────────────H───X───────
701
+ a: ───H───X───PhXZ(a=0.25,x=-1,z=0)───PhXZ(a=0.5,x=1,z=0)───@───
702
+
703
+ b: ───H───H───H───────────────────────H─────────────────────X───
765
704
  """,
766
705
  schema="XX_PAIR",
767
706
  )
768
707
 
769
708
 
770
- def test_pull_through_phxz_gate_case2():
709
+ def test_pull_through_phxz_gate_case2() -> None:
771
710
  """Test case diagrams.
772
- Input:
711
+
712
+ Input:
773
713
  a: ───H───────PhXZ(a=0.2,x=-1,z=0)───────@───
774
714
 
775
715
  b: ───H───H───H───────────────────────H───X───
776
- Output: expected circuit diagram below.
716
+ Output: expected circuit diagram below.
777
717
  """
778
718
  a = cirq.NamedQubit('a')
779
719
  b = cirq.NamedQubit('b')
@@ -788,15 +728,15 @@ def test_pull_through_phxz_gate_case2():
788
728
  cirq.Moment(CNOT(a, b)),
789
729
  ),
790
730
  expected_circuit="""
791
- a: ───H───X───PhXZ(a=0.1,x=0,z=0.4)───X───@───X───
792
-
793
- b: ───H───H───H───────────────────────H───X───X───
731
+ a: ───H───I───PhXZ(a=0.2,x=-1,z=0)───I───@───
732
+
733
+ b: ───H───H───H──────────────────────H───X───
794
734
  """,
795
735
  schema="XX_PAIR",
796
736
  )
797
737
 
798
738
 
799
- def test_merge_before_non_cliffords():
739
+ def test_merge_before_non_cliffords() -> None:
800
740
  """Test case diagrams.
801
741
  Input circuit:
802
742
  0: ───X──────────────────────────────────────────────────M───
@@ -819,58 +759,112 @@ def test_merge_before_non_cliffords():
819
759
  assert_dd(
820
760
  input_circuit=input_circuit,
821
761
  expected_circuit="""
822
- 0: ───X───X───X───────────────────────X──────────────────────X───M───
762
+ 0: ───X───X───X──────────────────────────────────────────M───
823
763
 
824
- 1: ───X───X───PhXZ(a=-1,x=0,z=-0.5)───Y───FSim(0, 0.0637π)───────M───
825
-
826
- 2: ───X───X───S───────────────────────────FSim(0, 0.0637π)───────M───
764
+ 1: ───X───X───PhXZ(a=-1.25,x=1,z=0)───FSim(0, 0.0637π)───M───
765
+
766
+ 2: ───X───X───S───────────────────────FSim(0, 0.0637π)───M───
827
767
  """,
828
768
  schema="XX_PAIR",
829
769
  )
830
770
 
831
771
 
832
- @pytest.mark.parametrize(
833
- 'single_qubit_gate_moments_only, expected_diagram',
834
- [
835
- (
836
- True,
837
- # With single_qubit_gate_moments_only=True, the second DD gate on q2
838
- # is inserted in a new moment after the CZ gate.
839
- """
840
- 0: ───X───X───@───────M───
841
-
842
- 1: ───X───X───@───────M───
772
+ def test_runtime_error_if_pulled_through_not_empty_mocked() -> None:
773
+ """Tests that a RuntimeError is raised if pulled_through is not empty at the end.
843
774
 
844
- 2: ───X───X───────X───M───
845
- """,
846
- ),
847
- (
848
- False,
849
- # With single_qubit_gate_moments_only=False, the second DD gate on q2
850
- # is inserted in the same moment as the CZ gate.
851
- """
852
- 0: ───X───X───@───M───
853
-
854
- 1: ───X───X───@───M───
775
+ This test explicitly mocks the internal state to simulate a scenario where
776
+ the `pulled_through` PauliString is not empty after processing all moments.
777
+ Under normal operation, the `_Grid` and `add_dynamical_decoupling`
778
+ logic should ensure `pulled_through` is always empty at the end, making
779
+ this RuntimeError theoretically unreachable. This test verifies the
780
+ defensive check itself.
781
+ """
782
+ q0: cirq.Qid = cirq.NamedQubit('q0')
783
+ circuit = cirq.FrozenCircuit(cirq.Moment(cirq.I(q0))) # A minimal circuit
855
784
 
856
- 2: ───X───X───X───M───
857
- """,
858
- ),
859
- ],
860
- )
861
- def test_single_qubit_gate_moments_only_true_vs_false(
862
- single_qubit_gate_moments_only, expected_diagram
863
- ):
785
+ # Create a mock _Grid instance that would lead to an unabsorbed Pauli.
786
+ # We need an INSERTABLE slot, but no STOP label, and no self-cancellation.
787
+ # To achieve this, we'll mock the `pulled_through.after` method to *not* clear it.
788
+ # This is a deep mock to hit the specific RuntimeError line.
789
+
790
+ # First, create a _Grid that allows insertion but no stopping.
791
+ # This is a hypothetical scenario that `_Grid.from_circuit` should prevent.
792
+ mock_gate_types = {q0: {0: _CellType.INSERTABLE}}
793
+ mock_need_to_stop = {q0: {0: False}} # Crucially, no stop gate
794
+
795
+ mock_labeled_circuit = _Grid(
796
+ gate_types=mock_gate_types, need_to_stop=mock_need_to_stop, circuit=circuit
797
+ )
798
+
799
+ # Mock _Grid.from_circuit to return our custom mock
800
+ with mock.patch(
801
+ 'cirq.transformers.dynamical_decoupling._Grid.from_circuit',
802
+ return_value=mock_labeled_circuit,
803
+ ):
804
+ # Mock the PauliString.after method to ensure `pulled_through` remains non-empty.
805
+ with mock.patch('cirq.ops.PauliString.after', return_value=cirq.PauliString({q0: cirq.X})):
806
+ with pytest.raises(
807
+ RuntimeError, match="Expect empty remaining Paulis after the dd insertion."
808
+ ):
809
+ add_dynamical_decoupling(
810
+ circuit, schema='XX_PAIR', single_qubit_gate_moments_only=True
811
+ )
812
+
813
+
814
+ def test_labeled_circuit_str():
815
+ """Input circuit:
816
+ 0: ───X──────────────────────────────────────────────────M───
817
+
818
+ 1: ───X───────PhXZ(a=-1,x=0,z=-0.5)───FSim(0, 0.0637π)───M───
819
+
820
+ 2: ───X───X───S───────────────────────FSim(0, 0.0637π)───M───
821
+ """
864
822
  q0, q1, q2 = cirq.LineQubit.range(3)
865
823
  input_circuit = cirq.Circuit(
866
824
  cirq.Moment([X(q) for q in [q0, q1, q2]]),
867
- cirq.Moment([X(q) for q in [q0, q1]]),
868
- cirq.Moment(CZ(q0, q1)),
825
+ cirq.Moment(X(q2)),
826
+ cirq.Moment(
827
+ cirq.PhasedXZGate(axis_phase_exponent=-1, x_exponent=0, z_exponent=-0.5).on(q1),
828
+ (Z**0.5).on(q2),
829
+ ),
830
+ cirq.Moment(cirq.FSimGate(theta=0, phi=0.2).on(q1, q2)),
869
831
  cirq.Moment([cirq.M(q) for q in [q0, q1, q2]]),
870
832
  )
871
- assert_dd(
872
- input_circuit=input_circuit,
873
- expected_circuit=expected_diagram,
874
- schema="XX_PAIR",
875
- single_qubit_gate_moments_only=single_qubit_gate_moments_only,
833
+ labeled_circuit = _Grid.from_circuit(input_circuit, single_qubit_gate_moments_only=True)
834
+ assert str(labeled_circuit) == (
835
+ """Grid Repr:
836
+ | 0 | 1 | 2 | 3 | 4 |
837
+ -----+-----+-----+-----+-----+-----+
838
+ q(0) | d | i | i,s | d | w |
839
+ q(1) | d | i | d,s | w | w |
840
+ q(2) | d | d | d,s | w | w |"""
876
841
  )
842
+
843
+
844
+ def test_labeled_circuit_str_empty():
845
+ """Tests the __str__ method of _Grid for empty and no-qubit circuits."""
846
+ # Test case for an empty circuit (no moments, no qubits)
847
+ empty_circuit = cirq.Circuit()
848
+ labeled_empty = _Grid.from_circuit(empty_circuit, single_qubit_gate_moments_only=True)
849
+ assert str(labeled_empty) == "Grid(empty)"
850
+
851
+
852
+ def test_add_dynamical_decoupling_with_deep_context_raises_error():
853
+ """Tests that add_dynamical_decoupling raises an error with deep context."""
854
+ q = cirq.NamedQubit('q')
855
+ circuit = cirq.Circuit(cirq.H(q))
856
+ context = cirq.TransformerContext(deep=True)
857
+ with pytest.raises(ValueError, match="Deep transformation is not supported."):
858
+ add_dynamical_decoupling(circuit, context=context)
859
+
860
+
861
+ def test_context_logger():
862
+ q = cirq.NamedQubit('q')
863
+ circuit = cirq.Circuit(cirq.H(q))
864
+ mock_logger = mock.MagicMock(spec=cirq.TransformerLogger)
865
+ context = cirq.TransformerContext(logger=mock_logger)
866
+
867
+ add_dynamical_decoupling(circuit, context=context)
868
+
869
+ mock_logger.log.assert_called_once()
870
+ assert "Preprocessed input circuit grid repr:" in mock_logger.log.call_args[0][0]