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
@@ -11,11 +11,15 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
+
14
15
  """Metadata subtype for 2D Homogenous devices."""
15
16
 
16
- from typing import TYPE_CHECKING, cast, FrozenSet, Iterable, Mapping, Optional, Tuple
17
+ from __future__ import annotations
18
+
19
+ from typing import cast, FrozenSet, Iterable, Mapping, Optional, Tuple, TYPE_CHECKING
17
20
 
18
21
  import networkx as nx
22
+
19
23
  from cirq import value
20
24
  from cirq.devices import device
21
25
 
@@ -29,11 +33,11 @@ class GridDeviceMetadata(device.DeviceMetadata):
29
33
 
30
34
  def __init__(
31
35
  self,
32
- qubit_pairs: Iterable[Tuple['cirq.GridQubit', 'cirq.GridQubit']],
33
- gateset: 'cirq.Gateset',
34
- gate_durations: Optional[Mapping['cirq.GateFamily', 'cirq.Duration']] = None,
35
- all_qubits: Optional[Iterable['cirq.GridQubit']] = None,
36
- compilation_target_gatesets: Iterable['cirq.CompilationTargetGateset'] = (),
36
+ qubit_pairs: Iterable[Tuple[cirq.GridQubit, cirq.GridQubit]],
37
+ gateset: cirq.Gateset,
38
+ gate_durations: Optional[Mapping[cirq.GateFamily, cirq.Duration]] = None,
39
+ all_qubits: Optional[Iterable[cirq.GridQubit]] = None,
40
+ compilation_target_gatesets: Iterable[cirq.CompilationTargetGateset] = (),
37
41
  ):
38
42
  """Create a GridDeviceMetadata object.
39
43
 
@@ -114,7 +118,7 @@ class GridDeviceMetadata(device.DeviceMetadata):
114
118
  self._gate_durations = gate_durations
115
119
 
116
120
  @property
117
- def qubit_set(self) -> FrozenSet['cirq.GridQubit']:
121
+ def qubit_set(self) -> FrozenSet[cirq.GridQubit]:
118
122
  """Returns the set of grid qubits on the device.
119
123
 
120
124
  Returns:
@@ -123,7 +127,7 @@ class GridDeviceMetadata(device.DeviceMetadata):
123
127
  return cast(FrozenSet['cirq.GridQubit'], super().qubit_set)
124
128
 
125
129
  @property
126
- def qubit_pairs(self) -> FrozenSet[FrozenSet['cirq.GridQubit']]:
130
+ def qubit_pairs(self) -> FrozenSet[FrozenSet[cirq.GridQubit]]:
127
131
  """Returns the set of all couple-able qubits on the device.
128
132
 
129
133
  Each element in the outer frozenset is a 2-element frozenset representing a bidirectional
@@ -132,22 +136,22 @@ class GridDeviceMetadata(device.DeviceMetadata):
132
136
  return self._qubit_pairs
133
137
 
134
138
  @property
135
- def isolated_qubits(self) -> FrozenSet['cirq.GridQubit']:
139
+ def isolated_qubits(self) -> FrozenSet[cirq.GridQubit]:
136
140
  """Returns the set of all isolated qubits on the device (if applicable)."""
137
141
  return self._isolated_qubits
138
142
 
139
143
  @property
140
- def gateset(self) -> 'cirq.Gateset':
144
+ def gateset(self) -> cirq.Gateset:
141
145
  """Returns the `cirq.Gateset` of supported gates on this device."""
142
146
  return self._gateset
143
147
 
144
148
  @property
145
- def compilation_target_gatesets(self) -> Tuple['cirq.CompilationTargetGateset', ...]:
149
+ def compilation_target_gatesets(self) -> Tuple[cirq.CompilationTargetGateset, ...]:
146
150
  """Returns a sequence of valid `cirq.CompilationTargetGateset`s for this device."""
147
151
  return self._compilation_target_gatesets
148
152
 
149
153
  @property
150
- def gate_durations(self) -> Optional[Mapping['cirq.GateFamily', 'cirq.Duration']]:
154
+ def gate_durations(self) -> Optional[Mapping[cirq.GateFamily, cirq.Duration]]:
151
155
  """Get a dictionary mapping from gate family to duration for gates.
152
156
 
153
157
  To look up the duration of a specific gate instance / gate type / operation which is part of
@@ -13,9 +13,10 @@
13
13
  # limitations under the License.
