cirq-core 1.7.0.dev20250924231107__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 (392) 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 +7 -13
  10. cirq/circuits/circuit_operation.py +2 -1
  11. cirq/circuits/circuit_test.py +13 -12
  12. cirq/circuits/frozen_circuit.py +3 -2
  13. cirq/circuits/moment.py +3 -15
  14. cirq/circuits/optimization_pass.py +2 -1
  15. cirq/circuits/qasm_output.py +39 -10
  16. cirq/circuits/qasm_output_test.py +51 -2
  17. cirq/circuits/text_diagram_drawer.py +2 -1
  18. cirq/contrib/acquaintance/bipartite.py +2 -1
  19. cirq/contrib/acquaintance/devices.py +1 -1
  20. cirq/contrib/acquaintance/executor.py +4 -5
  21. cirq/contrib/acquaintance/executor_test.py +2 -1
  22. cirq/contrib/acquaintance/gates.py +2 -1
  23. cirq/contrib/acquaintance/gates_test.py +1 -1
  24. cirq/contrib/acquaintance/inspection_utils.py +2 -1
  25. cirq/contrib/acquaintance/mutation_utils.py +2 -1
  26. cirq/contrib/acquaintance/optimizers.py +2 -1
  27. cirq/contrib/acquaintance/permutation.py +2 -1
  28. cirq/contrib/acquaintance/permutation_test.py +1 -1
  29. cirq/contrib/acquaintance/shift.py +2 -1
  30. cirq/contrib/acquaintance/shift_swap_network.py +2 -1
  31. cirq/contrib/acquaintance/strategies/complete.py +3 -2
  32. cirq/contrib/acquaintance/strategies/cubic.py +2 -1
  33. cirq/contrib/acquaintance/strategies/quartic_paired.py +2 -1
  34. cirq/contrib/acquaintance/strategies/quartic_paired_test.py +1 -1
  35. cirq/contrib/acquaintance/testing.py +2 -1
  36. cirq/contrib/acquaintance/topological_sort.py +2 -1
  37. cirq/contrib/bayesian_network/bayesian_network_gate.py +3 -2
  38. cirq/contrib/circuitdag/circuit_dag.py +4 -2
  39. cirq/contrib/custom_simulators/custom_state_simulator.py +2 -1
  40. cirq/contrib/custom_simulators/custom_state_simulator_test.py +1 -1
  41. cirq/contrib/graph_device/graph_device.py +2 -1
  42. cirq/contrib/graph_device/graph_device_test.py +2 -1
  43. cirq/contrib/graph_device/hypergraph.py +2 -1
  44. cirq/contrib/graph_device/uniform_graph_device.py +2 -1
  45. cirq/contrib/json.py +14 -2
  46. cirq/contrib/json_test_data/BayesianNetworkGate.json +10 -0
  47. cirq/contrib/json_test_data/BayesianNetworkGate.repr +3 -0
  48. cirq/contrib/json_test_data/QuantumVolumeResult.json +169 -0
  49. cirq/contrib/json_test_data/QuantumVolumeResult.repr +22 -0
  50. cirq/contrib/json_test_data/SwapPermutationGate.json +3 -0
  51. cirq/contrib/json_test_data/SwapPermutationGate.repr +1 -0
  52. cirq/contrib/json_test_data/spec.py +0 -2
  53. cirq/contrib/noise_models/noise_models.py +2 -1
  54. cirq/contrib/paulistring/clifford_optimize.py +20 -2
  55. cirq/contrib/paulistring/optimize.py +1 -1
  56. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +146 -35
  57. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +74 -171
  58. cirq/contrib/paulistring/recombine.py +5 -2
  59. cirq/contrib/paulistring/separate.py +1 -1
  60. cirq/contrib/qasm_import/_parser.py +2 -1
  61. cirq/contrib/qasm_import/_parser_test.py +3 -3
  62. cirq/contrib/quantikz/__init__.py +21 -0
  63. cirq/contrib/quantikz/circuit_to_latex_quantikz.py +680 -0
  64. cirq/contrib/quantikz/circuit_to_latex_quantikz_test.py +253 -0
  65. cirq/contrib/quantikz/circuit_to_latex_render.py +424 -0
  66. cirq/contrib/quantikz/circuit_to_latex_render_test.py +44 -0
  67. cirq/contrib/quantum_volume/quantum_volume.py +2 -1
  68. cirq/contrib/quimb/density_matrix.py +1 -1
  69. cirq/contrib/quimb/grid_circuits.py +2 -1
  70. cirq/contrib/quimb/grid_circuits_test.py +1 -1
  71. cirq/contrib/quimb/mps_simulator.py +4 -3
  72. cirq/contrib/quimb/state_vector.py +2 -1
  73. cirq/contrib/quirk/export_to_quirk.py +2 -1
  74. cirq/contrib/quirk/linearize_circuit.py +1 -1
  75. cirq/contrib/quirk/quirk_gate.py +2 -1
  76. cirq/contrib/routing/device.py +1 -1
  77. cirq/contrib/routing/greedy.py +2 -1
  78. cirq/contrib/routing/initialization.py +2 -1
  79. cirq/contrib/routing/router.py +2 -1
  80. cirq/contrib/routing/swap_network.py +2 -1
  81. cirq/contrib/routing/utils.py +2 -1
  82. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +7 -5
  83. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +6 -6
  84. cirq/devices/device.py +2 -1
  85. cirq/devices/grid_device_metadata.py +2 -1
  86. cirq/devices/grid_qubit.py +7 -6
  87. cirq/devices/insertion_noise_model.py +2 -1
  88. cirq/devices/line_qubit.py +2 -1
  89. cirq/devices/named_topologies.py +2 -1
  90. cirq/devices/noise_model.py +2 -1
  91. cirq/devices/noise_model_test.py +1 -1
  92. cirq/devices/noise_properties.py +2 -1
  93. cirq/devices/superconducting_qubits_noise_properties_test.py +2 -1
  94. cirq/devices/thermal_noise_model.py +2 -1
  95. cirq/experiments/__init__.py +2 -0
  96. cirq/experiments/benchmarking/parallel_xeb.py +2 -1
  97. cirq/experiments/benchmarking/parallel_xeb_test.py +1 -1
  98. cirq/experiments/fidelity_estimation.py +2 -1
  99. cirq/experiments/fidelity_estimation_test.py +1 -1
  100. cirq/experiments/ghz_2d.py +150 -0
  101. cirq/experiments/ghz_2d_test.py +155 -0
  102. cirq/experiments/n_qubit_tomography.py +2 -1
  103. cirq/experiments/n_qubit_tomography_test.py +1 -1
  104. cirq/experiments/purity_estimation.py +1 -1
  105. cirq/experiments/qubit_characterizations.py +2 -1
  106. cirq/experiments/random_quantum_circuit_generation.py +2 -1
  107. cirq/experiments/random_quantum_circuit_generation_test.py +2 -1
  108. cirq/experiments/readout_confusion_matrix.py +2 -1
  109. cirq/experiments/readout_confusion_matrix_test.py +1 -1
  110. cirq/experiments/single_qubit_readout_calibration.py +2 -1
  111. cirq/experiments/single_qubit_readout_calibration_test.py +1 -1
  112. cirq/experiments/t1_decay_experiment.py +2 -1
  113. cirq/experiments/two_qubit_xeb.py +2 -1
  114. cirq/experiments/two_qubit_xeb_test.py +1 -1
  115. cirq/experiments/xeb_fitting.py +2 -1
  116. cirq/experiments/xeb_fitting_test.py +1 -1
  117. cirq/experiments/xeb_sampling.py +5 -3
  118. cirq/experiments/xeb_sampling_test.py +1 -1
  119. cirq/experiments/xeb_simulation.py +2 -1
  120. cirq/experiments/xeb_simulation_test.py +2 -1
  121. cirq/experiments/z_phase_calibration.py +2 -1
  122. cirq/experiments/z_phase_calibration_test.py +18 -3
  123. cirq/interop/quirk/cells/__init__.py +1 -2
  124. cirq/interop/quirk/cells/all_cells.py +2 -1
  125. cirq/interop/quirk/cells/arithmetic_cells.py +2 -1
  126. cirq/interop/quirk/cells/cell.py +2 -1
  127. cirq/interop/quirk/cells/composite_cell.py +2 -1
  128. cirq/interop/quirk/cells/composite_cell_test.py +1 -1
  129. cirq/interop/quirk/cells/control_cells.py +2 -1
  130. cirq/interop/quirk/cells/frequency_space_cells.py +1 -1
  131. cirq/interop/quirk/cells/ignored_cells.py +1 -1
  132. cirq/interop/quirk/cells/input_cells.py +2 -1
  133. cirq/interop/quirk/cells/input_rotation_cells.py +2 -1
  134. cirq/interop/quirk/cells/measurement_cells.py +2 -1
  135. cirq/interop/quirk/cells/parse.py +2 -11
  136. cirq/interop/quirk/cells/qubit_permutation_cells.py +2 -1
  137. cirq/interop/quirk/cells/scalar_cells.py +2 -1
  138. cirq/interop/quirk/cells/single_qubit_rotation_cells.py +2 -1
  139. cirq/interop/quirk/cells/swap_cell.py +2 -1
  140. cirq/interop/quirk/cells/unsupported_cells.py +1 -1
  141. cirq/interop/quirk/url_to_circuit.py +2 -1
  142. cirq/json_resolver_cache.py +0 -2
  143. cirq/linalg/decompositions.py +6 -2
  144. cirq/linalg/decompositions_test.py +1 -0
  145. cirq/linalg/diagonalize.py +1 -1
  146. cirq/linalg/predicates.py +2 -1
  147. cirq/linalg/tolerance.py +2 -1
  148. cirq/linalg/transformations.py +2 -1
  149. cirq/ops/arithmetic_operation.py +2 -1
  150. cirq/ops/arithmetic_operation_test.py +1 -1
  151. cirq/ops/boolean_hamiltonian.py +4 -3
  152. cirq/ops/classically_controlled_operation.py +3 -2
  153. cirq/ops/clifford_gate.py +2 -1
  154. cirq/ops/clifford_gate_test.py +1 -2
  155. cirq/ops/common_channels.py +2 -1
  156. cirq/ops/common_gates.py +2 -1
  157. cirq/ops/control_values.py +2 -1
  158. cirq/ops/controlled_gate.py +3 -2
  159. cirq/ops/controlled_gate_test.py +2 -1
  160. cirq/ops/controlled_operation.py +3 -2
  161. cirq/ops/controlled_operation_test.py +2 -1
  162. cirq/ops/dense_pauli_string.py +3 -13
  163. cirq/ops/diagonal_gate.py +3 -2
  164. cirq/ops/eigen_gate.py +9 -7
  165. cirq/ops/fourier_transform.py +3 -2
  166. cirq/ops/fourier_transform_test.py +2 -4
  167. cirq/ops/fsim_gate.py +3 -2
  168. cirq/ops/gate_operation.py +8 -12
  169. cirq/ops/gateset.py +22 -2
  170. cirq/ops/global_phase_op.py +3 -2
  171. cirq/ops/greedy_qubit_manager.py +2 -1
  172. cirq/ops/identity.py +2 -1
  173. cirq/ops/kraus_channel.py +2 -1
  174. cirq/ops/linear_combinations.py +8 -3
  175. cirq/ops/linear_combinations_test.py +23 -1
  176. cirq/ops/matrix_gates.py +2 -1
  177. cirq/ops/measure_util.py +2 -1
  178. cirq/ops/measurement_gate.py +2 -1
  179. cirq/ops/mixed_unitary_channel.py +2 -1
  180. cirq/ops/named_qubit.py +2 -2
  181. cirq/ops/op_tree.py +2 -1
  182. cirq/ops/parallel_gate.py +3 -2
  183. cirq/ops/parity_gates.py +2 -1
  184. cirq/ops/pauli_interaction_gate.py +2 -1
  185. cirq/ops/pauli_measurement_gate.py +2 -1
  186. cirq/ops/pauli_string.py +6 -12
  187. cirq/ops/pauli_string_phasor.py +3 -2
  188. cirq/ops/pauli_string_raw_types.py +2 -1
  189. cirq/ops/pauli_string_test.py +2 -2
  190. cirq/ops/pauli_sum_exponential.py +2 -1
  191. cirq/ops/permutation_gate.py +2 -1
  192. cirq/ops/phased_iswap_gate.py +3 -2
  193. cirq/ops/phased_x_gate.py +5 -4
  194. cirq/ops/phased_x_z_gate.py +12 -5
  195. cirq/ops/projector.py +2 -1
  196. cirq/ops/qubit_manager.py +2 -1
  197. cirq/ops/qubit_order.py +2 -1
  198. cirq/ops/qubit_order_or_list.py +1 -1
  199. cirq/ops/random_gate_channel.py +3 -2
  200. cirq/ops/raw_types.py +7 -15
  201. cirq/ops/raw_types_test.py +4 -3
  202. cirq/ops/state_preparation_channel.py +2 -1
  203. cirq/ops/three_qubit_gates.py +3 -2
  204. cirq/ops/two_qubit_diagonal_gate.py +3 -2
  205. cirq/ops/uniform_superposition_gate.py +2 -1
  206. cirq/ops/wait_gate.py +10 -4
  207. cirq/protocols/act_on_protocol.py +2 -1
  208. cirq/protocols/act_on_protocol_test.py +2 -1
  209. cirq/protocols/apply_channel_protocol.py +2 -1
  210. cirq/protocols/apply_mixture_protocol.py +2 -1
  211. cirq/protocols/apply_mixture_protocol_test.py +2 -1
  212. cirq/protocols/apply_unitary_protocol.py +2 -1
  213. cirq/protocols/apply_unitary_protocol_test.py +2 -0
  214. cirq/protocols/approximate_equality_protocol.py +2 -1
  215. cirq/protocols/circuit_diagram_info_protocol.py +2 -1
  216. cirq/protocols/decompose_protocol.py +2 -12
  217. cirq/protocols/has_stabilizer_effect_protocol.py +1 -1
  218. cirq/protocols/hash_from_pickle_test.py +2 -2
  219. cirq/protocols/inverse_protocol.py +2 -1
  220. cirq/protocols/json_serialization.py +2 -1
  221. cirq/protocols/kraus_protocol.py +4 -3
  222. cirq/protocols/kraus_protocol_test.py +2 -2
  223. cirq/protocols/measurement_key_protocol.py +2 -1
  224. cirq/protocols/mixture_protocol.py +2 -1
  225. cirq/protocols/pow_protocol.py +2 -1
  226. cirq/protocols/qasm.py +2 -1
  227. cirq/protocols/qid_shape_protocol.py +2 -1
  228. cirq/protocols/resolve_parameters.py +16 -14
  229. cirq/protocols/trace_distance_bound.py +2 -1
  230. cirq/protocols/unitary_protocol.py +21 -21
  231. cirq/qis/channels.py +1 -1
  232. cirq/qis/channels_test.py +1 -1
  233. cirq/qis/clifford_tableau.py +2 -1
  234. cirq/qis/entropy.py +2 -2
  235. cirq/qis/quantum_state_representation.py +2 -1
  236. cirq/qis/states.py +7 -2
  237. cirq/sim/classical_simulator.py +2 -1
  238. cirq/sim/clifford/clifford_simulator.py +2 -1
  239. cirq/sim/clifford/clifford_simulator_test.py +1 -1
  240. cirq/sim/clifford/clifford_tableau_simulation_state.py +2 -1
  241. cirq/sim/clifford/stabilizer_ch_form_simulation_state.py +2 -1
  242. cirq/sim/clifford/stabilizer_sampler.py +1 -1
  243. cirq/sim/clifford/stabilizer_simulation_state.py +2 -1
  244. cirq/sim/clifford/stabilizer_state_ch_form.py +3 -2
  245. cirq/sim/clifford/stabilizer_state_ch_form_test.py +0 -1
  246. cirq/sim/density_matrix_simulation_state.py +2 -1
  247. cirq/sim/density_matrix_simulator.py +2 -1
  248. cirq/sim/density_matrix_utils.py +2 -1
  249. cirq/sim/mux.py +2 -1
  250. cirq/sim/mux_test.py +0 -1
  251. cirq/sim/simulation_product_state.py +2 -1
  252. cirq/sim/simulation_product_state_test.py +2 -1
  253. cirq/sim/simulation_state.py +2 -1
  254. cirq/sim/simulation_state_base.py +2 -1
  255. cirq/sim/simulation_state_test.py +2 -1
  256. cirq/sim/simulation_utils.py +2 -1
  257. cirq/sim/simulator.py +2 -1
  258. cirq/sim/simulator_base.py +2 -1
  259. cirq/sim/simulator_base_test.py +2 -1
  260. cirq/sim/simulator_test.py +2 -1
  261. cirq/sim/sparse_simulator.py +2 -1
  262. cirq/sim/state_vector.py +2 -1
  263. cirq/sim/state_vector_simulation_state.py +2 -1
  264. cirq/sim/state_vector_simulator.py +2 -1
  265. cirq/sim/state_vector_test.py +1 -2
  266. cirq/study/__init__.py +1 -0
  267. cirq/study/flatten_expressions.py +2 -1
  268. cirq/study/resolver.py +31 -18
  269. cirq/study/resolver_test.py +1 -1
  270. cirq/study/result.py +2 -1
  271. cirq/study/sweepable.py +2 -1
  272. cirq/study/sweeps.py +26 -1
  273. cirq/study/sweeps_test.py +24 -0
  274. cirq/testing/_compat_test_data/__init__.py +3 -3
  275. cirq/testing/circuit_compare.py +2 -1
  276. cirq/testing/consistent_act_on_test.py +1 -1
  277. cirq/testing/consistent_controlled_gate_op.py +1 -1
  278. cirq/testing/consistent_controlled_gate_op_test.py +2 -1
  279. cirq/testing/consistent_protocols.py +2 -1
  280. cirq/testing/consistent_protocols_test.py +3 -3
  281. cirq/testing/consistent_qasm.py +2 -1
  282. cirq/testing/consistent_resolve_parameters.py +1 -1
  283. cirq/testing/consistent_unitary.py +1 -1
  284. cirq/testing/consistent_unitary_test.py +1 -1
  285. cirq/testing/deprecation.py +1 -1
  286. cirq/testing/devices.py +3 -2
  287. cirq/testing/equals_tester.py +4 -3
  288. cirq/testing/equivalent_basis_map.py +4 -2
  289. cirq/testing/json.py +3 -2
  290. cirq/testing/logs.py +1 -1
  291. cirq/testing/op_tree.py +1 -1
  292. cirq/testing/order_tester.py +2 -2
  293. cirq/testing/pytest_utils.py +2 -1
  294. cirq/testing/random_circuit.py +2 -1
  295. cirq/testing/random_circuit_test.py +2 -1
  296. cirq/testing/repr_pretty_tester.py +3 -3
  297. cirq/transformers/__init__.py +1 -0
  298. cirq/transformers/_connected_component.py +231 -0
  299. cirq/transformers/_connected_component_test.py +200 -0
  300. cirq/transformers/align_test.py +13 -13
  301. cirq/transformers/analytical_decompositions/clifford_decomposition.py +8 -7
  302. cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +5 -5
  303. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +11 -10
  304. cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +6 -6
  305. cirq/transformers/analytical_decompositions/cphase_to_fsim.py +3 -2
  306. cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +11 -10
  307. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +8 -7
  308. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +17 -20
  309. cirq/transformers/analytical_decompositions/single_qubit_decompositions_test.py +33 -27
  310. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +1 -1
  311. cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +1 -1
  312. cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +12 -11
  313. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +5 -2
  314. cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +3 -3
  315. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +2 -1
  316. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +2 -1
  317. cirq/transformers/analytical_decompositions/two_qubit_to_ms_test.py +2 -2
  318. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +2 -1
  319. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +32 -30
  320. cirq/transformers/drop_negligible_operations_test.py +7 -7
  321. cirq/transformers/dynamical_decoupling.py +185 -112
  322. cirq/transformers/dynamical_decoupling_test.py +195 -201
  323. cirq/transformers/eject_phased_paulis.py +2 -1
  324. cirq/transformers/eject_phased_paulis_test.py +3 -2
  325. cirq/transformers/eject_z.py +4 -3
  326. cirq/transformers/eject_z_test.py +23 -25
  327. cirq/transformers/expand_composite.py +3 -2
  328. cirq/transformers/expand_composite_test.py +14 -14
  329. cirq/transformers/gauge_compiling/__init__.py +8 -0
  330. cirq/transformers/gauge_compiling/gauge_compiling.py +3 -2
  331. cirq/transformers/gauge_compiling/gauge_compiling_test.py +14 -12
  332. cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +3 -3
  333. cirq/transformers/gauge_compiling/idle_moments_gauge.py +5 -2
  334. cirq/transformers/gauge_compiling/multi_moment_cphase_gauge.py +242 -0
  335. cirq/transformers/gauge_compiling/multi_moment_cphase_gauge_test.py +243 -0
  336. cirq/transformers/gauge_compiling/multi_moment_gauge_compiling.py +151 -0
  337. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +2 -1
  338. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +1 -1
  339. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +6 -6
  340. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +2 -1
  341. cirq/transformers/measurement_transformers.py +2 -1
  342. cirq/transformers/measurement_transformers_test.py +45 -39
  343. cirq/transformers/merge_k_qubit_gates.py +2 -1
  344. cirq/transformers/merge_k_qubit_gates_test.py +1 -1
  345. cirq/transformers/merge_single_qubit_gates.py +2 -1
  346. cirq/transformers/merge_single_qubit_gates_test.py +22 -22
  347. cirq/transformers/noise_adding_test.py +2 -2
  348. cirq/transformers/optimize_for_target_gateset.py +2 -1
  349. cirq/transformers/optimize_for_target_gateset_test.py +11 -9
  350. cirq/transformers/qubit_management_transformers_test.py +6 -2
  351. cirq/transformers/routing/mapping_manager.py +2 -1
  352. cirq/transformers/routing/route_circuit_cqc.py +2 -1
  353. cirq/transformers/stratify.py +2 -1
  354. cirq/transformers/symbolize.py +2 -1
  355. cirq/transformers/tag_transformers.py +2 -1
  356. cirq/transformers/target_gatesets/compilation_target_gateset.py +2 -1
  357. cirq/transformers/target_gatesets/cz_gateset.py +2 -1
  358. cirq/transformers/target_gatesets/cz_gateset_test.py +1 -1
  359. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +2 -1
  360. cirq/transformers/transformer_api.py +2 -1
  361. cirq/transformers/transformer_primitives.py +271 -145
  362. cirq/transformers/transformer_primitives_test.py +185 -1
  363. cirq/value/abc_alt.py +2 -1
  364. cirq/value/classical_data.py +2 -1
  365. cirq/value/condition.py +2 -1
  366. cirq/value/digits.py +9 -2
  367. cirq/value/duration.py +6 -5
  368. cirq/value/linear_dict.py +4 -9
  369. cirq/value/measurement_key.py +2 -1
  370. cirq/value/periodic_value.py +3 -2
  371. cirq/value/product_state.py +2 -1
  372. cirq/value/value_equality_attr.py +2 -1
  373. cirq/vis/density_matrix.py +1 -1
  374. cirq/vis/heatmap.py +2 -1
  375. cirq/vis/histogram.py +2 -1
  376. cirq/vis/state_histogram.py +2 -1
  377. cirq/work/collector.py +2 -1
  378. cirq/work/observable_grouping.py +2 -1
  379. cirq/work/observable_measurement.py +2 -1
  380. cirq/work/observable_measurement_data.py +2 -1
  381. cirq/work/observable_measurement_test.py +1 -1
  382. cirq/work/observable_readout_calibration.py +2 -1
  383. cirq/work/observable_readout_calibration_test.py +1 -1
  384. cirq/work/observable_settings.py +2 -1
  385. cirq/work/sampler.py +2 -1
  386. cirq/work/sampler_test.py +1 -1
  387. {cirq_core-1.7.0.dev20250924231107.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/METADATA +4 -4
  388. {cirq_core-1.7.0.dev20250924231107.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/RECORD +391 -374
  389. cirq/contrib/json_test.py +0 -33
  390. {cirq_core-1.7.0.dev20250924231107.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/WHEEL +0 -0
  391. {cirq_core-1.7.0.dev20250924231107.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/licenses/LICENSE +0 -0
  392. {cirq_core-1.7.0.dev20250924231107.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,200 @@
1
+ # Copyright 2025 The Cirq Developers
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ import pytest
18
+
19
+ import cirq
20
+ from cirq.transformers._connected_component import (
21
+ ComponentSet,
22
+ ComponentWithCircuitOpSet,
23
+ ComponentWithOpsSet,
24
+ )
25
+
26
+
27
+ def _always_mergeable(_: cirq.Operation) -> bool:
28
+ return True
29
+
30
+
31
+ def _never_mergeable(_: cirq.Operation) -> bool:
32
+ return False
33
+
34
+
35
+ def _always_can_merge(_ops1: list[cirq.Operation], _ops2: list[cirq.Operation]) -> bool:
36
+ return True
37
+
38
+
39
+ def _never_can_merge(_ops1: list[cirq.Operation], _ops2: list[cirq.Operation]) -> bool:
40
+ return False
41
+
42
+
43
+ def _merge_as_first_operation(op1: cirq.Operation, _op2: cirq.Operation) -> cirq.Operation:
44
+ return op1
45
+
46
+
47
+ def _merge_never_successful(op1: cirq.Operation, _op2: cirq.Operation) -> None:
48
+ return None
49
+
50
+
51
+ def test_find_returns_itself_for_singleton():
52
+ cset = ComponentSet(_always_mergeable)
53
+
54
+ q = cirq.NamedQubit('x')
55
+ c = cset.new_component(op=cirq.X(q), moment_id=0)
56
+ assert cset.find(c) is c
57
+
58
+
59
+ def test_merge_components():
60
+ cset = ComponentSet(_always_mergeable)
61
+
62
+ q = cirq.NamedQubit('x')
63
+ c = [cset.new_component(op=cirq.X(q), moment_id=i) for i in range(5)]
64
+ cset.merge(c[1], c[0])
65
+ cset.merge(c[2], c[1])
66
+ cset.merge(c[4], c[3])
67
+ cset.merge(c[3], c[0])
68
+
69
+ for i in range(5):
70
+ assert cset.find(c[i]) is cset.find(c[0])
71
+
72
+
73
+ def test_merge_same_component():
74
+ cset = ComponentSet(_always_mergeable)
75
+
76
+ q = cirq.NamedQubit('x')
77
+ c = [cset.new_component(op=cirq.X(q), moment_id=i) for i in range(3)]
78
+ cset.merge(c[1], c[0])
79
+ cset.merge(c[2], c[1])
80
+
81
+ root = cset.find(c[0])
82
+
83
+ assert cset.merge(c[0], c[2]) is root
84
+
85
+
86
+ def test_merge_returns_None_if_one_component_is_not_mergeable():
87
+ cset = ComponentSet(_always_mergeable)
88
+
89
+ q = cirq.NamedQubit('x')
90
+ c0 = cset.new_component(op=cirq.X(q), moment_id=0, is_mergeable=True)
91
+ c1 = cset.new_component(op=cirq.X(q), moment_id=1, is_mergeable=False)
92
+ assert cset.merge(c0, c1) is None
93
+
94
+
95
+ def test_cset_merge_returns_None_if_is_mergeable_is_false():
96
+ q = cirq.NamedQubit('x')
97
+ cset = ComponentSet(is_mergeable=_never_mergeable)
98
+
99
+ c0 = cset.new_component(op=cirq.X(q), moment_id=0, is_mergeable=True)
100
+ c1 = cset.new_component(op=cirq.X(q), moment_id=1, is_mergeable=True)
101
+ assert cset.merge(c0, c1) is None
102
+
103
+
104
+ @pytest.mark.parametrize("merge_left,expected_moment_id", [(True, 0), (False, 1)])
105
+ def test_merge_qubits_with_merge_left(merge_left: bool, expected_moment_id: int) -> None:
106
+ cset = ComponentSet(_always_mergeable)
107
+
108
+ q0 = cirq.NamedQubit('x')
109
+ q1 = cirq.NamedQubit('y')
110
+ c0 = cset.new_component(op=cirq.X(q0), moment_id=0)
111
+ c1 = cset.new_component(op=cirq.X(q1), moment_id=1)
112
+ c2 = cset.new_component(op=cirq.X(q1), moment_id=2)
113
+ cset.merge(c1, c2)
114
+ cset.merge(c0, c1, merge_left=merge_left)
115
+ assert cset.find(c1).qubits == frozenset([q0, q1])
116
+ assert cset.find(c1).moment_id == expected_moment_id
117
+
118
+
119
+ def test_component_with_ops_merge():
120
+ cset = ComponentWithOpsSet(_always_mergeable, _always_can_merge)
121
+
122
+ q = cirq.LineQubit.range(3)
123
+ ops = [cirq.X(q[i]) for i in range(3)]
124
+ c = [cset.new_component(op=ops[i], moment_id=i) for i in range(3)]
125
+ cset.merge(c[0], c[1])
126
+ cset.merge(c[1], c[2])
127
+ assert cset.find(c[0]).ops == ops
128
+ # check merge of indirectly merged components does not make a difference
129
+ assert cset.merge(c[0], c[2]).ops == ops
130
+
131
+
132
+ def test_component_with_ops_merge_when_merge_fails():
133
+ cset = ComponentWithOpsSet(_always_mergeable, _never_can_merge)
134
+
135
+ q = cirq.LineQubit.range(3)
136
+ ops = [cirq.X(q[i]) for i in range(3)]
137
+ c = [cset.new_component(op=ops[i], moment_id=i) for i in range(3)]
138
+
139
+ cset.merge(c[0], c[1])
140
+ cset.merge(c[1], c[2])
141
+ # No merge happened
142
+ for i in range(3):
143
+ assert cset.find(c[i]) is c[i]
144
+
145
+
146
+ def test_component_with_ops_merge_when_is_mergeable_is_false():
147
+ cset = ComponentWithOpsSet(_never_mergeable, _always_can_merge)
148
+
149
+ q = cirq.LineQubit.range(3)
150
+ ops = [cirq.X(q[i]) for i in range(3)]
151
+ c = [cset.new_component(op=ops[i], moment_id=i) for i in range(3)]
152
+
153
+ cset.merge(c[0], c[1])
154
+ cset.merge(c[1], c[2])
155
+ # No merge happened
156
+ for i in range(3):
157
+ assert cset.find(c[i]) is c[i]
158
+
159
+
160
+ def test_component_with_circuit_op_merge():
161
+ cset = ComponentWithCircuitOpSet(_always_mergeable, _merge_as_first_operation)
162
+
163
+ q = cirq.LineQubit.range(3)
164
+ ops = [cirq.X(q[i]) for i in range(3)]
165
+ c = [cset.new_component(op=ops[i], moment_id=i) for i in range(3)]
166
+
167
+ cset.merge(c[0], c[1])
168
+ cset.merge(c[1], c[2])
169
+ for i in range(3):
170
+ assert cset.find(c[i]).circuit_op == ops[0]
171
+ # check merge of indirectly merged components does not make a difference
172
+ assert cset.merge(c[0], c[2]) is cset.find(c[1])
173
+
174
+
175
+ def test_component_with_circuit_op_merge_func_is_none():
176
+ cset = ComponentWithCircuitOpSet(_always_mergeable, _merge_never_successful)
177
+
178
+ q = cirq.LineQubit.range(3)
179
+ ops = [cirq.X(q[i]) for i in range(3)]
180
+ c = [cset.new_component(op=ops[i], moment_id=i) for i in range(3)]
181
+
182
+ cset.merge(c[0], c[1])
183
+ cset.merge(c[1], c[2])
184
+ # No merge happened
185
+ for i in range(3):
186
+ assert cset.find(c[i]) is c[i]
187
+
188
+
189
+ def test_component_with_circuit_op_merge_when_is_mergeable_is_false():
190
+ cset = ComponentWithCircuitOpSet(_never_mergeable, _merge_as_first_operation)
191
+
192
+ q = cirq.LineQubit.range(3)
193
+ ops = [cirq.X(q[i]) for i in range(3)]
194
+ c = [cset.new_component(op=ops[i], moment_id=i) for i in range(3)]
195
+
196
+ cset.merge(c[0], c[1])
197
+ cset.merge(c[1], c[2])
198
+ # No merge happened
199
+ for i in range(3):
200
+ assert cset.find(c[i]) is c[i]
@@ -17,7 +17,7 @@ from __future__ import annotations
17
17
  import cirq
18
18
 
19
19
 
20
- def test_align_basic_no_context():
20
+ def test_align_basic_no_context() -> None:
21
21
  q1 = cirq.NamedQubit('q1')
22
22
  q2 = cirq.NamedQubit('q2')
23
23
  c = cirq.Circuit(
@@ -45,7 +45,7 @@ def test_align_basic_no_context():
45
45
  )
46
46
 
47
47
 
48
- def test_align_left_no_compile_context():
48
+ def test_align_left_no_compile_context() -> None:
49
49
  q1 = cirq.NamedQubit('q1')
50
50
  q2 = cirq.NamedQubit('q2')
51
51
  cirq.testing.assert_same_circuits(
@@ -59,7 +59,7 @@ def test_align_left_no_compile_context():
59
59
  cirq.measure(*[q1, q2], key='a'),
60
60
  ]
61
61
  ),
62
- context=cirq.TransformerContext(tags_to_ignore=["nocompile"]),
62
+ context=cirq.TransformerContext(tags_to_ignore=("nocompile",)),
63
63
  ),
64
64
  cirq.Circuit(
65
65
  [
@@ -73,7 +73,7 @@ def test_align_left_no_compile_context():
73
73
  )
74
74
 
75
75
 
76
- def test_align_left_deep():
76
+ def test_align_left_deep() -> None:
77
77
  q1, q2 = cirq.LineQubit.range(2)
78
78
  c_nested = cirq.FrozenCircuit(
79
79
  [
@@ -104,11 +104,11 @@ def test_align_left_deep():
104
104
  c_nested_aligned,
105
105
  cirq.CircuitOperation(c_nested_aligned).repeat(5).with_tags("preserve_tag"),
106
106
  )
107
- context = cirq.TransformerContext(tags_to_ignore=["nocompile"], deep=True)
107
+ context = cirq.TransformerContext(tags_to_ignore=("nocompile",), deep=True)
108
108
  cirq.testing.assert_same_circuits(cirq.align_left(c_orig, context=context), c_expected)
109
109
 
110
110
 
111
- def test_align_left_subset_of_operations():
111
+ def test_align_left_subset_of_operations() -> None:
112
112
  q1 = cirq.NamedQubit('q1')
113
113
  q2 = cirq.NamedQubit('q2')
114
114
  tag = "op_to_align"
@@ -134,7 +134,7 @@ def test_align_left_subset_of_operations():
134
134
  cirq.toggle_tags(
135
135
  cirq.align_left(
136
136
  cirq.toggle_tags(c_orig, [tag]),
137
- context=cirq.TransformerContext(tags_to_ignore=[tag]),
137
+ context=cirq.TransformerContext(tags_to_ignore=(tag,)),
138
138
  ),
139
139
  [tag],
140
140
  ),
@@ -142,7 +142,7 @@ def test_align_left_subset_of_operations():
142
142
  )
143
143
 
144
144
 
145
- def test_align_right_no_compile_context():
145
+ def test_align_right_no_compile_context() -> None:
146
146
  q1 = cirq.NamedQubit('q1')
147
147
  q2 = cirq.NamedQubit('q2')
148
148
  cirq.testing.assert_same_circuits(
@@ -156,7 +156,7 @@ def test_align_right_no_compile_context():
156
156
  cirq.measure(*[q1, q2], key='a'),
157
157
  ]
158
158
  ),
159
- context=cirq.TransformerContext(tags_to_ignore=["nocompile"]),
159
+ context=cirq.TransformerContext(tags_to_ignore=("nocompile",)),
160
160
  ),
161
161
  cirq.Circuit(
162
162
  [
@@ -170,7 +170,7 @@ def test_align_right_no_compile_context():
170
170
  )
171
171
 
172
172
 
173
- def test_align_right_deep():
173
+ def test_align_right_deep() -> None:
174
174
  q1, q2 = cirq.LineQubit.range(2)
175
175
  c_nested = cirq.FrozenCircuit(
176
176
  cirq.Moment([cirq.X(q1)]),
@@ -199,11 +199,11 @@ def test_align_right_deep():
199
199
  c_nested_aligned,
200
200
  cirq.CircuitOperation(c_nested_aligned).repeat(5).with_tags("preserve_tag"),
201
201
  )
202
- context = cirq.TransformerContext(tags_to_ignore=["nocompile"], deep=True)
202
+ context = cirq.TransformerContext(tags_to_ignore=("nocompile",), deep=True)
203
203
  cirq.testing.assert_same_circuits(cirq.align_right(c_orig, context=context), c_expected)
204
204
 
205
205
 
206
- def test_classical_control():
206
+ def test_classical_control() -> None:
207
207
  q0, q1 = cirq.LineQubit.range(2)
208
208
  circuit = cirq.Circuit(
209
209
  cirq.H(q0), cirq.measure(q0, key='m'), cirq.X(q1).with_classical_controls('m')
@@ -212,7 +212,7 @@ def test_classical_control():
212
212
  cirq.testing.assert_same_circuits(cirq.align_right(circuit), circuit)
213
213
 
214
214
 
215
- def test_measurement_and_classical_control_same_moment_preserve_order():
215
+ def test_measurement_and_classical_control_same_moment_preserve_order() -> None:
216
216
  q0, q1 = cirq.LineQubit.range(2)
217
217
  circuit = cirq.Circuit()
218
218
  op_measure = cirq.measure(q0, key='m')
@@ -17,6 +17,7 @@
17
17
  from __future__ import annotations
18
18
 
19
19
  import functools
20
+ from collections.abc import Sequence
20
21
  from typing import TYPE_CHECKING
21
22
 
22
23
  import numpy as np
@@ -31,7 +32,7 @@ def _X(
31
32
  q: int,
32
33
  args: sim.CliffordTableauSimulationState,
33
34
  operations: list[ops.Operation],
34
- qubits: list[cirq.Qid],
35
+ qubits: Sequence[cirq.Qid],
35
36
  ):
36
37
  protocols.act_on(ops.X, args, qubits=[qubits[q]], allow_decompose=False)
37
38
  operations.append(ops.X(qubits[q]))
@@ -41,7 +42,7 @@ def _Z(
41
42
  q: int,
42
43
  args: sim.CliffordTableauSimulationState,
43
44
  operations: list[ops.Operation],
44
- qubits: list[cirq.Qid],
45
+ qubits: Sequence[cirq.Qid],
45
46
  ):
46
47
  protocols.act_on(ops.Z, args, qubits=[qubits[q]], allow_decompose=False)
47
48
  operations.append(ops.Z(qubits[q]))
@@ -51,7 +52,7 @@ def _Sdg(
51
52
  q: int,
52
53
  args: sim.CliffordTableauSimulationState,
53
54
  operations: list[ops.Operation],
54
- qubits: list[cirq.Qid],
55
+ qubits: Sequence[cirq.Qid],
55
56
  ):
56
57
  # Apply the tableau with S^\{dagger}
57
58
  protocols.act_on(ops.S**-1, args, qubits=[qubits[q]], allow_decompose=False)
@@ -62,7 +63,7 @@ def _H(
62
63
  q: int,
63
64
  args: sim.CliffordTableauSimulationState,
64
65
  operations: list[ops.Operation],
65
- qubits: list[cirq.Qid],
66
+ qubits: Sequence[cirq.Qid],
66
67
  ):
67
68
  protocols.act_on(ops.H, args, qubits=[qubits[q]], allow_decompose=False)
68
69
  operations.append(ops.H(qubits[q]))
@@ -73,7 +74,7 @@ def _CNOT(
73
74
  q2: int,
74
75
  args: sim.CliffordTableauSimulationState,
75
76
  operations: list[ops.Operation],
76
- qubits: list[cirq.Qid],
77
+ qubits: Sequence[cirq.Qid],
77
78
  ):
78
79
  protocols.act_on(ops.CNOT, args, qubits=[qubits[q1], qubits[q2]], allow_decompose=False)
79
80
  operations.append(ops.CNOT(qubits[q1], qubits[q2]))
@@ -84,14 +85,14 @@ def _SWAP(
84
85
  q2: int,
85
86
  args: sim.CliffordTableauSimulationState,
86
87
  operations: list[ops.Operation],
87
- qubits: list[cirq.Qid],
88
+ qubits: Sequence[cirq.Qid],
88
89
  ):
89
90
  protocols.act_on(ops.SWAP, args, qubits=[qubits[q1], qubits[q2]], allow_decompose=False)
90
91
  operations.append(ops.SWAP(qubits[q1], qubits[q2]))
91
92
 
92
93
 
93
94
  def decompose_clifford_tableau_to_operations(
94
- qubits: list[cirq.Qid], clifford_tableau: qis.CliffordTableau
95
+ qubits: Sequence[cirq.Qid], clifford_tableau: qis.CliffordTableau
95
96
  ) -> list[ops.Operation]:
96
97
  """Decompose an n-qubit Clifford Tableau into a list of one/two qubit operations.
97
98
 
@@ -21,14 +21,14 @@ import cirq
21
21
  from cirq.testing import assert_allclose_up_to_global_phase
22
22
 
23
23
 
24
- def test_misaligned_qubits():
24
+ def test_misaligned_qubits() -> None:
25
25
  qubits = cirq.LineQubit.range(1)
26
26
  tableau = cirq.CliffordTableau(num_qubits=2)
27
27
  with pytest.raises(ValueError):
28
28
  cirq.decompose_clifford_tableau_to_operations(qubits, tableau)
29
29
 
30
30
 
31
- def test_clifford_decompose_one_qubit():
31
+ def test_clifford_decompose_one_qubit() -> None:
32
32
  """Two random instance for one qubit decomposition."""
33
33
  qubits = cirq.LineQubit.range(1)
34
34
  args = cirq.CliffordTableauSimulationState(
@@ -63,7 +63,7 @@ def test_clifford_decompose_one_qubit():
63
63
  assert_allclose_up_to_global_phase(cirq.unitary(expect_circ), cirq.unitary(circ), atol=1e-7)
64
64
 
65
65
 
66
- def test_clifford_decompose_two_qubits():
66
+ def test_clifford_decompose_two_qubits() -> None:
67
67
  """Two random instance for two qubits decomposition."""
68
68
  qubits = cirq.LineQubit.range(2)
69
69
  args = cirq.CliffordTableauSimulationState(
@@ -98,7 +98,7 @@ def test_clifford_decompose_two_qubits():
98
98
  assert_allclose_up_to_global_phase(cirq.unitary(expect_circ), cirq.unitary(circ), atol=1e-7)
99
99
 
100
100
 
101
- def test_clifford_decompose_by_unitary():
101
+ def test_clifford_decompose_by_unitary() -> None:
102
102
  """Validate the decomposition of random Clifford Tableau by unitary matrix.
103
103
 
104
104
  Due to the exponential growth in dimension, it cannot validate very large number of qubits.
@@ -125,7 +125,7 @@ def test_clifford_decompose_by_unitary():
125
125
  assert_allclose_up_to_global_phase(cirq.unitary(expect_circ), cirq.unitary(circ), atol=1e-7)
126
126
 
127
127
 
128
- def test_clifford_decompose_by_reconstruction():
128
+ def test_clifford_decompose_by_reconstruction() -> None:
129
129
  """Validate the decomposition of random Clifford Tableau by reconstruction.
130
130
 
131
131
  This approach can validate large number of qubits compared with the unitary one.
@@ -15,6 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import itertools
18
+ from collections.abc import Sequence
18
19
  from typing import TYPE_CHECKING
19
20
 
20
21
  import numpy as np
@@ -114,7 +115,7 @@ def _ccnot_congruent(c0: cirq.Qid, c1: cirq.Qid, target: cirq.Qid) -> list[cirq.
114
115
 
115
116
 
116
117
  def decompose_multi_controlled_x(
117
- controls: list[cirq.Qid], target: cirq.Qid, free_qubits: list[cirq.Qid]
118
+ controls: Sequence[cirq.Qid], target: cirq.Qid, free_qubits: Sequence[cirq.Qid]
118
119
  ) -> list[cirq.Operation]:
119
120
  """Implements action of multi-controlled Pauli X gate.
120
121
 
@@ -152,11 +153,11 @@ def decompose_multi_controlled_x(
152
153
  elif len(free_qubits) >= 1:
153
154
  # See [1], Lemma 7.3.
154
155
  m1 = n // 2
155
- free1 = controls[m1:] + [target] + free_qubits[1:]
156
+ free1 = [*controls[m1:], target, *free_qubits[1:]]
156
157
  ctrl1 = controls[:m1]
157
158
  part1 = decompose_multi_controlled_x(ctrl1, free_qubits[0], free1)
158
- free2 = controls[:m1] + free_qubits[1:]
159
- ctrl2 = controls[m1:] + [free_qubits[0]]
159
+ free2 = [*controls[:m1], *free_qubits[1:]]
160
+ ctrl2 = [*controls[m1:], free_qubits[0]]
160
161
  part2 = decompose_multi_controlled_x(ctrl2, target, free2)
161
162
  return [*part1, *part2, *part1, *part2]
162
163
  else:
@@ -167,7 +168,7 @@ def decompose_multi_controlled_x(
167
168
 
168
169
 
169
170
  def _decompose_su(
170
- matrix: np.ndarray, controls: list[cirq.Qid], target: cirq.Qid
171
+ matrix: np.ndarray, controls: Sequence[cirq.Qid], target: cirq.Qid
171
172
  ) -> list[cirq.Operation]:
172
173
  """Decomposes controlled special unitary gate into elementary gates.
173
174
 
@@ -193,9 +194,9 @@ def _decompose_su(
193
194
  def _decompose_recursive(
194
195
  matrix: np.ndarray,
195
196
  power: float,
196
- controls: list[cirq.Qid],
197
+ controls: Sequence[cirq.Qid],
197
198
  target: cirq.Qid,
198
- free_qubits: list[cirq.Qid],
199
+ free_qubits: Sequence[cirq.Qid],
199
200
  ) -> list[cirq.Operation]:
200
201
  """Decomposes controlled unitary gate into elementary gates.
201
202
 
@@ -205,20 +206,20 @@ def _decompose_recursive(
205
206
  if len(controls) == 1:
206
207
  return _decompose_single_ctrl(_unitary_power(matrix, power), controls[0], target)
207
208
 
208
- cnots = decompose_multi_controlled_x(controls[:-1], controls[-1], free_qubits + [target])
209
+ cnots = decompose_multi_controlled_x(controls[:-1], controls[-1], [*free_qubits, target])
209
210
  return [
210
211
  *_decompose_single_ctrl(_unitary_power(matrix, 0.5 * power), controls[-1], target),
211
212
  *cnots,
212
213
  *_decompose_single_ctrl(_unitary_power(matrix, -0.5 * power), controls[-1], target),
213
214
  *cnots,
214
215
  *_decompose_recursive(
215
- matrix, 0.5 * power, controls[:-1], target, [controls[-1]] + free_qubits
216
+ matrix, 0.5 * power, controls[:-1], target, [controls[-1], *free_qubits]
216
217
  ),
217
218
  ]
218
219
 
219
220
 
220
221
  def decompose_multi_controlled_rotation(
221
- matrix: np.ndarray, controls: list[cirq.Qid], target: cirq.Qid
222
+ matrix: np.ndarray, controls: Sequence[cirq.Qid], target: cirq.Qid
222
223
  ) -> list[cirq.Operation]:
223
224
  """Implements action of multi-controlled unitary gate.
224
225
 
@@ -20,7 +20,7 @@ import scipy.stats
20
20
  import cirq
21
21
 
22
22
 
23
- def test_decompose_x():
23
+ def test_decompose_x() -> None:
24
24
  """Verifies correctness of multi-controlled X decomposition."""
25
25
  for total_qubits_count in range(1, 8):
26
26
  qubits = cirq.LineQubit.range(total_qubits_count)
@@ -83,14 +83,14 @@ def _test_decompose(matrix, controls_count):
83
83
  cirq.testing.assert_allclose_up_to_global_phase(expected_matrix, result_matrix, atol=1e-8)
84
84
 
85
85
 
86
- def test_decompose_specific_matrices():
86
+ def test_decompose_specific_matrices() -> None:
87
87
  for gate in [cirq.X, cirq.Y, cirq.Z, cirq.H, cirq.I, cirq.T, cirq.S]:
88
88
  for controls_count in range(7):
89
89
  _test_decompose(cirq.unitary(gate), controls_count)
90
90
 
91
91
 
92
92
  @cirq.testing.retry_once_with_later_random_values
93
- def test_decompose_random_unitary():
93
+ def test_decompose_random_unitary() -> None:
94
94
  for controls_count in range(5):
95
95
  for _ in range(10):
96
96
  _test_decompose(_random_unitary(), controls_count)
@@ -99,7 +99,7 @@ def test_decompose_random_unitary():
99
99
 
100
100
 
101
101
  @cirq.testing.retry_once_with_later_random_values
102
- def test_decompose_random_special_unitary():
102
+ def test_decompose_random_special_unitary() -> None:
103
103
  for controls_count in range(5):
104
104
  for _ in range(10):
105
105
  _test_decompose(_random_special_unitary(), controls_count)
@@ -113,7 +113,7 @@ def _decomposition_size(U, controls_count):
113
113
  return _count_operations(operations)
114
114
 
115
115
 
116
- def test_decompose_size_special_unitary():
116
+ def test_decompose_size_special_unitary() -> None:
117
117
  np.random.seed(0)
118
118
  u = _random_special_unitary()
119
119
  assert _decomposition_size(u, 0) == (1, 0, 0)
@@ -126,7 +126,7 @@ def test_decompose_size_special_unitary():
126
126
  assert _decomposition_size(u, i) == (64 * i - 312, 48 * i - 234, 16)
127
127
 
128
128
 
129
- def test_decompose_size_unitary():
129
+ def test_decompose_size_unitary() -> None:
130
130
  np.random.seed(0)
131
131
  u = _random_unitary()
132
132
  assert _decomposition_size(u, 0) == (1, 0, 0)
@@ -14,7 +14,8 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Sequence, TYPE_CHECKING
17
+ from collections.abc import Sequence
18
+ from typing import TYPE_CHECKING
18
19
 
19
20
  import numpy as np
20
21
  import sympy
@@ -100,7 +101,7 @@ def decompose_cphase_into_two_fsim(
100
101
  fsim_gate: cirq.FSimGate,
101
102
  qubits: Sequence[cirq.Qid] | None = None,
102
103
  atol: float = 1e-8,
103
- ) -> cirq.OP_TREE:
104
+ ) -> Sequence[cirq.Operation]:
104
105
  """Decomposes CZPowGate into two FSimGates.
105
106
 
106
107
  This function implements the decomposition described in section VII F I
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import itertools
18
- from typing import Sequence
18
+ from collections.abc import Sequence
19
19
 
20
20
  import numpy as np
21
21
  import pytest
@@ -24,7 +24,7 @@ import sympy
24
24
  import cirq
25
25
 
26
26
 
27
- def test_symbols():
27
+ def test_symbols() -> None:
28
28
  with pytest.raises(ValueError, match='Symbolic arguments'):
29
29
  cirq.compute_cphase_exponents_for_fsim_decomposition(
30
30
  cirq.FSimGate(theta=sympy.Symbol('t'), phi=sympy.Symbol('phi'))
@@ -36,8 +36,9 @@ class FakeSycamoreGate(cirq.FSimGate):
36
36
  super().__init__(theta=np.pi / 2, phi=np.pi / 6)
37
37
 
38
38
 
39
- def test_parameterized_gates():
39
+ def test_parameterized_gates() -> None:
40
40
  t = sympy.Symbol('t')
41
+ fsim_gate: cirq.FSimGate
41
42
  with pytest.raises(ValueError):
42
43
  cphase_gate = cirq.CZPowGate(exponent=t)
43
44
  fsim_gate = FakeSycamoreGate()
@@ -54,14 +55,14 @@ def test_parameterized_gates():
54
55
  cirq.decompose_cphase_into_two_fsim(cphase_gate, fsim_gate=fsim_gate)
55
56
 
56
57
 
57
- def test_invalid_qubits():
58
+ def test_invalid_qubits() -> None:
58
59
  with pytest.raises(ValueError):
59
60
  cirq.decompose_cphase_into_two_fsim(
60
61
  cphase_gate=cirq.CZ, fsim_gate=FakeSycamoreGate(), qubits=cirq.LineQubit.range(3)
61
62
  )
62
63
 
63
64
 
64
- def test_circuit_structure():
65
+ def test_circuit_structure() -> None:
65
66
  syc = FakeSycamoreGate()
66
67
  ops = cirq.decompose_cphase_into_two_fsim(cirq.CZ, fsim_gate=syc)
67
68
  num_interaction_moments = 0
@@ -73,7 +74,7 @@ def test_circuit_structure():
73
74
  assert num_interaction_moments == 2
74
75
 
75
76
 
76
- def assert_decomposition_valid(cphase_gate, fsim_gate):
77
+ def assert_decomposition_valid(cphase_gate, fsim_gate) -> None:
77
78
  u_expected = cirq.unitary(cphase_gate)
78
79
  ops = cirq.decompose_cphase_into_two_fsim(cphase_gate, fsim_gate=fsim_gate)
79
80
  u_actual = cirq.unitary(cirq.Circuit(ops))
@@ -83,7 +84,7 @@ def assert_decomposition_valid(cphase_gate, fsim_gate):
83
84
  @pytest.mark.parametrize(
84
85
  'exponent', (-5.5, -3, -1.5, -1, -0.65, -0.2, 0, 0.1, 0.75, 1, 1.5, 2, 5.5)
85
86
  )
86
- def test_decomposition_to_sycamore_gate(exponent):
87
+ def test_decomposition_to_sycamore_gate(exponent) -> None:
87
88
  cphase_gate = cirq.CZPowGate(exponent=exponent)
88
89
  assert_decomposition_valid(cphase_gate, FakeSycamoreGate())
89
90
 
@@ -95,7 +96,7 @@ def test_decomposition_to_sycamore_gate(exponent):
95
96
  (-1.4 * np.pi, -np.pi / 9, np.pi / 11, np.pi / 2, 2.4 * np.pi),
96
97
  ),
97
98
  )
98
- def test_valid_cphase_exponents(theta, phi):
99
+ def test_valid_cphase_exponents(theta, phi) -> None:
99
100
  fsim_gate = cirq.FSimGate(theta=theta, phi=phi)
100
101
  valid_exponent_intervals = cirq.compute_cphase_exponents_for_fsim_decomposition(fsim_gate)
101
102
  assert valid_exponent_intervals
@@ -131,7 +132,7 @@ def complement_intervals(intervals: Sequence[tuple[float, float]]) -> Sequence[t
131
132
  (-1.7 * np.pi, -np.pi / 5, np.pi / 7, 2.5 * np.pi),
132
133
  ),
133
134
  )
134
- def test_invalid_cphase_exponents(theta, phi):
135
+ def test_invalid_cphase_exponents(theta, phi) -> None:
135
136
  fsim_gate = cirq.FSimGate(theta=theta, phi=phi)
136
137
  valid_exponent_intervals = cirq.compute_cphase_exponents_for_fsim_decomposition(fsim_gate)
137
138
  invalid_exponent_intervals = complement_intervals(valid_exponent_intervals)
@@ -151,6 +152,6 @@ def test_invalid_cphase_exponents(theta, phi):
151
152
  @pytest.mark.parametrize(
152
153
  'bad_fsim_gate', (cirq.FSimGate(theta=0, phi=0), cirq.FSimGate(theta=np.pi / 4, phi=np.pi / 2))
153
154
  )
154
- def test_invalid_fsim_gate(bad_fsim_gate):
155
+ def test_invalid_fsim_gate(bad_fsim_gate) -> None:
155
156
  with pytest.raises(ValueError):
156
157
  cirq.decompose_cphase_into_two_fsim(cirq.CZ, fsim_gate=bad_fsim_gate)