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
@@ -24,7 +24,6 @@ from typing import (
24
24
  Iterable,
25
25
  List,
26
26
  Optional,
27
- Set,
28
27
  Tuple,
29
28
  TYPE_CHECKING,
30
29
  TypeVar,
@@ -32,12 +31,12 @@ from typing import (
32
31
  )
33
32
 
34
33
  import matplotlib.pyplot as plt
34
+ import numpy as np
35
35
 
36
36
  # this is for older systems with matplotlib <3.2 otherwise 3d projections fail
37
37
  from mpl_toolkits import mplot3d
38
- import numpy as np
39
38
 
40
- from cirq import value, protocols
39
+ from cirq import protocols, value
41
40
  from cirq._compat import proper_repr
42
41
  from cirq._import import LazyLoader
43
42
  from cirq.linalg import combinators, diagonalize, predicates, transformations
@@ -106,29 +105,6 @@ def deconstruct_single_qubit_matrix_into_angles(mat: np.ndarray) -> Tuple[float,
106
105
  return right_phase + diagonal_phase, rotation * 2, bottom_phase
107
106
 
108
107
 
109
- def _group_similar(items: List[T], comparer: Callable[[T, T], bool]) -> List[List[T]]:
110
- """Combines similar items into groups.
111
-
112
- Args:
113
- items: The list of items to group.
114
- comparer: Determines if two items are similar.
115
-
116
- Returns:
117
- A list of groups of items.
118
- """
119
- groups: List[List[T]] = []
120
- used: Set[int] = set()
121
- for i in range(len(items)):
122
- if i not in used:
123
- group = [items[i]]
124
- for j in range(i + 1, len(items)):
125
- if j not in used and comparer(items[i], items[j]):
126
- used.add(j)
127
- group.append(items[j])
128
- groups.append(group)
129
- return groups
130
-
131
-
132
108
  def unitary_eig(
133
109
  matrix: np.ndarray, check_preconditions: bool = True, atol: float = 1e-8
134
110
  ) -> Tuple[np.ndarray, np.ndarray]:
@@ -175,7 +151,6 @@ def map_eigenvalues(
175
151
  Args:
176
152
  matrix: The matrix to modify with the function.
177
153
  func: The function to apply to the eigenvalues of the matrix.
178
- rtol: Relative threshold used when separating eigenspaces.
179
154
  atol: Absolute threshold used when separating eigenspaces.
180
155
 
181
156
  Returns:
@@ -191,15 +166,18 @@ def map_eigenvalues(
191
166
  return total
192
167
 
193
168
 
194
- def kron_factor_4x4_to_2x2s(matrix: np.ndarray) -> Tuple[complex, np.ndarray, np.ndarray]:
169
+ def kron_factor_4x4_to_2x2s(
170
+ matrix: np.ndarray, rtol=1e-5, atol=1e-8
171
+ ) -> Tuple[complex, np.ndarray, np.ndarray]:
195
172
  """Splits a 4x4 matrix U = kron(A, B) into A, B, and a global factor.
196
173
 
197
174
  Requires the matrix to be the kronecker product of two 2x2 unitaries.
198
175
  Requires the matrix to have a non-zero determinant.
199
- Giving an incorrect matrix will cause garbage output.
200
176
 
201
177
  Args:
202
178
  matrix: The 4x4 unitary matrix to factor.
179
+ rtol: Per-matrix-entry relative tolerance on equality.
180
+ atol: Per-matrix-entry absolute tolerance on equality.
203
181
 
204
182
  Returns:
205
183
  A scalar factor and a pair of 2x2 unit-determinant matrices. The
@@ -232,6 +210,9 @@ def kron_factor_4x4_to_2x2s(matrix: np.ndarray) -> Tuple[complex, np.ndarray, np
232
210
  f1 *= -1
233
211
  g = -g
234
212
 
213
+ if not np.allclose(matrix, g * np.kron(f1, f2), rtol=rtol, atol=atol):
214
+ raise ValueError("Invalid 4x4 kronecker product.")
215
+
235
216
  return g, f1, f2
236
217
 
237
218
 
@@ -266,7 +247,7 @@ def so4_to_magic_su2s(
266
247
  raise ValueError('mat must be 4x4 special orthogonal.')
267
248
 
268
249
  ab = combinators.dot(MAGIC, mat, MAGIC_CONJ_T)
269
- _, a, b = kron_factor_4x4_to_2x2s(ab)
250
+ _, a, b = kron_factor_4x4_to_2x2s(ab, rtol, atol)
270
251
 
271
252
  return a, b
272
253
 
@@ -283,13 +264,7 @@ class AxisAngleDecomposition:
283
264
  rotation axis, and g is the global phase.
284
265
  """
285
266
 
286
- def __init__(
287
- self,
288
- *,
289
- angle: float,
290
- axis: Tuple[float, float, float],
291
- global_phase: Union[int, float, complex],
292
- ):
267
+ def __init__(self, *, angle: float, axis: Tuple[float, float, float], global_phase: complex):
293
268
  if not np.isclose(np.linalg.norm(axis, 2), 1, atol=1e-8):
294
269
  raise ValueError('Axis vector must be normalized.')
295
270
  self.global_phase = complex(global_phase)
@@ -629,12 +604,12 @@ def scatter_plot_normalized_kak_interaction_coefficients(
629
604
  >>> plt.show()
630
605
  """
631
606
  show_plot = not ax
632
- if not ax:
607
+ if ax is None:
633
608
  fig = plt.figure()
634
609
  ax = cast(mplot3d.axes3d.Axes3D, fig.add_subplot(1, 1, 1, projection='3d'))
635
610
 
636
611
  def coord_transform(
637
- pts: Union[List[Tuple[int, int, int]], np.ndarray]
612
+ pts: Union[List[Tuple[int, int, int]], np.ndarray],
638
613
  ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
639
614
  if len(pts) == 0:
640
615
  return np.array([]), np.array([]), np.array([])
@@ -993,7 +968,7 @@ def _canonicalize_kak_vector(k_vec: np.ndarray, atol: float) -> np.ndarray:
993
968
  unitaries required to bring the KAK vector into canonical form.
994
969
 
995
970
  Args:
996
- k_vec: THe KAK vector to be canonicalized. This input may be vectorized,
971
+ k_vec: The KAK vector to be canonicalized. This input may be vectorized,
997
972
  with shape (...,3), where the final axis denotes the k_vector and
998
973
  all other axes are broadcast.
999
974
  atol: How close x2 must be to π/4 to guarantee z2 >= 0.
@@ -18,8 +18,8 @@ import numpy as np
18
18
  import pytest
19
19
 
20
20
  import cirq
21
- from cirq import value
22
- from cirq import unitary_eig
21
+ from cirq import unitary_eig, value
22
+ from cirq.linalg.decompositions import MAGIC, MAGIC_CONJ_T
23
23
 
24
24
  X = np.array([[0, 1], [1, 0]])
25
25
  Y = np.array([[0, -1j], [1j, 0]])
@@ -39,15 +39,8 @@ def assert_kronecker_factorization_within_tolerance(matrix, g, f1, f2):
39
39
  assert np.allclose(restored, matrix), "Can't factor kronecker product."
40
40
 
41
41
 
42
- def assert_kronecker_factorization_not_within_tolerance(matrix, g, f1, f2):
43
- restored = g * cirq.linalg.combinators.kron(f1, f2)
44
- assert np.any(np.isnan(restored) or not np.allclose(restored, matrix))
45
-
46
-
47
42
  def assert_magic_su2_within_tolerance(mat, a, b):
48
- M = cirq.linalg.decompositions.MAGIC
49
- MT = cirq.linalg.decompositions.MAGIC_CONJ_T
50
- recon = cirq.linalg.combinators.dot(MT, cirq.linalg.combinators.kron(a, b), M)
43
+ recon = cirq.linalg.combinators.dot(MAGIC_CONJ_T, cirq.linalg.combinators.kron(a, b), MAGIC)
51
44
  assert np.allclose(recon, mat), "Failed to decompose within tolerance."
52
45
 
53
46
 
@@ -149,14 +142,15 @@ def test_kron_factor_special_unitaries(f1, f2):
149
142
  assert_kronecker_factorization_within_tolerance(p, g, g1, g2)
150
143
 
151
144
 
152
- def test_kron_factor_fail():
153
- mat = cirq.kron_with_controls(cirq.CONTROL_TAG, X)
154
- g, f1, f2 = cirq.kron_factor_4x4_to_2x2s(mat)
155
- with pytest.raises(ValueError):
156
- assert_kronecker_factorization_not_within_tolerance(mat, g, f1, f2)
157
- mat = cirq.kron_factor_4x4_to_2x2s(np.diag([1, 1, 1, 1j]))
158
- with pytest.raises(ValueError):
159
- assert_kronecker_factorization_not_within_tolerance(mat, g, f1, f2)
145
+ def test_kron_factor_invalid_input():
146
+ mats = [
147
+ cirq.kron_with_controls(cirq.CONTROL_TAG, X),
148
+ np.array([[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 2, 3, 4]]),
149
+ np.diag([1, 1, 1, 1j]),
150
+ ]
151
+ for mat in mats:
152
+ with pytest.raises(ValueError, match="Invalid 4x4 kronecker product"):
153
+ cirq.kron_factor_4x4_to_2x2s(mat)
160
154
 
161
155
 
162
156
  def recompose_so4(a: np.ndarray, b: np.ndarray) -> np.ndarray:
@@ -165,8 +159,7 @@ def recompose_so4(a: np.ndarray, b: np.ndarray) -> np.ndarray:
165
159
  assert cirq.is_special_unitary(a)
166
160
  assert cirq.is_special_unitary(b)
167
161
 
168
- magic = np.array([[1, 0, 0, 1j], [0, 1j, 1, 0], [0, 1j, -1, 0], [1, 0, 0, -1j]]) * np.sqrt(0.5)
169
- result = np.real(cirq.dot(np.conj(magic.T), cirq.kron(a, b), magic))
162
+ result = np.real(cirq.dot(MAGIC_CONJ_T, cirq.kron(a, b), MAGIC))
170
163
  assert cirq.is_orthogonal(result)
171
164
  return result
172
165
 
@@ -656,7 +649,7 @@ def test_kak_vector_matches_vectorized():
656
649
  np.testing.assert_almost_equal(actual, expected)
657
650
 
658
651
 
659
- def test_KAK_vector_local_invariants_random_input():
652
+ def test_kak_vector_local_invariants_random_input():
660
653
  actual = _local_invariants_from_kak(cirq.kak_vector(_random_unitaries))
661
654
  expected = _local_invariants_from_kak(_kak_vecs)
662
655
 
@@ -697,7 +690,7 @@ def test_kak_vector_on_weyl_chamber_face():
697
690
  (np.kron(X, X), (0, 0, 0)),
698
691
  ),
699
692
  )
700
- def test_KAK_vector_weyl_chamber_vertices(unitary, expected):
693
+ def test_kak_vector_weyl_chamber_vertices(unitary, expected):
701
694
  actual = cirq.kak_vector(unitary)
702
695
  np.testing.assert_almost_equal(actual, expected)
703
696
 
@@ -741,6 +734,7 @@ def test_kak_decompose(unitary: np.ndarray):
741
734
  assert len(list(circuit.all_operations())) == 8
742
735
 
743
736
 
737
+ @cirq.testing.retry_once_with_later_random_values
744
738
  def test_num_two_qubit_gates_required():
745
739
  for i in range(4):
746
740
  assert (
@@ -14,7 +14,7 @@
14
14
 
15
15
  """Utility methods for diagonalizing matrices."""
16
16
 
17
- from typing import Tuple, Callable, List
17
+ from typing import Callable, List, Tuple
18
18
 
19
19
  import numpy as np
20
20
 
@@ -13,7 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import random
16
- from typing import Tuple, Optional
16
+ from typing import Optional, Tuple
17
17
 
18
18
  import numpy as np
19
19
  import pytest
@@ -13,13 +13,17 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Utilities for manipulating linear operators as elements of vector space."""
16
- from typing import Dict, Tuple
16
+ from typing import Dict, Tuple, TYPE_CHECKING
17
17
 
18
18
  import numpy as np
19
+ import sympy
19
20
 
20
21
  from cirq import value
21
22
  from cirq._doc import document
22
23
 
24
+ if TYPE_CHECKING:
25
+ import cirq
26
+
23
27
  PAULI_BASIS = {
24
28
  'I': np.eye(2),
25
29
  'X': np.array([[0.0, 1.0], [1.0, 0.0]]),
@@ -78,8 +82,17 @@ def matrix_from_basis_coefficients(
78
82
 
79
83
 
80
84
  def pow_pauli_combination(
81
- ai: value.Scalar, ax: value.Scalar, ay: value.Scalar, az: value.Scalar, exponent: int
82
- ) -> Tuple[value.Scalar, value.Scalar, value.Scalar, value.Scalar]:
85
+ ai: 'cirq.TParamValComplex',
86
+ ax: 'cirq.TParamValComplex',
87
+ ay: 'cirq.TParamValComplex',
88
+ az: 'cirq.TParamValComplex',
89
+ exponent: int,
90
+ ) -> Tuple[
91
+ 'cirq.TParamValComplex',
92
+ 'cirq.TParamValComplex',
93
+ 'cirq.TParamValComplex',
94
+ 'cirq.TParamValComplex',
95
+ ]:
83
96
  """Computes non-negative integer power of single-qubit Pauli combination.
84
97
 
85
98
  Returns scalar coefficients bi, bx, by, bz such that
@@ -96,7 +109,10 @@ def pow_pauli_combination(
96
109
  if exponent == 0:
97
110
  return 1, 0, 0, 0
98
111
 
99
- v = np.sqrt(ax * ax + ay * ay + az * az).item()
112
+ if any(isinstance(a, sympy.Basic) for a in [ax, ay, az]):
113
+ v = sympy.sqrt(ax * ax + ay * ay + az * az)
114
+ else:
115
+ v = np.sqrt(ax * ax + ay * ay + az * az).item()
100
116
  s = (ai + v) ** exponent
101
117
  t = (ai - v) ** exponent
102
118
 
@@ -17,6 +17,7 @@ import itertools
17
17
  import numpy as np
18
18
  import pytest
19
19
  import scipy.linalg
20
+ import sympy
20
21
 
21
22
  import cirq
22
23
 
@@ -287,11 +288,21 @@ def test_expand_is_inverse_of_reconstruct(m1, basis):
287
288
  (-1, -2, 3, 4),
288
289
  (1j, 2j, 3j, 4j),
289
290
  (1j, 2j, 3, 4),
291
+ (sympy.Symbol('i'), sympy.Symbol('x'), sympy.Symbol('y'), sympy.Symbol('z')),
292
+ (
293
+ sympy.Symbol('i') * 1j,
294
+ -sympy.Symbol('x'),
295
+ -sympy.Symbol('y') * 1j,
296
+ sympy.Symbol('z'),
297
+ ),
290
298
  ),
291
299
  (0, 1, 2, 3, 4, 5, 100, 101),
292
300
  ),
293
301
  )
294
302
  def test_pow_pauli_combination(coefficients, exponent):
303
+ is_symbolic = any(isinstance(a, sympy.Basic) for a in coefficients)
304
+ if is_symbolic and exponent > 2:
305
+ return # too slow
295
306
  i = cirq.PAULI_BASIS['I']
296
307
  x = cirq.PAULI_BASIS['X']
297
308
  y = cirq.PAULI_BASIS['Y']
@@ -303,5 +314,7 @@ def test_pow_pauli_combination(coefficients, exponent):
303
314
 
304
315
  bi, bx, by, bz = cirq.pow_pauli_combination(ai, ax, ay, az, exponent)
305
316
  result = bi * i + bx * x + by * y + bz * z
306
-
307
- assert np.allclose(result, expected_result)
317
+ if is_symbolic:
318
+ assert cirq.approx_eq(result, expected_result)
319
+ else:
320
+ assert np.allclose(result, expected_result)
cirq/linalg/predicates.py CHANGED
@@ -12,12 +12,12 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  """Utility methods for checking properties of matrices."""
15
- from typing import cast, List, Optional, Sequence, Union, Tuple
15
+ from typing import cast, List, Optional, Sequence, Tuple, Union
16
16
 
17
17
  import numpy as np
18
18
 
19
- from cirq.linalg import tolerance, transformations
20
19
  from cirq import value
20
+ from cirq.linalg import tolerance, transformations
21
21
 
22
22
 
23
23
  def is_diagonal(matrix: np.ndarray, *, atol: float = 1e-8) -> bool:
@@ -308,7 +308,7 @@ def slice_for_qubits_equal_to(
308
308
  else:
309
309
  if little_endian_qureg_value < 0 and not qid_shape_specified:
310
310
  # Allow negative binary numbers
311
- little_endian_qureg_value &= (1 << len(target_shape)) - 1
311
+ little_endian_qureg_value &= (1 << len(target_shape)) - 1 # pragma: no cover
312
312
  digits = value.big_endian_int_to_digits(little_endian_qureg_value, base=target_shape[::-1])[
313
313
  ::-1
314
314
  ]
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import cmath
16
+
16
17
  import numpy as np
17
18
  import pytest
18
19
 
cirq/linalg/tolerance.py CHANGED
@@ -14,7 +14,7 @@
14
14
 
15
15
  """Utility for testing approximate equality of matrices and scalars within
16
16
  tolerances."""
17
- from typing import Union, Iterable, TYPE_CHECKING
17
+ from typing import Iterable, TYPE_CHECKING, Union
18
18
 
19
19
  import numpy as np
20
20
 
@@ -33,7 +33,7 @@ def all_near_zero(a: 'ArrayLike', *, atol: float = 1e-8) -> bool:
33
33
 
34
34
 
35
35
  def all_near_zero_mod(
36
- a: Union[float, complex, Iterable[float], np.ndarray], period: float, *, atol: float = 1e-8
36
+ a: Union[float, Iterable[float], np.ndarray], period: float, *, atol: float = 1e-8
37
37
  ) -> bool:
38
38
  """Checks if the tensor's elements are all near multiples of the period.
39
39
 
@@ -15,6 +15,7 @@
15
15
  """Utility methods for transforming matrices or vectors."""
16
16
 
17
17
  import dataclasses
18
+ import functools
18
19
  from typing import Any, List, Optional, Sequence, Tuple, Union
19
20
 
20
21
  import numpy as np
@@ -29,8 +30,6 @@ from cirq.linalg import predicates
29
30
  # user provides a different np.array([]) value.
30
31
  RaiseValueErrorIfNotProvided: np.ndarray = np.array([])
31
32
 
32
- _NPY_MAXDIMS = 32 # Should be changed once numpy/numpy#5744 is resolved.
33
-
34
33
 
35
34
  def reflection_matrix_pow(reflection_matrix: np.ndarray, exponent: float):
36
35
  """Raises a matrix with two opposing eigenvalues to a power.
@@ -154,7 +153,6 @@ def targeted_left_multiply(
154
153
 
155
154
  all_indices = set(input_indices + data_indices + tuple(output_indices))
156
155
 
157
- # TODO(#5757): remove type ignore when numpy has proper override signature.
158
156
  return np.einsum(
159
157
  left_matrix,
160
158
  input_indices,
@@ -165,10 +163,8 @@ def targeted_left_multiply(
165
163
  # but this is a workaround for a bug in numpy:
166
164
  # https://github.com/numpy/numpy/issues/10926
167
165
  optimize=len(all_indices) >= 26,
168
- # And this is workaround for *another* bug!
169
- # Supposed to be able to just say 'old=old'.
170
- **({'out': out} if out is not None else {}),
171
- ) # type: ignore
166
+ out=out,
167
+ )
172
168
 
173
169
 
174
170
  @dataclasses.dataclass
@@ -407,13 +403,12 @@ def partial_trace(tensor: np.ndarray, keep_indices: Sequence[int]) -> np.ndarray
407
403
  if not all(i < ndim for i in keep_indices):
408
404
  raise ValueError(
409
405
  f'keep_indices were {keep_indices} but must be in first half, '
410
- f'i.e. have index less that {ndim}.'
406
+ f'i.e. have index less than {ndim}.'
411
407
  )
412
408
  keep_set = set(keep_indices)
413
409
  keep_map = dict(zip(keep_indices, sorted(keep_indices)))
414
410
  left_indices = [keep_map[i] if i in keep_set else i for i in range(ndim)]
415
411
  right_indices = [ndim + i if i in keep_set else i for i in left_indices]
416
- # TODO(#5757): remove type ignore when numpy has proper override signature.
417
412
  return np.einsum(tensor, left_indices + right_indices)
418
413
 
419
414
 
@@ -422,7 +417,7 @@ class EntangledStateError(ValueError):
422
417
 
423
418
 
424
419
  def partial_trace_of_state_vector_as_mixture(
425
- state_vector: np.ndarray, keep_indices: List[int], *, atol: Union[int, float] = 1e-8
420
+ state_vector: np.ndarray, keep_indices: List[int], *, atol: float = 1e-8
426
421
  ) -> Tuple[Tuple[float, np.ndarray], ...]:
427
422
  """Returns a mixture representing a state vector with only some qubits kept.
428
423
 
@@ -481,7 +476,7 @@ def sub_state_vector(
481
476
  keep_indices: List[int],
482
477
  *,
483
478
  default: np.ndarray = RaiseValueErrorIfNotProvided,
484
- atol: Union[int, float] = 1e-6,
479
+ atol: float = 1e-6,
485
480
  ) -> np.ndarray:
486
481
  r"""Attempts to factor a state vector into two parts and return one of them.
487
482
 
@@ -807,6 +802,29 @@ def transpose_flattened_array(t: np.ndarray, shape: Sequence[int], axes: Sequenc
807
802
  return ret
808
803
 
809
804
 
805
+ @functools.cache
806
+ def _can_numpy_support_dims(num_dims: int) -> bool:
807
+ try:
808
+ _ = np.empty((1,) * num_dims)
809
+ return True
810
+ except ValueError: # pragma: no cover
811
+ return False
812
+
813
+
810
814
  def can_numpy_support_shape(shape: Sequence[int]) -> bool:
811
815
  """Returns whether numpy supports the given shape or not numpy/numpy#5744."""
812
- return len(shape) <= _NPY_MAXDIMS
816
+ return min(shape, default=0) >= 0 and _can_numpy_support_dims(len(shape))
817
+
818
+
819
+ def phase_delta(u1: np.ndarray, u2: np.ndarray) -> complex:
820
+ """Calculates the phase delta of two unitaries.
821
+
822
+ The delta is from u1 to u2. i.e. u1 * phase_delta(u1, u2) == u2.
823
+
824
+ Assumes but does not verify that inputs are valid unitaries and differ only
825
+ by phase.
826
+ """
827
+ # All cells will have the same phase difference. Just choose the cell with the largest
828
+ # absolute value, to minimize rounding error.
829
+ max_index = np.unravel_index(np.abs(u1).argmax(), u1.shape)
830
+ return u2[max_index] / u1[max_index]
@@ -648,3 +648,16 @@ def test_transpose_flattened_array(num_dimensions):
648
648
  assert np.array_equal(want, got)
649
649
  got = linalg.transpose_flattened_array(A.reshape(shape), shape, axes).reshape(want.shape)
650
650
  assert np.array_equal(want, got)
651
+
652
+
653
+ @pytest.mark.parametrize('shape, result', [((), True), (30 * (1,), True), ((-3, 1, -1), False)])
654
+ def test_can_numpy_support_shape(shape: tuple[int, ...], result: bool) -> None:
655
+ assert linalg.can_numpy_support_shape(shape) is result
656
+
657
+
658
+ @pytest.mark.parametrize('coeff', [1, 1j, -1, -1j, 1j**0.5, 1j**0.3])
659
+ def test_phase_delta(coeff):
660
+ u1 = cirq.testing.random_unitary(4)
661
+ u2 = u1 * coeff
662
+ np.testing.assert_almost_equal(linalg.phase_delta(u1, u2), coeff)
663
+ np.testing.assert_almost_equal(u1 * linalg.phase_delta(u1, u2), u2)
@@ -15,6 +15,6 @@
15
15
  """Neutral atom devices and gates."""
16
16
 
17
17
  from cirq.neutral_atoms.convert_to_neutral_atom_gates import (
18
- is_native_neutral_atom_gate,
19
- is_native_neutral_atom_op,
18
+ is_native_neutral_atom_gate as is_native_neutral_atom_gate,
19
+ is_native_neutral_atom_op as is_native_neutral_atom_op,
20
20
  )
@@ -16,7 +16,6 @@ import pytest
16
16
 
17
17
  import cirq
18
18
 
19
-
20
19
  Q, Q2, Q3 = cirq.LineQubit.range(3)
21
20
 
22
21