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
@@ -16,17 +16,14 @@ from __future__ import annotations
16
16
 
17
17
  import itertools
18
18
  import random
19
- from typing import Sequence
19
+ from collections.abc import Sequence
20
20
 
21
21
  import numpy as np
22
22
  import pytest
23
23
 
24
24
  import cirq
25
25
  from cirq.contrib.paulistring import measure_pauli_strings
26
- from cirq.contrib.paulistring.pauli_string_measurement_with_readout_mitigation import (
27
- _process_pauli_measurement_results,
28
- )
29
- from cirq.experiments.single_qubit_readout_calibration import SingleQubitReadoutCalibrationResult
26
+ from cirq.experiments import SingleQubitReadoutCalibrationResult
30
27
  from cirq.experiments.single_qubit_readout_calibration_test import NoisySingleQubitReadoutSampler
31
28
 
32
29
 
@@ -107,7 +104,8 @@ def _ideal_expectation_based_on_pauli_string(
107
104
  )
108
105
 
109
106
 
110
- def test_pauli_string_measurement_errors_no_noise() -> None:
107
+ @pytest.mark.parametrize("use_sweep", [True, False])
108
+ def test_pauli_string_measurement_errors_no_noise(use_sweep: bool) -> None:
111
109
  """Test that the mitigated expectation is close to the ideal expectation
112
110
  based on the Pauli string"""
113
111
 
@@ -119,7 +117,7 @@ def test_pauli_string_measurement_errors_no_noise() -> None:
119
117
  circuits_to_pauli[circuit] = [_generate_random_pauli_string(qubits) for _ in range(3)]
120
118
 
121
119
  circuits_with_pauli_expectations = measure_pauli_strings(
122
- circuits_to_pauli, sampler, 1000, 1000, 1000, 1000
120
+ circuits_to_pauli, sampler, 300, 300, 300, 1234, use_sweep
123
121
  )
124
122
 
125
123
  for circuit_with_pauli_expectations in circuits_with_pauli_expectations:
@@ -141,7 +139,7 @@ def test_pauli_string_measurement_errors_no_noise() -> None:
141
139
  _ideal_expectation_based_on_pauli_string(
142
140
  pauli_string_measurement_results.pauli_string, final_state_vector
143
141
  ),
144
- atol=max(4 * pauli_string_measurement_results.mitigated_stddev, 0.1),
142
+ atol=10 * pauli_string_measurement_results.mitigated_stddev,
145
143
  )
146
144
  assert isinstance(
147
145
  pauli_string_measurement_results.calibration_result,
@@ -155,55 +153,8 @@ def test_pauli_string_measurement_errors_no_noise() -> None:
155
153
  }
156
154
 
157
155
 
158
- def test_pauli_string_measurement_errors_with_coefficient_no_noise() -> None:
159
- """Test that the mitigated expectation is close to the ideal expectation
160
- based on the Pauli string"""
161
-
162
- qubits = cirq.LineQubit.range(5)
163
- circuit = cirq.FrozenCircuit(_create_ghz(5, qubits))
164
- sampler = cirq.Simulator()
165
-
166
- circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
167
- circuits_to_pauli[circuit] = [_generate_random_pauli_string(qubits, True) for _ in range(3)]
168
-
169
- circuits_with_pauli_expectations = measure_pauli_strings(
170
- circuits_to_pauli, sampler, 1000, 1000, 1000, 1000
171
- )
172
-
173
- for circuit_with_pauli_expectations in circuits_with_pauli_expectations:
174
- assert isinstance(circuit_with_pauli_expectations.circuit, cirq.FrozenCircuit)
175
-
176
- expected_val_simulation = sampler.simulate(
177
- circuit_with_pauli_expectations.circuit.unfreeze()
178
- )
179
- final_state_vector = expected_val_simulation.final_state_vector
180
-
181
- for pauli_string_measurement_results in circuit_with_pauli_expectations.results:
182
- # Since there is no noise, the mitigated and unmitigated expectations should be the same
183
- assert np.isclose(
184
- pauli_string_measurement_results.mitigated_expectation,
185
- pauli_string_measurement_results.unmitigated_expectation,
186
- )
187
- assert np.isclose(
188
- pauli_string_measurement_results.mitigated_expectation,
189
- _ideal_expectation_based_on_pauli_string(
190
- pauli_string_measurement_results.pauli_string, final_state_vector
191
- ),
192
- atol=max(4 * pauli_string_measurement_results.mitigated_stddev, 0.1),
193
- )
194
- assert isinstance(
195
- pauli_string_measurement_results.calibration_result,
196
- SingleQubitReadoutCalibrationResult,
197
- )
198
- assert pauli_string_measurement_results.calibration_result.zero_state_errors == {
199
- q: 0 for q in pauli_string_measurement_results.pauli_string.qubits
200
- }
201
- assert pauli_string_measurement_results.calibration_result.one_state_errors == {
202
- q: 0 for q in pauli_string_measurement_results.pauli_string.qubits
203
- }
204
-
205
-
206
- def test_group_pauli_string_measurement_errors_no_noise_with_coefficient() -> None:
156
+ @pytest.mark.parametrize("use_sweep", [True, False])
157
+ def test_group_pauli_string_measurement_errors_no_noise_with_coefficient(use_sweep: bool) -> None:
207
158
  """Test that the mitigated expectation is close to the ideal expectation
208
159
  based on the group of Pauli strings"""
