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
cirq/vis/heatmap.py CHANGED
@@ -11,6 +11,9 @@
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
+
15
+ from __future__ import annotations
16
+
14
17
  import copy
15
18
  from dataclasses import astuple, dataclass
16
19
  from typing import (
@@ -111,6 +114,7 @@ class Heatmap:
111
114
  applying format(value, annotation_format) for each key in value_map.
112
115
  This is ignored if annotation_map is explicitly specified.
113
116
  annotation_text_kwargs: Matplotlib Text **kwargs,
117
+ highlighted_qubits: An iterable of qubits to highlight.
114
118
 
115
119
  colorbar_position: {'right', 'left', 'top', 'bottom'}, default = 'right'
116
120
  colorbar_size: str, default = '5%'
@@ -157,6 +161,7 @@ class Heatmap:
157
161
  "annotation_map",
158
162
  "annotation_text_kwargs",
159
163
  "annotation_format",
164
+ "highlighted_qubits",
160
165
  ]
161
166
  valid_kwargs = (
162
167
  valid_colorbar_kwargs
@@ -231,13 +236,14 @@ class Heatmap:
231
236
  ax: plt.Axes,
232
237
  ) -> None:
233
238
  """Writes annotations to the center of cells. Internal."""
234
- for (center, annotation), facecolor in zip(centers_and_annot, collection.get_facecolor()):
239
+ face_colors = cast(np.ndarray, collection.get_facecolor())
240
+ for (center, annotation), facecolor in zip(centers_and_annot, face_colors):
235
241
  # Calculate the center of the cell, assuming that it is a square
236
242
  # centered at (x=col, y=row).
237
243
  if not annotation:
238
244
  continue
239
245
  x, y = center
240
- face_luminance = vis_utils.relative_luminance(facecolor) # type: ignore
246
+ face_luminance = vis_utils.relative_luminance(facecolor)
241
247
  text_color = 'black' if face_luminance > 0.4 else 'white'
242
248
  text_kwargs: Dict[str, Any] = dict(color=text_color, ha="center", va="center")
243
249
  text_kwargs.update(self._config.get('annotation_text_kwargs', {}))
@@ -294,11 +300,41 @@ class Heatmap:
294
300
  is plotted on. ``collection`` is the collection of paths drawn and filled.
295
301
  """
296
302
  show_plot = not ax
297
- if not ax:
303
+ if ax is None:
298
304
  fig, ax = plt.subplots(figsize=(8, 8))
299
- ax = cast(plt.Axes, ax)
300
305
  original_config = copy.deepcopy(self._config)
301
306
  self.update_config(**kwargs)
307
+
308
+ highlighted_qubits = frozenset(kwargs.get("highlighted_qubits", ()))
309
+ if highlighted_qubits:
310
+ edgecolors = tuple(
311
+ (
312
+ "red"
313
+ if not highlighted_qubits.isdisjoint(qubits)
314
+ else self._config["collection_options"].get("edgecolors", "grey")
315
+ )
316
+ for qubits in sorted(self._value_map.keys())
317
+ )
318
+ linestyles = tuple(
319
+ (
320
+ "solid"
321
+ if not highlighted_qubits.isdisjoint(qubits)
322
+ else self._config["collection_options"].get("linestyles", "dashed")
323
+ )
324
+ for qubits in sorted(self._value_map.keys())
325
+ )
326
+ linewidths = tuple(
327
+ (
328
+ 4
329
+ if not highlighted_qubits.isdisjoint(qubits)
330
+ else self._config["collection_options"].get("linewidths", 2)
331
+ )
332
+ for qubits in sorted(self._value_map.keys())
333
+ )
334
+ self._config["collection_options"].update(
335
+ {"edgecolors": edgecolors, "linestyles": linestyles, "linewidths": linewidths}
336
+ )
337
+
302
338
  collection = self._plot_on_axis(ax)
303
339
  if show_plot:
304
340
  fig.show()
@@ -381,22 +417,23 @@ class TwoQubitInteractionHeatmap(Heatmap):
381
417
  is plotted on. ``collection`` is the collection of paths drawn and filled.
382
418
  """
383
419
  show_plot = not ax
384
- if not ax:
420
+ if ax is None:
385
421
  fig, ax = plt.subplots(figsize=(8, 8))