14
14
  """Tests for GridDevicemetadata."""
15
15
 
16
+ import networkx as nx
16
17
  import pytest
18
+
17
19
  import cirq
18
- import networkx as nx
19
20
 
20
21
 
21
22
  def test_griddevice_metadata():
@@ -12,13 +12,15 @@
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
18
  import functools
17
19
  import weakref
18
- from typing import Any, Dict, Iterable, List, Optional, Tuple, Set, TYPE_CHECKING, Union
19
- from typing_extensions import Self
20
+ from typing import Any, Dict, Iterable, List, Optional, Set, Tuple, TYPE_CHECKING, Union
20
21
 
21
22
  import numpy as np
23
+ from typing_extensions import Self
22
24
 
23
25
  from cirq import ops, protocols
24
26
 
@@ -34,11 +36,9 @@ class _BaseGridQid(ops.Qid):
34
36
  _col: int
35
37
  _dimension: int
36
38
  _comp_key: Optional[Tuple[int, int]] = None
37
- _hash: Optional[int] = None
39
+ _hash: int
38
40
 
39
41
  def __hash__(self) -> int:
40
- if self._hash is None:
41
- self._hash = hash((self._row, self._col, self._dimension))
42
42
  return self._hash
43
43
 
44
44
  def __eq__(self, other) -> bool:
@@ -106,17 +106,17 @@ class _BaseGridQid(ops.Qid):
106
106
  def dimension(self) -> int:
107
107
  return self._dimension
108
108
 
109
- def with_dimension(self, dimension: int) -> 'GridQid':
109
+ def with_dimension(self, dimension: int) -> GridQid:
110
110
  return GridQid(self._row, self._col, dimension=dimension)
111
111
 
112
- def is_adjacent(self, other: 'cirq.Qid') -> bool:
112
+ def is_adjacent(self, other: cirq.Qid) -> bool:
113
113
  """Determines if two qubits are adjacent qubits."""
114
114
  return (
115
115
  isinstance(other, GridQubit)
116
116
  and abs(self._row - other._row) + abs(self._col - other._col) == 1
117
117
  )
118
118
 
119
- def neighbors(self, qids: Optional[Iterable[ops.Qid]] = None) -> Set['_BaseGridQid']:
119
+ def neighbors(self, qids: Optional[Iterable[ops.Qid]] = None) -> Set[_BaseGridQid]:
120
120
  """Returns qubits that are potential neighbors to this GridQid
121
121
 
122
122
  Args:
@@ -206,7 +206,7 @@ class GridQid(_BaseGridQid):
206
206
  # Holds weak references so instances can still be garbage collected.
207
207
  _cache = weakref.WeakValueDictionary[Tuple[int, int, int], 'cirq.GridQid']()
208
208
 
209
- def __new__(cls, row: int, col: int, *, dimension: int) -> 'cirq.GridQid':
209
+ def __new__(cls, row: int, col: int, *, dimension: int) -> cirq.GridQid:
210
210
  """Creates a grid qid at the given row, col coordinate
211
211
 
212
212
  Args:
@@ -215,6 +215,7 @@ class GridQid(_BaseGridQid):
215
215
  dimension: The dimension of the qid's Hilbert space, i.e.
216
216
  the number of quantum levels.
217
217
  """
218
+ dimension = int(dimension)
218
219
  key = (row, col, dimension)
219
220
  inst = cls._cache.get(key)
220
221
  if inst is None:
@@ -223,6 +224,7 @@ class GridQid(_BaseGridQid):
223
224
  inst._row = row
224
225
  inst._col = col
225
226
  inst._dimension = dimension
227
+ inst._hash = ((dimension - 2) * 1_000_003 + hash(col)) * 1_000_003 + hash(row)
226
228
  cls._cache[key] = inst
227
229
  return inst
228
230
 
@@ -230,11 +232,15 @@ class GridQid(_BaseGridQid):
230
232
  """Returns a tuple of (args, kwargs) to pass to __new__ when unpickling."""
231
233
  return (self._row, self._col), {"dimension": self._dimension}
232
234
 
233
- def _with_row_col(self, row: int, col: int) -> 'GridQid':
235
+ # avoid pickling the _hash value, attributes are already stored with __getnewargs_ex__
236
+ def __getstate__(self) -> Dict[str, Any]:
237
+ return {}
238
+
239
+ def _with_row_col(self, row: int, col: int) -> GridQid:
234
240
  return GridQid(row, col, dimension=self._dimension)
235
241
 
236
242
  @staticmethod
237
- def square(diameter: int, top: int = 0, left: int = 0, *, dimension: int) -> List['GridQid']:
243
+ def square(diameter: int, top: int = 0, left: int = 0, *, dimension: int) -> List[GridQid]:
238
244
  """Returns a square of GridQid.