209
160
 
@@ -214,14 +165,14 @@ def test_group_pauli_string_measurement_errors_no_noise_with_coefficient() -> No
214
165
  circuits_to_pauli: dict[cirq.FrozenCircuit, list[list[cirq.PauliString]]] = {}
215
166
  circuits_to_pauli[circuit] = [
216
167
  _generate_qwc_paulis(
217
- _generate_random_pauli_string(qubits, enable_coeff=True, allow_pauli_i=False), 100, True
168
+ _generate_random_pauli_string(qubits, enable_coeff=True, allow_pauli_i=False), 10, True
218
169
  )
219
170
  for _ in range(3)
220
171
  ]
221
172
  circuits_to_pauli[circuit].append([cirq.PauliString({q: cirq.X for q in qubits})])
222
173
 
223
174
  circuits_with_pauli_expectations = measure_pauli_strings(
224
- circuits_to_pauli, sampler, 1000, 1000, 1000, 1000
175
+ circuits_to_pauli, sampler, 300, 300, 300, 1234, use_sweep
225
176
  )
226
177
 
227
178
  for circuit_with_pauli_expectations in circuits_with_pauli_expectations:
@@ -243,7 +194,7 @@ def test_group_pauli_string_measurement_errors_no_noise_with_coefficient() -> No
243
194
  _ideal_expectation_based_on_pauli_string(
244
195
  pauli_string_measurement_results.pauli_string, final_state_vector
245
196
  ),
246
- atol=max(4 * pauli_string_measurement_results.mitigated_stddev, 0.1),
197
+ atol=10 * pauli_string_measurement_results.mitigated_stddev,
247
198
  )
248
199
  assert isinstance(
249
200
  pauli_string_measurement_results.calibration_result,
@@ -257,19 +208,20 @@ def test_group_pauli_string_measurement_errors_no_noise_with_coefficient() -> No
257
208
  }
258
209
 
259
210
 
260
- def test_pauli_string_measurement_errors_with_noise() -> None:
211
+ @pytest.mark.parametrize("use_sweep", [True, False])
212
+ def test_pauli_string_measurement_errors_with_noise(use_sweep: bool) -> None:
261
213
  """Test that the mitigated expectation is close to the ideal expectation
262
214
  based on the Pauli string"""
263
215
  qubits = cirq.LineQubit.range(7)
264
216
  circuit = cirq.FrozenCircuit(_create_ghz(7, qubits))
265
- sampler = NoisySingleQubitReadoutSampler(p0=0.001, p1=0.005, seed=1234)
217
+ sampler = NoisySingleQubitReadoutSampler(p0=0.01, p1=0.05, seed=1234)
266
218
  simulator = cirq.Simulator()
267
219
 
268
220
  circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
269
221
  circuits_to_pauli[circuit] = [_generate_random_pauli_string(qubits) for _ in range(3)]
270
222
 
271
223
  circuits_with_pauli_expectations = measure_pauli_strings(
272
- circuits_to_pauli, sampler, 1000, 1000, 1000, np.random.default_rng()
224
+ circuits_to_pauli, sampler, 300, 300, 300, np.random.default_rng(), use_sweep
273
225
  )
274
226
 
275
227
  for circuit_with_pauli_expectations in circuits_with_pauli_expectations:
@@ -286,7 +238,7 @@ def test_pauli_string_measurement_errors_with_noise() -> None:
286
238
  _ideal_expectation_based_on_pauli_string(
287
239
  pauli_string_measurement_results.pauli_string, final_state_vector
288
240
  ),
289
- atol=max(4 * pauli_string_measurement_results.mitigated_stddev, 0.1),
241
+ atol=10 * pauli_string_measurement_results.mitigated_stddev,
290
242
  )
291
243
 
292
244
  assert isinstance(
@@ -297,19 +249,20 @@ def test_pauli_string_measurement_errors_with_noise() -> None:
297
249
  for (
298
250
  error
299
251
  ) in pauli_string_measurement_results.calibration_result.zero_state_errors.values():
300
- assert 0.0008 < error < 0.0012
252
+ assert 0.008 < error < 0.012
301
253
  for (
302
254
  error
303
255
  ) in pauli_string_measurement_results.calibration_result.one_state_errors.values():
304
- assert 0.0045 < error < 0.0055
256
+ assert 0.045 < error < 0.055
305
257
 
306
258
 
307
- def test_group_pauli_string_measurement_errors_with_noise() -> None:
259
+ @pytest.mark.parametrize("use_sweep", [True, False])
260
+ def test_group_pauli_string_measurement_errors_with_noise(use_sweep: bool) -> None:
308
261
  """Test that the mitigated expectation is close to the ideal expectation
309
262
  based on the group Pauli strings"""
310
263
  qubits = cirq.LineQubit.range(7)
311
264
  circuit = cirq.FrozenCircuit(_create_ghz(7, qubits))
312
- sampler = NoisySingleQubitReadoutSampler(p0=0.001, p1=0.005, seed=1234)
265
+ sampler = NoisySingleQubitReadoutSampler(p0=0.01, p1=0.05, seed=1234)
313
266
  simulator = cirq.Simulator()
314
267
 
315
268
  circuits_to_pauli: dict[cirq.FrozenCircuit, list[list[cirq.PauliString]]] = {}
@@ -320,7 +273,7 @@ def test_group_pauli_string_measurement_errors_with_noise() -> None:
320
273
  ]
321
274
 
322
275
  circuits_with_pauli_expectations = measure_pauli_strings(
323
- circuits_to_pauli, sampler, 800, 1000, 800, np.random.default_rng()
276
+ circuits_to_pauli, sampler, 300, 300, 300, np.random.default_rng(), use_sweep
324
277
  )
325
278
 
326
279
  for circuit_with_pauli_expectations in circuits_with_pauli_expectations:
@@ -337,7 +290,7 @@ def test_group_pauli_string_measurement_errors_with_noise() -> None:
337
290
  _ideal_expectation_based_on_pauli_string(
338
291
  pauli_string_measurement_results.pauli_string, final_state_vector
339
292
  ),
340
- atol=max(4 * pauli_string_measurement_results.mitigated_stddev, 0.1),
293
+ atol=10 * pauli_string_measurement_results.mitigated_stddev,
341
294
  )
342
295
 
343
296
  assert isinstance(
@@ -348,14 +301,15 @@ def test_group_pauli_string_measurement_errors_with_noise() -> None:
348
301
  for (
349
302
  error
350
303
  ) in pauli_string_measurement_results.calibration_result.zero_state_errors.values():
351
- assert 0.0008 < error < 0.0012
304
+ assert 0.008 < error < 0.012
352
305
  for (
353
306
  error
354
307
  ) in pauli_string_measurement_results.calibration_result.one_state_errors.values():
355
- assert 0.0045 < error < 0.0055
308
+ assert 0.045 < error < 0.055
356
309
 
357
310
 
358
- def test_many_circuits_input_measurement_with_noise() -> None:
311
+ @pytest.mark.parametrize("use_sweep", [True, False])
312
+ def test_many_circuits_input_measurement_with_noise(use_sweep: bool) -> None:
359
313
  """Test that the mitigated expectation is close to the ideal expectation
360
314
  based on the Pauli string for multiple circuits"""
361
315
  qubits_1 = cirq.LineQubit.range(3)
@@ -377,11 +331,11 @@ def test_many_circuits_input_measurement_with_noise() -> None:
377
331
  circuits_to_pauli[circuit_2] = [_generate_random_pauli_string(qubits_2) for _ in range(3)]
378
332
  circuits_to_pauli[circuit_3] = [_generate_random_pauli_string(qubits_3) for _ in range(3)]
379
333
 
380
- sampler = NoisySingleQubitReadoutSampler(p0=0.003, p1=0.005, seed=1234)
334
+ sampler = NoisySingleQubitReadoutSampler(p0=0.03, p1=0.05, seed=1234)
381
335
  simulator = cirq.Simulator()
382
336
 
383
337
  circuits_with_pauli_expectations = measure_pauli_strings(
384
- circuits_to_pauli, sampler, 1000, 1000, 1000, np.random.default_rng()
338
+ circuits_to_pauli, sampler, 300, 300, 300, np.random.default_rng(), use_sweep
385
339
  )
386
340
 
387
341
  for circuit_with_pauli_expectations in circuits_with_pauli_expectations:
@@ -398,7 +352,7 @@ def test_many_circuits_input_measurement_with_noise() -> None:
398
352
  _ideal_expectation_based_on_pauli_string(
399
353
  pauli_string_measurement_results.pauli_string, final_state_vector
400
354
  ),
401
- atol=max(4 * pauli_string_measurement_results.mitigated_stddev, 0.1),
355
+ atol=10 * pauli_string_measurement_results.mitigated_stddev,
402
356
  )