386
- ax = cast(plt.Axes, ax)
387
422
  original_config = copy.deepcopy(self._config)
388
423
  self.update_config(**kwargs)
389
424
  qubits = set([q for qubits in self._value_map.keys() for q in qubits])
425
+ collection_options: Dict[str, Any] = {"cmap": "binary"}
426
+ highlighted_qubits = frozenset(kwargs.get("highlighted_qubits", ()))
427
+ if not highlighted_qubits:
428
+ collection_options.update(
429
+ {"linewidths": 2, "edgecolors": "lightgrey", "linestyles": "dashed"}
430
+ )
390
431
  Heatmap({q: 0.0 for q in qubits}).plot(
391
432
  ax=ax,
392
- collection_options={
393
- 'cmap': 'binary',
394
- 'linewidths': 2,
395
- 'edgecolor': 'lightgrey',
396
- 'linestyle': 'dashed',
397
- },
433
+ collection_options=collection_options,
398
434
  plot_colorbar=False,
399
435
  annotation_format=None,
436
+ highlighted_qubits=highlighted_qubits,
400
437
  )
401
438
  collection = self._plot_on_axis(ax)
402
439
  if show_plot:
cirq/vis/heatmap_test.py CHANGED
@@ -18,11 +18,11 @@ import shutil
18
18
  import string
19
19
  from tempfile import mkdtemp
20
20
 
21
- import numpy as np
22
- import pytest
23
-
24
21
  import matplotlib as mpl
25
22
  import matplotlib.pyplot as plt
23
+ import numpy as np
24
+ import pytest
25
+ from matplotlib.colors import to_rgba_array
26
26
 
27
27
  from cirq.devices import grid_qubit
28
28
  from cirq.vis import heatmap
@@ -34,6 +34,11 @@ def ax():
34
34
  return figure.add_subplot(111)
35
35
 
36
36
 
37
+ def _to_linestyle_tuple(linestyles, linewidths=None):
38
+ collection = mpl.collections.Collection(linestyles=linestyles, linewidths=linewidths)
39
+ return collection.get_linestyles()[0]
40
+
41
+
37
42
  def test_default_ax():
38
43
  row_col_list = ((0, 5), (8, 1), (7, 0), (13, 5), (1, 6), (3, 2), (2, 8))
