cirq-core 1.4.1__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 +1 -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.1.dist-info → cirq_core-1.5.0.dist-info}/RECORD +586 -552
  584. {cirq_core-1.4.1.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.1.dist-info/METADATA +0 -45
  589. {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/LICENSE +0 -0
  590. {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/top_level.txt +0 -0
@@ -11,16 +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
- from typing import Optional, TYPE_CHECKING, Set, List
14
+
15
+ from typing import List, Optional, Set
15
16
 
16
17
  import pytest
18
+
17
19
  import cirq
18
- from cirq import PointOptimizer, PointOptimizationSummary, Operation
20
+ from cirq import Operation, PointOptimizationSummary, PointOptimizer
19
21
  from cirq.testing import EqualsTester
20
22
 
21
- if TYPE_CHECKING:
22
- import cirq
23
-
24
23
 
25
24
  def test_equality():
26
25
  a = cirq.NamedQubit('a')
@@ -62,8 +61,8 @@ class ReplaceWithXGates(PointOptimizer):
62
61
  """
63
62
 
64
63
  def optimization_at(
65
- self, circuit: 'cirq.Circuit', index: int, op: 'cirq.Operation'
66
- ) -> Optional['cirq.PointOptimizationSummary']:
64
+ self, circuit: cirq.Circuit, index: int, op: cirq.Operation
65
+ ) -> Optional[cirq.PointOptimizationSummary]:
67
66
  end = index + 1
68
67
  new_ops = [cirq.X(q) for q in op.qubits]
69
68
  done = False
@@ -156,8 +155,8 @@ def test_point_optimizer_raises_on_gates_changing_qubits():
156
155
  """Changes all single qubit operations to act on LineQubit(42)"""
157
156
 
158
157
  def optimization_at(
159
- self, circuit: 'cirq.Circuit', index: int, op: 'cirq.Operation'
160
- ) -> Optional['cirq.PointOptimizationSummary']:
158
+ self, circuit: cirq.Circuit, index: int, op: cirq.Operation
159
+ ) -> Optional[cirq.PointOptimizationSummary]:
161
160
  new_op = op
162
161
  if len(op.qubits) == 1 and isinstance(op, cirq.GateOperation):
163
162
  new_op = op.gate(cirq.LineQubit(42))
@@ -14,12 +14,14 @@
14
14
 
15
15
  """Utility classes for representing QASM."""
16
16
 
17
- from typing import Callable, Dict, Optional, Sequence, Set, Tuple, Union, TYPE_CHECKING
17
+ from __future__ import annotations
18
18
 
19
19
  import re
20
+ from typing import Callable, Dict, Iterator, Optional, Sequence, Tuple, TYPE_CHECKING, Union
21
+
20
22
  import numpy as np
21
23
 
22
- from cirq import ops, linalg, protocols, value
24
+ from cirq import linalg, ops, protocols, value
23
25
 
24
26
  if TYPE_CHECKING:
25
27
  import cirq
@@ -46,15 +48,15 @@ class QasmUGate(ops.Gate):
46
48
  return 1
47
49
 
48
50
  @staticmethod
49
- def from_matrix(mat: np.ndarray) -> 'QasmUGate':
51
+ def from_matrix(mat: np.ndarray) -> QasmUGate:
50
52
  pre_phase, rotation, post_phase = linalg.deconstruct_single_qubit_matrix_into_angles(mat)
51
53
  return QasmUGate(rotation / np.pi, post_phase / np.pi, pre_phase / np.pi)
52
54
 
53
55
  def _has_unitary_(self):
54
56
  return True
55
57
 
56
- def _qasm_(self, qubits: Tuple['cirq.Qid', ...], args: 'cirq.QasmArgs') -> str:
57
- args.validate_version('2.0')
58
+ def _qasm_(self, qubits: Tuple[cirq.Qid, ...], args: cirq.QasmArgs) -> str:
59
+ args.validate_version('2.0', '3.0')
58
60
  return args.format(
59
61
  'u3({0:half_turns},{1:half_turns},{2:half_turns}) {3};\n',
60
62
  self.theta,
@@ -86,13 +88,13 @@ class QasmUGate(ops.Gate):
86
88
  return {'theta': self.theta, 'phi': self.phi, 'lmda': self.lmda}
87
89
 
88
90
  @classmethod
89
- def _from_json_dict_(cls, theta: float, phi: float, lmda: float, **kwargs) -> 'QasmUGate':
91
+ def _from_json_dict_(cls, theta: float, phi: float, lmda: float, **kwargs) -> QasmUGate:
90
92
  return cls(theta, phi, lmda)
91
93
 
92
94
 
93
95
  @value.value_equality
94
96
  class QasmTwoQubitGate(ops.Gate):
95
- def __init__(self, kak: 'cirq.KakDecomposition') -> None:
97
+ def __init__(self, kak: cirq.KakDecomposition) -> None:
96
98
  """A two qubit gate represented in QASM by the KAK decomposition.
97
99
 
98
100
  All angles are in half turns. Assumes a canonicalized KAK
@@ -110,7 +112,7 @@ class QasmTwoQubitGate(ops.Gate):
110
112
  return self.kak
111
113
 
112
114
  @staticmethod
113
- def from_matrix(mat: np.ndarray, atol=1e-8) -> 'QasmTwoQubitGate':
115
+ def from_matrix(mat: np.ndarray, atol=1e-8) -> QasmTwoQubitGate:
114
116
  """Creates a QasmTwoQubitGate from the given matrix.
115
117
 
116
118
  Args:
@@ -126,7 +128,7 @@ class QasmTwoQubitGate(ops.Gate):
126
128
  def _unitary_(self):
127
129
  return protocols.unitary(self.kak)
128
130
 
129
- def _decompose_(self, qubits: Sequence['cirq.Qid']) -> 'cirq.OP_TREE':
131
+ def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
130
132
  q0, q1 = qubits
131
133
  x, y, z = self.kak.interaction_coefficients
132
134
  a = x * -2 / np.pi + 0.5
@@ -170,8 +172,8 @@ class QasmOutput:
170
172
 
171
173
  def __init__(
172
174
  self,
173
- operations: 'cirq.OP_TREE',
174
- qubits: Tuple['cirq.Qid', ...],
175
+ operations: cirq.OP_TREE,
176
+ qubits: Tuple[cirq.Qid, ...],
175
177
  header: str = '',
176
178
  precision: int = 10,
177
179
  version: str = '2.0',
@@ -197,11 +199,13 @@ class QasmOutput:
197
199
  meas_key_id_map, meas_comments = self._generate_measurement_ids()
198
200
  self.meas_comments = meas_comments
199
201
  qubit_id_map = self._generate_qubit_ids()
202
+ self.cregs = self._generate_cregs(meas_key_id_map)
200
203
  self.args = protocols.QasmArgs(
201
204
  precision=precision,
202
205
  version=version,
203
206
  qubit_id_map=qubit_id_map,
204
207
  meas_key_id_map=meas_key_id_map,
208
+ meas_key_bitcount={k: v[0] for k, v in self.cregs.items()},
205
209
  )
206
210
 
207
211
  def _generate_measurement_ids(self) -> Tuple[Dict[str, str], Dict[str, Optional[str]]]:
@@ -223,9 +227,33 @@ class QasmOutput:
223
227
  meas_key_id_map[key] = meas_id
224
228
  return meas_key_id_map, meas_comments
225
229
 
226
- def _generate_qubit_ids(self) -> Dict['cirq.Qid', str]:
230
+ def _generate_qubit_ids(self) -> Dict[cirq.Qid, str]:
227
231
  return {qubit: f'q[{i}]' for i, qubit in enumerate(self.qubits)}
228
232
 
233
+ def _generate_cregs(self, meas_key_id_map: Dict[str, str]) -> Dict[str, tuple[int, str]]:
234
+ """Pick an id for the creg that will store each measurement
235
+
236
+ This function finds the largest measurement using each key.
237
+ That is, if multiple measurements are made with the same key,
238
+ it will use the key with the most number of qubits.
239
+
240
+ Returns: dictionary with key of measurement id and value of (#qubits, comment).
241
+ """
242
+ cregs: Dict[str, tuple[int, str]] = {}
243
+ for meas in self.measurements:
244
+ key = protocols.measurement_key_name(meas)
245
+ meas_id = meas_key_id_map[key]
246
+
247
+ if self.meas_comments[key] is not None:
248
+ comment = f' // Measurement: {self.meas_comments[key]}'
249
+ else:
250
+ comment = ''
251
+
252
+ if meas_id not in cregs or cregs[meas_id][0] < len(meas.qubits):
253
+ cregs[meas_id] = (len(meas.qubits), comment)
254
+
255
+ return cregs
256
+
229
257
  def is_valid_qasm_id(self, id_str: str) -> bool:
230
258
  """Test if id_str is a valid id in QASM grammar."""
231
259
  return self.valid_id_re.match(id_str) is not None
@@ -246,7 +274,7 @@ class QasmOutput:
246
274
  return ''.join(output)
247
275
 
248
276
  def _write_qasm(self, output_func: Callable[[str], None]) -> None:
249
- self.args.validate_version('2.0')
277
+ self.args.validate_version('2.0', '3.0')
250
278
 
251
279
  # Generate nice line spacing
252
280
  line_gap = [0]
@@ -267,8 +295,12 @@ class QasmOutput:
267
295
  output('\n')
268
296
 
269
297
  # Version
270
- output('OPENQASM 2.0;\n')
271
- output('include "qelib1.inc";\n')
298
+ output(f'OPENQASM {self.args.version};\n')
299
+ if self.args.version == '2.0':
300
+ output('include "qelib1.inc";\n')
301
+ else:
302
+ output('include "stdgates.inc";\n')
303
+
272
304
  output_line_gap(2)
273
305
 
274
306
  # Function definitions
@@ -276,23 +308,22 @@ class QasmOutput:
276
308
 
277
309
  # Register definitions
278
310
  # Qubit registers
311
+
279
312
  output(f"// Qubits: [{', '.join(map(str, self.qubits))}]\n")
280
313
  if len(self.qubits) > 0:
281
- output(f'qreg q[{len(self.qubits)}];\n')
314
+ if self.args.version == '2.0':
315
+ output(f'qreg q[{len(self.qubits)}];\n')
316
+ else:
317
+ output(f'qubit[{len(self.qubits)}] q;\n')
318
+
282
319
  # Classical registers
283
- # Pick an id for the creg that will store each measurement
284
- already_output_keys: Set[str] = set()
285
- for meas in self.measurements:
286
- key = protocols.measurement_key_name(meas)
287
- if key in already_output_keys:
288
- continue
289
- already_output_keys.add(key)
290
- meas_id = self.args.meas_key_id_map[key]
291
- comment = self.meas_comments[key]
292
- if comment is None:
293
- output(f'creg {meas_id}[{len(meas.qubits)}];\n')
320
+ for meas_id in self.cregs:
321
+ length, comment = self.cregs[meas_id]
322
+ if self.args.version == '2.0':
323
+ output(f'creg {meas_id}[{length}];{comment}\n')
294
324
  else:
295
- output(f'creg {meas_id}[{len(meas.qubits)}]; // Measurement: {comment}\n')
325
+ output(f'bit[{length}] {meas_id};{comment}\n')
326
+
296
327
  # In OpenQASM 2.0, the transformation of global phase gates is ignored.
297
328
  # Therefore, no newline is created when the operations contained in
298
329
  # a circuit consist only of global phase gates.
@@ -304,11 +335,11 @@ class QasmOutput:
304
335
 
305
336
  def _write_operations(
306
337
  self,
307
- op_tree: 'cirq.OP_TREE',
338
+ op_tree: cirq.OP_TREE,
308
339
  output: Callable[[str], None],
309
340
  output_line_gap: Callable[[int], None],
310
341
  ) -> None:
311
- def keep(op: 'cirq.Operation') -> bool:
342
+ def keep(op: cirq.Operation) -> bool:
312
343
  return protocols.qasm(op, args=self.args, default=None) is not None
313
344
 
314
345
  def fallback(op):
@@ -320,7 +351,7 @@ class QasmOutput:
320
351
  return NotImplemented
321
352
 
322
353
  if len(op.qubits) == 1:
323
- return QasmUGate.from_matrix(mat).on(*op.qubits)
354
+ return QasmUGate.from_matrix(mat).on(*op.qubits) # pragma: no cover
324
355
  return QasmTwoQubitGate.from_matrix(mat).on(*op.qubits)
325
356
 
326
357
  def on_stuck(bad_op):
@@ -337,10 +368,10 @@ class QasmOutput:
337
368
  if should_annotate:
338
369
  output_line_gap(1)
339
370
  if isinstance(main_op, ops.GateOperation):
340
- x = str(main_op.gate).replace('\n', '\n //')
371
+ x = str(main_op.gate).replace('\n', '\n// ')
341
372
  output(f'// Gate: {x!s}\n')
342
373
  else:
343
- x = str(main_op).replace('\n', '\n //')
374
+ x = str(main_op).replace('\n', '\n// ')
344
375
  output(f'// Operation: {x!s}\n')
345
376
 
346
377
  for qasm in qasms:
@@ -11,8 +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
- import re
15
14
  import os
15
+ import re
16
+
16
17
  import numpy as np
17
18
  import pytest
18
19
 
@@ -52,6 +53,11 @@ def test_qasm_u_qubit_gate_unitary():
52
53
 
53
54
  cirq.testing.assert_implements_consistent_protocols(g)
54
55
 
56
+ u = cirq.unitary(cirq.Y)
57
+ g = QasmUGate.from_matrix(u)
58
+ cirq.testing.assert_allclose_up_to_global_phase(cirq.unitary(g), u, atol=1e-7)
59
+ cirq.testing.assert_implements_consistent_protocols(g)
60
+
55
61
 
56
62
  def test_qasm_two_qubit_gate_unitary():
57
63
  u = cirq.testing.random_unitary(4)
@@ -225,7 +231,7 @@ rx(pi*0.123) q[0];
225
231
  def test_version():
226
232
  (q0,) = _make_qubits(1)
227
233
  with pytest.raises(ValueError):
228
- output = cirq.QasmOutput((), (q0,), version='3.0')
234
+ output = cirq.QasmOutput((), (q0,), version='4.0')
229
235
  _ = str(output)
230
236
 
231
237
 
@@ -590,3 +596,58 @@ reset q[0];
590
596
  reset q[1];
591
597
  """.strip()
592
598
  )
599
+
600
+
601
+ def test_different_sized_registers():
602
+ qubits = cirq.LineQubit.range(2)
603
+ c = cirq.Circuit(cirq.measure(qubits[0], key='c'), cirq.measure(qubits, key='c'))
604
+ output = cirq.QasmOutput(
605
+ c.all_operations(), tuple(sorted(c.all_qubits())), header='Generated from Cirq!'
606
+ )
607
+ assert (
608
+ str(output)
609
+ == """// Generated from Cirq!
610
+
611
+ OPENQASM 2.0;
612
+ include "qelib1.inc";
613
+
614
+
615
+ // Qubits: [q(0), q(1)]
616
+ qreg q[2];
617
+ creg m_c[2];
618
+
619
+
620
+ measure q[0] -> m_c[0];
621
+
622
+ // Gate: cirq.MeasurementGate(2, cirq.MeasurementKey(name='c'), ())
623
+ measure q[0] -> m_c[0];
624
+ measure q[1] -> m_c[1];
625
+ """
626
+ )
627
+ # OPENQASM 3.0
628
+ output3 = cirq.QasmOutput(
629
+ c.all_operations(),
630
+ tuple(sorted(c.all_qubits())),
631
+ header='Generated from Cirq!',
632
+ version='3.0',
633
+ )
634
+ assert (
635
+ str(output3)
636
+ == """// Generated from Cirq!
637
+
638
+ OPENQASM 3.0;
639
+ include "stdgates.inc";
640
+
641
+
642
+ // Qubits: [q(0), q(1)]
643
+ qubit[2] q;
644
+ bit[2] m_c;
645
+
646
+
647
+ m_c[0] = measure q[0];
648
+
649
+ // Gate: cirq.MeasurementGate(2, cirq.MeasurementKey(name='c'), ())
650
+ m_c[0] = measure q[0];
651
+ m_c[1] = measure q[1];
652
+ """
653
+ )
@@ -12,6 +12,8 @@
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
  from typing import (
16
18
  Any,
17
19
  Callable,
@@ -25,7 +27,6 @@ from typing import (
25
27
  Sequence,
26
28
  Tuple,
27
29
  TYPE_CHECKING,
28
- Union,
29
30
  )
30
31
 
31
32
  import numpy as np
@@ -33,11 +34,11 @@ import numpy as np
33
34
  from cirq import value
34
35
  from cirq.circuits._block_diagram_drawer import BlockDiagramDrawer
35
36
  from cirq.circuits._box_drawing_character_data import (
36
- BoxDrawCharacterSet,
37
- NORMAL_BOX_CHARS,
38
- BOLD_BOX_CHARS,
39
37
  ASCII_BOX_CHARS,
38
+ BOLD_BOX_CHARS,
39
+ BoxDrawCharacterSet,
40
40
  DOUBLED_BOX_CHARS,
41
+ NORMAL_BOX_CHARS,
41
42
  )
42
43
 
43
44
  if TYPE_CHECKING:
@@ -45,23 +46,11 @@ if TYPE_CHECKING:
45
46
 
46
47
  _HorizontalLine = NamedTuple(
47
48
  '_HorizontalLine',
48
- [
49
- ('y', Union[int, float]),
50
- ('x1', Union[int, float]),
51
- ('x2', Union[int, float]),
52
- ('emphasize', bool),
53
- ('doubled', bool),
54
- ],
49
+ [('y', float), ('x1', float), ('x2', float), ('emphasize', bool), ('doubled', bool)],
55
50
  )
56
51
  _VerticalLine = NamedTuple(
57
52
  '_VerticalLine',
58
- [
59
- ('x', Union[int, float]),
60
- ('y1', Union[int, float]),
61
- ('y2', Union[int, float]),
62
- ('emphasize', bool),
63
- ('doubled', bool),
64
- ],
53
+ [('x', float), ('y1', float), ('y2', float), ('emphasize', bool), ('doubled', bool)],
65
54
  )
66
55
  _DiagramText = NamedTuple('_DiagramText', [('text', str), ('transposed_text', str)])
67
56
 
@@ -99,10 +88,10 @@ class TextDiagramDrawer:
99
88
  self.vertical_lines: List[_VerticalLine] = (
100
89
  [] if vertical_lines is None else list(vertical_lines)
101
90
  )
102
- self.horizontal_padding: Dict[int, Union[int, float]] = (
91
+ self.horizontal_padding: Dict[int, float] = (
103
92
  dict() if horizontal_padding is None else dict(horizontal_padding)
104
93
  )
105
- self.vertical_padding: Dict[int, Union[int, float]] = (
94
+ self.vertical_padding: Dict[int, float] = (
106
95
  dict() if vertical_padding is None else dict(vertical_padding)
107
96
  )
108
97
 
@@ -148,7 +137,7 @@ class TextDiagramDrawer:
148
137
 
149
138
  # Horizontal line?
150
139
  if any(line_y == y and x1 < x < x2 for line_y, x1, x2, _, _ in self.horizontal_lines):
151
- return True
140
+ return True # pragma: no cover
152
141
 
153
142
  return False
154
143
 
@@ -171,30 +160,20 @@ class TextDiagramDrawer:
171
160
  raise ValueError("Line is neither horizontal nor vertical")
172
161
 
173
162
  def vertical_line(
174
- self,
175
- x: Union[int, float],
176
- y1: Union[int, float],
177
- y2: Union[int, float],
178
- emphasize: bool = False,
179
- doubled: bool = False,
163
+ self, x: float, y1: float, y2: float, emphasize: bool = False, doubled: bool = False
180
164
  ) -> None:
181
165
  """Adds a line from (x, y1) to (x, y2)."""
182
166
  y1, y2 = sorted([y1, y2])
183
167
  self.vertical_lines.append(_VerticalLine(x, y1, y2, emphasize, doubled))
184
168
 
185
169
  def horizontal_line(
186
- self,
187
- y: Union[int, float],
188
- x1: Union[int, float],
189
- x2: Union[int, float],
190
- emphasize: bool = False,
191
- doubled: bool = False,
170
+ self, y: float, x1: float, x2: float, emphasize: bool = False, doubled: bool = False
192
171
  ) -> None:
193
172
  """Adds a line from (x1, y) to (x2, y)."""
194
173
  x1, x2 = sorted([x1, x2])
195
174
  self.horizontal_lines.append(_HorizontalLine(y, x1, x2, emphasize, doubled))
196
175
 
197
- def transpose(self) -> 'cirq.TextDiagramDrawer':
176
+ def transpose(self) -> cirq.TextDiagramDrawer:
198
177
  """Returns the same diagram, but mirrored across its diagonal."""
199
178
  out = TextDiagramDrawer()
200
179
  out.entries = {
@@ -228,26 +207,21 @@ class TextDiagramDrawer:
228
207
  max_y = max(max_y, v.y1, v.y2)
229
208
  return 1 + int(max_y)
230
209
 
231
- def force_horizontal_padding_after(self, index: int, padding: Union[int, float]) -> None:
210
+ def force_horizontal_padding_after(self, index: int, padding: float) -> None:
232
211
  """Change the padding after the given column."""
233
212
  self.horizontal_padding[index] = padding
234
213
 
235
- def force_vertical_padding_after(self, index: int, padding: Union[int, float]) -> None:
214
+ def force_vertical_padding_after(self, index: int, padding: float) -> None:
236
215
  """Change the padding after the given row."""
237
216
  self.vertical_padding[index] = padding
238
217
 
239
- def _transform_coordinates(
240
- self,
241
- func: Callable[
242
- [Union[int, float], Union[int, float]], Tuple[Union[int, float], Union[int, float]]
243
- ],
244
- ) -> None:
218
+ def _transform_coordinates(self, func: Callable[[float, float], Tuple[float, float]]) -> None:
245
219
  """Helper method to transformer either row or column coordinates."""
246
220
 
247
- def func_x(x: Union[int, float]) -> Union[int, float]:
221
+ def func_x(x: float) -> float:
248
222
  return func(x, 0)[0]
249
223
 
250
- def func_y(y: Union[int, float]) -> Union[int, float]:
224
+ def func_y(y: float) -> float:
251
225
  return func(0, y)[1]
252
226
 
253
227
  self.entries = {
@@ -271,9 +245,7 @@ class TextDiagramDrawer:
271
245
  def insert_empty_columns(self, x: int, amount: int = 1) -> None:
272
246
  """Insert a number of columns after the given column."""
273
247
 
274
- def transform_columns(
275
- column: Union[int, float], row: Union[int, float]
276
- ) -> Tuple[Union[int, float], Union[int, float]]:
248
+ def transform_columns(column: float, row: float) -> Tuple[float, float]:
277
249
  return column + (amount if column >= x else 0), row
278
250
 
279
251
  self._transform_coordinates(transform_columns)
@@ -281,9 +253,7 @@ class TextDiagramDrawer:
281
253
  def insert_empty_rows(self, y: int, amount: int = 1) -> None:
282
254
  """Insert a number of rows after the given row."""
283
255
 
284
- def transform_rows(
285
- column: Union[int, float], row: Union[int, float]
286
- ) -> Tuple[Union[int, float], Union[int, float]]:
256
+ def transform_rows(column: float, row: float) -> Tuple[float, float]:
287
257
  return column, row + (amount if row >= y else 0)
288
258
 
289
259
  self._transform_coordinates(transform_rows)
@@ -365,14 +335,14 @@ class TextDiagramDrawer:
365
335
  horizontal_padding=self.horizontal_padding,
366
336
  )
367
337
 
368
- def shift(self, dx: int = 0, dy: int = 0) -> 'cirq.TextDiagramDrawer':
338
+ def shift(self, dx: int = 0, dy: int = 0) -> cirq.TextDiagramDrawer:
369
339
  self._transform_coordinates(lambda x, y: (x + dx, y + dy))
370
340
  return self
371
341
 
372
- def shifted(self, dx: int = 0, dy: int = 0) -> 'cirq.TextDiagramDrawer':
342
+ def shifted(self, dx: int = 0, dy: int = 0) -> cirq.TextDiagramDrawer:
373
343
  return self.copy().shift(dx, dy)
374
344
 
375
- def superimpose(self, other: 'cirq.TextDiagramDrawer') -> 'cirq.TextDiagramDrawer':
345
+ def superimpose(self, other: cirq.TextDiagramDrawer) -> cirq.TextDiagramDrawer:
376
346
  self.entries.update(other.entries)
377
347
  self.horizontal_lines += other.horizontal_lines
378
348
  self.vertical_lines += other.vertical_lines
@@ -380,13 +350,13 @@ class TextDiagramDrawer:
380
350
  self.vertical_padding.update(other.vertical_padding)
381
351
  return self
382
352
 
383
- def superimposed(self, other: 'cirq.TextDiagramDrawer') -> 'cirq.TextDiagramDrawer':
353
+ def superimposed(self, other: cirq.TextDiagramDrawer) -> cirq.TextDiagramDrawer:
384
354
  return self.copy().superimpose(other)
385
355
 
386
356
  @classmethod
387
357
  def vstack(
388
358
  cls,
389
- diagrams: Sequence['cirq.TextDiagramDrawer'],
359
+ diagrams: Sequence[cirq.TextDiagramDrawer],
390
360
  padding_resolver: Optional[Callable[[Sequence[Optional[int]]], int]] = None,
391
361
  ):
392
362
  """Vertically stack text diagrams.
@@ -427,7 +397,7 @@ class TextDiagramDrawer:
427
397
  @classmethod
428
398
  def hstack(
429
399
  cls,
430
- diagrams: Sequence['cirq.TextDiagramDrawer'],
400
+ diagrams: Sequence[cirq.TextDiagramDrawer],
431
401
  padding_resolver: Optional[Callable[[Sequence[Optional[int]]], int]] = None,
432
402
  ):
433
403
  """Horizontally stack text diagrams.
@@ -13,23 +13,24 @@
13
13
  # limitations under the License.
14
14
 
15
15
  from unittest import mock
16
+
16
17
  import pytest
17
18
 
19
+ import cirq.testing as ct
18
20
  from cirq.circuits import TextDiagramDrawer
19
21
  from cirq.circuits._block_diagram_drawer_test import _assert_same_diagram
20
22
  from cirq.circuits._box_drawing_character_data import (
21
23
  ASCII_BOX_CHARS,
22
- NORMAL_BOX_CHARS,
23
- DOUBLED_BOX_CHARS,
24
24
  BOLD_BOX_CHARS,
25
+ DOUBLED_BOX_CHARS,
26
+ NORMAL_BOX_CHARS,
25
27
  )
26
28
  from cirq.circuits.text_diagram_drawer import (
29
+ _DiagramText,
27
30
  _HorizontalLine,
28
31
  _VerticalLine,
29
- _DiagramText,
30
32
  pick_charset,
31
33
  )
32
- import cirq.testing as ct
33
34
 
34
35
 
35
36
  def assert_has_rendering(actual: TextDiagramDrawer, desired: str, **kwargs) -> None:
cirq/contrib/__init__.py CHANGED
@@ -21,6 +21,6 @@ this package.
21
21
  from cirq.contrib import acquaintance
22
22
  from cirq.contrib import graph_device
23
23
  from cirq.contrib import quirk
24
- from cirq.contrib.qcircuit import circuit_to_latex_using_qcircuit
24
+ from cirq.contrib.qcircuit import circuit_to_latex_using_qcircuit as circuit_to_latex_using_qcircuit
25
25
  from cirq.contrib import json
26
- from cirq.contrib.circuitdag import CircuitDag, Unique
26
+ from cirq.contrib.circuitdag import CircuitDag as CircuitDag, Unique as Unique