403
357
  assert isinstance(
404
358
  pauli_string_measurement_results.calibration_result,
@@ -407,48 +361,19 @@ def test_many_circuits_input_measurement_with_noise() -> None:
407
361
  for (
408
362
  error
409
363
  ) in pauli_string_measurement_results.calibration_result.zero_state_errors.values():
410
- assert 0.0025 < error < 0.0035
364
+ assert 0.025 < error < 0.035
411
365
  for (
412
366
  error
413
367
  ) in pauli_string_measurement_results.calibration_result.one_state_errors.values():
414
- assert 0.0045 < error < 0.0055
415
-
416
-
417
- def test_allow_measurement_without_readout_mitigation() -> None:
418
- """Test that the function allows to measure without error mitigation"""
419
- qubits = cirq.LineQubit.range(7)
420
- circuit = cirq.FrozenCircuit(_create_ghz(7, qubits))
421
- sampler = NoisySingleQubitReadoutSampler(p0=0.001, p1=0.005, seed=1234)
422
-
423
- circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
424
- circuits_to_pauli[circuit] = [
425
- _generate_random_pauli_string(qubits, True),
426
- _generate_random_pauli_string(qubits),
427
- _generate_random_pauli_string(qubits),
428
- ]
429
-
430
- circuits_with_pauli_expectations = measure_pauli_strings(
431
- circuits_to_pauli, sampler, 1000, 1000, 0, np.random.default_rng()
432
- )
433
-
434
- for circuit_with_pauli_expectations in circuits_with_pauli_expectations:
435
- assert isinstance(circuit_with_pauli_expectations.circuit, cirq.FrozenCircuit)
436
-
437
- for pauli_string_measurement_results in circuit_with_pauli_expectations.results:
438
- # Since there's no mitigation, the mitigated and unmitigated expectations
439
- # should be the same
440
- assert np.isclose(
441
- pauli_string_measurement_results.mitigated_expectation,
442
- pauli_string_measurement_results.unmitigated_expectation,
443
- )
444
- assert pauli_string_measurement_results.calibration_result is None
368
+ assert 0.045 < error < 0.055
445
369
 
446
370
 
447
- def test_allow_group_pauli_measurement_without_readout_mitigation() -> None:
371
+ @pytest.mark.parametrize("use_sweep", [True, False])
372
+ def test_allow_group_pauli_measurement_without_readout_mitigation(use_sweep: bool) -> None:
448
373
  """Test that the function allows to measure without error mitigation"""
449
374
  qubits = cirq.LineQubit.range(7)
450
375
  circuit = cirq.FrozenCircuit(_create_ghz(7, qubits))
451
- sampler = NoisySingleQubitReadoutSampler(p0=0.001, p1=0.005, seed=1234)
376
+ sampler = NoisySingleQubitReadoutSampler(p0=0.01, p1=0.005, seed=1234)
452
377
 
453
378
  circuits_to_pauli: dict[cirq.FrozenCircuit, list[list[cirq.PauliString]]] = {}
454
379
  circuits_to_pauli[circuit] = [
@@ -458,7 +383,7 @@ def test_allow_group_pauli_measurement_without_readout_mitigation() -> None:
458
383
  ]
459
384
 
460
385
  circuits_with_pauli_expectations = measure_pauli_strings(
461
- circuits_to_pauli, sampler, 100, 100, 0, np.random.default_rng()
386
+ circuits_to_pauli, sampler, 300, 300, 0, np.random.default_rng(), use_sweep
462
387
  )
463
388
 
464
389
  for circuit_with_pauli_expectations in circuits_with_pauli_expectations:
@@ -474,7 +399,13 @@ def test_allow_group_pauli_measurement_without_readout_mitigation() -> None:
474
399
  assert pauli_string_measurement_results.calibration_result is None
475
400
 
476
401
 
477
- def test_many_circuits_with_coefficient() -> None:
402
+ @pytest.mark.parametrize("use_sweep", [True, False])
403
+ @pytest.mark.parametrize(
404
+ "insert_strategy", [cirq.InsertStrategy.INLINE, cirq.InsertStrategy.EARLIEST]
405
+ )
406
+ def test_many_circuits_with_coefficient(
407
+ use_sweep: bool, insert_strategy: cirq.InsertStrategy
408
+ ) -> None:
478
409
  """Test that the mitigated expectation is close to the ideal expectation
479
410
  based on the Pauli string for multiple circuits"""
480
411
  qubits_1 = cirq.LineQubit.range(3)
@@ -496,11 +427,18 @@ def test_many_circuits_with_coefficient() -> None:
496
427
  circuits_to_pauli[circuit_2] = [_generate_random_pauli_string(qubits_2, True) for _ in range(3)]
497
428
  circuits_to_pauli[circuit_3] = [_generate_random_pauli_string(qubits_3, True) for _ in range(3)]
498
429
 
499
- sampler = NoisySingleQubitReadoutSampler(p0=0.003, p1=0.005, seed=1234)
430
+ sampler = NoisySingleQubitReadoutSampler(p0=0.03, p1=0.05, seed=1234)
500
431
  simulator = cirq.Simulator()
501
432
 
502
433
  circuits_with_pauli_expectations = measure_pauli_strings(
503
- circuits_to_pauli, sampler, 1000, 1000, 1000, np.random.default_rng()
434
+ circuits_to_pauli,
435
+ sampler,
436
+ 300,
437
+ 300,
438
+ 300,
439
+ np.random.default_rng(),
440
+ use_sweep,
441
+ insert_strategy,
504
442
  )
505
443
 
506
444
  for circuit_with_pauli_expectations in circuits_with_pauli_expectations:
@@ -517,7 +455,7 @@ def test_many_circuits_with_coefficient() -> None:
517
455
  _ideal_expectation_based_on_pauli_string(
518
456
  pauli_string_measurement_results.pauli_string, final_state_vector
519
457
  ),
520
- atol=max(4 * pauli_string_measurement_results.mitigated_stddev, 0.1),
458
+ atol=10 * pauli_string_measurement_results.mitigated_stddev,
521
459
  )