239
245
 
240
246
  Args:
@@ -250,9 +256,7 @@ class GridQid(_BaseGridQid):
250
256
  return GridQid.rect(diameter, diameter, top=top, left=left, dimension=dimension)
251
257
 
252
258
  @staticmethod
253
- def rect(
254
- rows: int, cols: int, top: int = 0, left: int = 0, *, dimension: int
255
- ) -> List['GridQid']:
259
+ def rect(rows: int, cols: int, top: int = 0, left: int = 0, *, dimension: int) -> List[GridQid]:
256
260
  """Returns a rectangle of GridQid.
257
261
 
258
262
  Args:
@@ -273,7 +277,7 @@ class GridQid(_BaseGridQid):
273
277
  ]
274
278
 
275
279
  @staticmethod
276
- def from_diagram(diagram: str, dimension: int) -> List['GridQid']:
280
+ def from_diagram(diagram: str, dimension: int) -> List[GridQid]:
277
281
  """Parse ASCII art device layout into a device.
278
282
 
279
283
  As an example, the below diagram will create a list of GridQid in a
@@ -333,9 +337,7 @@ class GridQid(_BaseGridQid):
333
337
  def __str__(self) -> str:
334
338
  return f"q({self._row}, {self._col}) (d={self._dimension})"
335
339
 
336
- def _circuit_diagram_info_(
337
- self, args: 'cirq.CircuitDiagramInfoArgs'
338
- ) -> 'cirq.CircuitDiagramInfo':
340
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
339
341
  return protocols.CircuitDiagramInfo(
340
342
  wire_symbols=(f"({self._row}, {self._col}) (d={self._dimension})",)
341
343
  )
@@ -367,7 +369,7 @@ class GridQubit(_BaseGridQid):
367
369
  # Holds weak references so instances can still be garbage collected.
368
370
  _cache = weakref.WeakValueDictionary[Tuple[int, int], 'cirq.GridQubit']()
369
371
 
370
- def __new__(cls, row: int, col: int) -> 'cirq.GridQubit':
372
+ def __new__(cls, row: int, col: int) -> cirq.GridQubit:
371
373
  """Creates a grid qubit at the given row, col coordinate
372
374
 
373
375
  Args:
@@ -380,6 +382,7 @@ class GridQubit(_BaseGridQid):
380
382
  inst = super().__new__(cls)
381
383
  inst._row = row
382
384
  inst._col = col
385
+ inst._hash = hash(col) * 1_000_003 + hash(row)
383
386
  cls._cache[key] = inst
384
387
  return inst
385
388
 
@@ -387,11 +390,15 @@ class GridQubit(_BaseGridQid):
387
390
  """Returns a tuple of args to pass to __new__ when unpickling."""
388
391
  return (self._row, self._col)
389
392
 
390
- def _with_row_col(self, row: int, col: int) -> 'GridQubit':
393
+ # avoid pickling the _hash value, attributes are already stored with __getnewargs__
394
+ def __getstate__(self) -> Dict[str, Any]:
395
+ return {}
396
+
397
+ def _with_row_col(self, row: int, col: int) -> GridQubit:
391
398
  return GridQubit(row, col)
392
399
 
393
400
  @staticmethod
394
- def square(diameter: int, top: int = 0, left: int = 0) -> List['GridQubit']:
401
+ def square(diameter: int, top: int = 0, left: int = 0) -> List[GridQubit]:
395
402
  """Returns a square of GridQubits.
396
403
 
397
404
  Args:
@@ -405,7 +412,7 @@ class GridQubit(_BaseGridQid):
405
412
  return GridQubit.rect(diameter, diameter, top=top, left=left)
406
413
 
407
414
  @staticmethod
408
- def rect(rows: int, cols: int, top: int = 0, left: int = 0) -> List['GridQubit']:
415
+ def rect(rows: int, cols: int, top: int = 0, left: int = 0) -> List[GridQubit]:
409
416
  """Returns a rectangle of GridQubits.
410
417
 
411
418
  Args:
@@ -424,7 +431,7 @@ class GridQubit(_BaseGridQid):
424
431
  ]
425
432
 
426
433
  @staticmethod
427
- def from_diagram(diagram: str) -> List['GridQubit']:
434
+ def from_diagram(diagram: str) -> List[GridQubit]:
428
435
  """Parse ASCII art into device layout info.
