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
@@ -19,30 +19,46 @@ Based on:
19
19
  Synthesis of Quantum Logic Circuits. Tech. rep. 2006,
20
20
  https://arxiv.org/abs/quant-ph/0406176
21
21
  """
22
- from typing import List, Callable, TYPE_CHECKING
23
-
24
- from scipy.linalg import cossin
22
+ from typing import Callable, Iterable, List, TYPE_CHECKING
25
23
 
26
24
  import numpy as np
25
+ from scipy.linalg import cossin
27
26
 
28
27
  from cirq import ops
28
+ from cirq.circuits.frozen_circuit import FrozenCircuit
29
29
  from cirq.linalg import decompositions, predicates
30
+ from cirq.protocols import unitary_protocol
31
+ from cirq.transformers.analytical_decompositions.three_qubit_decomposition import (
32
+ three_qubit_matrix_to_operations,
33
+ )
34
+ from cirq.transformers.analytical_decompositions.two_qubit_to_cz import (
35
+ two_qubit_matrix_to_cz_operations,
36
+ )
30
37
 
31
38
  if TYPE_CHECKING:
32
39
  import cirq
33
- from cirq.ops import op_tree
34
40
 
35
41
 
36
- def quantum_shannon_decomposition(qubits: 'List[cirq.Qid]', u: np.ndarray) -> 'op_tree.OpTree':
37
- """Decomposes n-qubit unitary into CX/YPow/ZPow/CNOT gates, preserving global phase.
42
+ def quantum_shannon_decomposition(
43
+ qubits: 'List[cirq.Qid]', u: np.ndarray, atol: float = 1e-8
44
+ ) -> Iterable['cirq.Operation']:
45
+ """Decomposes n-qubit unitary 1-q, 2-q and GlobalPhase gates, preserving global phase.
46
+
47
+ The gates used are CX/YPow/ZPow/CNOT/GlobalPhase/CZ/PhasedXZGate/PhasedXPowGate.
38
48
 
39
49
  The algorithm is described in Shende et al.:
40
50
  Synthesis of Quantum Logic Circuits. Tech. rep. 2006,
41
51
  https://arxiv.org/abs/quant-ph/0406176
42
52
 
53
+ Note: Shannon decomposition is sensitive to the numerical accuracy of doing eigendecomposition.
54
+ Eigendecomposition is obtained using `np.linalg.eig` and the resulting difference between
55
+ the input and output unitary is heavily affected by the accuracy of `np.linalg.eig`.
56
+
57
+
43
58
  Args:
44
59
  qubits: List of qubits in order of significance
45
60
  u: Numpy array for unitary matrix representing gate to be decomposed
61
+ atol: Absolute tolerance of floating point checks.
46
62
 
47
63
  Calls:
48
64
  (Base Case)
@@ -62,7 +78,7 @@ def quantum_shannon_decomposition(qubits: 'List[cirq.Qid]', u: np.ndarray) -> 'o
62
78
  ValueError: If the u matrix is non-unitary
63
79
  ValueError: If the u matrix is not of shape (2^n,2^n)
64
80
  """