522
460
  assert isinstance(
523
461
  pauli_string_measurement_results.calibration_result,
@@ -526,14 +464,15 @@ def test_many_circuits_with_coefficient() -> None:
526
464
  for (
527
465
  error
528
466
  ) in pauli_string_measurement_results.calibration_result.zero_state_errors.values():
529
- assert 0.0025 < error < 0.0035
467
+ assert 0.025 < error < 0.035
530
468
  for (
531
469
  error
532
470
  ) in pauli_string_measurement_results.calibration_result.one_state_errors.values():
533
- assert 0.0045 < error < 0.0055
471
+ assert 0.045 < error < 0.055
534
472
 
535
473
 
536
- def test_many_group_pauli_in_circuits_with_coefficient() -> None:
474
+ @pytest.mark.parametrize("use_sweep", [True, False])
475
+ def test_many_group_pauli_in_circuits_with_coefficient(use_sweep: bool) -> None:
537
476
  """Test that the mitigated expectation is close to the ideal expectation
538
477
  based on the Pauli string for multiple circuits"""
539
478
  qubits_1 = cirq.LineQubit.range(3)
@@ -567,11 +506,11 @@ def test_many_group_pauli_in_circuits_with_coefficient() -> None:
567
506
  )
568
507
  ]
569
508
 
