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

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

Potentially problematic release.


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

Files changed (590) hide show
  1. cirq/__init__.py +587 -569
  2. cirq/_compat.py +9 -0
  3. cirq/_compat_test.py +11 -9
  4. cirq/_import.py +7 -8
  5. cirq/_version.py +31 -1
  6. cirq/_version_test.py +1 -1
  7. cirq/circuits/__init__.py +15 -9
  8. cirq/circuits/_block_diagram_drawer.py +1 -2
  9. cirq/circuits/_block_diagram_drawer_test.py +3 -3
  10. cirq/circuits/_box_drawing_character_data.py +0 -1
  11. cirq/circuits/_box_drawing_character_data_test.py +2 -2
  12. cirq/circuits/_bucket_priority_queue.py +0 -1
  13. cirq/circuits/_bucket_priority_queue_test.py +1 -1
  14. cirq/circuits/circuit.py +336 -234
  15. cirq/circuits/circuit_operation.py +102 -52
  16. cirq/circuits/circuit_operation_test.py +85 -4
  17. cirq/circuits/circuit_test.py +101 -32
  18. cirq/circuits/frozen_circuit.py +36 -32
  19. cirq/circuits/insert_strategy.py +10 -0
  20. cirq/circuits/insert_strategy_test.py +20 -0
  21. cirq/circuits/moment.py +79 -80
  22. cirq/circuits/moment_test.py +105 -2
  23. cirq/circuits/optimization_pass.py +15 -15
  24. cirq/circuits/optimization_pass_test.py +8 -9
  25. cirq/circuits/qasm_output.py +64 -33
  26. cirq/circuits/qasm_output_test.py +63 -2
  27. cirq/circuits/text_diagram_drawer.py +26 -56
  28. cirq/circuits/text_diagram_drawer_test.py +5 -4
  29. cirq/contrib/__init__.py +2 -2
  30. cirq/contrib/acquaintance/__init__.py +44 -29
  31. cirq/contrib/acquaintance/bipartite.py +8 -7
  32. cirq/contrib/acquaintance/bipartite_test.py +11 -1
  33. cirq/contrib/acquaintance/devices.py +5 -4
  34. cirq/contrib/acquaintance/devices_test.py +5 -1
  35. cirq/contrib/acquaintance/executor.py +18 -21
  36. cirq/contrib/acquaintance/executor_test.py +3 -2
  37. cirq/contrib/acquaintance/gates.py +36 -27
  38. cirq/contrib/acquaintance/gates_test.py +1 -1
  39. cirq/contrib/acquaintance/inspection_utils.py +10 -9
  40. cirq/contrib/acquaintance/inspection_utils_test.py +6 -1
  41. cirq/contrib/acquaintance/mutation_utils.py +10 -10
  42. cirq/contrib/acquaintance/optimizers.py +7 -6
  43. cirq/contrib/acquaintance/optimizers_test.py +1 -1
  44. cirq/contrib/acquaintance/permutation.py +22 -21
  45. cirq/contrib/acquaintance/permutation_test.py +1 -1
  46. cirq/contrib/acquaintance/shift.py +8 -6
  47. cirq/contrib/acquaintance/shift_swap_network.py +6 -4
  48. cirq/contrib/acquaintance/strategies/__init__.py +9 -3
  49. cirq/contrib/acquaintance/strategies/complete.py +4 -3
  50. cirq/contrib/acquaintance/strategies/cubic.py +5 -3
  51. cirq/contrib/acquaintance/strategies/quartic_paired.py +8 -6
  52. cirq/contrib/acquaintance/topological_sort.py +4 -2
  53. cirq/contrib/bayesian_network/__init__.py +3 -1
  54. cirq/contrib/bayesian_network/bayesian_network_gate.py +5 -3
  55. cirq/contrib/circuitdag/__init__.py +1 -1
  56. cirq/contrib/circuitdag/circuit_dag.py +24 -24
  57. cirq/contrib/circuitdag/circuit_dag_test.py +1 -1
  58. cirq/contrib/custom_simulators/custom_state_simulator.py +10 -8
  59. cirq/contrib/custom_simulators/custom_state_simulator_test.py +15 -11
  60. cirq/contrib/graph_device/__init__.py +8 -8
  61. cirq/contrib/graph_device/graph_device.py +8 -8
  62. cirq/contrib/graph_device/graph_device_test.py +0 -1
  63. cirq/contrib/graph_device/hypergraph_test.py +1 -0
  64. cirq/contrib/json.py +1 -2
  65. cirq/contrib/json_test.py +2 -2
  66. cirq/contrib/noise_models/__init__.py +5 -6
  67. cirq/contrib/noise_models/noise_models.py +8 -6
  68. cirq/contrib/paulistring/__init__.py +22 -10
  69. cirq/contrib/paulistring/clifford_optimize.py +1 -1
  70. cirq/contrib/paulistring/clifford_optimize_test.py +0 -1
  71. cirq/contrib/paulistring/clifford_target_gateset.py +15 -12
  72. cirq/contrib/paulistring/optimize.py +2 -2
  73. cirq/contrib/paulistring/optimize_test.py +0 -1
  74. cirq/contrib/paulistring/pauli_string_dag_test.py +0 -1
  75. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +379 -0
  76. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +523 -0
  77. cirq/contrib/paulistring/pauli_string_optimize.py +3 -1
  78. cirq/contrib/paulistring/pauli_string_optimize_test.py +1 -3
  79. cirq/contrib/paulistring/recombine.py +2 -2
  80. cirq/contrib/paulistring/recombine_test.py +2 -2
  81. cirq/contrib/paulistring/separate.py +3 -4
  82. cirq/contrib/qasm_import/__init__.py +2 -2
  83. cirq/contrib/qasm_import/_lexer.py +21 -26
  84. cirq/contrib/qasm_import/_lexer_test.py +90 -6
  85. cirq/contrib/qasm_import/_parser.py +238 -47
  86. cirq/contrib/qasm_import/_parser_test.py +514 -59
  87. cirq/contrib/qasm_import/qasm_test.py +1 -1
  88. cirq/contrib/qcircuit/__init__.py +6 -4
  89. cirq/contrib/qcircuit/qcircuit_diagram.py +5 -2
  90. cirq/contrib/qcircuit/qcircuit_pdf.py +1 -2
  91. cirq/{experiments/grid_parallel_two_qubit_xeb_test.py → contrib/qcircuit/qcircuit_pdf_test.py} +13 -12
  92. cirq/contrib/qcircuit/qcircuit_test.py +1 -1
  93. cirq/contrib/quantum_volume/__init__.py +7 -7
  94. cirq/contrib/quantum_volume/quantum_volume.py +6 -11
  95. cirq/contrib/quantum_volume/quantum_volume_test.py +3 -1
  96. cirq/contrib/quimb/__init__.py +16 -13
  97. cirq/contrib/quimb/density_matrix.py +1 -1
  98. cirq/contrib/quimb/mps_simulator.py +27 -28
  99. cirq/contrib/quimb/mps_simulator_test.py +5 -0
  100. cirq/contrib/quimb/state_vector.py +3 -10
  101. cirq/contrib/quirk/__init__.py +1 -1
  102. cirq/contrib/quirk/export_to_quirk.py +3 -3
  103. cirq/contrib/routing/__init__.py +12 -9
  104. cirq/contrib/routing/device.py +1 -1
  105. cirq/contrib/routing/device_test.py +1 -2
  106. cirq/contrib/routing/greedy.py +7 -5
  107. cirq/contrib/routing/greedy_test.py +5 -3
  108. cirq/contrib/routing/initialization.py +3 -1
  109. cirq/contrib/routing/initialization_test.py +1 -1
  110. cirq/contrib/routing/swap_network.py +6 -6
  111. cirq/contrib/routing/utils.py +6 -4
  112. cirq/contrib/routing/utils_test.py +1 -2
  113. cirq/{type_workarounds.py → contrib/shuffle_circuits/__init__.py} +5 -10
  114. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +250 -0
  115. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +363 -0
  116. cirq/contrib/svg/__init__.py +1 -1
  117. cirq/contrib/svg/svg.py +12 -10
  118. cirq/contrib/svg/svg_test.py +3 -2
  119. cirq/devices/__init__.py +34 -25
  120. cirq/devices/device.py +16 -12
  121. cirq/devices/device_test.py +1 -0
  122. cirq/devices/grid_device_metadata.py +16 -12
  123. cirq/devices/grid_device_metadata_test.py +2 -1
  124. cirq/devices/grid_qubit.py +31 -26
  125. cirq/devices/grid_qubit_test.py +30 -1
  126. cirq/devices/insertion_noise_model.py +6 -6
  127. cirq/devices/insertion_noise_model_test.py +1 -1
  128. cirq/devices/line_qubit.py +28 -20
  129. cirq/devices/line_qubit_test.py +26 -0
  130. cirq/devices/named_topologies.py +12 -10
  131. cirq/devices/named_topologies_test.py +5 -4
  132. cirq/devices/noise_model.py +29 -33
  133. cirq/devices/noise_properties.py +2 -2
  134. cirq/devices/noise_properties_test.py +2 -2
  135. cirq/devices/noise_utils.py +3 -3
  136. cirq/devices/superconducting_qubits_noise_properties.py +2 -2
  137. cirq/devices/superconducting_qubits_noise_properties_test.py +3 -3
  138. cirq/devices/thermal_noise_model.py +2 -1
  139. cirq/devices/unconstrained_device.py +1 -1
  140. cirq/devices/unconstrained_device_test.py +6 -0
  141. cirq/experiments/__init__.py +51 -34
  142. cirq/experiments/qubit_characterizations.py +17 -15
  143. cirq/experiments/qubit_characterizations_test.py +4 -6
  144. cirq/experiments/random_quantum_circuit_generation.py +10 -9
  145. cirq/experiments/random_quantum_circuit_generation_test.py +21 -4
  146. cirq/experiments/readout_confusion_matrix.py +73 -8
  147. cirq/experiments/readout_confusion_matrix_test.py +104 -1
  148. cirq/experiments/single_qubit_readout_calibration.py +8 -6
  149. cirq/experiments/single_qubit_readout_calibration_test.py +1 -1
  150. cirq/experiments/t1_decay_experiment.py +4 -5
  151. cirq/experiments/t1_decay_experiment_test.py +1 -2
  152. cirq/experiments/t2_decay_experiment.py +0 -1
  153. cirq/experiments/t2_decay_experiment_test.py +1 -2
  154. cirq/experiments/two_qubit_xeb.py +157 -33
  155. cirq/experiments/two_qubit_xeb_test.py +38 -22
  156. cirq/experiments/xeb_fitting.py +99 -19
  157. cirq/experiments/xeb_fitting_test.py +64 -25
  158. cirq/experiments/xeb_sampling.py +14 -18
  159. cirq/experiments/xeb_simulation.py +4 -3
  160. cirq/experiments/xeb_simulation_test.py +20 -14
  161. cirq/experiments/z_phase_calibration.py +368 -0
  162. cirq/experiments/z_phase_calibration_test.py +241 -0
  163. cirq/interop/__init__.py +4 -1
  164. cirq/interop/quirk/__init__.py +7 -4
  165. cirq/interop/quirk/cells/__init__.py +17 -6
  166. cirq/interop/quirk/cells/arithmetic_cells.py +8 -8
  167. cirq/interop/quirk/cells/arithmetic_cells_test.py +1 -1
  168. cirq/interop/quirk/cells/cell.py +6 -6
  169. cirq/interop/quirk/cells/composite_cell.py +5 -5
  170. cirq/interop/quirk/cells/composite_cell_test.py +1 -1
  171. cirq/interop/quirk/cells/control_cells.py +1 -1
  172. cirq/interop/quirk/cells/frequency_space_cells.py +2 -2
  173. cirq/interop/quirk/cells/ignored_cells.py +1 -1
  174. cirq/interop/quirk/cells/input_cells.py +1 -1
  175. cirq/interop/quirk/cells/input_cells_test.py +1 -1
  176. cirq/interop/quirk/cells/input_rotation_cells.py +1 -1
  177. cirq/interop/quirk/cells/input_rotation_cells_test.py +1 -1
  178. cirq/interop/quirk/cells/measurement_cells.py +1 -1
  179. cirq/interop/quirk/cells/parse.py +8 -7
  180. cirq/interop/quirk/cells/parse_test.py +2 -2
  181. cirq/interop/quirk/cells/single_qubit_rotation_cells.py +1 -1
  182. cirq/interop/quirk/cells/swap_cell_test.py +1 -1
  183. cirq/interop/quirk/cells/unsupported_cells.py +1 -1
  184. cirq/interop/quirk/url_to_circuit.py +7 -7
  185. cirq/interop/quirk/url_to_circuit_test.py +1 -1
  186. cirq/ion/__init__.py +4 -2
  187. cirq/json_resolver_cache.py +15 -7
  188. cirq/linalg/__init__.py +62 -51
  189. cirq/linalg/combinators.py +4 -4
  190. cirq/linalg/combinators_test.py +4 -1
  191. cirq/linalg/decompositions.py +15 -40
  192. cirq/linalg/decompositions_test.py +16 -22
  193. cirq/linalg/diagonalize.py +1 -1
  194. cirq/linalg/diagonalize_test.py +1 -1
  195. cirq/linalg/operator_spaces.py +20 -4
  196. cirq/linalg/operator_spaces_test.py +15 -2
  197. cirq/linalg/predicates.py +3 -3
  198. cirq/linalg/predicates_test.py +1 -0
  199. cirq/linalg/tolerance.py +2 -2
  200. cirq/linalg/transformations.py +30 -12
  201. cirq/linalg/transformations_test.py +13 -0
  202. cirq/neutral_atoms/__init__.py +2 -2
  203. cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +0 -1
  204. cirq/ops/__init__.py +172 -132
  205. cirq/ops/arithmetic_operation.py +2 -2
  206. cirq/ops/arithmetic_operation_test.py +2 -2
  207. cirq/ops/boolean_hamiltonian.py +3 -2
  208. cirq/ops/classically_controlled_operation.py +39 -12
  209. cirq/ops/classically_controlled_operation_test.py +147 -1
  210. cirq/ops/clifford_gate.py +38 -36
  211. cirq/ops/clifford_gate_test.py +75 -1
  212. cirq/ops/common_channels.py +16 -45
  213. cirq/ops/common_channels_test.py +10 -0
  214. cirq/ops/common_gate_families.py +1 -1
  215. cirq/ops/common_gate_families_test.py +1 -0
  216. cirq/ops/common_gates.py +48 -49
  217. cirq/ops/common_gates_test.py +18 -2
  218. cirq/ops/control_values.py +3 -3
  219. cirq/ops/control_values_test.py +2 -1
  220. cirq/ops/controlled_gate.py +36 -23
  221. cirq/ops/controlled_gate_test.py +70 -3
  222. cirq/ops/controlled_operation.py +6 -5
  223. cirq/ops/controlled_operation_test.py +7 -3
  224. cirq/ops/dense_pauli_string.py +11 -11
  225. cirq/ops/diagonal_gate.py +2 -2
  226. cirq/ops/diagonal_gate_test.py +1 -0
  227. cirq/ops/eigen_gate.py +16 -36
  228. cirq/ops/eigen_gate_test.py +60 -10
  229. cirq/ops/fourier_transform.py +1 -3
  230. cirq/ops/fourier_transform_test.py +2 -1
  231. cirq/ops/fsim_gate.py +42 -3
  232. cirq/ops/fsim_gate_test.py +21 -0
  233. cirq/ops/gate_operation.py +8 -8
  234. cirq/ops/gate_operation_test.py +4 -2
  235. cirq/ops/gateset_test.py +11 -2
  236. cirq/ops/global_phase_op.py +8 -7
  237. cirq/ops/global_phase_op_test.py +1 -1
  238. cirq/ops/greedy_qubit_manager_test.py +5 -0
  239. cirq/ops/identity.py +14 -4
  240. cirq/ops/identity_test.py +24 -0
  241. cirq/ops/kraus_channel.py +1 -0
  242. cirq/ops/kraus_channel_test.py +3 -1
  243. cirq/ops/linear_combinations.py +27 -21
  244. cirq/ops/linear_combinations_test.py +23 -4
  245. cirq/ops/matrix_gates.py +24 -8
  246. cirq/ops/measure_util.py +2 -2
  247. cirq/ops/measurement_gate.py +7 -4
  248. cirq/ops/measurement_gate_test.py +2 -1
  249. cirq/ops/mixed_unitary_channel.py +1 -0
  250. cirq/ops/mixed_unitary_channel_test.py +3 -1
  251. cirq/ops/named_qubit.py +8 -1
  252. cirq/ops/op_tree.py +3 -30
  253. cirq/ops/op_tree_test.py +4 -0
  254. cirq/ops/parallel_gate.py +2 -3
  255. cirq/ops/parallel_gate_test.py +2 -1
  256. cirq/ops/parity_gates.py +7 -8
  257. cirq/ops/parity_gates_test.py +1 -0
  258. cirq/ops/pauli_gates.py +5 -11
  259. cirq/ops/pauli_gates_test.py +1 -0
  260. cirq/ops/pauli_interaction_gate.py +11 -5
  261. cirq/ops/pauli_interaction_gate_test.py +2 -3
  262. cirq/ops/pauli_measurement_gate.py +6 -5
  263. cirq/ops/pauli_measurement_gate_test.py +1 -0
  264. cirq/ops/pauli_string.py +115 -130
  265. cirq/ops/pauli_string_phasor.py +21 -20
  266. cirq/ops/pauli_string_phasor_test.py +13 -3
  267. cirq/ops/pauli_string_raw_types.py +1 -0
  268. cirq/ops/pauli_string_test.py +192 -55
  269. cirq/ops/pauli_sum_exponential.py +3 -4
  270. cirq/ops/pauli_sum_exponential_test.py +0 -1
  271. cirq/ops/permutation_gate.py +2 -2
  272. cirq/ops/permutation_gate_test.py +1 -1
  273. cirq/ops/phased_iswap_gate.py +6 -7
  274. cirq/ops/phased_iswap_gate_test.py +21 -5
  275. cirq/ops/phased_x_gate.py +11 -25
  276. cirq/ops/phased_x_gate_test.py +19 -3
  277. cirq/ops/phased_x_z_gate.py +12 -11
  278. cirq/ops/projector.py +4 -5
  279. cirq/ops/qubit_manager.py +2 -1
  280. cirq/ops/qubit_manager_test.py +2 -1
  281. cirq/ops/qubit_order.py +1 -1
  282. cirq/ops/random_gate_channel.py +1 -1
  283. cirq/ops/random_gate_channel_test.py +0 -6
  284. cirq/ops/raw_types.py +146 -50
  285. cirq/ops/raw_types_test.py +37 -3
  286. cirq/ops/state_preparation_channel.py +2 -2
  287. cirq/ops/state_preparation_channel_test.py +2 -1
  288. cirq/ops/swap_gates.py +9 -4
  289. cirq/ops/three_qubit_gates.py +8 -8
  290. cirq/ops/three_qubit_gates_test.py +1 -0
  291. cirq/ops/two_qubit_diagonal_gate.py +4 -3
  292. cirq/ops/uniform_superposition_gate.py +4 -4
  293. cirq/ops/uniform_superposition_gate_test.py +1 -0
  294. cirq/ops/wait_gate.py +6 -8
  295. cirq/protocols/__init__.py +135 -83
  296. cirq/protocols/act_on_protocol.py +1 -1
  297. cirq/protocols/act_on_protocol_test.py +1 -1
  298. cirq/protocols/apply_channel_protocol.py +3 -3
  299. cirq/protocols/apply_mixture_protocol.py +15 -9
  300. cirq/protocols/apply_mixture_protocol_test.py +11 -0
  301. cirq/protocols/apply_unitary_protocol.py +2 -2
  302. cirq/protocols/apply_unitary_protocol_test.py +2 -1
  303. cirq/protocols/approximate_equality_protocol.py +7 -8
  304. cirq/protocols/approximate_equality_protocol_test.py +3 -1
  305. cirq/protocols/circuit_diagram_info_protocol.py +8 -6
  306. cirq/protocols/circuit_diagram_info_protocol_test.py +5 -0
  307. cirq/protocols/commutes_protocol.py +6 -6
  308. cirq/protocols/control_key_protocol.py +1 -1
  309. cirq/protocols/decompose_protocol.py +4 -5
  310. cirq/protocols/decompose_protocol_test.py +2 -1
  311. cirq/protocols/equal_up_to_global_phase_protocol.py +3 -3
  312. cirq/protocols/equal_up_to_global_phase_protocol_test.py +7 -0
  313. cirq/protocols/has_stabilizer_effect_protocol.py +5 -5
  314. cirq/protocols/has_unitary_protocol.py +1 -1
  315. cirq/protocols/has_unitary_protocol_test.py +8 -7
  316. cirq/protocols/hash_from_pickle_test.py +120 -0
  317. cirq/protocols/inverse_protocol.py +1 -1
  318. cirq/protocols/json_serialization.py +14 -1
  319. cirq/protocols/json_serialization_test.py +28 -7
  320. cirq/protocols/json_test_data/BitMaskKeyCondition.json +86 -0
  321. cirq/protocols/json_test_data/BitMaskKeyCondition.repr +7 -0
  322. cirq/protocols/json_test_data/Concat.json +19 -0
  323. cirq/protocols/json_test_data/Concat.repr +1 -0
  324. cirq/protocols/json_test_data/README.md +4 -2
  325. cirq/protocols/json_test_data/SympyCondition.json +60 -15
  326. cirq/protocols/json_test_data/SympyCondition.repr +4 -1
  327. cirq/protocols/json_test_data/_InverseCompositeGate.json +10 -0
  328. cirq/protocols/json_test_data/_InverseCompositeGate.repr +1 -0
  329. cirq/protocols/json_test_data/__init__.py +1 -1
  330. cirq/protocols/json_test_data/sympy.And.json +13 -0
  331. cirq/protocols/json_test_data/sympy.And.repr +1 -0
  332. cirq/protocols/json_test_data/sympy.Indexed.json +18 -0
  333. cirq/protocols/json_test_data/sympy.Indexed.repr +1 -0
  334. cirq/protocols/json_test_data/sympy.IndexedBase.json +9 -0
  335. cirq/protocols/json_test_data/sympy.IndexedBase.repr +1 -0
  336. cirq/protocols/json_test_data/sympy.Not.json +9 -0
  337. cirq/protocols/json_test_data/sympy.Not.repr +1 -0
  338. cirq/protocols/json_test_data/sympy.Or.json +13 -0
  339. cirq/protocols/json_test_data/sympy.Or.repr +1 -0
  340. cirq/protocols/json_test_data/sympy.Xor.json +13 -0
  341. cirq/protocols/json_test_data/sympy.Xor.repr +1 -0
  342. cirq/protocols/kraus_protocol.py +8 -8
  343. cirq/protocols/kraus_protocol_test.py +0 -1
  344. cirq/protocols/measurement_key_protocol.py +1 -1
  345. cirq/protocols/measurement_key_protocol_test.py +7 -7
  346. cirq/protocols/mixture_protocol.py +6 -4
  347. cirq/protocols/mixture_protocol_test.py +21 -13
  348. cirq/protocols/pauli_expansion_protocol.py +1 -0
  349. cirq/protocols/pow_protocol.py +1 -1
  350. cirq/protocols/qasm.py +25 -6
  351. cirq/protocols/qasm_test.py +17 -0
  352. cirq/protocols/qid_shape_protocol.py +2 -2
  353. cirq/protocols/resolve_parameters.py +2 -3
  354. cirq/protocols/resolve_parameters_test.py +2 -1
  355. cirq/protocols/trace_distance_bound.py +1 -1
  356. cirq/protocols/trace_distance_bound_test.py +1 -0
  357. cirq/protocols/unitary_protocol.py +3 -3
  358. cirq/protocols/unitary_protocol_test.py +1 -1
  359. cirq/qis/__init__.py +48 -35
  360. cirq/qis/channels_test.py +0 -9
  361. cirq/qis/clifford_tableau.py +46 -26
  362. cirq/qis/clifford_tableau_test.py +2 -1
  363. cirq/qis/entropy.py +115 -0
  364. cirq/qis/entropy_test.py +43 -0
  365. cirq/qis/measures.py +5 -4
  366. cirq/qis/measures_test.py +7 -0
  367. cirq/qis/noise_utils_test.py +4 -4
  368. cirq/qis/quantum_state_representation.py +1 -1
  369. cirq/qis/states.py +7 -7
  370. cirq/sim/__init__.py +55 -37
  371. cirq/sim/classical_simulator.py +7 -6
  372. cirq/sim/classical_simulator_test.py +3 -1
  373. cirq/sim/clifford/__init__.py +17 -9
  374. cirq/sim/clifford/clifford_simulator.py +5 -4
  375. cirq/sim/clifford/clifford_simulator_test.py +32 -9
  376. cirq/sim/clifford/clifford_tableau_simulation_state.py +1 -1
  377. cirq/sim/clifford/stabilizer_simulation_state.py +1 -1
  378. cirq/sim/clifford/stabilizer_state_ch_form.py +4 -3
  379. cirq/sim/density_matrix_simulator.py +3 -2
  380. cirq/sim/density_matrix_simulator_test.py +12 -4
  381. cirq/sim/density_matrix_utils.py +1 -1
  382. cirq/sim/mux.py +2 -2
  383. cirq/sim/simulation_state.py +4 -5
  384. cirq/sim/simulation_state_base.py +2 -2
  385. cirq/sim/simulation_state_test.py +1 -1
  386. cirq/sim/simulation_utils.py +3 -1
  387. cirq/sim/simulation_utils_test.py +2 -3
  388. cirq/sim/simulator.py +7 -6
  389. cirq/sim/simulator_base.py +5 -5
  390. cirq/sim/simulator_test.py +14 -3
  391. cirq/sim/sparse_simulator.py +4 -3
  392. cirq/sim/sparse_simulator_test.py +17 -9
  393. cirq/sim/state_vector.py +2 -2
  394. cirq/sim/state_vector_simulation_state_test.py +1 -1
  395. cirq/sim/state_vector_simulator.py +4 -4
  396. cirq/sim/state_vector_test.py +27 -32
  397. cirq/study/__init__.py +27 -21
  398. cirq/study/flatten_expressions.py +5 -6
  399. cirq/study/flatten_expressions_test.py +1 -1
  400. cirq/study/resolver.py +14 -11
  401. cirq/study/resolver_test.py +10 -1
  402. cirq/study/result.py +3 -3
  403. cirq/study/sweepable.py +15 -9
  404. cirq/study/sweepable_test.py +27 -0
  405. cirq/study/sweeps.py +65 -10
  406. cirq/study/sweeps_test.py +123 -0
  407. cirq/testing/__init__.py +86 -57
  408. cirq/testing/_compat_test_data/module_a/__init__.py +2 -2
  409. cirq/testing/_compat_test_data/module_a/sub/subsub/__init__.py +1 -1
  410. cirq/testing/circuit_compare.py +3 -4
  411. cirq/testing/circuit_compare_test.py +7 -8
  412. cirq/testing/consistent_act_on.py +3 -3
  413. cirq/testing/consistent_channels_test.py +2 -1
  414. cirq/testing/consistent_controlled_gate_op.py +3 -2
  415. cirq/testing/consistent_controlled_gate_op_test.py +2 -3
  416. cirq/testing/consistent_decomposition.py +1 -1
  417. cirq/testing/consistent_decomposition_test.py +1 -2
  418. cirq/testing/consistent_pauli_expansion_test.py +1 -1
  419. cirq/testing/consistent_phase_by.py +1 -1
  420. cirq/testing/consistent_phase_by_test.py +1 -2
  421. cirq/testing/consistent_protocols.py +11 -11
  422. cirq/testing/consistent_protocols_test.py +4 -5
  423. cirq/testing/consistent_qasm.py +8 -12
  424. cirq/testing/consistent_qasm_test.py +1 -1
  425. cirq/testing/consistent_resolve_parameters.py +2 -1
  426. cirq/testing/consistent_specified_has_unitary_test.py +1 -1
  427. cirq/testing/consistent_unitary.py +3 -1
  428. cirq/testing/consistent_unitary_test.py +3 -3
  429. cirq/testing/devices.py +1 -1
  430. cirq/testing/devices_test.py +1 -0
  431. cirq/testing/equals_tester.py +2 -4
  432. cirq/testing/equals_tester_test.py +6 -5
  433. cirq/testing/equivalent_basis_map.py +1 -0
  434. cirq/testing/equivalent_basis_map_test.py +0 -1
  435. cirq/testing/gate_features_test.py +5 -0
  436. cirq/testing/json.py +4 -4
  437. cirq/testing/lin_alg_utils_test.py +1 -1
  438. cirq/testing/order_tester.py +1 -1
  439. cirq/testing/order_tester_test.py +1 -1
  440. cirq/testing/pytest_utils.py +57 -0
  441. cirq/testing/pytest_utils_test.py +35 -0
  442. cirq/testing/random_circuit.py +2 -2
  443. cirq/testing/random_circuit_test.py +2 -2
  444. cirq/testing/routing_devices_test.py +2 -1
  445. cirq/testing/sample_circuits.py +1 -1
  446. cirq/testing/sample_gates.py +5 -4
  447. cirq/testing/sample_gates_test.py +2 -2
  448. cirq/transformers/__init__.py +101 -82
  449. cirq/transformers/align.py +12 -1
  450. cirq/transformers/align_test.py +13 -0
  451. cirq/transformers/analytical_decompositions/__init__.py +27 -24
  452. cirq/transformers/analytical_decompositions/clifford_decomposition.py +2 -1
  453. cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +1 -1
  454. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +1 -1
  455. cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
  456. cirq/transformers/analytical_decompositions/cphase_to_fsim.py +1 -1
  457. cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +1 -1
  458. cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +2 -2
  459. cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +4 -4
  460. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +99 -24
  461. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +105 -14
  462. cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +1 -1
  463. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +1 -1
  464. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +1 -0
  465. cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +3 -4
  466. cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +1 -1
  467. cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +2 -1
  468. cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -1
  469. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +5 -6
  470. cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +2 -2
  471. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +1 -1
  472. cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +1 -2
  473. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +2 -2
  474. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +2 -2
  475. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -1
  476. cirq/transformers/drop_empty_moments.py +1 -0
  477. cirq/transformers/drop_negligible_operations.py +1 -0
  478. cirq/transformers/dynamical_decoupling.py +255 -43
  479. cirq/transformers/dynamical_decoupling_test.py +730 -17
  480. cirq/transformers/eject_phased_paulis.py +29 -15
  481. cirq/transformers/eject_phased_paulis_test.py +3 -8
  482. cirq/transformers/eject_z.py +3 -2
  483. cirq/transformers/eject_z_test.py +3 -3
  484. cirq/transformers/gauge_compiling/__init__.py +25 -9
  485. cirq/transformers/gauge_compiling/cphase_gauge.py +146 -0
  486. cirq/transformers/gauge_compiling/cphase_gauge_test.py +42 -0
  487. cirq/transformers/gauge_compiling/cz_gauge.py +4 -4
  488. cirq/transformers/gauge_compiling/gauge_compiling.py +245 -6
  489. cirq/transformers/gauge_compiling/gauge_compiling_test.py +107 -2
  490. cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +39 -2
  491. cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +10 -1
  492. cirq/transformers/gauge_compiling/iswap_gauge.py +2 -2
  493. cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -2
  494. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +23 -5
  495. cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +3 -2
  496. cirq/transformers/heuristic_decompositions/__init__.py +3 -3
  497. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +2 -1
  498. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +1 -1
  499. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +4 -4
  500. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +4 -4
  501. cirq/transformers/insertion_sort.py +64 -0
  502. cirq/transformers/insertion_sort_test.py +34 -0
  503. cirq/transformers/measurement_transformers.py +14 -1
  504. cirq/transformers/measurement_transformers_test.py +35 -0
  505. cirq/transformers/merge_k_qubit_gates.py +2 -2
  506. cirq/transformers/merge_single_qubit_gates.py +1 -1
  507. cirq/transformers/merge_single_qubit_gates_test.py +1 -1
  508. cirq/transformers/noise_adding.py +115 -0
  509. cirq/transformers/noise_adding_test.py +54 -0
  510. cirq/transformers/optimize_for_target_gateset.py +1 -1
  511. cirq/transformers/optimize_for_target_gateset_test.py +3 -2
  512. cirq/transformers/qubit_management_transformers.py +1 -1
  513. cirq/transformers/randomized_measurements.py +171 -0
  514. cirq/transformers/randomized_measurements_test.py +68 -0
  515. cirq/transformers/routing/__init__.py +14 -5
  516. cirq/transformers/routing/initial_mapper.py +1 -1
  517. cirq/transformers/routing/initial_mapper_test.py +1 -0
  518. cirq/transformers/routing/line_initial_mapper.py +3 -2
  519. cirq/transformers/routing/mapping_manager.py +2 -2
  520. cirq/transformers/routing/mapping_manager_test.py +2 -2
  521. cirq/transformers/routing/route_circuit_cqc.py +3 -2
  522. cirq/transformers/routing/route_circuit_cqc_test.py +2 -1
  523. cirq/transformers/routing/visualize_routed_circuit.py +1 -0
  524. cirq/transformers/routing/visualize_routed_circuit_test.py +1 -0
  525. cirq/transformers/stratify.py +2 -2
  526. cirq/transformers/synchronize_terminal_measurements.py +2 -1
  527. cirq/transformers/target_gatesets/__init__.py +7 -5
  528. cirq/transformers/target_gatesets/compilation_target_gateset.py +16 -3
  529. cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -0
  530. cirq/transformers/target_gatesets/cz_gateset.py +5 -1
  531. cirq/transformers/target_gatesets/cz_gateset_test.py +23 -2
  532. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +1 -1
  533. cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +3 -2
  534. cirq/transformers/transformer_api.py +5 -4
  535. cirq/transformers/transformer_api_test.py +11 -3
  536. cirq/transformers/transformer_primitives.py +9 -31
  537. cirq/transformers/transformer_primitives_test.py +6 -5
  538. cirq/value/__init__.py +51 -30
  539. cirq/value/abc_alt.py +1 -2
  540. cirq/value/angle.py +2 -0
  541. cirq/value/classical_data.py +1 -0
  542. cirq/value/condition.py +149 -3
  543. cirq/value/condition_test.py +254 -0
  544. cirq/value/digits.py +1 -1
  545. cirq/value/duration.py +4 -4
  546. cirq/value/duration_test.py +2 -1
  547. cirq/value/linear_dict.py +85 -24
  548. cirq/value/linear_dict_test.py +94 -3
  549. cirq/value/measurement_key.py +9 -2
  550. cirq/value/periodic_value.py +2 -3
  551. cirq/value/periodic_value_test.py +5 -0
  552. cirq/value/probability.py +1 -0
  553. cirq/value/random_state.py +1 -1
  554. cirq/value/timestamp.py +2 -4
  555. cirq/value/timestamp_test.py +2 -1
  556. cirq/value/type_alias.py +2 -2
  557. cirq/value/value_equality_attr.py +14 -2
  558. cirq/value/value_equality_attr_test.py +1 -1
  559. cirq/vis/__init__.py +9 -6
  560. cirq/vis/density_matrix.py +1 -1
  561. cirq/vis/density_matrix_test.py +2 -5
  562. cirq/vis/heatmap.py +49 -12
  563. cirq/vis/heatmap_test.py +168 -4
  564. cirq/vis/histogram.py +1 -1
  565. cirq/vis/histogram_test.py +1 -2
  566. cirq/vis/state_histogram.py +7 -5
  567. cirq/vis/state_histogram_test.py +2 -2
  568. cirq/work/__init__.py +19 -13
  569. cirq/work/collector.py +2 -2
  570. cirq/work/observable_grouping.py +2 -2
  571. cirq/work/observable_measurement.py +3 -3
  572. cirq/work/observable_measurement_data.py +5 -2
  573. cirq/work/observable_measurement_test.py +8 -8
  574. cirq/work/observable_readout_calibration.py +2 -2
  575. cirq/work/observable_readout_calibration_test.py +2 -1
  576. cirq/work/observable_settings.py +8 -7
  577. cirq/work/observable_settings_test.py +3 -2
  578. cirq/work/pauli_sum_collector.py +1 -1
  579. cirq/work/sampler.py +8 -20
  580. cirq/work/sampler_test.py +4 -3
  581. cirq/work/zeros_sampler.py +1 -1
  582. cirq_core-1.5.0.dist-info/METADATA +125 -0
  583. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/RECORD +586 -552
  584. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/WHEEL +1 -1
  585. cirq/experiments/grid_parallel_two_qubit_xeb.py +0 -62
  586. cirq/protocols/json_test_data/GridParallelXEBMetadata.json +0 -119
  587. cirq/protocols/json_test_data/GridParallelXEBMetadata.repr +0 -1
  588. cirq_core-1.4.0.dev20240529225110.dist-info/METADATA +0 -50
  589. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/LICENSE +0 -0
  590. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,363 @@
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
+ import itertools
15
+
16
+ import numpy as np
17
+ import pytest
18
+
19
+ import cirq
20
+ from cirq.experiments import (
21
+ random_quantum_circuit_generation as rqcg,
22
+ SingleQubitReadoutCalibrationResult,
23
+ )
24
+ from cirq.experiments.single_qubit_readout_calibration_test import NoisySingleQubitReadoutSampler
25
+ from cirq.study import ResultDict
26
+
27
+
28
+ def _create_test_circuits(qubits: list[cirq.Qid], n_circuits: int) -> list[cirq.Circuit]:
29
+ """Helper function to generate circuits for testing."""
30
+ if len(qubits) < 2:
31
+ raise ValueError(
32
+ "Need at least two qubits to generate two-qubit circuits."
33
+ ) # pragma: no cover
34
+ two_qubit_gates = [cirq.ISWAP**0.5, cirq.CNOT**0.5]
35
+ input_circuits = []
36
+ qubit_pairs = list(itertools.combinations(qubits, 2))
37
+ num_pairs = len(qubit_pairs)
38
+ for i in range(n_circuits):
39
+ gate = two_qubit_gates[i % len(two_qubit_gates)]
40
+ q0, q1 = qubit_pairs[i % num_pairs]
41
+ circuits = rqcg.generate_library_of_2q_circuits(
42
+ n_library_circuits=5, two_qubit_gate=gate, q0=q0, q1=q1
43
+ )
44
+ for circuit in circuits:
45
+ circuit.append(cirq.measure(*qubits, key="m"))
46
+ input_circuits.extend(circuits)
47
+ return input_circuits
48
+
49
+
50
+ def test_shuffled_circuits_with_readout_benchmarking_errors_no_noise():
51
+ """Test shuffled circuits with readout benchmarking with no noise from sampler."""
52
+ qubits = cirq.LineQubit.range(5)
53
+
54
+ # Generate random input circuits
55
+ input_circuits = _create_test_circuits(qubits, 3)
56
+
57
+ sampler = cirq.Simulator()
58
+ circuit_repetitions = 1
59
+ # allow passing a seed
60
+ rng = 123
61
+ readout_repetitions = 1000
62
+
63
+ measurements, readout_calibration_results = (
64
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
65
+ input_circuits,
66
+ sampler,
67
+ circuit_repetitions,
68
+ rng,
69
+ num_random_bitstrings=100,
70
+ readout_repetitions=readout_repetitions,
71
+ )
72
+ )
73
+
74
+ for measurement in measurements:
75
+ assert isinstance(measurement, ResultDict)
76
+
77
+ for qlist, readout_calibration_result in readout_calibration_results.items():
78
+ assert isinstance(qlist, tuple)
79
+ assert all(isinstance(q, cirq.Qid) for q in qlist)
80
+ assert isinstance(readout_calibration_result, SingleQubitReadoutCalibrationResult)
81
+
82
+ assert readout_calibration_result.zero_state_errors == {q: 0 for q in qubits}
83
+ assert readout_calibration_result.one_state_errors == {q: 0 for q in qubits}
84
+ assert readout_calibration_result.repetitions == readout_repetitions
85
+ assert isinstance(readout_calibration_result.timestamp, float)
86
+
87
+
88
+ def test_shuffled_circuits_with_readout_benchmarking_errors_with_noise():
89
+ """Test shuffled circuits with readout benchmarking with noise from sampler."""
90
+ qubits = cirq.LineQubit.range(6)
91
+
92
+ # Generate random input circuits
93
+ input_circuits = _create_test_circuits(qubits, 6)
94
+
95
+ sampler = NoisySingleQubitReadoutSampler(p0=0.1, p1=0.2, seed=1234)
96
+ circuit_repetitions = 1
97
+ rng = np.random.default_rng()
98
+ readout_repetitions = 1000
99
+
100
+ measurements, readout_calibration_results = (
101
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
102
+ input_circuits,
103
+ sampler,
104
+ circuit_repetitions,
105
+ rng,
106
+ num_random_bitstrings=100,
107
+ readout_repetitions=readout_repetitions,
108
+ )
109
+ )
110
+
111
+ for measurement in measurements:
112
+ assert isinstance(measurement, ResultDict)
113
+
114
+ for qlist, readout_calibration_result in readout_calibration_results.items():
115
+ assert isinstance(qlist, tuple)
116
+ assert all(isinstance(q, cirq.Qid) for q in qlist)
117
+ assert isinstance(readout_calibration_result, SingleQubitReadoutCalibrationResult)
118
+
119
+ for error in readout_calibration_result.zero_state_errors.values():
120
+ assert 0.08 < error < 0.12
121
+ for error in readout_calibration_result.one_state_errors.values():
122
+ assert 0.18 < error < 0.22
123
+ assert readout_calibration_result.repetitions == readout_repetitions
124
+ assert isinstance(readout_calibration_result.timestamp, float)
125
+
126
+
127
+ def test_shuffled_circuits_with_readout_benchmarking_errors_with_noise_and_input_qubits():
128
+ """Test shuffled circuits with readout benchmarking with noise from sampler and input qubits."""
129
+ qubits = cirq.LineQubit.range(6)
130
+ readout_qubits = qubits[:4]
131
+
132
+ # Generate random input circuits
133
+ input_circuits = _create_test_circuits(qubits, 6)
134
+
135
+ sampler = NoisySingleQubitReadoutSampler(p0=0.1, p1=0.3, seed=1234)
136
+ circuit_repetitions = 1
137
+ rng = np.random.default_rng()
138
+ readout_repetitions = 1000
139
+
140
+ measurements, readout_calibration_results = (
141
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
142
+ input_circuits,
143
+ sampler,
144
+ circuit_repetitions,
145
+ rng,
146
+ num_random_bitstrings=100,
147
+ readout_repetitions=readout_repetitions,
148
+ qubits=readout_qubits,
149
+ )
150
+ )
151
+
152
+ for measurement in measurements:
153
+ assert isinstance(measurement, ResultDict)
154
+
155
+ for qlist, readout_calibration_result in readout_calibration_results.items():
156
+ assert isinstance(qlist, tuple)
157
+ assert all(isinstance(q, cirq.Qid) for q in qlist)
158
+ assert isinstance(readout_calibration_result, SingleQubitReadoutCalibrationResult)
159
+
160
+ for error in readout_calibration_result.zero_state_errors.values():
161
+ assert 0.08 < error < 0.12
162
+ for error in readout_calibration_result.one_state_errors.values():
163
+ assert 0.28 < error < 0.32
164
+ assert readout_calibration_result.repetitions == readout_repetitions
165
+ assert isinstance(readout_calibration_result.timestamp, float)
166
+
167
+
168
+ def test_shuffled_circuits_with_readout_benchmarking_errors_with_noise_and_lists_input_qubits():
169
+ """Test shuffled circuits with readout benchmarking with noise from sampler and input qubits."""
170
+ qubits_1 = cirq.LineQubit.range(3)
171
+ qubits_2 = cirq.LineQubit.range(4)
172
+
173
+ readout_qubits = [qubits_1, qubits_2]
174
+
175
+ # Generate random input circuits and append measurements
176
+ input_circuits = _create_test_circuits(qubits_1, 6) + _create_test_circuits(qubits_2, 4)
177
+
178
+ sampler = NoisySingleQubitReadoutSampler(p0=0.1, p1=0.3, seed=1234)
179
+ circuit_repetitions = 1
180
+ rng = np.random.default_rng()
181
+ readout_repetitions = 1000
182
+
183
+ measurements, readout_calibration_results = (
184
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
185
+ input_circuits,
186
+ sampler,
187
+ circuit_repetitions,
188
+ rng,
189
+ num_random_bitstrings=100,
190
+ readout_repetitions=readout_repetitions,
191
+ qubits=readout_qubits,
192
+ )
193
+ )
194
+
195
+ for measurement in measurements:
196
+ assert isinstance(measurement, ResultDict)
197
+
198
+ for qlist, readout_calibration_result in readout_calibration_results.items():
199
+ assert isinstance(qlist, tuple)
200
+ assert all(isinstance(q, cirq.Qid) for q in qlist)
201
+ assert isinstance(readout_calibration_result, SingleQubitReadoutCalibrationResult)
202
+
203
+ for error in readout_calibration_result.zero_state_errors.values():
204
+ assert 0.08 < error < 0.12
205
+ for error in readout_calibration_result.one_state_errors.values():
206
+ assert 0.28 < error < 0.32
207
+ assert readout_calibration_result.repetitions == readout_repetitions
208
+ assert isinstance(readout_calibration_result.timestamp, float)
209
+
210
+
211
+ def test_can_handle_zero_random_bitstring():
212
+ """Test shuffled circuits without readout benchmarking."""
213
+ qubits_1 = cirq.LineQubit.range(3)
214
+ qubits_2 = cirq.LineQubit.range(4)
215
+
216
+ readout_qubits = [qubits_1, qubits_2]
217
+
218
+ # Generate random input circuits and append measurements
219
+ input_circuits = _create_test_circuits(qubits_1, 6) + _create_test_circuits(qubits_2, 4)
220
+
221
+ sampler = NoisySingleQubitReadoutSampler(p0=0.1, p1=0.3, seed=1234)
222
+ circuit_repetitions = 1
223
+ rng = np.random.default_rng()
224
+ readout_repetitions = 1000
225
+
226
+ measurements, readout_calibration_results = (
227
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
228
+ input_circuits,
229
+ sampler,
230
+ circuit_repetitions,
231
+ rng,
232
+ num_random_bitstrings=0,
233
+ readout_repetitions=readout_repetitions,
234
+ qubits=readout_qubits,
235
+ )
236
+ )
237
+
238
+ for measurement in measurements:
239
+ assert isinstance(measurement, ResultDict)
240
+ # Check that the readout_calibration_results is empty
241
+ assert len(readout_calibration_results.items()) == 0
242
+
243
+
244
+ def test_empty_input_circuits():
245
+ """Test that the input circuits are empty."""
246
+ with pytest.raises(ValueError, match="Input circuits must not be empty."):
247
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
248
+ [],
249
+ cirq.ZerosSampler(),
250
+ circuit_repetitions=10,
251
+ rng_or_seed=np.random.default_rng(456),
252
+ num_random_bitstrings=5,
253
+ readout_repetitions=100,
254
+ )
255
+
256
+
257
+ def test_non_circuit_input():
258
+ """Test that the input circuits are not of type cirq.Circuit."""
259
+ q = cirq.LineQubit(0)
260
+ with pytest.raises(ValueError, match="Input circuits must be of type cirq.Circuit."):
261
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
262
+ [q],
263
+ cirq.ZerosSampler(),
264
+ circuit_repetitions=10,
265
+ rng_or_seed=np.random.default_rng(456),
266
+ num_random_bitstrings=5,
267
+ readout_repetitions=100,
268
+ )
269
+
270
+
271
+ def test_no_measurements():
272
+ """Test that the input circuits don't have measurements."""
273
+ q = cirq.LineQubit(0)
274
+ circuit = cirq.Circuit(cirq.H(q))
275
+ with pytest.raises(ValueError, match="Input circuits must have measurements."):
276
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
277
+ [circuit],
278
+ cirq.ZerosSampler(),
279
+ circuit_repetitions=10,
280
+ rng_or_seed=np.random.default_rng(456),
281
+ num_random_bitstrings=5,
282
+ readout_repetitions=100,
283
+ )
284
+
285
+
286
+ def test_zero_circuit_repetitions():
287
+ """Test that the circuit repetitions are zero."""
288
+ q = cirq.LineQubit(0)
289
+ circuit = cirq.Circuit(cirq.H(q), cirq.measure(q))
290
+ with pytest.raises(ValueError, match="Must provide non-zero circuit_repetitions."):
291
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
292
+ [circuit],
293
+ cirq.ZerosSampler(),
294
+ circuit_repetitions=0,
295
+ rng_or_seed=np.random.default_rng(456),
296
+ num_random_bitstrings=5,
297
+ readout_repetitions=100,
298
+ )
299
+
300
+
301
+ def test_mismatch_circuit_repetitions():
302
+ """Test that the number of circuit repetitions don't match the number of input circuits."""
303
+ q = cirq.LineQubit(0)
304
+ circuit = cirq.Circuit(cirq.H(q), cirq.measure(q))
305
+ with pytest.raises(
306
+ ValueError,
307
+ match="Number of circuit_repetitions must match the number of" + " input circuits.",
308
+ ):
309
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
310
+ [circuit],
311
+ cirq.ZerosSampler(),
312
+ circuit_repetitions=[10, 20],
313
+ rng_or_seed=np.random.default_rng(456),
314
+ num_random_bitstrings=5,
315
+ readout_repetitions=100,
316
+ )
317
+
318
+
319
+ def test_zero_num_random_bitstrings():
320
+ """Test that the number of random bitstrings is smaller than zero."""
321
+ q = cirq.LineQubit(0)
322
+ circuit = cirq.Circuit(cirq.H(q), cirq.measure(q))
323
+ with pytest.raises(ValueError, match="Must provide zero or more num_random_bitstrings."):
324
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
325
+ [circuit],
326
+ cirq.ZerosSampler(),
327
+ circuit_repetitions=10,
328
+ rng_or_seed=np.random.default_rng(456),
329
+ num_random_bitstrings=-1,
330
+ readout_repetitions=100,
331
+ )
332
+
333
+
334
+ def test_zero_readout_repetitions():
335
+ """Test that the readout repetitions is zero."""
336
+ q = cirq.LineQubit(0)
337
+ circuit = cirq.Circuit(cirq.H(q), cirq.measure(q))
338
+ with pytest.raises(
339
+ ValueError, match="Must provide non-zero readout_repetitions for readout" + " calibration."
340
+ ):
341
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
342
+ [circuit],
343
+ cirq.ZerosSampler(),
344
+ circuit_repetitions=10,
345
+ rng_or_seed=np.random.default_rng(456),
346
+ num_random_bitstrings=5,
347
+ readout_repetitions=0,
348
+ )
349
+
350
+
351
+ def test_rng_type_mismatch():
352
+ """Test that the rng is not a numpy random generator or a seed."""
353
+ q = cirq.LineQubit(0)
354
+ circuit = cirq.Circuit(cirq.H(q), cirq.measure(q))
355
+ with pytest.raises(ValueError, match="Must provide a numpy random generator or a seed"):
356
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
357
+ [circuit],
358
+ cirq.ZerosSampler(),
359
+ circuit_repetitions=10,
360
+ rng_or_seed="not a random generator or seed",
361
+ num_random_bitstrings=5,
362
+ readout_repetitions=100,
363
+ )
@@ -1,2 +1,2 @@
1
1
  # pylint: disable=wrong-or-nonexistent-copyright-notice