429
436
 
430
437
  As an example, the below diagram will create a list of
@@ -481,9 +488,7 @@ class GridQubit(_BaseGridQid):
481
488
  def __str__(self) -> str:
482
489
  return f"q({self._row}, {self._col})"
483
490
 
484
- def _circuit_diagram_info_(
485
- self, args: 'cirq.CircuitDiagramInfoArgs'
486
- ) -> 'cirq.CircuitDiagramInfo':
491
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
487
492
  return protocols.CircuitDiagramInfo(wire_symbols=(f"({self._row}, {self._col})",))
488
493
 
489
494
  def _json_dict_(self) -> Dict[str, Any]:
@@ -58,7 +58,7 @@ def test_grid_qid_pickled_hash():
58
58
  _test_qid_pickled_hash(q, q_bad)
59
59
 
60
60
 
61
- def _test_qid_pickled_hash(q: 'cirq.Qid', q_bad: 'cirq.Qid') -> None:
61
+ def _test_qid_pickled_hash(q: cirq.Qid, q_bad: cirq.Qid) -> None:
62
62
  """Test that hashes are not pickled with Qid instances."""
63
63
  assert q_bad is not q
64
64
  _ = hash(q_bad) # compute hash to ensure it is cached.
@@ -391,3 +391,32 @@ def test_immutable():
391
391
  def test_complex():
392
392
  assert complex(cirq.GridQubit(row=1, col=2)) == 2 + 1j
393
393
  assert isinstance(complex(cirq.GridQubit(row=1, col=2)), complex)
394
+
395
+
396
+ @pytest.mark.parametrize('dtype', (np.int8, np.int64, float, np.float64))
397
+ def test_numpy_index(dtype):
398
+ np5, np6, np3 = [dtype(i) for i in [5, 6, 3]]
399
+ q = cirq.GridQubit(np5, np6)
400
+ assert hash(q) == hash(cirq.GridQubit(5, 6))
401
+ assert q.row == 5
402
+ assert q.col == 6
403
+ assert q.dimension == 2
404
+ assert isinstance(q.dimension, int)
405
+
406
+ q = cirq.GridQid(np5, np6, dimension=np3)
407
+ assert hash(q) == hash(cirq.GridQid(5, 6, dimension=3))
408
+ assert q.row == 5
409
+ assert q.col == 6
410
+ assert q.dimension == 3
411
+ assert isinstance(q.dimension, int)
412
+
413
+
414
+ @pytest.mark.parametrize('dtype', (float, np.float64))
415
+ def test_non_integer_index(dtype):
416
+ # Not supported type-wise, but is used in practice, so behavior needs to be preserved.
417
+ q = cirq.GridQubit(dtype(5.5), dtype(6.5))
418
+ assert hash(q) == hash(cirq.GridQubit(5.5, 6.5))
419
+ assert q.row == 5.5
420
+ assert q.col == 6.5
421
+ assert isinstance(q.row, dtype)
422
+ assert isinstance(q.col, dtype)
@@ -12,8 +12,10 @@
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 dataclasses
16
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence
18
+ from typing import Any, Dict, List, Optional, Sequence, TYPE_CHECKING
17
19
 
18
20
  from cirq import devices
19
21
  from cirq.devices import noise_utils
@@ -42,16 +44,14 @@ class InsertionNoiseModel(devices.NoiseModel):
42
44
  with PHYSICAL_GATE_TAG.