39
44
  test_value_map = {
@@ -240,7 +245,7 @@ def test_non_float_values(ax, format_string):
240
245
  for artist in ax.get_children():
241
246
  if isinstance(artist, mpl.text.Text):
242
247
  col, row = artist.get_position()
243
- if (row, col) in test_value_map:
248
+ if (row, col) in test_value_map: # pragma: no cover
244
249
  foo = test_value_map[(row, col)]
245
250
  actual_text = artist.get_text()
246
251
  expected_text = format(foo, format_string)
@@ -343,3 +348,162 @@ def test_plot_updates_local_config():
343
348
  _, ax = plt.subplots()
344
349
  random_heatmap.plot(ax)
345
350
  assert ax.get_title() == original_title
351
+
352
+
353
+ @pytest.mark.usefixtures('closefigures')
354
+ def test_heatmap_plot_highlighted_qubits():
355
+ value_map = {
356
+ (grid_qubit.GridQubit(0, 0),): 0.1,
357
+ (grid_qubit.GridQubit(0, 1),): 0.2,
358
+ (grid_qubit.GridQubit(0, 2),): 0.3,
359
+ (grid_qubit.GridQubit(1, 0),): 0.4,
360
+ }
361
+ single_qubit_heatmap = heatmap.Heatmap(value_map)
362
+
363
+ highlighted_qubits = [grid_qubit.GridQubit(0, 1), grid_qubit.GridQubit(1, 0)]
364
+
365
+ expected_linewidths = [2, 4, 2, 4]
366
+ expected_edgecolors = np.vstack(
367
+ (to_rgba_array("grey"), to_rgba_array("red"), to_rgba_array("grey"), to_rgba_array("red"))
368
+ )
369
+ # list of tuples: (offset, onoffseq), onoffseq = None for solid line.
370
+ expected_linestyles = [
371
+ _to_linestyle_tuple("dashed", linewidths=2),
372
+ _to_linestyle_tuple("solid"),
373
+ _to_linestyle_tuple("dashed", linewidths=2),
374
+ _to_linestyle_tuple("solid"),
375
+ ]
376
+
377
+ _, ax = plt.subplots()
378
+ _ = single_qubit_heatmap.plot(ax, highlighted_qubits=highlighted_qubits)
379
+
380
+ for artist in ax.get_children():
381
+ if isinstance(artist, mpl.collections.PolyCollection):
382
+ assert np.all(artist.get_linewidths() == expected_linewidths)
383
+ assert np.array_equal(artist.get_edgecolors(), expected_edgecolors)
384
+ assert artist.get_linestyles() == expected_linestyles
385
+
386
+
387
+ @pytest.mark.usefixtures('closefigures')
388
+ def test_heatmap_plot_highlighted_qubits_two_qubit():
389
+ value_map = {
390
+ (grid_qubit.GridQubit(0, 0), grid_qubit.GridQubit(0, 1)): 0.1,
391
+ (grid_qubit.GridQubit(0, 1), grid_qubit.GridQubit(0, 2)): 0.2,
392
+ (grid_qubit.GridQubit(1, 0), grid_qubit.GridQubit(0, 0)): 0.3,
393
+ (grid_qubit.GridQubit(3, 3), grid_qubit.GridQubit(3, 2)): 0.9,
394
+ }
395
+ two_qubit_interaction_heatmap = heatmap.TwoQubitInteractionHeatmap(value_map)
396
+
397
+ highlighted_qubits = [
398
+ grid_qubit.GridQubit(0, 1),
399
+ grid_qubit.GridQubit(0, 0),
400
+ grid_qubit.GridQubit(3, 3),
401
+ ]
402
+
403
+ expected_linewidths = [4, 4, 2, 2, 2, 4]
404
+ expected_edgecolors = np.vstack(
405
+ (
406
+ to_rgba_array("red"),
407
+ to_rgba_array("red"),
408
+ to_rgba_array("grey"),
409
+ to_rgba_array("grey"),
410
+ to_rgba_array("grey"),
411
+ to_rgba_array("red"),
412
+ )
413
+ )
414
+ # list of tuples: (offset, onoffseq), onoffseq = None for solid line.
415
+ expected_linestyles = [
416
+ _to_linestyle_tuple("solid"),
417
+ _to_linestyle_tuple("solid"),
418
+ _to_linestyle_tuple("dashed", linewidths=2),
419
+ _to_linestyle_tuple("dashed", linewidths=2),
420
+ _to_linestyle_tuple("dashed", linewidths=2),
421
+ _to_linestyle_tuple("solid"),
422
+ ]
423
+
424
+ _, ax = plt.subplots()
425
+ _ = two_qubit_interaction_heatmap.plot(ax, highlighted_qubits=highlighted_qubits)
426
+
427
+ for artist in ax.get_children():
428
+ if isinstance(artist, mpl.collections.PolyCollection):
429
+ # Since for two qubit interactions, there are two collections:
430
+ # one to highlight individual qubits and one showing their interaction.
431
+ # Here, the former is required, so the latter is excluded.
432
+ if artist.get_cmap().name != 'viridis': # assuming 'viridis' is the default cmap used.
433
+ assert np.all(artist.get_linewidths() == expected_linewidths)
434
+ assert np.array_equal(artist.get_edgecolors(), expected_edgecolors)
435
+ assert artist.get_linestyles() == expected_linestyles
436
+
437
+
438
+ @pytest.mark.usefixtures('closefigures')
439
+ def test_heatmap_highlighted_repeat_qubits():
440
+ value_map = {
441
+ (grid_qubit.GridQubit(0, 0), grid_qubit.GridQubit(0, 1)): 0.1,
442
+ (grid_qubit.GridQubit(0, 1), grid_qubit.GridQubit(0, 2)): 0.2,
443
+ (grid_qubit.GridQubit(1, 0), grid_qubit.GridQubit(0, 0)): 0.3,
444
+ (grid_qubit.GridQubit(3, 3), grid_qubit.GridQubit(3, 2)): 0.9,
445
+ }
446
+ two_qubit_interaction_heatmap = heatmap.TwoQubitInteractionHeatmap(value_map)
447
+
448
+ highlighted_qubits_1 = [
449
+ grid_qubit.GridQubit(0, 1),
450
+ grid_qubit.GridQubit(0, 0),
451
+ grid_qubit.GridQubit(3, 3),
452
+ ]
453
+ highlighted_qubits_2 = highlighted_qubits_1 + [grid_qubit.GridQubit(0, 0)] * 5
454
+
455
+ _, ax1 = plt.subplots()
456
+ _ = two_qubit_interaction_heatmap.plot(ax1, highlighted_qubits=highlighted_qubits_1)
457
+ _, ax2 = plt.subplots()
458
+ _ = two_qubit_interaction_heatmap.plot(ax2, highlighted_qubits=highlighted_qubits_2)
459
+
460
+ for artist_1, artist_2 in zip(ax1.get_children(), ax2.get_children()):
461
+ if isinstance(artist_1, mpl.collections.PolyCollection) and isinstance(
462
+ artist_2, mpl.collections.PolyCollection
463
+ ):
464
+ # Since for two qubit interactions, there are two collections:
465
+ # one to highlight individual qubits and one showing their interaction.
466
+ # Here, the former is required, so the latter is excluded.
467
+ if (
468
+ artist_1.get_cmap().name != 'viridis' and artist_2.get_cmap().name != 'viridis'
469
+ ): # assuming 'viridis' is the default cmap used.
470
+ assert np.all(artist_1.get_linewidths() == artist_1.get_linewidths())
471
+ assert np.array_equal(artist_1.get_edgecolors(), artist_2.get_edgecolors())
472
+ assert artist_1.get_linestyles() == artist_2.get_linestyles()
473
+
474
+
475
+ @pytest.mark.usefixtures('closefigures')
476
+ def test_heatmap_highlighted_init_collection_options_used():
477
+ value_map = {
478
+ (grid_qubit.GridQubit(0, 0),): 0.1,
479
+ (grid_qubit.GridQubit(0, 1),): 0.2,
480
+ (grid_qubit.GridQubit(0, 2),): 0.3,
481
+ (grid_qubit.GridQubit(1, 0),): 0.4,
482
+ }
483
+ single_qubit_heatmap = heatmap.Heatmap(
484
+ value_map,
485
+ collection_options={"edgecolors": "blue", "linewidths": 6, "linestyles": "dashed"},
486
+ )
487
+
488
+ highlighted_qubits = [grid_qubit.GridQubit(0, 1), grid_qubit.GridQubit(1, 0)]
489
+
490
+ expected_linewidths = [6, 4, 6, 4]
491
+ expected_edgecolors = np.vstack(
492
+ (to_rgba_array("blue"), to_rgba_array("red"), to_rgba_array("blue"), to_rgba_array("red"))
493
+ )
494
+ # list of tuples: (offset, onoffseq), onoffseq = None for solid line.
495
+ expected_linestyles = [
496
+ _to_linestyle_tuple("dashed", linewidths=6),
497
+ _to_linestyle_tuple("solid"),
498
+ _to_linestyle_tuple("dashed", linewidths=6),
499
+ _to_linestyle_tuple("solid"),
500
+ ]
501
+
502
+ _, ax = plt.subplots()
503
+ _ = single_qubit_heatmap.plot(ax, highlighted_qubits=highlighted_qubits)
504
+
505
+ for artist in ax.get_children():
506
+ if isinstance(artist, mpl.collections.PolyCollection):
507
+ assert np.all(artist.get_linewidths() == expected_linewidths)
508
+ assert np.array_equal(artist.get_edgecolors(), expected_edgecolors)
509
+ assert artist.get_linestyles() == expected_linestyles
cirq/vis/histogram.py CHANGED
@@ -11,7 +11,7 @@
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
- from typing import Any, Mapping, Optional, Sequence, Union, SupportsFloat
14
+ from typing import Any, Mapping, Optional, Sequence, SupportsFloat, Union
15
15
 
16
16
  import numpy as np
17
17
  from matplotlib import pyplot as plt
@@ -13,11 +13,10 @@
13
13
  # limitations under the License.
14
14
  """Tests for Histogram."""
15
15
 
16
+ import matplotlib.pyplot as plt
16
17
  import numpy as np
17
18
  import pytest
18
19
 
19
- import matplotlib.pyplot as plt
20
-
21
20
  from cirq.vis import integrated_histogram
22
21
 
23
22
 
@@ -14,10 +14,12 @@
14
14
 
15
15
  """Tool to visualize the results of a study."""
16
16
 
17
- from typing import cast, Optional, Sequence, SupportsFloat, Union
18
17
  import collections
19
- import numpy as np
18
+ from typing import Optional, Sequence, SupportsFloat, Union
19
+
20
20
  import matplotlib.pyplot as plt
21
+ import numpy as np
22
+
21
23
  import cirq.study.result as result
22
24
 
23
25
 
@@ -85,13 +87,13 @@ def plot_state_histogram(
85
87
  The axis that was plotted on.
86
88
  """
87
89
  show_fig = not ax
88
- if not ax:
90
+ if ax is None:
89
91
  fig, ax = plt.subplots(1, 1)
90
- ax = cast(plt.Axes, ax)
91
92
  if isinstance(data, result.Result):
92
93
  values = get_state_histogram(data)
93
94
  elif isinstance(data, collections.Counter):
94
- tick_label, values = zip(*sorted(data.items()))
95
+ tick_label, counts = zip(*sorted(data.items()))
96
+ values = np.asarray(counts)
95
97
  else:
96
98
  values = np.array(data)
97
99
  if tick_label is None:
@@ -14,10 +14,10 @@
14
14
 
15
15
  """Tests for state_histogram."""
16
16
 
17
- import numpy as np
18
- from matplotlib import pyplot as plt
19
17
  import matplotlib as mpl
18
+ import numpy as np
20
19
  import pytest
20
+ from matplotlib import pyplot as plt
21
21
 
22
22
  import cirq
23
23
  from cirq.devices import GridQubit
cirq/work/__init__.py CHANGED
@@ -14,20 +14,26 @@
14
14
 
15
15
  """Workflow utilities for sampling and measurement collection."""
16
16
 
17
- from cirq.work.collector import CircuitSampleJob, Collector
18
- from cirq.work.pauli_sum_collector import PauliSumCollector
19
- from cirq.work.observable_settings import InitObsSetting, _MeasurementSpec, observables_to_settings
20
- from cirq.work.observable_grouping import group_settings_greedy
17
+ from cirq.work.collector import CircuitSampleJob as CircuitSampleJob, Collector as Collector
18
+ from cirq.work.pauli_sum_collector import PauliSumCollector as PauliSumCollector
19
+ from cirq.work.observable_settings import (
20
+ InitObsSetting as InitObsSetting,
21
+ _MeasurementSpec as _MeasurementSpec,
22
+ observables_to_settings as observables_to_settings,
23
+ )
24
+ from cirq.work.observable_grouping import group_settings_greedy as group_settings_greedy
21
25
  from cirq.work.observable_measurement_data import (
22
- ObservableMeasuredResult,
23
- BitstringAccumulator,
24
- flatten_grouped_results,
26
+ ObservableMeasuredResult as ObservableMeasuredResult,
27
+ BitstringAccumulator as BitstringAccumulator,
28
+ flatten_grouped_results as flatten_grouped_results,
25
29
  )
26
30
  from cirq.work.observable_measurement import (
27
- VarianceStoppingCriteria,
28
- RepetitionsStoppingCriteria,
29
- measure_grouped_settings,
31
+ VarianceStoppingCriteria as VarianceStoppingCriteria,
32
+ RepetitionsStoppingCriteria as RepetitionsStoppingCriteria,
33
+ measure_grouped_settings as measure_grouped_settings,
34
+ )
35
+ from cirq.work.observable_readout_calibration import (
36
+ calibrate_readout_error as calibrate_readout_error,
30
37
  )
31
- from cirq.work.observable_readout_calibration import calibrate_readout_error
32
- from cirq.work.sampler import Sampler
33
- from cirq.work.zeros_sampler import ZerosSampler
38
+ from cirq.work.sampler import Sampler as Sampler
39
+ from cirq.work.zeros_sampler import ZerosSampler as ZerosSampler
cirq/work/collector.py CHANGED
@@ -14,10 +14,10 @@
14
14
 
15
15
  import abc
16
16
  from typing import Any, Iterator, List, Optional, Tuple, TYPE_CHECKING, Union
17
- from typing_extensions import Protocol
18
17
 
19
18
  import duet
20
19
  import numpy as np
20
+ from typing_extensions import Protocol
21
21
 
22
22
  from cirq import study, value
23
23
 
@@ -171,7 +171,7 @@ class Collector(metaclass=abc.ABCMeta):
171
171
  job_error = None
172
172
  running_jobs = 0
173
173
  queued_jobs: List[CircuitSampleJob] = []
174
- remaining_samples = np.infty if max_total_samples is None else max_total_samples
174
+ remaining_samples = np.inf if max_total_samples is None else max_total_samples
175
175
 
176
176
  async def run_job(job):
177
177
  nonlocal job_error
@@ -12,10 +12,10 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import Iterable, Dict, List, TYPE_CHECKING, cast, Callable
15
+ from typing import Callable, cast, Dict, Iterable, List, TYPE_CHECKING
16
16
 
17
17
  from cirq import ops, value
18
- from cirq.work.observable_settings import InitObsSetting, _max_weight_state, _max_weight_observable
18
+ from cirq.work.observable_settings import _max_weight_observable, _max_weight_state, InitObsSetting
19
19
 
20
20
  if TYPE_CHECKING:
21
21
  pass
@@ -24,15 +24,15 @@ import numpy as np
24
24
  import pandas as pd
25
25
  import sympy
26
26
 
27
- from cirq import circuits, study, ops, value, protocols
27
+ from cirq import circuits, ops, protocols, study, value
28
28
  from cirq._doc import document
29
29
  from cirq.work.observable_grouping import group_settings_greedy, GROUPER_T
30
30
  from cirq.work.observable_measurement_data import (
31
31
  BitstringAccumulator,
32
- ObservableMeasuredResult,
33
32
  flatten_grouped_results,
33
+ ObservableMeasuredResult,
34
34
  )
35
- from cirq.work.observable_settings import InitObsSetting, observables_to_settings, _MeasurementSpec
35
+ from cirq.work.observable_settings import _MeasurementSpec, InitObsSetting, observables_to_settings
36
36
 
37
37
  if TYPE_CHECKING:
38
38
  import cirq
@@ -18,14 +18,14 @@ from typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple, TYPE_CHE
18
18
 
19
19
  import numpy as np
20
20
  import sympy
21
- from cirq import ops, protocols, value
22
21
 
22
+ from cirq import ops, protocols, value
23
23
  from cirq._compat import proper_repr
24
24
  from cirq.work.observable_settings import (
25
- InitObsSetting,
26
25
  _max_weight_observable,
27
26
  _max_weight_state,
28
27
  _MeasurementSpec,
28
+ InitObsSetting,
29
29
  zeros_state,
30
30
  )
31
31
 
@@ -109,6 +109,9 @@ class ObservableMeasuredResult:
109
109
  repetitions: int
110
110
  circuit_params: Mapping[Union[str, sympy.Expr], Union[value.Scalar, sympy.Expr]]
111
111
 
112
+ # unhashable because of the mapping-type circuit_params attribute
113
+ __hash__ = None # type: ignore
114
+
112
115
  def __repr__(self):
113
116
  # I wish we could use the default dataclass __repr__ but
114
117
  # we need to prefix our class name with `cirq.work.`
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  import tempfile
15
- from typing import Iterable, Dict, List
15
+ from typing import Dict, Iterable, List
16
16
 
17
17
  import numpy as np
18
18
  import pytest
@@ -21,19 +21,19 @@ import cirq
21
21
  import cirq.work as cw
22
22
  from cirq.work import _MeasurementSpec, BitstringAccumulator, group_settings_greedy, InitObsSetting
23
23
  from cirq.work.observable_measurement import (
24
- _with_parameterized_layers,
25
- _get_params_for_setting,
26
- _pad_setting,
27
- _subdivide_meas_specs,
28
24
  _aggregate_n_repetitions,
29
25
  _check_meas_specs_still_todo,
30
- StoppingCriteria,
26
+ _get_params_for_setting,
27
+ _pad_setting,
31
28
  _parse_checkpoint_options,
32
- measure_observables_df,
29
+ _subdivide_meas_specs,
30
+ _with_parameterized_layers,
33
31
  CheckpointFileOptions,
34
- VarianceStoppingCriteria,
35
32
  measure_observables,
33
+ measure_observables_df,
36
34
  RepetitionsStoppingCriteria,
35
+ StoppingCriteria,
36
+ VarianceStoppingCriteria,
37
37
  )
38
38
 
39
39
 
@@ -1,8 +1,8 @@
1
1
  # pylint: disable=wrong-or-nonexistent-copyright-notice
2
2
  import dataclasses
3
- from typing import Union, Iterable, TYPE_CHECKING
3
+ from typing import Iterable, TYPE_CHECKING, Union
4
4
 
5
- from cirq import circuits, study, ops
5
+ from cirq import circuits, ops, study
6
6
  from cirq.work.observable_measurement import measure_grouped_settings, StoppingCriteria
7
7
  from cirq.work.observable_settings import InitObsSetting, zeros_state
8
8
 
@@ -1,9 +1,10 @@
1
1
  # pylint: disable=wrong-or-nonexistent-copyright-notice
2
2
  from typing import Sequence
3
3
 
4
+ import numpy as np
5
+
4
6
  import cirq
5
7
  import cirq.work as cw
6
- import numpy as np
7
8
 
8
9
 
9
10
  class DepolarizingWithDampedReadoutNoiseModel(cirq.NoiseModel):
@@ -16,19 +16,19 @@ import dataclasses
16
16
  import numbers
17
17
  from typing import (
18
18
  AbstractSet,
19
- Mapping,
20
- Union,
21
- Iterable,
22
19
  Dict,
20
+ FrozenSet,
21
+ Iterable,
22
+ Mapping,
23
23
  Optional,
24
- TYPE_CHECKING,
25
24
  Tuple,
26
- FrozenSet,
25
+ TYPE_CHECKING,
26
+ Union,
27
27
  )
28
28
 
29
29
  import sympy
30
30
 
31
- from cirq import ops, value, protocols
31
+ from cirq import ops, protocols, value
32
32
 
33
33
  if TYPE_CHECKING:
34
34
  import cirq
@@ -149,7 +149,8 @@ def _fix_precision(val: Union[value.Scalar, sympy.Expr], precision) -> Union[int
149
149
  raise ValueError(f'Cannot convert {val} to fixed precision in observable settings')
150
150
  if isinstance(val, (complex, numbers.Complex)):
151
151
  return int(val.real * precision), int(val.imag * precision)
152
- return int(val * precision)
152
+ # Pretty much all numbers are instances of numbers.Complex
153
+ return int(val * precision) # pragma: no cover
153
154
 
154
155
 
155
156
  def _hashable_param(
@@ -16,8 +16,8 @@ import pytest
16
16
  import sympy
17
17
 
18
18
  import cirq
19
- from cirq.work.observable_settings import _max_weight_state, _max_weight_observable, _hashable_param
20
- from cirq.work import InitObsSetting, observables_to_settings, _MeasurementSpec
19
+ from cirq.work import _MeasurementSpec, InitObsSetting, observables_to_settings
20
+ from cirq.work.observable_settings import _hashable_param, _max_weight_observable, _max_weight_state
21
21
 
22
22
 
23
23
  def test_init_obs_setting():
@@ -68,6 +68,7 @@ def test_param_hash():
68
68
  params3 = [('beta', 1.24), ('gamma', 4.57)]
69
69
  params4 = [('beta', 1.23 + 0.01j), ('gamma', 4.56 + 0.01j)]
70
70
  params5 = [('beta', 1.23 + 0.01j), ('gamma', 4.56 + 0.01j)]
71
+ params3 = [('beta', 1.24), ('gamma', 4.57)]
71
72
  assert _hashable_param(params1) == _hashable_param(params1)
72
73
  assert hash(_hashable_param(params1)) == hash(_hashable_param(params1))
73
74
  assert _hashable_param(params1) == _hashable_param(params2)
@@ -13,7 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import collections
16
- from typing import cast, Dict, Optional, Union, TYPE_CHECKING
16
+ from typing import cast, Dict, Optional, TYPE_CHECKING, Union
17
17
 
18
18
  import numpy as np
19
19