570
- sampler = NoisySingleQubitReadoutSampler(p0=0.003, p1=0.005, seed=1234)
509
+ sampler = NoisySingleQubitReadoutSampler(p0=0.03, p1=0.05, seed=1234)
571
510
  simulator = cirq.Simulator()
572
511
 
573
512
  circuits_with_pauli_expectations = measure_pauli_strings(
574
- circuits_to_pauli, sampler, 1000, 1000, 1000, np.random.default_rng()
513
+ circuits_to_pauli, sampler, 300, 300, 300, np.random.default_rng(), use_sweep
575
514
  )
576
515
 
577
516
  for circuit_with_pauli_expectations in circuits_with_pauli_expectations:
@@ -588,7 +527,7 @@ def test_many_group_pauli_in_circuits_with_coefficient() -> None:
588
527
  _ideal_expectation_based_on_pauli_string(
589
528
  pauli_string_measurement_results.pauli_string, final_state_vector
590
529
  ),
591
- atol=max(4 * pauli_string_measurement_results.mitigated_stddev, 0.1),
530
+ atol=10 * pauli_string_measurement_results.mitigated_stddev,
592
531
  )
593
532
  assert isinstance(
594
533
  pauli_string_measurement_results.calibration_result,
@@ -597,11 +536,11 @@ def test_many_group_pauli_in_circuits_with_coefficient() -> None:
597
536
  for (
598
537
  error
599
538
  ) in pauli_string_measurement_results.calibration_result.zero_state_errors.values():
600
- assert 0.0025 < error < 0.035
539
+ assert 0.025 < error < 0.035
601
540
  for (
602
541
  error
603
542
  ) in pauli_string_measurement_results.calibration_result.one_state_errors.values():
604
- assert 0.0045 < error < 0.0055
543
+ assert 0.045 < error < 0.055
605
544
 
606
545
 
607
546
  def test_coefficient_not_real_number() -> None:
@@ -624,7 +563,7 @@ def test_coefficient_not_real_number() -> None:
624
563
  "non-Hermitian PauliString. Coefficient must be real.",
625
564
  ):
626
565
  measure_pauli_strings(
627
- circuits_to_pauli, cirq.Simulator(), 1000, 1000, 1000, np.random.default_rng()
566
+ circuits_to_pauli, cirq.Simulator(), 300, 300, 300, np.random.default_rng()
628
567
  )
629
568
 
630
569
 
@@ -633,12 +572,7 @@ def test_empty_input_circuits_to_pauli_mapping() -> None:
633
572
 
634
573
  with pytest.raises(ValueError, match="Input circuits must not be empty."):
635
574
  measure_pauli_strings(
636
- [], # type: ignore[arg-type]
637
- cirq.Simulator(),
638
- 1000,
639
- 1000,
640
- 1000,
641
- np.random.default_rng(),
575
+ [], cirq.Simulator(), 300, 300, 300, np.random.default_rng() # type: ignore[arg-type]
642
576
  )
643
577
 
644
578
 
@@ -654,9 +588,9 @@ def test_invalid_input_circuit_type() -> None:
654
588
  measure_pauli_strings(
655
589
  qubits_to_pauli, # type: ignore[arg-type]
656
590
  cirq.Simulator(),
657
- 1000,
658
- 1000,
659
- 1000,
591
+ 300,
592
+ 300,
593
+ 300,
660
594
  np.random.default_rng(),
661
595
  )
662
596
 
@@ -687,9 +621,9 @@ def test_invalid_input_pauli_string_type() -> None:
687
621
  measure_pauli_strings(
688
622
  circuits_to_pauli, # type: ignore[arg-type]
689
623
  cirq.Simulator(),
690
- 1000,
691
- 1000,
692
- 1000,
624
+ 300,
625
+ 300,
626
+ 300,
693
627
  np.random.default_rng(),
694
628
  )
695
629
 
@@ -722,7 +656,7 @@ def test_all_pauli_strings_are_pauli_i() -> None:
722
656
  "valid input Pauli strings.",
723
657
  ):
724
658
  measure_pauli_strings(
725
- circuits_to_pauli, cirq.Simulator(), 1000, 1000, 1000, np.random.default_rng()
659
+ circuits_to_pauli, cirq.Simulator(), 300, 300, 300, np.random.default_rng()
726
660
  )
727
661
 
728
662
 
@@ -734,9 +668,9 @@ def test_zero_pauli_repetitions() -> None:
734
668
 
735
669
  circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