43
45
  """
44
46
 
45
- ops_added: Dict[noise_utils.OpIdentifier, 'cirq.Operation'] = dataclasses.field(
47
+ ops_added: Dict[noise_utils.OpIdentifier, cirq.Operation] = dataclasses.field(
46
48
  default_factory=dict
47
49
  )
48
50
  prepend: bool = False
49
51
  require_physical_tag: bool = True
50
52
 
51
- def noisy_moment(
52
- self, moment: 'cirq.Moment', system_qubits: Sequence['cirq.Qid']
53
- ) -> 'cirq.OP_TREE':
54
- noise_ops: List['cirq.Operation'] = []
53
+ def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]) -> cirq.OP_TREE:
54
+ noise_ops: List[cirq.Operation] = []
55
55
  candidate_ops = [
56
56
  op
57
57
  for op in moment
@@ -14,7 +14,7 @@
14
14
 
15
15
  import cirq
16
16
  from cirq.devices.insertion_noise_model import InsertionNoiseModel
17
- from cirq.devices.noise_utils import PHYSICAL_GATE_TAG, OpIdentifier
17
+ from cirq.devices.noise_utils import OpIdentifier, PHYSICAL_GATE_TAG
18
18
 
19
19
 
20
20
  def test_insertion_noise():
@@ -12,10 +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
18
  import functools
17
19
  import weakref
18
20
  from typing import Any, Dict, Iterable, List, Optional, Sequence, Set, Tuple, TYPE_CHECKING, Union
21
+
19
22
  from typing_extensions import Self
20
23
 
21
24
  from cirq import ops, protocols
@@ -30,11 +33,9 @@ class _BaseLineQid(ops.Qid):
30
33
 
31
34
  _x: int
32
35
  _dimension: int
33
- _hash: Optional[int] = None
36
+ _hash: int
34
37
 
35
38
  def __hash__(self) -> int:
36
- if self._hash is None:
37
- self._hash = hash((self._x, self._dimension))
38
39
  return self._hash
39
40
 
40
41
  def __eq__(self, other) -> bool:
@@ -94,10 +95,10 @@ class _BaseLineQid(ops.Qid):
94
95
  def dimension(self) -> int:
95
96
  return self._dimension
96
97
 
97
- def with_dimension(self, dimension: int) -> 'LineQid':
98
+ def with_dimension(self, dimension: int) -> LineQid:
98
99
  return LineQid(self._x, dimension)
99
100
 
100
- def is_adjacent(self, other: 'cirq.Qid') -> bool:
101
+ def is_adjacent(self, other: cirq.Qid) -> bool:
101
102
  """Determines if two qubits are adjacent line qubits.
102
103
 
103
104
  Args:
@@ -107,7 +108,7 @@ class _BaseLineQid(ops.Qid):
107
108
  """
108
109
  return isinstance(other, _BaseLineQid) and abs(self._x - other._x) == 1
109
110
 
110
- def neighbors(self, qids: Optional[Iterable[ops.Qid]] = None) -> Set['_BaseLineQid']:
111
+ def neighbors(self, qids: Optional[Iterable[ops.Qid]] = None) -> Set[_BaseLineQid]:
111
112
  """Returns qubits that are potential neighbors to this LineQubit
112
113
 
113
114
  Args:
@@ -185,7 +186,7 @@ class LineQid(_BaseLineQid):
185
186
  # Holds weak references so instances can still be garbage collected.
186
187
  _cache = weakref.WeakValueDictionary[Tuple[int, int], 'cirq.LineQid']()
187
188
 
188
- def __new__(cls, x: int, dimension: int) -> 'cirq.LineQid':
189
+ def __new__(cls, x: int, dimension: int) -> cirq.LineQid:
189
190
  """Initializes a line qid at the given x coordinate.
190
191
 
191
192
  Args:
@@ -193,6 +194,7 @@ class LineQid(_BaseLineQid):
193
194
  dimension: The dimension of the qid's Hilbert space, i.e.
194
195
  the number of quantum levels.
195
196
  """
197
+ dimension = int(dimension)
196
198
  key = (x, dimension)
197
199
  inst = cls._cache.get(key)
198
200
  if inst is None:
@@ -200,6 +202,7 @@ class LineQid(_BaseLineQid):
200
202
  inst = super().__new__(cls)
201
203
  inst._x = x
202
204
  inst._dimension = dimension
205
+ inst._hash = (dimension - 2) * 1_000_003 + hash(x)
203
206
  cls._cache[key] = inst
204
207
  return inst
205
208
 
@@ -207,11 +210,15 @@ class LineQid(_BaseLineQid):
207
210
  """Returns a tuple of args to pass to __new__ when unpickling."""
208
211
  return (self._x, self._dimension)
209
212
 
210
- def _with_x(self, x: int) -> 'LineQid':
213
+ # avoid pickling the _hash value, attributes are already stored with __getnewargs__
214
+ def __getstate__(self) -> Dict[str, Any]:
215
+ return {}
216
+
217
+ def _with_x(self, x: int) -> LineQid:
211
218
  return LineQid(x, dimension=self._dimension)
212
219
 