2
- from cirq.contrib.svg.svg import SVGCircuit, circuit_to_svg
2
+ from cirq.contrib.svg.svg import SVGCircuit as SVGCircuit, circuit_to_svg as circuit_to_svg
cirq/contrib/svg/svg.py CHANGED
@@ -1,9 +1,11 @@
1
1
  # pylint: disable=wrong-or-nonexistent-copyright-notice
2
- from typing import TYPE_CHECKING, List, Tuple, cast, Dict
3
2
 
4
- import matplotlib.textpath
5
- import matplotlib.font_manager
3
+ from __future__ import annotations
4
+
5
+ from typing import cast, Dict, List, Tuple, TYPE_CHECKING
6
6
 
7
+ import matplotlib.font_manager
8
+ import matplotlib.textpath
7
9
 
8
10
  if TYPE_CHECKING:
9
11
  import cirq
@@ -60,7 +62,7 @@ def _text(x: float, y: float, text: str, fontsize: int = 14):
60
62
 
61
63
 
62
64
  def _fit_horizontal(
63
- tdd: 'cirq.TextDiagramDrawer', ref_boxwidth: float, col_padding: float
65
+ tdd: cirq.TextDiagramDrawer, ref_boxwidth: float, col_padding: float
64
66
  ) -> Tuple[List[float], List[float]]:
65
67
  """Figure out the horizontal spacing of columns to fit everything in.
66
68
 
@@ -90,7 +92,7 @@ def _fit_horizontal(
90
92
 
91
93
 
92
94
  def _fit_vertical(
93
- tdd: 'cirq.TextDiagramDrawer', ref_boxheight: float, row_padding: float
95
+ tdd: cirq.TextDiagramDrawer, ref_boxheight: float, row_padding: float
94
96
  ) -> Tuple[List[float], List[float], Dict[float, int]]:
95
97
  """Return data structures used to turn tdd vertical coordinates into
96
98
  well-spaced SVG coordinates.
@@ -165,7 +167,7 @@ def _debug_spacing(col_starts, row_starts): # pragma: no cover
165
167
 
166
168
 
167
169
  def tdd_to_svg(
168
- tdd: 'cirq.TextDiagramDrawer',
170
+ tdd: cirq.TextDiagramDrawer,
169
171
  ref_boxwidth: float = 40,
170
172
  ref_boxheight: float = 40,
171
173
  col_padding: float = 20,
@@ -200,7 +202,7 @@ def tdd_to_svg(
200
202
  # qubits start at far left and their wires shall be blue
201
203
  stroke = QBLUE
202
204
  else:
203
- stroke = 'black'
205
+ stroke = 'black' # pragma: no cover
204
206
  t += f'<line x1="{x1}" x2="{x2}" y1="{y}" y2="{y}" stroke="{stroke}" stroke-width="1" />'
205
207
 
206
208
  for xi, yi1, yi2, _, _ in tdd.vertical_lines:
@@ -247,7 +249,7 @@ def tdd_to_svg(
247
249
  return t
248
250
 
249
251
 
250
- def _validate_circuit(circuit: 'cirq.Circuit'):
252
+ def _validate_circuit(circuit: cirq.Circuit):
251
253
  if len(circuit) == 0:
252
254
  raise ValueError("Can't draw SVG diagram for empty circuits")
253
255
 
@@ -261,14 +263,14 @@ class SVGCircuit:
261
263
  which will cause the circuit to be displayed as an SVG image.
262
264
  """
263
265
 
264
- def __init__(self, circuit: 'cirq.Circuit'):
266
+ def __init__(self, circuit: cirq.Circuit):
265
267
  self.circuit = circuit
266
268
 
267
269
  def _repr_svg_(self) -> str:
268
270
  return circuit_to_svg(self.circuit)
269
271
 
270
272
 
271
- def circuit_to_svg(circuit: 'cirq.Circuit') -> str:
273
+ def circuit_to_svg(circuit: cirq.Circuit) -> str:
272
274
  """Render a circuit as SVG."""
273
275
  _validate_circuit(circuit)
274
276
  tdd = circuit.to_text_diagram_drawer(transpose=False)
@@ -4,7 +4,7 @@ import numpy as np
4
4
  import pytest
5
5
 
6
6
  import cirq
7
- from cirq.contrib.svg import circuit_to_svg
7
+ from cirq.contrib.svg import circuit_to_svg, SVGCircuit
8
8
 
9
9
 
10
10
  def test_svg():
@@ -82,7 +82,8 @@ def test_gate_with_less_greater_str(symbol, svg_symbol):
82
82
  return cirq.CircuitDiagramInfo(wire_symbols=[symbol])
83
83
 
84
84
  circuit = cirq.Circuit(CustomGate().on(cirq.LineQubit(0)))
85
- svg = circuit_to_svg(circuit)
85
+ svg_circuit = SVGCircuit(circuit)
86
+ svg = svg_circuit._repr_svg_()
86
87
 
87
88
  _ = IPython.display.SVG(svg)
88
89
  assert svg_symbol in svg
cirq/devices/__init__.py CHANGED
@@ -14,45 +14,54 @@
14
14
 
15
15
  """Device classes, qubits, and topologies, as well as noise models."""
16
16
 
17
- from cirq.devices.device import Device, DeviceMetadata
18
17
 
19
- from cirq.devices.grid_device_metadata import GridDeviceMetadata
18
+ from cirq.devices.device import Device as Device, DeviceMetadata as DeviceMetadata
20
19
 
21
- from cirq.devices.grid_qubit import GridQid, GridQubit
20
+ from cirq.devices.grid_device_metadata import GridDeviceMetadata as GridDeviceMetadata
22
21
 
23
- from cirq.devices.line_qubit import LineQubit, LineQid
22
+ from cirq.devices.grid_qubit import GridQid as GridQid, GridQubit as GridQubit
24
23
 
25
- from cirq.devices.unconstrained_device import UNCONSTRAINED_DEVICE
24
+ from cirq.devices.line_qubit import LineQubit as LineQubit, LineQid as LineQid
26
25
 
27
- from cirq.devices.noise_model import NO_NOISE, NOISE_MODEL_LIKE, NoiseModel, ConstantQubitNoiseModel
26
+ from cirq.devices.unconstrained_device import UNCONSTRAINED_DEVICE as UNCONSTRAINED_DEVICE
27
+
28
+ from cirq.devices.noise_model import (
29
+ NO_NOISE as NO_NOISE,
30
+ NOISE_MODEL_LIKE as NOISE_MODEL_LIKE,
31
+ NoiseModel as NoiseModel,
32
+ ConstantQubitNoiseModel as ConstantQubitNoiseModel,
33
+ )
28
34
 
29
35
  from cirq.devices.named_topologies import (
30
- NamedTopology,
31
- draw_gridlike,
32
- LineTopology,
33
- TiltedSquareLattice,
34
- get_placements,
35
- is_valid_placement,
36
- draw_placements,
36
+ NamedTopology as NamedTopology,
37
+ draw_gridlike as draw_gridlike,
38
+ LineTopology as LineTopology,
39
+ TiltedSquareLattice as TiltedSquareLattice,
40
+ get_placements as get_placements,
41
+ is_valid_placement as is_valid_placement,
42
+ draw_placements as draw_placements,
37
43
  )
38
44
 
39
- from cirq.devices.insertion_noise_model import InsertionNoiseModel
45
+ from cirq.devices.insertion_noise_model import InsertionNoiseModel as InsertionNoiseModel
40
46
 
41
- from cirq.devices.thermal_noise_model import ThermalNoiseModel
47
+ from cirq.devices.thermal_noise_model import ThermalNoiseModel as ThermalNoiseModel
42
48
 
43
- from cirq.devices.noise_properties import NoiseModelFromNoiseProperties, NoiseProperties
49
+ from cirq.devices.noise_properties import (
50
+ NoiseModelFromNoiseProperties as NoiseModelFromNoiseProperties,
51
+ NoiseProperties as NoiseProperties,
52
+ )
44
53
 
45
54
  from cirq.devices.superconducting_qubits_noise_properties import (
46
- SuperconductingQubitsNoiseProperties,
55
+ SuperconductingQubitsNoiseProperties as SuperconductingQubitsNoiseProperties,
47
56
  )
48
57
 
49
58
  from cirq.devices.noise_utils import (
50
- OpIdentifier,
51
- decay_constant_to_xeb_fidelity,
52
- decay_constant_to_pauli_error,
53
- pauli_error_to_decay_constant,
54
- xeb_fidelity_to_decay_constant,
55
- pauli_error_from_t1,
56
- average_error,
57
- decoherence_pauli_error,
59
+ OpIdentifier as OpIdentifier,
60
+ decay_constant_to_xeb_fidelity as decay_constant_to_xeb_fidelity,
61
+ decay_constant_to_pauli_error as decay_constant_to_pauli_error,
62
+ pauli_error_to_decay_constant as pauli_error_to_decay_constant,
63
+ xeb_fidelity_to_decay_constant as xeb_fidelity_to_decay_constant,
64
+ pauli_error_from_t1 as pauli_error_from_t1,
65
+ average_error as average_error,
66
+ decoherence_pauli_error as decoherence_pauli_error,
58
67
  )
cirq/devices/device.py CHANGED
@@ -12,9 +12,13 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import abc
16
- from typing import TYPE_CHECKING, Optional, FrozenSet, Iterable
18
+ from typing import FrozenSet, Iterable, Optional, TYPE_CHECKING
19
+
17
20
  import networkx as nx
21
+
18
22
  from cirq import value
19
23
 
20
24
  if TYPE_CHECKING:
@@ -55,7 +59,7 @@ class Device(metaclass=abc.ABCMeta):
55
59
  """
56
60
 
57
61
  @property
58
- def metadata(self) -> Optional['DeviceMetadata']:
62
+ def metadata(self) -> Optional[DeviceMetadata]:
59
63
  """Returns the associated Metadata with the device if applicable.
60
64
 
61
65
  Returns:
@@ -63,7 +67,7 @@ class Device(metaclass=abc.ABCMeta):
63
67
  """
64
68
  return None
65
69
 
66
- def validate_operation(self, operation: 'cirq.Operation') -> None:
70
+ def validate_operation(self, operation: cirq.Operation) -> None:
67
71
  """Raises an exception if an operation is not valid.
68
72
 
69
73
  Args:
@@ -73,7 +77,7 @@ class Device(metaclass=abc.ABCMeta):
73
77
  ValueError: The operation isn't valid for this device.
74
78
  """
75
79
 
76
- def validate_circuit(self, circuit: 'cirq.AbstractCircuit') -> None:
80
+ def validate_circuit(self, circuit: cirq.AbstractCircuit) -> None:
77
81
  """Raises an exception if a circuit is not valid.
78
82
 
79
83
  Args:
@@ -85,7 +89,7 @@ class Device(metaclass=abc.ABCMeta):
85
89
  for moment in circuit:
86
90
  self.validate_moment(moment)
87
91
 
88
- def validate_moment(self, moment: 'cirq.Moment') -> None:
92
+ def validate_moment(self, moment: cirq.Moment) -> None:
89
93
  """Raises an exception if a moment is not valid.
90
94
 
91
95
  Args:
@@ -102,7 +106,7 @@ class Device(metaclass=abc.ABCMeta):
102
106
  class DeviceMetadata:
103
107
  """Parent type for all device specific metadata classes."""
104
108
 
105
- def __init__(self, qubits: Iterable['cirq.Qid'], nx_graph: 'nx.Graph'):
109
+ def __init__(self, qubits: Iterable[cirq.Qid], nx_graph: nx.Graph):
106
110
  """Construct a DeviceMetadata object.
107
111
 
108
112
  Args:
@@ -112,11 +116,11 @@ class DeviceMetadata:
112
116
  directional coupling, undirected edges indicate bi-directional
113
117
  coupling.
114
118
  """
115
- self._qubits_set: FrozenSet['cirq.Qid'] = frozenset(qubits)
119
+ self._qubits_set: FrozenSet[cirq.Qid] = frozenset(qubits)
116
120
  self._nx_graph = nx_graph
117
121
 
118
122
  @property
119
- def qubit_set(self) -> FrozenSet['cirq.Qid']:
123
+ def qubit_set(self) -> FrozenSet[cirq.Qid]:
120
124
  """Returns the set of qubits on the device.
121
125
 
122
126
  Returns:
@@ -125,7 +129,7 @@ class DeviceMetadata:
125
129
  return self._qubits_set
126
130
 
127
131
  @property
128
- def nx_graph(self) -> 'nx.Graph':
132
+ def nx_graph(self) -> nx.Graph:
129
133
  """Returns a nx.Graph where nodes are qubits and edges are couple-able qubits.
130
134
 
131
135
  Returns:
@@ -142,12 +146,12 @@ class DeviceMetadata:
142
146
  return self._qubits_set, graph_equality
143
147
 
144
148
  def _json_dict_(self):
145
- graph_payload = nx.readwrite.json_graph.node_link_data(self._nx_graph)
149
+ graph_payload = nx.readwrite.json_graph.node_link_data(self._nx_graph, edges='links')
146
150
  qubits_payload = sorted(list(self._qubits_set))
147
151
 
148
152
  return {'qubits': qubits_payload, 'nx_graph': graph_payload}
149
153
 
150
154
  @classmethod
151
- def _from_json_dict_(cls, qubits: Iterable['cirq.Qid'], nx_graph: 'nx.Graph', **kwargs):
152
- graph_obj = nx.readwrite.json_graph.node_link_graph(nx_graph)
155
+ def _from_json_dict_(cls, qubits: Iterable[cirq.Qid], nx_graph: nx.Graph, **kwargs):
156
+ graph_obj = nx.readwrite.json_graph.node_link_graph(nx_graph, edges='links')
153
157
  return cls(qubits, graph_obj)
@@ -1,5 +1,6 @@
1
1
  # pylint: disable=wrong-or-nonexistent-copyright-notice
2
2
  import networkx as nx
3
+
3
4
  import cirq
4
5
 
5
6