736
670
  circuits_to_pauli[circuit] = [cirq.PauliString({q: cirq.X for q in qubits})]
737
- with pytest.raises(ValueError, match="Must provide non-zero pauli_repetitions."):
671
+ with pytest.raises(ValueError, match="Must provide positive pauli_repetitions."):
738
672
  measure_pauli_strings(
739
- circuits_to_pauli, cirq.Simulator(), 0, 1000, 1000, np.random.default_rng()
673
+ circuits_to_pauli, cirq.Simulator(), 0, 300, 300, np.random.default_rng()
740
674
  )
741
675
 
742
676
 
@@ -750,7 +684,7 @@ def test_negative_num_random_bitstrings() -> None:
750
684
  circuits_to_pauli[circuit] = [cirq.PauliString({q: cirq.X for q in qubits})]
751
685
  with pytest.raises(ValueError, match="Must provide zero or more num_random_bitstrings."):
752
686
  measure_pauli_strings(
753
- circuits_to_pauli, cirq.Simulator(), 1000, 1000, -1, np.random.default_rng()
687
+ circuits_to_pauli, cirq.Simulator(), 300, 300, -1, np.random.default_rng()
754
688
  )
755
689
 
756
690
 
@@ -763,10 +697,10 @@ def test_zero_readout_repetitions() -> None:
763
697
  circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
764
698
  circuits_to_pauli[circuit] = [cirq.PauliString({q: cirq.X for q in qubits})]
765
699
  with pytest.raises(
766
- ValueError, match="Must provide non-zero readout_repetitions for readout" + " calibration."
700
+ ValueError, match="Must provide positive readout_repetitions for readout" + " calibration."
767
701
  ):
768
702
  measure_pauli_strings(
769
- circuits_to_pauli, cirq.Simulator(), 1000, 0, 1000, np.random.default_rng()
703
+ circuits_to_pauli, cirq.Simulator(), 300, 0, 300, np.random.default_rng()
770
704
  )
771
705
 
772
706
 
@@ -780,7 +714,7 @@ def test_rng_type_mismatch() -> None:
780
714
  circuits_to_pauli[circuit] = [cirq.PauliString({q: cirq.X for q in qubits})]
781
715
  with pytest.raises(ValueError, match="Must provide a numpy random generator or a seed"):
782
716
  measure_pauli_strings(
783
- circuits_to_pauli, cirq.Simulator(), 1000, 1000, 1000, "test" # type: ignore[arg-type]
717
+ circuits_to_pauli, cirq.Simulator(), 300, 300, 300, "test" # type: ignore[arg-type]
784
718
  )
785
719
 
786
720
 
@@ -798,7 +732,7 @@ def test_pauli_type_mismatch() -> None:
798
732
  " ops.PauliStrings. Got <class 'int'> instead.",
799
733
  ):
800
734
  measure_pauli_strings(
801
- circuits_to_pauli, cirq.Simulator(), 1000, 1000, 1000, "test" # type: ignore[arg-type]
735
+ circuits_to_pauli, cirq.Simulator(), 300, 300, 300, 1234 # type: ignore[arg-type]
802
736
  )
803
737
 
804
738
 
@@ -817,7 +751,7 @@ def test_group_paulis_are_not_qwc() -> None:
817
751
  ValueError, match="The group of Pauli strings are not Qubit-Wise Commuting with each other."
818
752
  ):
819
753
  measure_pauli_strings(
820
- circuits_to_pauli, cirq.Simulator(), 1000, 1000, 1000, np.random.default_rng()
754
+ circuits_to_pauli, cirq.Simulator(), 300, 300, 300, np.random.default_rng()
821
755
  )
822
756
 
823
757
 
@@ -831,7 +765,7 @@ def test_empty_group_paulis_not_allowed() -> None:
831
765
  circuits_to_pauli[circuit] = [[]] # type: ignore
832
766
  with pytest.raises(ValueError, match="Empty group of Pauli strings is not allowed"):
833
767
  measure_pauli_strings(
834
- circuits_to_pauli, cirq.Simulator(), 1000, 1000, 1000, np.random.default_rng()
768
+ circuits_to_pauli, cirq.Simulator(), 300, 300, 300, np.random.default_rng()
835
769
  )
836
770
 
837
771
 
@@ -867,36 +801,5 @@ def test_group_paulis_type_mismatch() -> None:
867
801
  "but found <class 'cirq.ops.pauli_string.PauliString'>.",