213
220
  @staticmethod
214
- def range(*range_args, dimension: int) -> List['LineQid']:
221
+ def range(*range_args, dimension: int) -> List[LineQid]:
215
222
  """Returns a range of line qids.
216
223
 
217
224
  Args:
@@ -225,7 +232,7 @@ class LineQid(_BaseLineQid):
225
232
  return [LineQid(i, dimension=dimension) for i in range(*range_args)]
226
233
 
227
234
  @staticmethod
228
- def for_qid_shape(qid_shape: Sequence[int], start: int = 0, step: int = 1) -> List['LineQid']:
235
+ def for_qid_shape(qid_shape: Sequence[int], start: int = 0, step: int = 1) -> List[LineQid]:
229
236
  """Returns a range of line qids for each entry in `qid_shape` with
230
237
  matching dimension.
231
238
 
@@ -239,7 +246,7 @@ class LineQid(_BaseLineQid):
239
246
  ]
240
247
 
241
248
  @staticmethod
242
- def for_gate(val: Any, start: int = 0, step: int = 1) -> List['LineQid']:
249
+ def for_gate(val: Any, start: int = 0, step: int = 1) -> List[LineQid]:
243
250
  """Returns a range of line qids with the same qid shape as the gate.
244
251
 
245
252
  Args:
@@ -259,9 +266,7 @@ class LineQid(_BaseLineQid):
259
266
  def __str__(self) -> str:
260
267
  return f"q({self._x}) (d={self._dimension})"
261
268
 
262
- def _circuit_diagram_info_(
263
- self, args: 'cirq.CircuitDiagramInfoArgs'
264
- ) -> 'cirq.CircuitDiagramInfo':
269
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
265
270
  return protocols.CircuitDiagramInfo(wire_symbols=(f"{self._x} (d={self._dimension})",))
266
271
 
267
272
  def _json_dict_(self) -> Dict[str, Any]:
@@ -291,7 +296,7 @@ class LineQubit(_BaseLineQid):
291
296
  # Holds weak references so instances can still be garbage collected.
292
297
  _cache = weakref.WeakValueDictionary[int, 'cirq.LineQubit']()
293
298
 
294
- def __new__(cls, x: int) -> 'cirq.LineQubit':
299
+ def __new__(cls, x: int) -> cirq.LineQubit:
295
300
  """Initializes a line qid at the given x coordinate.
296
301
 
297
302
  Args:
@@ -301,6 +306,7 @@ class LineQubit(_BaseLineQid):
301
306
  if inst is None:
302
307
  inst = super().__new__(cls)
303
308
  inst._x = x
309
+ inst._hash = hash(x)
304
310
  cls._cache[x] = inst
305
311
  return inst
306
312
 
@@ -308,11 +314,15 @@ class LineQubit(_BaseLineQid):
308
314
  """Returns a tuple of args to pass to __new__ when unpickling."""
309
315
  return (self._x,)
310
316
 
311
- def _with_x(self, x: int) -> 'LineQubit':
317
+ # avoid pickling the _hash value, attributes are already stored with __getnewargs__
318
+ def __getstate__(self) -> Dict[str, Any]:
319
+ return {}
320
+
321
+ def _with_x(self, x: int) -> LineQubit:
312
322
  return LineQubit(x)
313
323
 
314
324
  @staticmethod