65
- if not predicates.is_unitary(u): # Check that u is unitary
81
+ if not predicates.is_unitary(u, atol=atol): # Check that u is unitary
66
82
  raise ValueError(
67
83
  "Expected input matrix u to be unitary, \
68
84
  but it fails cirq.is_unitary check"
@@ -80,6 +96,32 @@ def quantum_shannon_decomposition(qubits: 'List[cirq.Qid]', u: np.ndarray) -> 'o
80
96
  yield from _single_qubit_decomposition(qubits[0], u)
81
97
  return
82
98
 
99
+ if n == 4:
100
+ operations = tuple(
101
+ two_qubit_matrix_to_cz_operations(
102
+ qubits[0], qubits[1], u, allow_partial_czs=True, clean_operations=True, atol=atol
103
+ )
104
+ )
105
+ yield from operations
106
+ i, j = np.unravel_index(np.argmax(np.abs(u)), u.shape)
107
+ new_unitary = unitary_protocol.unitary(FrozenCircuit.from_moments(*operations))
108
+ global_phase = np.angle(u[i, j]) - np.angle(new_unitary[i, j])
109
+ if np.abs(global_phase) > 1e-9:
110
+ yield ops.global_phase_operation(np.exp(1j * global_phase))
111
+ return
112
+
113
+ if n == 8:
114
+ operations = tuple(
115
+ three_qubit_matrix_to_operations(qubits[0], qubits[1], qubits[2], u, atol=atol)
116
+ )
117
+ yield from operations
118
+ i, j = np.unravel_index(np.argmax(np.abs(u)), u.shape)
119
+ new_unitary = unitary_protocol.unitary(FrozenCircuit.from_moments(*operations))
120
+ global_phase = np.angle(u[i, j]) - np.angle(new_unitary[i, j])
121
+ if np.abs(global_phase) > 1e-9:
122
+ yield ops.global_phase_operation(np.exp(1j * global_phase))
123
+ return
124
+
83
125
  # Perform a cosine-sine (linalg) decomposition on u
84
126
  # X = [ u1 , 0 ] [ cos(theta) , -sin(theta) ] [ v1 , 0 ]
85
127
  # [ 0 , u2 ] [ sin(theta) , cos(theta) ] [ 0 , v2 ]
@@ -97,7 +139,7 @@ def quantum_shannon_decomposition(qubits: 'List[cirq.Qid]', u: np.ndarray) -> 'o
97
139
  yield from _msb_demuxer(qubits, u1, u2)
98
140
 
99
141
 
100
- def _single_qubit_decomposition(qubit: 'cirq.Qid', u: np.ndarray) -> 'op_tree.OpTree':
142
+ def _single_qubit_decomposition(qubit: 'cirq.Qid', u: np.ndarray) -> Iterable['cirq.Operation']:
101
143
  """Decomposes single-qubit gate, and returns list of operations, keeping phase invariant.
102
144
 
103
145
  Args:
@@ -108,22 +150,41 @@ def _single_qubit_decomposition(qubit: 'cirq.Qid', u: np.ndarray) -> 'op_tree.Op
108
150
  A single operation from OP TREE of 3 operations (rz,ry,ZPowGate)
109
151
  """
110
152
  # Perform native ZYZ decomposition
111
- phi_0, phi_1, phi_2 = decompositions.deconstruct_single_qubit_matrix_into_angles(u)
153
+ phi_0, phi_1, phi_2 = np.array(
154
+ decompositions.deconstruct_single_qubit_matrix_into_angles(u)
155
+ ) % (2 * np.pi)
112
156
 
113
157
  # Determine global phase picked up
114
- phase = np.angle(u[0, 0] / (np.exp(-1j * (phi_0) / 2) * np.cos(phi_1 / 2)))
115
-
116
- # Append first two operations operations
117
- yield ops.rz(phi_0).on(qubit)
118
- yield ops.ry(phi_1).on(qubit)
119
-
120
- # Append third operation with global phase added
121
- yield ops.ZPowGate(exponent=phi_2 / np.pi, global_shift=phase / phi_2).on(qubit)
158
+ global_phase = np.angle(u[0, 0]) + phi_0 / 2 + phi_2 / 2
159
+ if np.abs(u[0, 0]) < 1e-9:
160
+ global_phase = np.angle(u[1, 0]) + phi_0 / 2 - phi_2 / 2
161
+
162
+ if np.abs(phi_2) > 1e-18:
163
+ # Append first two operations operations
164
+ yield ops.rz(phi_0).on(qubit)
165
+ yield ops.ry(phi_1).on(qubit)
166
+
167
+ # Append third operation with global phase added
168
+ yield ops.ZPowGate(exponent=phi_2 / np.pi, global_shift=global_phase / phi_2 - 0.5)(qubit)
169
+ elif np.abs(phi_1) > 1e-18:
170
+ # Just a Z -> Y rotation so we attach the global phase to the Y rotation.
171
+ if np.abs(phi_0) > 1e-18:
172
+ yield ops.rz(phi_0)(qubit)
173
+ yield ops.YPowGate(exponent=phi_1 / np.pi, global_shift=global_phase / phi_1 - 0.5)(qubit)
174
+ elif np.abs(phi_0) > 1e-18:
175
+ # Just an Rz with a potential global phase.
176
+ yield ops.ZPowGate(exponent=phi_0 / np.pi, global_shift=global_phase / phi_0 - 0.5)(qubit)
177
+ elif np.abs(global_phase) > 1e-18:
178
+ # Global Phase.
179
+ yield ops.global_phase_operation(np.exp(1j * global_phase))
180
+ else:
181
+ # Identity.
182
+ return
122
183
 
123
184
 
124
185
  def _msb_demuxer(
125
186
  demux_qubits: 'List[cirq.Qid]', u1: np.ndarray, u2: np.ndarray
126
- ) -> 'op_tree.OpTree':
187
+ ) -> Iterable['cirq.Operation']:
127
188
  """Demultiplexes a unitary matrix that is multiplexed in its most-significant-qubit.
128
189
 
129
190
  Decomposition structure:
@@ -146,8 +207,21 @@ def _msb_demuxer(
146
207
  Yields: Single operation from OP TREE of 2-qubit and 1-qubit operations
147
208
  """