868
802
  ):
869
803
  measure_pauli_strings(
870
- circuits_to_pauli, cirq.Simulator(), 1000, 1000, 1000, np.random.default_rng()
871
- )
872
-
873
-
874
- def test_process_pauli_measurement_results_raises_error_on_missing_calibration() -> None:
875
- """Test that the function raises an error if the calibration result is missing."""
876
- qubits: Sequence[cirq.Qid] = cirq.LineQubit.range(5)
877
-
878
- measurement_op = cirq.measure(*qubits, key='m')
879
- test_circuits: list[cirq.Circuit] = [_create_ghz(5, qubits) + measurement_op for _ in range(3)]
880
-
881
- pauli_strings = [_generate_random_pauli_string(qubits, True) for _ in range(3)]
882
- sampler = cirq.Simulator()
883
-
884
- circuit_results = sampler.run_batch(test_circuits, repetitions=1000)
885
-
886
- pauli_strings_qubits = sorted(
887
- set(itertools.chain.from_iterable(ps.qubits for ps in pauli_strings))
888
- )
889
- empty_calibration_result_dict = {tuple(pauli_strings_qubits): None}
890
-
891
- with pytest.raises(
892
- ValueError,
893
- match="Readout mitigation is enabled, but no calibration result was found for qubits",
894
- ):
895
- _process_pauli_measurement_results(
896
- qubits,
897
- [pauli_strings],
898
- circuit_results[0],
899
- empty_calibration_result_dict, # type: ignore[arg-type]
900
- 1000,
901
- 1.0,
804
+ circuits_to_pauli, cirq.Simulator(), 300, 300, 300, np.random.default_rng()
902
805
  )
@@ -14,7 +14,8 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Any, Callable, cast, Iterable, Sequence
17
+ from collections.abc import Callable, Iterable, Sequence
18
+ from typing import Any, cast
18
19
 
19
20
  from cirq import circuits, ops, protocols
20
21
  from cirq.contrib import circuitdag
@@ -69,7 +70,9 @@ def move_pauli_strings_into_circuit(
69
70
  circuit_left: circuits.Circuit | circuitdag.CircuitDag, circuit_right: circuits.Circuit
70
71
  ) -> circuits.Circuit:
71
72
  if isinstance(circuit_left, circuitdag.CircuitDag):
72
- string_dag = circuitdag.CircuitDag(pauli_string_reorder_pred, circuit_left)
73
+ string_dag = circuitdag.CircuitDag(
74
+ incoming_graph_data=circuit_left, can_reorder=pauli_string_reorder_pred
75
+ )
73
76
  else:
74
77
  string_dag = pauli_string_dag_from_circuit(cast(circuits.Circuit, circuit_left))
75
78
  output_ops = list(circuit_right.all_operations())
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Iterator
17
+ from collections.abc import Iterator
18
18
 
19
19
  from cirq import circuits, ops, transformers
20
20
  from cirq.contrib.paulistring.clifford_target_gateset import CliffordTargetGateset
@@ -48,6 +48,7 @@ class QasmLexer:
48
48
  'ID',
49
49
  'ARROW',
50
50
  'EQ',
51
+ 'AND',
51
52
  ] + list(reserved.values())
52
53
 
53
54
  def t_newline(self, t):
@@ -101,8 +102,12 @@ class QasmLexer:
101
102
  """=="""
102
103
  return t
103
104
 
105
+ def t_AND(self, t):
106
+ """&&"""
107
+ return t
108
+
104
109
  def t_ID(self, t):
105
- r"""[a-zA-Z][a-zA-Z\d_]*"""
110
+ r"""[a-zA-Z_][a-zA-Z\d_]*"""
106
111
  if t.value in QasmLexer.reserved:
107
112
  t.type = QasmLexer.reserved[t.value]
108
113
  return t
@@ -84,7 +84,7 @@ def test_measurement() -> None:
84
84
 
85
85
 
86
86
  @pytest.mark.parametrize(
87
- 'identifier', ['b', 'CX', 'abc', 'aXY03', 'a_valid_name_with_02_digits_and_underscores']
87
+ 'identifier', ['b', 'CX', 'abc', '_abc', 'aXY03', 'a_valid_name_with_02_digits_and_underscores']
88
88
  )
89
89
  def test_valid_ids(identifier: str) -> None:
90
90
  lexer = QasmLexer()