315
- def range(*range_args) -> List['LineQubit']:
325
+ def range(*range_args) -> List[LineQubit]:
316
326
  """Returns a range of line qubits.
317
327
 
318
328
  Args:
@@ -329,9 +339,7 @@ class LineQubit(_BaseLineQid):
329
339
  def __str__(self) -> str:
330
340
  return f"q({self._x})"
331
341
 
332
- def _circuit_diagram_info_(
333
- self, args: 'cirq.CircuitDiagramInfoArgs'
334
- ) -> 'cirq.CircuitDiagramInfo':
342
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
335
343
  return protocols.CircuitDiagramInfo(wire_symbols=(f"{self._x}",))
336
344
 
337
345
  def _json_dict_(self) -> Dict[str, Any]:
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ import numpy as np
15
16
  import pytest
16
17
 
17
18
  import cirq
@@ -284,3 +285,28 @@ def test_numeric():
284
285
  assert isinstance(int(cirq.LineQubit(x=5)), int)
285
286
  assert isinstance(float(cirq.LineQubit(x=5)), float)
286
287
  assert isinstance(complex(cirq.LineQubit(x=5)), complex)
288
+
289
+
290
+ @pytest.mark.parametrize('dtype', (np.int8, np.int64, float, np.float64))
291
+ def test_numpy_index(dtype):
292
+ np5 = dtype(5)
293
+ q = cirq.LineQubit(np5)
294
+ assert hash(q) == 5
295
+ assert q.x == 5
296
+ assert q.dimension == 2
297
+ assert isinstance(q.dimension, int)
298
+
299
+ q = cirq.LineQid(np5, dtype(3))
300
+ hash(q) # doesn't throw
301
+ assert q.x == 5
302
+ assert q.dimension == 3
303
+ assert isinstance(q.dimension, int)
304
+
305
+
306
+ @pytest.mark.parametrize('dtype', (float, np.float64))
307
+ def test_non_integer_index(dtype):
308
+ # Not supported type-wise, but is used in practice, so behavior needs to be preserved.
309
+ q = cirq.LineQubit(dtype(5.5))
310
+ assert q.x == 5.5
311
+ assert q.x == dtype(5.5)
312
+ assert isinstance(q.x, dtype)
@@ -12,20 +12,22 @@
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
18
  import warnings
17
19
  from dataclasses import dataclass
18
20
  from typing import (
21
+ Any,
22
+ Callable,
19
23
  Dict,
24
+ Iterable,
20
25
  List,
21
- Tuple,
22
- Any,
26
+ Optional,
23
27
  Sequence,
24
- Union,
25
- Iterable,
28
+ Tuple,
26
29
  TYPE_CHECKING,
27
- Callable,
28
- Optional,
30
+ Union,
29
31
  )
30
32
 
31
33
  import networkx as nx
@@ -127,7 +129,7 @@ class LineTopology(NamedTopology):
127
129
  )
128
130
  object.__setattr__(self, 'graph', graph)
129
131
 
130
- def nodes_as_linequbits(self) -> List['cirq.LineQubit']:
132
+ def nodes_as_linequbits(self) -> List[cirq.LineQubit]:
131
133
  """Get the graph nodes as cirq.LineQubit"""
132
134
  return [LineQubit(x) for x in sorted(self.graph.nodes)]
133
135
 
@@ -142,7 +144,7 @@ class LineTopology(NamedTopology):
142
144
  g2 = nx.relabel_nodes(self.graph, {n: (n, 1) for n in self.graph.nodes})
143
145
  return draw_gridlike(g2, ax=ax, tilted=tilted, **kwargs)
144
146
 
145
- def nodes_to_linequbits(self, offset: int = 0) -> Dict[int, 'cirq.LineQubit']:
147
+ def nodes_to_linequbits(self, offset: int = 0) -> Dict[int, cirq.LineQubit]:
146
148
  """Return a mapping from graph nodes to `cirq.LineQubit`
147
149
 
148
150
  Args:
@@ -240,11 +242,11 @@ class TiltedSquareLattice(NamedTopology):
240
242
  """
241
243
  return draw_gridlike(self.graph, ax=ax, tilted=tilted, **kwargs)
242
244
 
243
- def nodes_as_gridqubits(self) -> List['cirq.GridQubit']:
245
+ def nodes_as_gridqubits(self) -> List[cirq.GridQubit]:
244
246
  """Get the graph nodes as cirq.GridQubit"""
245
247
  return [GridQubit(r, c) for r, c in sorted(self.graph.nodes)]
246
248
 
247
- def nodes_to_gridqubits(self, offset=(0, 0)) -> Dict[Tuple[int, int], 'cirq.GridQubit']:
249
+ def nodes_to_gridqubits(self, offset=(0, 0)) -> Dict[Tuple[int, int], cirq.GridQubit]:
248
250
  """Return a mapping from graph nodes to `cirq.GridQubit`
249
251
 
250
252
  Args:
@@ -14,16 +14,17 @@
14
14
  import itertools
15
15
  from unittest.mock import MagicMock
16
16
 
17
- import cirq
18
17
  import networkx as nx
19
18
  import pytest
19
+
20
+ import cirq
20
21
  from cirq import (
21
22
  draw_gridlike,
22
- LineTopology,
23
- TiltedSquareLattice,
24
- get_placements,
25
23
  draw_placements,
24
+ get_placements,
26
25
  is_valid_placement,
26
+ LineTopology,
27
+ TiltedSquareLattice,
27
28
  )
28
29
 
29
30