148
209
  # Perform a diagonalization to find values
210
+ u1 = u1.astype(np.complex128)
211
+ u2 = u2.astype(np.complex128)
149
212
  u = u1 @ u2.T.conjugate()
150
- dsquared, V = np.linalg.eig(u)
213
+ if predicates.is_hermitian(u):
214
+ # If `u` is hermitian, use the more accurate `eigh` method.
215
+ dsquared, V = np.linalg.eigh(u)
216
+ else:
217
+ dsquared, V = np.linalg.eig(u)
218
+ # Use Gram–Schmidt to obtain orthonormal eigenvectors for each of the subspaces.
219
+ for i in range(V.shape[0]):
220
+ for j in range(i):
221
+ if np.abs(dsquared[i] - dsquared[j]) < 1e-9:
222
+ V[:, i] -= np.dot(V[:, j].conj(), V[:, i]) * V[:, j]
223
+ V[:, i] /= np.linalg.norm(V[:, i]) # normalize.
224
+ dsquared = dsquared.astype(np.complex128)
151
225
  d = np.sqrt(dsquared)
152
226
  D = np.diag(d)
153
227
  W = D @ V.T.conjugate() @ u2
@@ -155,7 +229,7 @@ def _msb_demuxer(
155
229
  # Last term is given by ( I ⊗ W ), demultiplexed
156
230
  # Remove most-significant (demuxed) control-qubit
157
231
  # Yield operations for QSD on W
158
- yield from quantum_shannon_decomposition(demux_qubits[1:], W)
232
+ yield from quantum_shannon_decomposition(demux_qubits[1:], W, atol=1e-6)
159
233
 
160
234
  # Use complex phase of d_i to give theta_i (so d_i* gives -theta_i)
161
235
  # Observe that middle part looks like Σ_i( Rz(theta_i)⊗|i><i| )
@@ -163,7 +237,7 @@ def _msb_demuxer(
163
237
  yield from _multiplexed_cossin(demux_qubits, -np.angle(d), ops.rz)
164
238
 
165
239
  # Yield operations for QSD on V
166
- yield from quantum_shannon_decomposition(demux_qubits[1:], V)
240
+ yield from quantum_shannon_decomposition(demux_qubits[1:], V, atol=1e-6)
167
241
 
168
242
 
169
243
  def _nth_gray(n: int) -> int:
@@ -173,7 +247,7 @@ def _nth_gray(n: int) -> int:
173
247
 
174
248
  def _multiplexed_cossin(
175
249
  cossin_qubits: 'List[cirq.Qid]', angles: List[float], rot_func: Callable = ops.ry
176
- ) -> 'op_tree.OpTree':
250
+ ) -> Iterable['cirq.Operation']:
177
251
  """Performs a multiplexed rotation over all qubits in this unitary matrix,
178
252
 
179
253
  Uses ry and rz multiplexing for quantum shannon decomposition
@@ -223,8 +297,9 @@ def _multiplexed_cossin(
223
297
  # so introduce max function
224
298
  select_qubit = max(-select_qubit - 1, -len(control_qubits))
225
299
 
226
- # Add a rotation on the main qubit
227
- yield rot_func(rotation).on(main_qubit)
300
+ if np.abs(rotation) > 1e-9:
301
+ # Add a rotation on the main qubit
302
+ yield rot_func(rotation).on(main_qubit)
228
303
 
229
304
  # Add a CNOT from the select qubit to the main qubit
230
305
  yield ops.CNOT(control_qubits[select_qubit], main_qubit)
@@ -12,21 +12,22 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ import numpy as np
16
+ import pytest
17
+ from scipy.stats import unitary_group
18
+
15
19
  import cirq
16
20
  from cirq.ops import common_gates
17
21
  from cirq.transformers.analytical_decompositions.quantum_shannon_decomposition import (
22
+ _msb_demuxer,
18
23
  _multiplexed_cossin,
19
24
  _nth_gray,
20
- _msb_demuxer,
21
25
  _single_qubit_decomposition,
22
26
  quantum_shannon_decomposition,
23
27
  )
24
28
 
25
- import pytest
26
- import numpy as np
27
- from scipy.stats import unitary_group
28
-
29
29
 
30
+ @pytest.mark.xfail(reason='#6765')
30
31
  @pytest.mark.parametrize('n_qubits', list(range(1, 8)))
31
32
  def test_random_qsd_n_qubit(n_qubits):
32
33
  U = unitary_group.rvs(2**n_qubits)
@@ -34,9 +35,8 @@ def test_random_qsd_n_qubit(n_qubits):
34
35
  circuit = cirq.Circuit(quantum_shannon_decomposition(qubits, U))
35
36
  # Test return is equal to inital unitary
36
37
  assert cirq.approx_eq(U, circuit.unitary(), atol=1e-9)
37
- # Test all operations in gate set
38
- gates = (common_gates.Rz, common_gates.Ry, common_gates.ZPowGate, common_gates.CXPowGate)
39
- assert all(isinstance(op.gate, gates) for op in circuit.all_operations())
38
+ # Test all operations have at most 2 qubits.
39
+ assert all(cirq.num_qubits(op) <= 2 for op in circuit.all_operations())
40
40
 
41
41
 
42
42
  def test_qsd_n_qubit_errors():
@@ -53,9 +53,8 @@ def test_random_single_qubit_decomposition():
53
53
  circuit = cirq.Circuit(_single_qubit_decomposition(qubit, U))
54
54
  # Test return is equal to inital unitary
55
55
  assert cirq.approx_eq(U, circuit.unitary(), atol=1e-9)
56
- # Test all operations in gate set
57
- gates = (common_gates.Rz, common_gates.Ry, common_gates.ZPowGate, common_gates.CXPowGate)
58
- assert all(isinstance(op.gate, gates) for op in circuit.all_operations())
56
+ # Test all operations have at most 2 qubits.
57
+ assert all(cirq.num_qubits(op) <= 2 for op in circuit.all_operations())
59
58
 
60
59
 
61
60
  def test_msb_demuxer():
@@ -66,9 +65,8 @@ def test_msb_demuxer():
66
65
  circuit = cirq.Circuit(_msb_demuxer(qubits, U1, U2))
67
66
  # Test return is equal to inital unitary
68
67
  assert cirq.approx_eq(U_full, circuit.unitary(), atol=1e-9)
69
- # Test all operations in gate set
70
- gates = (common_gates.Rz, common_gates.Ry, common_gates.ZPowGate, common_gates.CXPowGate)
71
- assert all(isinstance(op.gate, gates) for op in circuit.all_operations())
68
+ # Test all operations have at most 2 qubits.
69
+ assert all(cirq.num_qubits(op) <= 2 for op in circuit.all_operations())
72
70
 
73
71
 
74
72
  def test_multiplexed_cossin():
@@ -110,3 +108,96 @@ def test_multiplexed_cossin():
110
108
  )
111
109
  def test_nth_gray(n, gray):
112
110
  assert _nth_gray(n) == gray
111
+
112
+
113
+ def test_ghz_circuit_decomposes():
114
+ # Test case from #6725
115
+ ghz_circuit = cirq.Circuit(cirq.H(cirq.q(0)), cirq.CNOT(cirq.q(0), cirq.q(1)))
116
+ ghz_unitary = cirq.unitary(ghz_circuit)
117
+ decomposed_circuit = cirq.Circuit(
118
+ quantum_shannon_decomposition(cirq.LineQubit.range(2), ghz_unitary)
119
+ )
120
+ new_unitary = cirq.unitary(decomposed_circuit)
121
+ np.testing.assert_allclose(new_unitary, ghz_unitary, atol=1e-6)
122
+
123
+
124
+ def test_qft_decomposes():
125
+ # Test case from #6666
126
+ qs = cirq.LineQubit.range(4)
127
+ qft_circuit = cirq.Circuit(cirq.qft(*qs))
128
+ qft_unitary = cirq.unitary(qft_circuit)
129
+ decomposed_circuit = cirq.Circuit(quantum_shannon_decomposition(qs, qft_unitary))
130
+ new_unitary = cirq.unitary(decomposed_circuit)
131
+ np.testing.assert_allclose(new_unitary, qft_unitary, atol=1e-6)
132
+
133
+
134
+ # Cliffords test the different corner cases of the ZYZ decomposition.
135
+ @pytest.mark.parametrize(
136
+ ['gate', 'num_ops'],
137
+ [
138
+ (cirq.I, 0),
139
+ (cirq.X, 2), # rz & ry
140
+ (cirq.Y, 1), # ry
141
+ (cirq.Z, 1), # rz
142
+ (cirq.H, 2), # rz & ry
143
+ (cirq.S, 1), # rz & ry
144
+ ],
145
+ )
146
+ def test_cliffords(gate, num_ops):
147
+ desired_unitary = cirq.unitary(gate)
148
+ shannon_circuit = cirq.Circuit(quantum_shannon_decomposition((cirq.q(0),), desired_unitary))
149
+ new_unitary = cirq.unitary(shannon_circuit)
150
+ assert len([*shannon_circuit.all_operations()]) == num_ops
151
+ if num_ops:
152
+ np.testing.assert_allclose(new_unitary, desired_unitary)
153
+
154
+
155
+ @pytest.mark.parametrize('gate', [cirq.X, cirq.Y, cirq.Z, cirq.H, cirq.S])
156
+ def test_cliffords_with_global_phase(gate):
157
+ global_phase = np.exp(1j * np.random.choice(np.linspace(0.1, 2 * np.pi, 10)))
158
+ desired_unitary = cirq.unitary(gate) * global_phase
159
+ shannon_circuit = cirq.Circuit(quantum_shannon_decomposition((cirq.q(0),), desired_unitary))
160
+ new_unitary = cirq.unitary(shannon_circuit)
161
+ np.testing.assert_allclose(new_unitary, desired_unitary)
162
+
163
+
164
+ def test_global_phase():
165
+ global_phase = np.exp(1j * np.random.choice(np.linspace(0, 2 * np.pi, 10)))
166
+ shannon_circuit = cirq.Circuit(
167
+ quantum_shannon_decomposition((cirq.q(0),), np.eye(2) * global_phase)
168
+ )
169
+ new_unitary = cirq.unitary(shannon_circuit)
170
+ np.testing.assert_allclose(np.diag(new_unitary), global_phase)
171
+
172
+
173
+ @pytest.mark.parametrize('gate', [cirq.CZ, cirq.CNOT, cirq.XX, cirq.YY, cirq.ZZ])
174
+ def test_two_qubit_gate(gate):
175
+ global_phase = np.exp(1j * np.random.choice(np.linspace(0, 2 * np.pi, 10)))
176
+ desired_unitary = cirq.unitary(gate) * global_phase
177
+ shannon_circuit = cirq.Circuit(
178
+ quantum_shannon_decomposition(cirq.LineQubit.range(2), desired_unitary)
179
+ )
180
+ new_unitary = cirq.unitary(shannon_circuit)
181
+ np.testing.assert_allclose(new_unitary, desired_unitary, atol=1e-6)
182
+
183
+
184
+ @pytest.mark.parametrize('gate', [cirq.CCNOT, cirq.qft(*cirq.LineQubit.range(3))])
185
+ def test_three_qubit_gate(gate):
186
+ global_phase = np.exp(1j * np.random.choice(np.linspace(0, 2 * np.pi, 10)))
187
+ desired_unitary = cirq.unitary(gate) * global_phase
188
+ shannon_circuit = cirq.Circuit(
189
+ quantum_shannon_decomposition(cirq.LineQubit.range(3), desired_unitary)
190
+ )
191
+ new_unitary = cirq.unitary(shannon_circuit)
192
+ np.testing.assert_allclose(new_unitary, desired_unitary, atol=1e-6)
193
+
194
+
195
+ @pytest.mark.xfail(reason='#6765')
196
+ def test_qft5():
197
+ global_phase = np.exp(1j * np.random.choice(np.linspace(0, 2 * np.pi, 10)))
198
+ desired_unitary = cirq.unitary(cirq.qft(*cirq.LineQubit.range(5))) * global_phase
199
+ shannon_circuit = cirq.Circuit(
200
+ quantum_shannon_decomposition(cirq.LineQubit.range(5), desired_unitary)
201
+ )
202
+ new_unitary = cirq.unitary(shannon_circuit)
203
+ np.testing.assert_allclose(new_unitary, desired_unitary, atol=1e-6)
@@ -20,7 +20,7 @@ from typing import List, Optional, Tuple
20
20
  import numpy as np
21
21
  import sympy
22
22
 
23
- from cirq import ops, linalg, protocols
23
+ from cirq import linalg, ops, protocols
24
24
  from cirq.linalg.tolerance import near_zero_mod
25
25
 
26
26
 
@@ -14,10 +14,10 @@
14
14
 
15
15
  """Analytical decompositions for 2-qubit unitaries when one input qubit is in the |0> state."""
16
16
  from typing import List, TYPE_CHECKING
17
+
17
18
  import numpy as np
18
19
 
19
20
  from cirq import ops
20
-
21
21
  from cirq.transformers.analytical_decompositions import two_qubit_to_cz
22
22
 
23
23
  if TYPE_CHECKING:
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
  import numpy as np
15
15
  import pytest
16
+
16
17
  import cirq
17
18
 
18
19
  VALID_INITIAL_STATES = [
@@ -14,18 +14,17 @@
14
14
 
15
15
  """Utility methods for decomposing three-qubit unitaries."""
16
16
 
17
- from typing import Union, Tuple, Sequence, List, Optional
17
+ from typing import List, Optional, Sequence, Tuple, Union
18
18
 
19
19
  import numpy as np
20
20
 
21
21
  import cirq
22
- from cirq import ops
23
- from cirq import transformers as opt
22
+ from cirq import ops, transformers as opt
24
23
 
25
24
 
26
25
  def three_qubit_matrix_to_operations(
27
26
  q0: ops.Qid, q1: ops.Qid, q2: ops.Qid, u: np.ndarray, atol: float = 1e-8
28
- ) -> Sequence[ops.Operation]:
27
+ ) -> List[ops.Operation]:
29
28
  """Returns operations for a 3 qubit unitary.
30
29
 
31
30
  The algorithm is described in Shende et al.:
@@ -22,9 +22,9 @@ from scipy.linalg import block_diag
22
22
 
23
23
  import cirq
24
24
  from cirq.transformers.analytical_decompositions.three_qubit_decomposition import (
25
- _multiplexed_angles,
26
25
  _cs_to_ops,
27
26
  _middle_multiplexor_to_ops,
27
+ _multiplexed_angles,
28
28
  _two_qubit_multiplexor_to_ops,
29
29
  )
30
30
 
@@ -15,9 +15,10 @@
15
15
  """Utility methods for efficiently preparing two qubit states."""
16
16
 
17
17
  from typing import List, TYPE_CHECKING
18
+
18
19
  import numpy as np
19
20
 
20
- from cirq import ops, qis, circuits
21
+ from cirq import circuits, ops, qis
21
22
  from cirq.transformers.analytical_decompositions import single_qubit_decompositions
22
23
 
23
24
  if TYPE_CHECKING:
@@ -16,8 +16,9 @@
16
16
 
17
17
  import copy
18
18
 
19
- import pytest
20
19
  import numpy as np
20
+ import pytest
21
+
21
22
  import cirq
22
23
 
23
24
 
@@ -14,18 +14,17 @@
14
14
 
15
15
  """Utility methods for decomposing two-qubit unitaries into CZ gates."""
16
16
 
17
- from typing import Iterable, List, Sequence, Tuple, Optional, cast, TYPE_CHECKING
17
+ from typing import cast, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING
18
18
 
19
19
  import numpy as np
20
20
 
21
+ from cirq import circuits, linalg, ops, protocols
21
22
  from cirq.linalg import predicates
22
- from cirq.linalg.decompositions import num_cnots_required, extract_right_diag
23
-
24
- from cirq import ops, linalg, protocols, circuits
23
+ from cirq.linalg.decompositions import extract_right_diag, num_cnots_required
25
24
  from cirq.transformers.analytical_decompositions import single_qubit_decompositions
26
- from cirq.transformers.merge_single_qubit_gates import merge_single_qubit_gates_to_phased_x_and_z
27
- from cirq.transformers.eject_z import eject_z
28
25
  from cirq.transformers.eject_phased_paulis import eject_phased_paulis
26
+ from cirq.transformers.eject_z import eject_z
27
+ from cirq.transformers.merge_single_qubit_gates import merge_single_qubit_gates_to_phased_x_and_z
29
28
 
30
29
  if TYPE_CHECKING:
31
30
  import cirq
@@ -20,12 +20,12 @@ import pytest
20
20
 
21
21
  import cirq
22
22
  from cirq import value
23
+ from cirq.testing import random_two_qubit_circuit_with_czs
23
24
  from cirq.transformers.analytical_decompositions.two_qubit_to_cz import (
24
- _parity_interaction,
25
25
  _is_trivial_angle,
26
+ _parity_interaction,
26
27
  two_qubit_matrix_to_diagonal_and_cz_operations,
27
28
  )
28
- from cirq.testing import random_two_qubit_circuit_with_czs
29
29
 
30
30
 
31
31
  @pytest.mark.parametrize(
@@ -14,7 +14,7 @@
14
14
 
15
15
  """Utility methods for decomposing two-qubit unitaries into FSim gates."""
16
16
 
17
- from typing import Sequence, Union, List, Iterator, TYPE_CHECKING, Iterable, Optional
17
+ from typing import Iterable, Iterator, List, Optional, Sequence, TYPE_CHECKING, Union
18
18
 
19
19
  import numpy as np
20
20
 
@@ -22,13 +22,12 @@ import sympy
22
22
 
23
23
  import cirq
24
24
  from cirq.transformers.analytical_decompositions.two_qubit_to_fsim import (
25
+ _B,
25
26
  _decompose_two_qubit_interaction_into_two_b_gates,
26
27
  _decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops,
27
28
  _sticky_0_to_1,
28
- _B,
29
29
  )
30
30
 
31
-
32
31
  UNITARY_OBJS = [
33
32
  cirq.IdentityGate(2),
34
33
  cirq.XX**0.25,
@@ -19,11 +19,11 @@ Gate compilation methods implemented here are following the paper below:
19
19
  arXiv:1603.07678
20
20
  """
21
21
 
22
- from typing import Iterable, List, Optional, cast, Tuple, TYPE_CHECKING
22
+ from typing import cast, Iterable, List, Optional, Tuple, TYPE_CHECKING
23
23
 
24
24
  import numpy as np
25
25
 
26
- from cirq import ops, linalg, protocols
26
+ from cirq import linalg, ops, protocols
27
27
  from cirq.transformers.analytical_decompositions import single_qubit_decompositions, two_qubit_to_cz
28
28
 
29
29
  if TYPE_CHECKING:
@@ -25,7 +25,7 @@ from typing import Optional, Sequence, Tuple, TYPE_CHECKING
25
25
  import numpy as np
26
26
  import sympy
27
27
 
28
- from cirq import circuits, ops, linalg, protocols
28
+ from cirq import circuits, linalg, ops, protocols
29
29
  from cirq.transformers.analytical_decompositions import single_qubit_decompositions
30
30
  from cirq.transformers.merge_single_qubit_gates import merge_single_qubit_gates_to_phxz
31
31
 
@@ -426,7 +426,7 @@ def _single_qubit_matrices_with_sqrt_iswap(
426
426
  for can_decompose, decomposer in decomposers:
427
427
  if can_decompose(kak.interaction_coefficients, weyl_tol=atol / 10):
428
428
  return decomposer(kak, atol)
429
- assert False, 'The final can_decompose should always returns True'
429
+ assert False, 'The final can_decompose should always returns True' # pragma: no cover
430
430
 
431
431
 
432
432
  def _in_0_region(
@@ -13,11 +13,12 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import itertools
16
+
16
17
  import numpy as np
17
18
  import pytest
19
+ import sympy
18
20
 
19
21
  import cirq
20
- import sympy
21
22
 
22
23
 
23
24
  def random_unitary(seed):
@@ -15,6 +15,7 @@
15
15
  """Transformer pass that removes empty moments from a circuit."""
16
16
 
17
17
  from typing import Optional, TYPE_CHECKING
18
+
18
19
  from cirq.transformers import transformer_api, transformer_primitives
19
20
 
20
21
  if TYPE_CHECKING:
@@ -15,6 +15,7 @@
15
15
  """Transformer pass that removes operations with tiny effects."""
16
16
 
17
17
  from typing import Optional, TYPE_CHECKING
18
+
18
19
  from cirq import protocols
19
20
  from cirq.transformers import transformer_api, transformer_primitives
20
21