cirq-core 1.5.0.dev20250409222543__py3-none-any.whl → 1.6.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 (732) hide show
  1. cirq/__init__.py +16 -17
  2. cirq/_compat.py +21 -20
  3. cirq/_compat_test.py +14 -34
  4. cirq/_doc.py +4 -2
  5. cirq/_import.py +8 -6
  6. cirq/_import_test.py +4 -2
  7. cirq/_version.py +6 -6
  8. cirq/_version_test.py +2 -2
  9. cirq/circuits/_block_diagram_drawer.py +11 -10
  10. cirq/circuits/_block_diagram_drawer_test.py +8 -6
  11. cirq/circuits/_box_drawing_character_data.py +8 -8
  12. cirq/circuits/_box_drawing_character_data_test.py +3 -1
  13. cirq/circuits/_bucket_priority_queue.py +9 -7
  14. cirq/circuits/_bucket_priority_queue_test.py +22 -20
  15. cirq/circuits/circuit.py +248 -172
  16. cirq/circuits/circuit_operation.py +73 -83
  17. cirq/circuits/circuit_operation_test.py +128 -90
  18. cirq/circuits/circuit_test.py +211 -151
  19. cirq/circuits/frozen_circuit.py +23 -60
  20. cirq/circuits/frozen_circuit_test.py +31 -8
  21. cirq/circuits/insert_strategy.py +7 -5
  22. cirq/circuits/insert_strategy_test.py +4 -2
  23. cirq/circuits/moment.py +88 -40
  24. cirq/circuits/moment_test.py +128 -51
  25. cirq/circuits/optimization_pass.py +5 -5
  26. cirq/circuits/optimization_pass_test.py +10 -10
  27. cirq/circuits/qasm_output.py +11 -11
  28. cirq/circuits/qasm_output_test.py +25 -22
  29. cirq/circuits/text_diagram_drawer.py +23 -38
  30. cirq/circuits/text_diagram_drawer_test.py +19 -17
  31. cirq/conftest.py +4 -3
  32. cirq/contrib/__init__.py +4 -4
  33. cirq/contrib/acquaintance/__init__.py +1 -1
  34. cirq/contrib/acquaintance/bipartite.py +5 -8
  35. cirq/contrib/acquaintance/bipartite_test.py +18 -13
  36. cirq/contrib/acquaintance/devices.py +2 -2
  37. cirq/contrib/acquaintance/devices_test.py +5 -3
  38. cirq/contrib/acquaintance/executor.py +5 -5
  39. cirq/contrib/acquaintance/executor_test.py +13 -9
  40. cirq/contrib/acquaintance/gates.py +18 -28
  41. cirq/contrib/acquaintance/gates_test.py +24 -20
  42. cirq/contrib/acquaintance/inspection_utils.py +8 -4
  43. cirq/contrib/acquaintance/inspection_utils_test.py +4 -2
  44. cirq/contrib/acquaintance/mutation_utils.py +4 -4
  45. cirq/contrib/acquaintance/mutation_utils_test.py +4 -2
  46. cirq/contrib/acquaintance/optimizers.py +4 -4
  47. cirq/contrib/acquaintance/optimizers_test.py +4 -1
  48. cirq/contrib/acquaintance/permutation.py +15 -27
  49. cirq/contrib/acquaintance/permutation_test.py +26 -17
  50. cirq/contrib/acquaintance/shift.py +4 -4
  51. cirq/contrib/acquaintance/shift_swap_network.py +4 -4
  52. cirq/contrib/acquaintance/shift_swap_network_test.py +9 -6
  53. cirq/contrib/acquaintance/shift_test.py +8 -6
  54. cirq/contrib/acquaintance/strategies/cubic.py +2 -2
  55. cirq/contrib/acquaintance/strategies/cubic_test.py +4 -2
  56. cirq/contrib/acquaintance/strategies/quartic_paired.py +6 -6
  57. cirq/contrib/acquaintance/strategies/quartic_paired_test.py +10 -6
  58. cirq/contrib/acquaintance/testing.py +2 -0
  59. cirq/contrib/acquaintance/topological_sort.py +2 -2
  60. cirq/contrib/acquaintance/topological_sort_test.py +3 -1
  61. cirq/contrib/bayesian_network/bayesian_network_gate.py +9 -10
  62. cirq/contrib/bayesian_network/bayesian_network_gate_test.py +14 -9
  63. cirq/contrib/circuitdag/circuit_dag.py +4 -4
  64. cirq/contrib/circuitdag/circuit_dag_test.py +17 -15
  65. cirq/contrib/custom_simulators/custom_state_simulator.py +5 -5
  66. cirq/contrib/custom_simulators/custom_state_simulator_test.py +22 -17
  67. cirq/contrib/graph_device/graph_device.py +12 -11
  68. cirq/contrib/graph_device/graph_device_test.py +18 -14
  69. cirq/contrib/graph_device/hypergraph.py +16 -14
  70. cirq/contrib/graph_device/hypergraph_test.py +13 -11
  71. cirq/contrib/graph_device/uniform_graph_device.py +6 -4
  72. cirq/contrib/graph_device/uniform_graph_device_test.py +11 -3
  73. cirq/contrib/hacks/disable_validation.py +6 -1
  74. cirq/contrib/hacks/disable_validation_test.py +3 -1
  75. cirq/contrib/json.py +31 -5
  76. cirq/contrib/json_test.py +6 -3
  77. cirq/contrib/json_test_data/DampedReadoutNoiseModel.json +12 -0
  78. cirq/contrib/json_test_data/DampedReadoutNoiseModel.repr +4 -0
  79. cirq/contrib/json_test_data/DepolarizingNoiseModel.json +12 -0
  80. cirq/contrib/json_test_data/DepolarizingNoiseModel.repr +4 -0
  81. cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.json +6 -0
  82. cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.repr +1 -0
  83. cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.json +5 -0
  84. cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.repr +1 -0
  85. cirq/contrib/json_test_data/ReadoutNoiseModel.json +12 -0
  86. cirq/contrib/json_test_data/ReadoutNoiseModel.repr +4 -0
  87. cirq/contrib/json_test_data/__init__.py +17 -0
  88. cirq/contrib/json_test_data/spec.py +32 -0
  89. cirq/contrib/noise_models/noise_models.py +119 -5
  90. cirq/contrib/noise_models/noise_models_test.py +37 -9
  91. cirq/contrib/paulistring/clifford_optimize.py +6 -4
  92. cirq/contrib/paulistring/clifford_optimize_test.py +6 -5
  93. cirq/contrib/paulistring/clifford_target_gateset.py +10 -10
  94. cirq/contrib/paulistring/clifford_target_gateset_test.py +13 -11
  95. cirq/contrib/paulistring/optimize.py +2 -0
  96. cirq/contrib/paulistring/optimize_test.py +4 -3
  97. cirq/contrib/paulistring/pauli_string_dag.py +2 -0
  98. cirq/contrib/paulistring/pauli_string_dag_test.py +3 -1
  99. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +255 -120
  100. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +398 -19
  101. cirq/contrib/paulistring/pauli_string_optimize.py +7 -1
  102. cirq/contrib/paulistring/pauli_string_optimize_test.py +5 -3
  103. cirq/contrib/paulistring/recombine.py +6 -4
  104. cirq/contrib/paulistring/recombine_test.py +3 -1
  105. cirq/contrib/paulistring/separate.py +9 -6
  106. cirq/contrib/paulistring/separate_test.py +3 -1
  107. cirq/contrib/qasm_import/_lexer.py +3 -2
  108. cirq/contrib/qasm_import/_lexer_test.py +49 -13
  109. cirq/contrib/qasm_import/_parser.py +547 -83
  110. cirq/contrib/qasm_import/_parser_test.py +988 -97
  111. cirq/contrib/qasm_import/exception.py +2 -0
  112. cirq/contrib/qasm_import/qasm.py +8 -2
  113. cirq/contrib/qasm_import/qasm_test.py +7 -4
  114. cirq/contrib/qcircuit/qcircuit_diagram_info.py +5 -5
  115. cirq/contrib/qcircuit/qcircuit_diagram_info_test.py +4 -1
  116. cirq/contrib/qcircuit/qcircuit_pdf.py +7 -3
  117. cirq/contrib/qcircuit/qcircuit_pdf_test.py +3 -1
  118. cirq/contrib/qcircuit/qcircuit_test.py +10 -8
  119. cirq/contrib/quantum_volume/quantum_volume.py +31 -27
  120. cirq/contrib/quantum_volume/quantum_volume_test.py +19 -16
  121. cirq/contrib/quimb/density_matrix.py +15 -14
  122. cirq/contrib/quimb/density_matrix_test.py +10 -7
  123. cirq/contrib/quimb/grid_circuits.py +5 -2
  124. cirq/contrib/quimb/grid_circuits_test.py +3 -0
  125. cirq/contrib/quimb/mps_simulator.py +20 -20
  126. cirq/contrib/quimb/mps_simulator_test.py +3 -0
  127. cirq/contrib/quimb/state_vector.py +12 -11
  128. cirq/contrib/quimb/state_vector_test.py +3 -0
  129. cirq/contrib/quirk/export_to_quirk.py +5 -3
  130. cirq/contrib/quirk/export_to_quirk_test.py +18 -16
  131. cirq/contrib/quirk/linearize_circuit.py +2 -0
  132. cirq/contrib/quirk/quirk_gate.py +18 -17
  133. cirq/contrib/routing/device.py +5 -3
  134. cirq/contrib/routing/device_test.py +2 -0
  135. cirq/contrib/routing/greedy.py +10 -21
  136. cirq/contrib/routing/greedy_test.py +4 -2
  137. cirq/contrib/routing/initialization.py +2 -2
  138. cirq/contrib/routing/initialization_test.py +5 -3
  139. cirq/contrib/routing/router.py +9 -5
  140. cirq/contrib/routing/router_test.py +2 -0
  141. cirq/contrib/routing/swap_network.py +3 -3
  142. cirq/contrib/routing/swap_network_test.py +3 -1
  143. cirq/contrib/routing/utils.py +2 -2
  144. cirq/contrib/routing/utils_test.py +3 -0
  145. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +15 -9
  146. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +3 -0
  147. cirq/contrib/svg/svg.py +3 -3
  148. cirq/contrib/svg/svg_test.py +8 -5
  149. cirq/devices/device.py +4 -4
  150. cirq/devices/device_test.py +7 -4
  151. cirq/devices/grid_device_metadata.py +10 -10
  152. cirq/devices/grid_device_metadata_test.py +3 -0
  153. cirq/devices/grid_qubit.py +29 -21
  154. cirq/devices/grid_qubit_test.py +3 -0
  155. cirq/devices/insertion_noise_model.py +7 -7
  156. cirq/devices/insertion_noise_model_test.py +7 -5
  157. cirq/devices/line_qubit.py +13 -13
  158. cirq/devices/line_qubit_test.py +2 -0
  159. cirq/devices/named_topologies.py +18 -29
  160. cirq/devices/named_topologies_test.py +13 -10
  161. cirq/devices/noise_model.py +3 -3
  162. cirq/devices/noise_model_test.py +19 -15
  163. cirq/devices/noise_properties.py +15 -6
  164. cirq/devices/noise_properties_test.py +34 -3
  165. cirq/devices/noise_utils.py +11 -9
  166. cirq/devices/noise_utils_test.py +2 -0
  167. cirq/devices/superconducting_qubits_noise_properties.py +23 -22
  168. cirq/devices/superconducting_qubits_noise_properties_test.py +6 -6
  169. cirq/devices/thermal_noise_model.py +107 -37
  170. cirq/devices/thermal_noise_model_test.py +21 -0
  171. cirq/devices/unconstrained_device.py +5 -3
  172. cirq/devices/unconstrained_device_test.py +2 -0
  173. cirq/experiments/__init__.py +4 -2
  174. cirq/experiments/benchmarking/__init__.py +17 -0
  175. cirq/experiments/benchmarking/parallel_xeb.py +677 -0
  176. cirq/experiments/benchmarking/parallel_xeb_test.py +447 -0
  177. cirq/experiments/fidelity_estimation.py +14 -8
  178. cirq/experiments/fidelity_estimation_test.py +3 -0
  179. cirq/experiments/n_qubit_tomography.py +17 -16
  180. cirq/experiments/n_qubit_tomography_test.py +8 -5
  181. cirq/experiments/purity_estimation.py +2 -0
  182. cirq/experiments/purity_estimation_test.py +2 -0
  183. cirq/experiments/qubit_characterizations.py +207 -103
  184. cirq/experiments/qubit_characterizations_test.py +40 -12
  185. cirq/experiments/random_quantum_circuit_generation.py +56 -70
  186. cirq/experiments/random_quantum_circuit_generation_test.py +11 -8
  187. cirq/experiments/readout_confusion_matrix.py +24 -22
  188. cirq/experiments/readout_confusion_matrix_test.py +2 -0
  189. cirq/experiments/single_qubit_readout_calibration.py +30 -15
  190. cirq/experiments/single_qubit_readout_calibration_test.py +5 -2
  191. cirq/experiments/t1_decay_experiment.py +9 -7
  192. cirq/experiments/t1_decay_experiment_test.py +13 -11
  193. cirq/experiments/t2_decay_experiment.py +16 -13
  194. cirq/experiments/t2_decay_experiment_test.py +2 -0
  195. cirq/experiments/two_qubit_xeb.py +64 -57
  196. cirq/experiments/two_qubit_xeb_test.py +10 -6
  197. cirq/experiments/xeb_fitting.py +39 -35
  198. cirq/experiments/xeb_sampling.py +37 -44
  199. cirq/experiments/xeb_sampling_test.py +3 -0
  200. cirq/experiments/xeb_simulation.py +14 -10
  201. cirq/experiments/xeb_simulation_test.py +5 -5
  202. cirq/experiments/z_phase_calibration.py +32 -29
  203. cirq/experiments/z_phase_calibration_test.py +3 -4
  204. cirq/interop/quirk/cells/__init__.py +1 -1
  205. cirq/interop/quirk/cells/all_cells.py +7 -2
  206. cirq/interop/quirk/cells/arithmetic_cells.py +29 -41
  207. cirq/interop/quirk/cells/arithmetic_cells_test.py +17 -14
  208. cirq/interop/quirk/cells/cell.py +19 -28
  209. cirq/interop/quirk/cells/cell_test.py +3 -0
  210. cirq/interop/quirk/cells/composite_cell.py +13 -28
  211. cirq/interop/quirk/cells/composite_cell_test.py +2 -0
  212. cirq/interop/quirk/cells/control_cells.py +15 -15
  213. cirq/interop/quirk/cells/control_cells_test.py +7 -5
  214. cirq/interop/quirk/cells/frequency_space_cells.py +4 -3
  215. cirq/interop/quirk/cells/frequency_space_cells_test.py +3 -1
  216. cirq/interop/quirk/cells/ignored_cells.py +3 -0
  217. cirq/interop/quirk/cells/ignored_cells_test.py +3 -1
  218. cirq/interop/quirk/cells/input_cells.py +7 -5
  219. cirq/interop/quirk/cells/input_cells_test.py +7 -5
  220. cirq/interop/quirk/cells/input_rotation_cells.py +15 -13
  221. cirq/interop/quirk/cells/input_rotation_cells_test.py +9 -7
  222. cirq/interop/quirk/cells/measurement_cells.py +5 -2
  223. cirq/interop/quirk/cells/measurement_cells_test.py +3 -1
  224. cirq/interop/quirk/cells/parse.py +22 -23
  225. cirq/interop/quirk/cells/parse_test.py +12 -10
  226. cirq/interop/quirk/cells/qubit_permutation_cells.py +5 -3
  227. cirq/interop/quirk/cells/qubit_permutation_cells_test.py +9 -7
  228. cirq/interop/quirk/cells/scalar_cells.py +4 -1
  229. cirq/interop/quirk/cells/scalar_cells_test.py +3 -1
  230. cirq/interop/quirk/cells/single_qubit_rotation_cells.py +5 -2
  231. cirq/interop/quirk/cells/single_qubit_rotation_cells_test.py +5 -3
  232. cirq/interop/quirk/cells/swap_cell.py +8 -6
  233. cirq/interop/quirk/cells/swap_cell_test.py +6 -4
  234. cirq/interop/quirk/cells/testing.py +6 -6
  235. cirq/interop/quirk/cells/testing_test.py +8 -6
  236. cirq/interop/quirk/cells/unsupported_cells.py +3 -0
  237. cirq/interop/quirk/cells/unsupported_cells_test.py +4 -2
  238. cirq/interop/quirk/url_to_circuit.py +23 -36
  239. cirq/interop/quirk/url_to_circuit_test.py +4 -1
  240. cirq/json_resolver_cache.py +14 -12
  241. cirq/linalg/__init__.py +4 -6
  242. cirq/linalg/combinators.py +7 -5
  243. cirq/linalg/combinators_test.py +10 -7
  244. cirq/linalg/decompositions.py +24 -35
  245. cirq/linalg/decompositions_test.py +3 -1
  246. cirq/linalg/diagonalize.py +6 -4
  247. cirq/linalg/diagonalize_test.py +15 -14
  248. cirq/linalg/operator_spaces.py +14 -14
  249. cirq/linalg/operator_spaces_test.py +13 -11
  250. cirq/linalg/predicates.py +18 -9
  251. cirq/linalg/predicates_test.py +5 -0
  252. cirq/linalg/tolerance.py +6 -3
  253. cirq/linalg/tolerance_test.py +6 -4
  254. cirq/linalg/transformations.py +23 -20
  255. cirq/linalg/transformations_test.py +73 -43
  256. cirq/neutral_atoms/convert_to_neutral_atom_gates.py +9 -3
  257. cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +3 -1
  258. cirq/neutral_atoms/neutral_atom_devices.py +2 -0
  259. cirq/ops/__init__.py +2 -0
  260. cirq/ops/arithmetic_operation.py +21 -21
  261. cirq/ops/arithmetic_operation_test.py +7 -8
  262. cirq/ops/boolean_hamiltonian.py +23 -22
  263. cirq/ops/boolean_hamiltonian_test.py +12 -9
  264. cirq/ops/classically_controlled_operation.py +31 -36
  265. cirq/ops/classically_controlled_operation_test.py +121 -117
  266. cirq/ops/clifford_gate.py +98 -81
  267. cirq/ops/clifford_gate_test.py +72 -57
  268. cirq/ops/common_channels.py +44 -44
  269. cirq/ops/common_channels_test.py +83 -81
  270. cirq/ops/common_gate_families.py +9 -7
  271. cirq/ops/common_gate_families_test.py +11 -7
  272. cirq/ops/common_gates.py +164 -183
  273. cirq/ops/common_gates_test.py +135 -95
  274. cirq/ops/control_values.py +23 -26
  275. cirq/ops/control_values_test.py +22 -20
  276. cirq/ops/controlled_gate.py +64 -112
  277. cirq/ops/controlled_gate_test.py +130 -35
  278. cirq/ops/controlled_operation.py +24 -35
  279. cirq/ops/controlled_operation_test.py +8 -6
  280. cirq/ops/dense_pauli_string.py +38 -49
  281. cirq/ops/dense_pauli_string_test.py +4 -2
  282. cirq/ops/diagonal_gate.py +18 -31
  283. cirq/ops/diagonal_gate_test.py +13 -13
  284. cirq/ops/eigen_gate.py +29 -29
  285. cirq/ops/eigen_gate_test.py +45 -28
  286. cirq/ops/fourier_transform.py +14 -20
  287. cirq/ops/fourier_transform_test.py +15 -12
  288. cirq/ops/fsim_gate.py +43 -42
  289. cirq/ops/fsim_gate_test.py +29 -29
  290. cirq/ops/gate_features.py +2 -0
  291. cirq/ops/gate_features_test.py +5 -3
  292. cirq/ops/gate_operation.py +43 -65
  293. cirq/ops/gate_operation_test.py +46 -42
  294. cirq/ops/gateset.py +28 -40
  295. cirq/ops/gateset_test.py +4 -2
  296. cirq/ops/global_phase_op.py +45 -20
  297. cirq/ops/global_phase_op_test.py +44 -20
  298. cirq/ops/greedy_qubit_manager.py +10 -8
  299. cirq/ops/greedy_qubit_manager_test.py +5 -3
  300. cirq/ops/identity.py +14 -12
  301. cirq/ops/identity_test.py +24 -20
  302. cirq/ops/kraus_channel.py +11 -8
  303. cirq/ops/kraus_channel_test.py +14 -11
  304. cirq/ops/linear_combinations.py +65 -77
  305. cirq/ops/linear_combinations_test.py +14 -9
  306. cirq/ops/matrix_gates.py +21 -18
  307. cirq/ops/matrix_gates_test.py +16 -0
  308. cirq/ops/measure_util.py +15 -20
  309. cirq/ops/measure_util_test.py +2 -0
  310. cirq/ops/measurement_gate.py +26 -37
  311. cirq/ops/measurement_gate_test.py +2 -0
  312. cirq/ops/mixed_unitary_channel.py +12 -9
  313. cirq/ops/mixed_unitary_channel_test.py +14 -11
  314. cirq/ops/named_qubit.py +16 -13
  315. cirq/ops/named_qubit_test.py +15 -13
  316. cirq/ops/op_tree.py +9 -7
  317. cirq/ops/op_tree_test.py +22 -19
  318. cirq/ops/parallel_gate.py +15 -17
  319. cirq/ops/parallel_gate_test.py +18 -16
  320. cirq/ops/parity_gates.py +23 -25
  321. cirq/ops/parity_gates_test.py +36 -32
  322. cirq/ops/pauli_gates.py +22 -21
  323. cirq/ops/pauli_gates_test.py +29 -20
  324. cirq/ops/pauli_interaction_gate.py +15 -19
  325. cirq/ops/pauli_interaction_gate_test.py +10 -8
  326. cirq/ops/pauli_measurement_gate.py +23 -35
  327. cirq/ops/pauli_measurement_gate_test.py +2 -0
  328. cirq/ops/pauli_string.py +92 -120
  329. cirq/ops/pauli_string_phasor.py +52 -45
  330. cirq/ops/pauli_string_phasor_test.py +4 -5
  331. cirq/ops/pauli_string_raw_types.py +9 -7
  332. cirq/ops/pauli_string_raw_types_test.py +2 -0
  333. cirq/ops/pauli_string_test.py +31 -154
  334. cirq/ops/pauli_sum_exponential.py +12 -12
  335. cirq/ops/pauli_sum_exponential_test.py +12 -10
  336. cirq/ops/permutation_gate.py +8 -6
  337. cirq/ops/permutation_gate_test.py +10 -8
  338. cirq/ops/phased_iswap_gate.py +16 -16
  339. cirq/ops/phased_iswap_gate_test.py +17 -15
  340. cirq/ops/phased_x_gate.py +16 -17
  341. cirq/ops/phased_x_gate_test.py +18 -16
  342. cirq/ops/phased_x_z_gate.py +24 -22
  343. cirq/ops/phased_x_z_gate_test.py +17 -11
  344. cirq/ops/projector.py +16 -11
  345. cirq/ops/projector_test.py +19 -16
  346. cirq/ops/qid_util.py +7 -5
  347. cirq/ops/qid_util_test.py +2 -0
  348. cirq/ops/qubit_manager.py +11 -9
  349. cirq/ops/qubit_manager_test.py +6 -4
  350. cirq/ops/qubit_order.py +11 -14
  351. cirq/ops/qubit_order_or_list.py +4 -2
  352. cirq/ops/qubit_order_test.py +12 -10
  353. cirq/ops/random_gate_channel.py +12 -10
  354. cirq/ops/random_gate_channel_test.py +14 -11
  355. cirq/ops/raw_types.py +109 -129
  356. cirq/ops/raw_types_test.py +63 -57
  357. cirq/ops/state_preparation_channel.py +7 -7
  358. cirq/ops/state_preparation_channel_test.py +11 -9
  359. cirq/ops/swap_gates.py +13 -15
  360. cirq/ops/swap_gates_test.py +19 -17
  361. cirq/ops/tags.py +5 -3
  362. cirq/ops/tags_test.py +4 -2
  363. cirq/ops/three_qubit_gates.py +43 -76
  364. cirq/ops/three_qubit_gates_test.py +19 -17
  365. cirq/ops/two_qubit_diagonal_gate.py +13 -13
  366. cirq/ops/two_qubit_diagonal_gate_test.py +10 -8
  367. cirq/ops/uniform_superposition_gate.py +5 -3
  368. cirq/ops/uniform_superposition_gate_test.py +5 -3
  369. cirq/ops/wait_gate.py +17 -14
  370. cirq/ops/wait_gate_test.py +9 -6
  371. cirq/protocols/__init__.py +0 -3
  372. cirq/protocols/act_on_protocol.py +8 -6
  373. cirq/protocols/act_on_protocol_test.py +15 -12
  374. cirq/protocols/apply_channel_protocol.py +10 -14
  375. cirq/protocols/apply_channel_protocol_test.py +2 -0
  376. cirq/protocols/apply_mixture_protocol.py +13 -42
  377. cirq/protocols/apply_mixture_protocol_test.py +7 -5
  378. cirq/protocols/apply_unitary_protocol.py +39 -34
  379. cirq/protocols/apply_unitary_protocol_test.py +4 -1
  380. cirq/protocols/approximate_equality_protocol.py +2 -0
  381. cirq/protocols/approximate_equality_protocol_test.py +2 -0
  382. cirq/protocols/circuit_diagram_info_protocol.py +58 -42
  383. cirq/protocols/circuit_diagram_info_protocol_test.py +70 -12
  384. cirq/protocols/commutes_protocol.py +8 -7
  385. cirq/protocols/commutes_protocol_test.py +2 -0
  386. cirq/protocols/control_key_protocol.py +6 -4
  387. cirq/protocols/control_key_protocol_test.py +3 -1
  388. cirq/protocols/decompose_protocol.py +49 -48
  389. cirq/protocols/decompose_protocol_test.py +27 -16
  390. cirq/protocols/equal_up_to_global_phase_protocol.py +2 -0
  391. cirq/protocols/equal_up_to_global_phase_protocol_test.py +9 -6
  392. cirq/protocols/has_stabilizer_effect_protocol.py +7 -5
  393. cirq/protocols/has_stabilizer_effect_protocol_test.py +7 -5
  394. cirq/protocols/has_unitary_protocol.py +10 -6
  395. cirq/protocols/has_unitary_protocol_test.py +13 -8
  396. cirq/protocols/hash_from_pickle_test.py +2 -11
  397. cirq/protocols/inverse_protocol.py +13 -16
  398. cirq/protocols/inverse_protocol_test.py +5 -3
  399. cirq/protocols/json_serialization.py +35 -54
  400. cirq/protocols/json_serialization_test.py +14 -21
  401. cirq/protocols/json_test_data/CXSWAP.json +46 -0
  402. cirq/protocols/json_test_data/CXSWAP.repr +13 -0
  403. cirq/protocols/json_test_data/CZSWAP.json +46 -0
  404. cirq/protocols/json_test_data/CZSWAP.repr +13 -0
  405. cirq/protocols/json_test_data/CircuitOperation.json +6 -3
  406. cirq/protocols/json_test_data/CircuitOperation.repr_inward +4 -2
  407. cirq/protocols/json_test_data/Moment.json +24 -1
  408. cirq/protocols/json_test_data/Moment.repr +6 -1
  409. cirq/protocols/json_test_data/ThermalNoiseModel.json +32 -0
  410. cirq/protocols/json_test_data/ThermalNoiseModel.repr +1 -0
  411. cirq/protocols/json_test_data/spec.py +6 -2
  412. cirq/protocols/kraus_protocol.py +47 -7
  413. cirq/protocols/kraus_protocol_test.py +86 -12
  414. cirq/protocols/measurement_key_protocol.py +15 -16
  415. cirq/protocols/measurement_key_protocol_test.py +13 -11
  416. cirq/protocols/mixture_protocol.py +7 -5
  417. cirq/protocols/mixture_protocol_test.py +4 -2
  418. cirq/protocols/mul_protocol.py +2 -3
  419. cirq/protocols/mul_protocol_test.py +2 -0
  420. cirq/protocols/pauli_expansion_protocol.py +6 -3
  421. cirq/protocols/pauli_expansion_protocol_test.py +5 -3
  422. cirq/protocols/phase_protocol.py +2 -0
  423. cirq/protocols/phase_protocol_test.py +3 -1
  424. cirq/protocols/pow_protocol.py +11 -16
  425. cirq/protocols/pow_protocol_test.py +2 -0
  426. cirq/protocols/qasm.py +14 -20
  427. cirq/protocols/qasm_test.py +6 -3
  428. cirq/protocols/qid_shape_protocol.py +8 -8
  429. cirq/protocols/qid_shape_protocol_test.py +3 -1
  430. cirq/protocols/resolve_parameters.py +5 -3
  431. cirq/protocols/resolve_parameters_test.py +8 -7
  432. cirq/protocols/trace_distance_bound.py +6 -4
  433. cirq/protocols/trace_distance_bound_test.py +3 -1
  434. cirq/protocols/unitary_protocol.py +17 -7
  435. cirq/protocols/unitary_protocol_test.py +12 -2
  436. cirq/qis/channels.py +6 -2
  437. cirq/qis/channels_test.py +20 -16
  438. cirq/qis/clifford_tableau.py +21 -19
  439. cirq/qis/clifford_tableau_test.py +2 -2
  440. cirq/qis/entropy.py +14 -3
  441. cirq/qis/entropy_test.py +3 -1
  442. cirq/qis/measures.py +13 -13
  443. cirq/qis/measures_test.py +20 -14
  444. cirq/qis/noise_utils.py +2 -0
  445. cirq/qis/noise_utils_test.py +9 -7
  446. cirq/qis/quantum_state_representation.py +7 -8
  447. cirq/qis/states.py +58 -56
  448. cirq/qis/states_test.py +2 -0
  449. cirq/sim/classical_simulator.py +23 -22
  450. cirq/sim/classical_simulator_test.py +2 -0
  451. cirq/sim/clifford/clifford_simulator.py +23 -21
  452. cirq/sim/clifford/clifford_simulator_test.py +7 -4
  453. cirq/sim/clifford/clifford_tableau_simulation_state.py +10 -7
  454. cirq/sim/clifford/clifford_tableau_simulation_state_test.py +5 -5
  455. cirq/sim/clifford/stabilizer_ch_form_simulation_state.py +8 -6
  456. cirq/sim/clifford/stabilizer_ch_form_simulation_state_test.py +8 -6
  457. cirq/sim/clifford/stabilizer_sampler.py +9 -7
  458. cirq/sim/clifford/stabilizer_sampler_test.py +4 -2
  459. cirq/sim/clifford/stabilizer_simulation_state.py +14 -13
  460. cirq/sim/clifford/stabilizer_simulation_state_test.py +6 -4
  461. cirq/sim/clifford/stabilizer_state_ch_form.py +13 -11
  462. cirq/sim/clifford/stabilizer_state_ch_form_test.py +4 -2
  463. cirq/sim/density_matrix_simulation_state.py +26 -27
  464. cirq/sim/density_matrix_simulation_state_test.py +10 -8
  465. cirq/sim/density_matrix_simulator.py +30 -28
  466. cirq/sim/density_matrix_simulator_test.py +48 -48
  467. cirq/sim/density_matrix_utils.py +13 -11
  468. cirq/sim/density_matrix_utils_test.py +38 -36
  469. cirq/sim/mux.py +33 -31
  470. cirq/sim/mux_test.py +3 -0
  471. cirq/sim/simulation_product_state.py +15 -15
  472. cirq/sim/simulation_product_state_test.py +29 -26
  473. cirq/sim/simulation_state.py +29 -38
  474. cirq/sim/simulation_state_base.py +21 -32
  475. cirq/sim/simulation_state_test.py +15 -13
  476. cirq/sim/simulation_utils.py +5 -2
  477. cirq/sim/simulation_utils_test.py +5 -2
  478. cirq/sim/simulator.py +90 -106
  479. cirq/sim/simulator_base.py +33 -45
  480. cirq/sim/simulator_base_test.py +20 -15
  481. cirq/sim/simulator_test.py +23 -14
  482. cirq/sim/sparse_simulator.py +19 -17
  483. cirq/sim/sparse_simulator_test.py +41 -40
  484. cirq/sim/state_vector.py +15 -12
  485. cirq/sim/state_vector_simulation_state.py +31 -31
  486. cirq/sim/state_vector_simulation_state_test.py +16 -14
  487. cirq/sim/state_vector_simulator.py +17 -14
  488. cirq/sim/state_vector_simulator_test.py +2 -0
  489. cirq/sim/state_vector_test.py +6 -3
  490. cirq/study/flatten_expressions.py +16 -15
  491. cirq/study/flatten_expressions_test.py +13 -11
  492. cirq/study/resolver.py +18 -17
  493. cirq/study/resolver_test.py +22 -20
  494. cirq/study/result.py +17 -27
  495. cirq/study/result_test.py +2 -0
  496. cirq/study/sweepable.py +12 -10
  497. cirq/study/sweepable_test.py +3 -0
  498. cirq/study/sweeps.py +42 -61
  499. cirq/study/sweeps_test.py +33 -0
  500. cirq/testing/__init__.py +7 -11
  501. cirq/testing/_compat_test_data/module_a/__init__.py +1 -0
  502. cirq/testing/_compat_test_data/module_a/module_b/__init__.py +1 -0
  503. cirq/testing/_compat_test_data/module_a/sub/__init__.py +1 -0
  504. cirq/testing/circuit_compare.py +8 -17
  505. cirq/testing/circuit_compare_test.py +2 -0
  506. cirq/testing/consistent_act_on.py +13 -11
  507. cirq/testing/consistent_act_on_test.py +5 -3
  508. cirq/testing/consistent_channels.py +2 -0
  509. cirq/testing/consistent_channels_test.py +10 -8
  510. cirq/testing/consistent_controlled_gate_op.py +5 -5
  511. cirq/testing/consistent_controlled_gate_op_test.py +18 -18
  512. cirq/testing/consistent_decomposition.py +2 -2
  513. cirq/testing/consistent_decomposition_test.py +4 -2
  514. cirq/testing/consistent_pauli_expansion.py +2 -0
  515. cirq/testing/consistent_pauli_expansion_test.py +3 -1
  516. cirq/testing/consistent_phase_by.py +2 -0
  517. cirq/testing/consistent_phase_by_test.py +3 -1
  518. cirq/testing/consistent_protocols.py +14 -20
  519. cirq/testing/consistent_protocols_test.py +13 -11
  520. cirq/testing/consistent_qasm.py +6 -4
  521. cirq/testing/consistent_qasm_test.py +7 -7
  522. cirq/testing/consistent_resolve_parameters.py +2 -0
  523. cirq/testing/consistent_specified_has_unitary.py +2 -2
  524. cirq/testing/consistent_specified_has_unitary_test.py +6 -4
  525. cirq/testing/consistent_unitary.py +1 -0
  526. cirq/testing/consistent_unitary_test.py +4 -2
  527. cirq/testing/deprecation.py +5 -2
  528. cirq/testing/deprecation_test.py +5 -2
  529. cirq/testing/devices.py +7 -4
  530. cirq/testing/devices_test.py +7 -4
  531. cirq/testing/equals_tester.py +4 -2
  532. cirq/testing/equals_tester_test.py +21 -17
  533. cirq/testing/equivalent_basis_map.py +6 -4
  534. cirq/testing/equivalent_basis_map_test.py +6 -4
  535. cirq/testing/equivalent_repr_eval.py +6 -4
  536. cirq/testing/equivalent_repr_eval_test.py +5 -3
  537. cirq/testing/gate_features.py +2 -0
  538. cirq/testing/gate_features_test.py +7 -5
  539. cirq/testing/json.py +19 -15
  540. cirq/testing/json_test.py +5 -3
  541. cirq/testing/lin_alg_utils.py +10 -11
  542. cirq/testing/lin_alg_utils_test.py +14 -12
  543. cirq/testing/logs.py +7 -6
  544. cirq/testing/logs_test.py +9 -7
  545. cirq/testing/no_identifier_qubit.py +4 -2
  546. cirq/testing/no_identifier_qubit_test.py +5 -3
  547. cirq/testing/op_tree.py +2 -0
  548. cirq/testing/op_tree_test.py +4 -1
  549. cirq/testing/order_tester.py +2 -0
  550. cirq/testing/order_tester_test.py +8 -6
  551. cirq/testing/pytest_utils.py +2 -0
  552. cirq/testing/pytest_utils_test.py +4 -2
  553. cirq/testing/random_circuit.py +21 -20
  554. cirq/testing/random_circuit_test.py +12 -9
  555. cirq/testing/repr_pretty_tester.py +1 -0
  556. cirq/testing/repr_pretty_tester_test.py +5 -3
  557. cirq/testing/routing_devices.py +4 -1
  558. cirq/testing/routing_devices_test.py +9 -6
  559. cirq/testing/sample_circuits.py +4 -1
  560. cirq/testing/sample_circuits_test.py +3 -1
  561. cirq/testing/sample_gates.py +3 -0
  562. cirq/testing/sample_gates_test.py +5 -2
  563. cirq/transformers/__init__.py +11 -4
  564. cirq/transformers/align.py +9 -7
  565. cirq/transformers/align_test.py +2 -0
  566. cirq/transformers/analytical_decompositions/__init__.py +3 -6
  567. cirq/transformers/analytical_decompositions/clifford_decomposition.py +18 -16
  568. cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +2 -0
  569. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +19 -16
  570. cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
  571. cirq/transformers/analytical_decompositions/cphase_to_fsim.py +11 -9
  572. cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +5 -3
  573. cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +5 -3
  574. cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +5 -3
  575. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +141 -44
  576. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +35 -1
  577. cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +8 -7
  578. cirq/transformers/analytical_decompositions/single_qubit_decompositions_test.py +2 -0
  579. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +7 -4
  580. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +3 -0
  581. cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +11 -19
  582. cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +8 -33
  583. cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +9 -11
  584. cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -0
  585. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +91 -27
  586. cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +36 -7
  587. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +20 -21
  588. cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +8 -6
  589. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +13 -15
  590. cirq/transformers/analytical_decompositions/two_qubit_to_ms_test.py +3 -1
  591. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +39 -41
  592. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -0
  593. cirq/transformers/drop_empty_moments.py +5 -3
  594. cirq/transformers/drop_empty_moments_test.py +4 -2
  595. cirq/transformers/drop_negligible_operations.py +7 -5
  596. cirq/transformers/drop_negligible_operations_test.py +2 -0
  597. cirq/transformers/dynamical_decoupling.py +49 -42
  598. cirq/transformers/dynamical_decoupling_test.py +223 -205
  599. cirq/transformers/eject_phased_paulis.py +28 -26
  600. cirq/transformers/eject_phased_paulis_test.py +12 -9
  601. cirq/transformers/eject_z.py +12 -12
  602. cirq/transformers/eject_z_test.py +2 -2
  603. cirq/transformers/expand_composite.py +6 -4
  604. cirq/transformers/expand_composite_test.py +3 -1
  605. cirq/transformers/gauge_compiling/__init__.py +3 -1
  606. cirq/transformers/gauge_compiling/cphase_gauge.py +2 -0
  607. cirq/transformers/gauge_compiling/cphase_gauge_test.py +2 -0
  608. cirq/transformers/gauge_compiling/cz_gauge.py +2 -0
  609. cirq/transformers/gauge_compiling/cz_gauge_test.py +1 -0
  610. cirq/transformers/gauge_compiling/gauge_compiling.py +45 -41
  611. cirq/transformers/gauge_compiling/gauge_compiling_test.py +2 -0
  612. cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +1 -0
  613. cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +5 -1
  614. cirq/transformers/gauge_compiling/iswap_gauge.py +2 -0
  615. cirq/transformers/gauge_compiling/iswap_gauge_test.py +1 -0
  616. cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -0
  617. cirq/transformers/gauge_compiling/spin_inversion_gauge_test.py +2 -0
  618. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +7 -6
  619. cirq/transformers/gauge_compiling/sqrt_cz_gauge_test.py +2 -0
  620. cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +2 -0
  621. cirq/transformers/gauge_compiling/sqrt_iswap_gauge_test.py +2 -0
  622. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +6 -3
  623. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +3 -0
  624. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +12 -9
  625. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +9 -7
  626. cirq/transformers/insertion_sort.py +8 -6
  627. cirq/transformers/insertion_sort_test.py +3 -1
  628. cirq/transformers/measurement_transformers.py +29 -29
  629. cirq/transformers/measurement_transformers_test.py +2 -0
  630. cirq/transformers/merge_k_qubit_gates.py +12 -10
  631. cirq/transformers/merge_k_qubit_gates_test.py +18 -18
  632. cirq/transformers/merge_single_qubit_gates.py +197 -20
  633. cirq/transformers/merge_single_qubit_gates_test.py +177 -5
  634. cirq/transformers/noise_adding.py +5 -3
  635. cirq/transformers/noise_adding_test.py +2 -0
  636. cirq/transformers/optimize_for_target_gateset.py +19 -17
  637. cirq/transformers/optimize_for_target_gateset_test.py +11 -8
  638. cirq/transformers/qubit_management_transformers.py +13 -11
  639. cirq/transformers/qubit_management_transformers_test.py +5 -3
  640. cirq/transformers/randomized_measurements.py +16 -14
  641. cirq/transformers/randomized_measurements_test.py +10 -4
  642. cirq/transformers/routing/initial_mapper.py +6 -4
  643. cirq/transformers/routing/initial_mapper_test.py +2 -0
  644. cirq/transformers/routing/line_initial_mapper.py +16 -14
  645. cirq/transformers/routing/line_initial_mapper_test.py +9 -7
  646. cirq/transformers/routing/mapping_manager.py +10 -10
  647. cirq/transformers/routing/mapping_manager_test.py +2 -0
  648. cirq/transformers/routing/route_circuit_cqc.py +33 -31
  649. cirq/transformers/routing/route_circuit_cqc_test.py +15 -13
  650. cirq/transformers/routing/visualize_routed_circuit.py +8 -7
  651. cirq/transformers/routing/visualize_routed_circuit_test.py +4 -2
  652. cirq/transformers/stratify.py +17 -15
  653. cirq/transformers/stratify_test.py +3 -0
  654. cirq/transformers/symbolize.py +103 -0
  655. cirq/transformers/symbolize_test.py +62 -0
  656. cirq/transformers/synchronize_terminal_measurements.py +10 -10
  657. cirq/transformers/synchronize_terminal_measurements_test.py +12 -10
  658. cirq/transformers/tag_transformers.py +97 -0
  659. cirq/transformers/tag_transformers_test.py +103 -0
  660. cirq/transformers/target_gatesets/compilation_target_gateset.py +21 -19
  661. cirq/transformers/target_gatesets/compilation_target_gateset_test.py +20 -16
  662. cirq/transformers/target_gatesets/cz_gateset.py +7 -5
  663. cirq/transformers/target_gatesets/cz_gateset_test.py +21 -19
  664. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +9 -7
  665. cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +25 -25
  666. cirq/transformers/transformer_api.py +34 -47
  667. cirq/transformers/transformer_api_test.py +9 -8
  668. cirq/transformers/transformer_primitives.py +39 -49
  669. cirq/transformers/transformer_primitives_test.py +10 -17
  670. cirq/value/abc_alt.py +6 -4
  671. cirq/value/abc_alt_test.py +5 -3
  672. cirq/value/angle.py +11 -12
  673. cirq/value/angle_test.py +5 -3
  674. cirq/value/classical_data.py +27 -27
  675. cirq/value/classical_data_test.py +11 -8
  676. cirq/value/condition.py +26 -24
  677. cirq/value/condition_test.py +2 -0
  678. cirq/value/digits.py +14 -11
  679. cirq/value/digits_test.py +2 -0
  680. cirq/value/duration.py +23 -20
  681. cirq/value/duration_test.py +2 -0
  682. cirq/value/linear_dict.py +25 -30
  683. cirq/value/linear_dict_test.py +10 -8
  684. cirq/value/measurement_key.py +12 -12
  685. cirq/value/measurement_key_test.py +2 -0
  686. cirq/value/periodic_value.py +4 -4
  687. cirq/value/periodic_value_test.py +11 -7
  688. cirq/value/probability.py +3 -1
  689. cirq/value/probability_test.py +4 -2
  690. cirq/value/product_state.py +15 -13
  691. cirq/value/product_state_test.py +4 -1
  692. cirq/value/random_state.py +2 -0
  693. cirq/value/random_state_test.py +5 -3
  694. cirq/value/timestamp.py +11 -7
  695. cirq/value/timestamp_test.py +14 -12
  696. cirq/value/type_alias.py +4 -4
  697. cirq/value/value_equality_attr.py +8 -9
  698. cirq/value/value_equality_attr_test.py +14 -11
  699. cirq/vis/density_matrix.py +3 -3
  700. cirq/vis/density_matrix_test.py +20 -17
  701. cirq/vis/heatmap.py +24 -37
  702. cirq/vis/heatmap_test.py +3 -0
  703. cirq/vis/histogram.py +9 -6
  704. cirq/vis/histogram_test.py +5 -2
  705. cirq/vis/state_histogram.py +10 -8
  706. cirq/vis/state_histogram_test.py +7 -5
  707. cirq/vis/vis_utils.py +4 -1
  708. cirq/vis/vis_utils_test.py +4 -1
  709. cirq/work/collector.py +12 -18
  710. cirq/work/collector_test.py +15 -10
  711. cirq/work/observable_grouping.py +6 -7
  712. cirq/work/observable_grouping_test.py +10 -9
  713. cirq/work/observable_measurement.py +47 -45
  714. cirq/work/observable_measurement_data.py +22 -17
  715. cirq/work/observable_measurement_data_test.py +4 -1
  716. cirq/work/observable_measurement_test.py +48 -29
  717. cirq/work/observable_readout_calibration.py +5 -2
  718. cirq/work/observable_readout_calibration_test.py +5 -2
  719. cirq/work/observable_settings.py +13 -22
  720. cirq/work/observable_settings_test.py +9 -7
  721. cirq/work/pauli_sum_collector.py +12 -10
  722. cirq/work/pauli_sum_collector_test.py +9 -9
  723. cirq/work/sampler.py +42 -43
  724. cirq/work/sampler_test.py +31 -24
  725. cirq/work/zeros_sampler.py +6 -4
  726. cirq/work/zeros_sampler_test.py +7 -5
  727. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/METADATA +7 -8
  728. cirq_core-1.6.0.dist-info/RECORD +1241 -0
  729. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/WHEEL +1 -1
  730. cirq_core-1.5.0.dev20250409222543.dist-info/RECORD +0 -1216
  731. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/licenses/LICENSE +0 -0
  732. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/top_level.txt +0 -0
@@ -12,8 +12,9 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import random
16
- from typing import Optional, Tuple
17
18
 
18
19
  import numpy as np
19
20
  import pytest
@@ -29,7 +30,7 @@ CNOT = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
29
30
  QFT = np.array([[1, 1, 1, 1], [1, 1j, -1, -1j], [1, -1, 1, -1], [1, -1j, -1, 1j]]) * 0.5
30
31
 
31
32
 
32
- def random_real_diagonal_matrix(n: int, d: Optional[int] = None) -> np.ndarray:
33
+ def random_real_diagonal_matrix(n: int, d: int | None = None) -> np.ndarray:
33
34
  return np.diag([random.random() if d is None or k < d else 0 for k in range(n)])
34
35
 
35
36
 
@@ -48,8 +49,8 @@ def random_block_diagonal_symmetric_matrix(*ns: int) -> np.ndarray:
48
49
 
49
50
 
50
51
  def random_bi_diagonalizable_pair(
51
- n: int, d1: Optional[int] = None, d2: Optional[int] = None
52
- ) -> Tuple[np.ndarray, np.ndarray]:
52
+ n: int, d1: int | None = None, d2: int | None = None
53
+ ) -> tuple[np.ndarray, np.ndarray]:
53
54
  u = cirq.testing.random_orthogonal(n)
54
55
  s = random_real_diagonal_matrix(n, d1)
55
56
  z = random_real_diagonal_matrix(n, d2)
@@ -107,7 +108,7 @@ def assert_bidiagonalized_by(m, p, q, rtol: float = 1e-5, atol: float = 1e-8):
107
108
  + [random_symmetric_matrix(4) for _ in range(10)]
108
109
  + [random_symmetric_matrix(k) for k in range(1, 10)],
109
110
  )
110
- def test_diagonalize_real_symmetric_matrix(matrix):
111
+ def test_diagonalize_real_symmetric_matrix(matrix) -> None:
111
112
  p = cirq.diagonalize_real_symmetric_matrix(matrix)
112
113
  assert_diagonalized_by(matrix, p)
113
114
 
@@ -122,12 +123,12 @@ def test_diagonalize_real_symmetric_matrix(matrix):
122
123
  np.array([[3, 1], [7, 3]]),
123
124
  ],
124
125
  )
125
- def test_diagonalize_real_symmetric_matrix_fails(matrix):
126
+ def test_diagonalize_real_symmetric_matrix_fails(matrix) -> None:
126
127
  with pytest.raises(ValueError):
127
128
  _ = cirq.diagonalize_real_symmetric_matrix(matrix)
128
129
 
129
130
 
130
- def test_diagonalize_real_symmetric_matrix_assertion_error():
131
+ def test_diagonalize_real_symmetric_matrix_assertion_error() -> None:
131
132
  with pytest.raises(AssertionError):
132
133
  matrix = np.array([[0.5, 0], [0, 1]])
133
134
  m = np.array([[0, 1], [0, 0]])
@@ -151,7 +152,7 @@ def test_diagonalize_real_symmetric_matrix_assertion_error():
151
152
  ]
152
153
  + [([6, 6, 5, 5, 5], random_block_diagonal_symmetric_matrix(2, 3)) for _ in range(10)],
153
154
  )
154
- def test_simultaneous_diagonalize_real_symmetric_matrix_vs_singulars(s, m):
155
+ def test_simultaneous_diagonalize_real_symmetric_matrix_vs_singulars(s, m) -> None:
155
156
  m = np.array(m)
156
157
  s = np.diag(s)
157
158
  p = cirq.diagonalize_real_symmetric_and_sorted_diagonal_matrices(m, s)
@@ -171,7 +172,7 @@ def test_simultaneous_diagonalize_real_symmetric_matrix_vs_singulars(s, m):
171
172
  ([3, 2, 1], QFT, 'must be real symmetric'),
172
173
  ],
173
174
  )
174
- def test_simultaneous_diagonalize_real_symmetric_matrix_vs_singulars_fail(s, m, match: str):
175
+ def test_simultaneous_diagonalize_real_symmetric_matrix_vs_singulars_fail(s, m, match: str) -> None:
175
176
  m = np.array(m)
176
177
  s = np.diag(s)
177
178
  with pytest.raises(ValueError, match=match):
@@ -199,7 +200,7 @@ def test_simultaneous_diagonalize_real_symmetric_matrix_vs_singulars_fail(s, m,
199
200
  ]
200
201
  + [random_bi_diagonalizable_pair(k) for k in range(1, 10)],
201
202
  )
202
- def test_bidiagonalize_real_matrix_pair_with_symmetric_products(a, b):
203
+ def test_bidiagonalize_real_matrix_pair_with_symmetric_products(a, b) -> None:
203
204
  a = np.array(a)
204
205
  b = np.array(b)
205
206
  p, q = cirq.bidiagonalize_real_matrix_pair_with_symmetric_products(a, b)
@@ -220,14 +221,14 @@ def test_bidiagonalize_real_matrix_pair_with_symmetric_products(a, b):
220
221
  [np.array([[1, 1], [1, 0]]), np.array([[1, 0], [1, 1]]), 'mat1 @ mat2.T must be symmetric'],
221
222
  ],
222
223
  )
223
- def test_bidiagonalize_real_fails(a, b, match: str):
224
+ def test_bidiagonalize_real_fails(a, b, match: str) -> None:
224
225
  a = np.array(a)
225
226
  b = np.array(b)
226
227
  with pytest.raises(ValueError, match=match):
227
228
  cirq.bidiagonalize_real_matrix_pair_with_symmetric_products(a, b)
228
229
 
229
230
 
230
- def test_bidiagonalize__assertion_error():
231
+ def test_bidiagonalize__assertion_error() -> None:
231
232
  with pytest.raises(AssertionError):
232
233
  a = np.diag([0, 1])
233
234
  assert_bidiagonalized_by(a, a, a)
@@ -261,7 +262,7 @@ def test_bidiagonalize__assertion_error():
261
262
  + [cirq.testing.random_unitary(4) for _ in range(10)]
262
263
  + [cirq.testing.random_unitary(k) for k in range(1, 10)],
263
264
  )
264
- def test_bidiagonalize_unitary_with_special_orthogonals(mat):
265
+ def test_bidiagonalize_unitary_with_special_orthogonals(mat) -> None:
265
266
  p, d, q = cirq.bidiagonalize_unitary_with_special_orthogonals(mat)
266
267
  assert cirq.is_special_orthogonal(p)
267
268
  assert cirq.is_special_orthogonal(q)
@@ -273,6 +274,6 @@ def test_bidiagonalize_unitary_with_special_orthogonals(mat):
273
274
  'mat',
274
275
  [np.diag([0]), np.diag([0.5]), np.diag([1, 0]), np.diag([0.5, 2]), np.array([[0, 1], [0, 0]])],
275
276
  )
276
- def test_bidiagonalize_unitary_fails(mat):
277
+ def test_bidiagonalize_unitary_fails(mat) -> None:
277
278
  with pytest.raises(ValueError):
278
279
  cirq.bidiagonalize_unitary_with_special_orthogonals(mat)
@@ -13,7 +13,10 @@
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, TYPE_CHECKING
16
+
17
+ from __future__ import annotations
18
+
19
+ from typing import TYPE_CHECKING
17
20
 
18
21
  import numpy as np
19
22
  import sympy
@@ -33,7 +36,7 @@ PAULI_BASIS = {
33
36
  document(PAULI_BASIS, """The four Pauli matrices (including identity) keyed by character.""")
34
37
 
35
38
 
36
- def kron_bases(*bases: Dict[str, np.ndarray], repeat: int = 1) -> Dict[str, np.ndarray]:
39
+ def kron_bases(*bases: dict[str, np.ndarray], repeat: int = 1) -> dict[str, np.ndarray]:
37
40
  """Creates tensor product of bases."""
38
41
  product_basis = {'': np.array([[1]])}
39
42
  for basis in bases * repeat:
@@ -54,7 +57,7 @@ def hilbert_schmidt_inner_product(m1: np.ndarray, m2: np.ndarray) -> complex:
54
57
 
55
58
 
56
59
  def expand_matrix_in_orthogonal_basis(
57
- m: np.ndarray, basis: Dict[str, np.ndarray]
60
+ m: np.ndarray, basis: dict[str, np.ndarray]
58
61
  ) -> value.LinearDict[str]:
59
62
  """Computes coefficients of expansion of m in basis.
60
63
 
@@ -71,27 +74,24 @@ def expand_matrix_in_orthogonal_basis(
71
74
 
72
75
 
73
76
  def matrix_from_basis_coefficients(
74
- expansion: value.LinearDict[str], basis: Dict[str, np.ndarray]
77
+ expansion: value.LinearDict[str], basis: dict[str, np.ndarray]
75
78
  ) -> np.ndarray:
76
79
  """Computes linear combination of basis vectors with given coefficients."""
77
80
  some_element = next(iter(basis.values()))
78
81
  result = np.zeros_like(some_element, dtype=np.complex128)
79
82
  for name, coefficient in expansion.items():
80
- result += coefficient * basis[name]
83
+ result += complex(coefficient) * basis[name]
81
84
  return result
82
85
 
83
86
 
84
87
  def pow_pauli_combination(
85
- ai: 'cirq.TParamValComplex',
86
- ax: 'cirq.TParamValComplex',
87
- ay: 'cirq.TParamValComplex',
88
- az: 'cirq.TParamValComplex',
88
+ ai: cirq.TParamValComplex,
89
+ ax: cirq.TParamValComplex,
90
+ ay: cirq.TParamValComplex,
91
+ az: cirq.TParamValComplex,
89
92
  exponent: int,
90
- ) -> Tuple[
91
- 'cirq.TParamValComplex',
92
- 'cirq.TParamValComplex',
93
- 'cirq.TParamValComplex',
94
- 'cirq.TParamValComplex',
93
+ ) -> tuple[
94
+ cirq.TParamValComplex, cirq.TParamValComplex, cirq.TParamValComplex, cirq.TParamValComplex
95
95
  ]:
96
96
  """Computes non-negative integer power of single-qubit Pauli combination.
97
97
 
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import itertools
16
18
 
17
19
  import numpy as np
@@ -84,7 +86,7 @@ def _one_hot_matrix(size: int, i: int, j: int) -> np.ndarray:
84
86
  ),
85
87
  ),
86
88
  )
87
- def test_kron_bases(basis1, basis2, expected_kron_basis):
89
+ def test_kron_bases(basis1, basis2, expected_kron_basis) -> None:
88
90
  kron_basis = cirq.kron_bases(basis1, basis2)
89
91
  assert len(kron_basis) == 16
90
92
  assert set(kron_basis.keys()) == set(expected_kron_basis.keys())
@@ -115,14 +117,14 @@ def test_kron_bases(basis1, basis2, expected_kron_basis):
115
117
  ),
116
118
  ),
117
119
  )
118
- def test_kron_bases_consistency(basis1, basis2):
120
+ def test_kron_bases_consistency(basis1, basis2) -> None:
119
121
  assert set(basis1.keys()) == set(basis2.keys())
120
122
  for name in basis1.keys():
121
123
  assert np.all(basis1[name] == basis2[name])
122
124
 
123
125
 
124
126
  @pytest.mark.parametrize('basis,repeat', itertools.product((PAULI_BASIS, STANDARD_BASIS), range(5)))
125
- def test_kron_bases_repeat_sanity_checks(basis, repeat):
127
+ def test_kron_bases_repeat_sanity_checks(basis, repeat) -> None:
126
128
  product_basis = cirq.kron_bases(basis, repeat=repeat)
127
129
  assert len(product_basis) == 4**repeat
128
130
  for name1, matrix1 in product_basis.items():
@@ -138,7 +140,7 @@ def test_kron_bases_repeat_sanity_checks(basis, repeat):
138
140
  'm1,m2,expect_real',
139
141
  ((X, X, True), (X, Y, True), (X, H, True), (X, SQRT_X, False), (I, SQRT_Z, False)),
140
142
  )
141
- def test_hilbert_schmidt_inner_product_is_conjugate_symmetric(m1, m2, expect_real):
143
+ def test_hilbert_schmidt_inner_product_is_conjugate_symmetric(m1, m2, expect_real) -> None:
142
144
  v1 = cirq.hilbert_schmidt_inner_product(m1, m2)
143
145
  v2 = cirq.hilbert_schmidt_inner_product(m2, m1)
144
146
  assert v1 == v2.conjugate()
@@ -149,7 +151,7 @@ def test_hilbert_schmidt_inner_product_is_conjugate_symmetric(m1, m2, expect_rea
149
151
 
150
152
 
151
153
  @pytest.mark.parametrize('a,m1,b,m2', ((1, X, 1, Z), (2, X, 3, Y), (2j, X, 3, I), (2, X, 3, X)))
152
- def test_hilbert_schmidt_inner_product_is_linear(a, m1, b, m2):
154
+ def test_hilbert_schmidt_inner_product_is_linear(a, m1, b, m2) -> None:
153
155
  v1 = cirq.hilbert_schmidt_inner_product(H, (a * m1 + b * m2))
154
156
  v2 = a * cirq.hilbert_schmidt_inner_product(H, m1) + b * cirq.hilbert_schmidt_inner_product(
155
157
  H, m2
@@ -158,7 +160,7 @@ def test_hilbert_schmidt_inner_product_is_linear(a, m1, b, m2):
158
160
 
159
161
 
160
162
  @pytest.mark.parametrize('m', (I, X, Y, Z, H, SQRT_X, SQRT_Y, SQRT_Z))
161
- def test_hilbert_schmidt_inner_product_is_positive_definite(m):
163
+ def test_hilbert_schmidt_inner_product_is_positive_definite(m) -> None:
162
164
  v = cirq.hilbert_schmidt_inner_product(m, m)
163
165
  # Cannot check using np.is_real due to bug in aarch64.
164
166
  # See https://github.com/quantumlib/Cirq/issues/4379
@@ -186,7 +188,7 @@ def test_hilbert_schmidt_inner_product_is_positive_definite(m):
186
188
  (SQRT_X, E11, np.sqrt(-0.5j)),
187
189
  ),
188
190
  )
189
- def test_hilbert_schmidt_inner_product_values(m1, m2, expected_value):
191
+ def test_hilbert_schmidt_inner_product_values(m1, m2, expected_value) -> None:
190
192
  v = cirq.hilbert_schmidt_inner_product(m1, m2)
191
193
  assert np.isclose(v, expected_value)
192
194
 
@@ -195,7 +197,7 @@ def test_hilbert_schmidt_inner_product_values(m1, m2, expected_value):
195
197
  'm,basis',
196
198
  itertools.product((I, X, Y, Z, H, SQRT_X, SQRT_Y, SQRT_Z), (PAULI_BASIS, STANDARD_BASIS)),
197
199
  )
198
- def test_expand_matrix_in_orthogonal_basis(m, basis):
200
+ def test_expand_matrix_in_orthogonal_basis(m, basis) -> None:
199
201
  expansion = cirq.expand_matrix_in_orthogonal_basis(m, basis)
200
202
 
201
203
  reconstructed = np.zeros(m.shape, dtype=complex)
@@ -216,7 +218,7 @@ def test_expand_matrix_in_orthogonal_basis(m, basis):
216
218
  {'I': 1, 'X': 2, 'Y': 3, 'Z': 4},
217
219
  ),
218
220
  )
219
- def test_matrix_from_basis_coefficients(expansion):
221
+ def test_matrix_from_basis_coefficients(expansion) -> None:
220
222
  m = cirq.matrix_from_basis_coefficients(expansion, PAULI_BASIS)
221
223
 
222
224
  for name, coefficient in expansion.items():
@@ -236,7 +238,7 @@ def test_matrix_from_basis_coefficients(expansion):
236
238
  )
237
239
  ),
238
240
  )
239
- def test_expand_is_inverse_of_reconstruct(m1, basis):
241
+ def test_expand_is_inverse_of_reconstruct(m1, basis) -> None:
240
242
  c1 = cirq.expand_matrix_in_orthogonal_basis(m1, basis)
241
243
  m2 = cirq.matrix_from_basis_coefficients(c1, basis)
242
244
  c2 = cirq.expand_matrix_in_orthogonal_basis(m2, basis)
@@ -299,7 +301,7 @@ def test_expand_is_inverse_of_reconstruct(m1, basis):
299
301
  (0, 1, 2, 3, 4, 5, 100, 101),
300
302
  ),
301
303
  )
302
- def test_pow_pauli_combination(coefficients, exponent):
304
+ def test_pow_pauli_combination(coefficients, exponent) -> None:
303
305
  is_symbolic = any(isinstance(a, sympy.Basic) for a in coefficients)
304
306
  if is_symbolic and exponent > 2:
305
307
  return # too slow
cirq/linalg/predicates.py CHANGED
@@ -11,8 +11,13 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
+
14
15
  """Utility methods for checking properties of matrices."""
15
- from typing import cast, List, Optional, Sequence, Tuple, Union
16
+
17
+ from __future__ import annotations
18
+
19
+ from types import EllipsisType
20
+ from typing import cast, Sequence
16
21
 
17
22
  import numpy as np
18
23
 
@@ -110,8 +115,12 @@ def is_unitary(matrix: np.ndarray, *, rtol: float = 1e-5, atol: float = 1e-8) ->
110
115
  Returns:
111
116
  Whether the matrix is unitary within the given tolerance.
112
117
  """
113
- return matrix.shape[0] == matrix.shape[1] and np.allclose(
114
- matrix.dot(np.conj(matrix.T)), np.eye(matrix.shape[0]), rtol=rtol, atol=atol
118
+ return (
119
+ matrix.ndim == 2
120
+ and matrix.shape[0] == matrix.shape[1]
121
+ and np.allclose(
122
+ matrix.dot(np.conj(matrix.T)), np.eye(matrix.shape[0]), rtol=rtol, atol=atol
123
+ )
115
124
  )
116
125
 
117
126
 
@@ -226,9 +235,9 @@ def slice_for_qubits_equal_to(
226
235
  little_endian_qureg_value: int = 0,
227
236
  *, # Forces keyword args.
228
237
  big_endian_qureg_value: int = 0,
229
- num_qubits: Optional[int] = None,
230
- qid_shape: Optional[Tuple[int, ...]] = None,
231
- ) -> Tuple[Union[slice, int, 'ellipsis'], ...]:
238
+ num_qubits: int | None = None,
239
+ qid_shape: tuple[int, ...] | None = None,
240
+ ) -> tuple[slice | int | EllipsisType, ...]:
232
241
  """Returns an index corresponding to a desired subset of an np.ndarray.
233
242
 
234
243
  It is assumed that the np.ndarray's shape is of the form (2, 2, 2, ..., 2).
@@ -283,10 +292,10 @@ def slice_for_qubits_equal_to(
283
292
  qid_shape_specified = qid_shape is not None
284
293
  if qid_shape is not None or num_qubits is not None:
285
294
  if num_qubits is None:
286
- num_qubits = len(cast(Tuple[int, ...], qid_shape))
295
+ num_qubits = len(cast(tuple[int, ...], qid_shape))
287
296
  elif qid_shape is None:
288
297
  qid_shape = (2,) * num_qubits
289
- if num_qubits != len(cast(Tuple[int, ...], qid_shape)):
298
+ if num_qubits != len(cast(tuple[int, ...], qid_shape)):
290
299
  raise ValueError('len(qid_shape) != num_qubits')
291
300
  if little_endian_qureg_value and big_endian_qureg_value:
292
301
  raise ValueError(
@@ -297,7 +306,7 @@ def slice_for_qubits_equal_to(
297
306
  out_size = (
298
307
  cast(int, num_qubits) if out_size_specified else max(target_qubit_axes, default=-1) + 1
299
308
  )
300
- result = cast(List[Union[slice, int, 'ellipsis']], [slice(None)] * out_size)
309
+ result = cast(list[slice | int | EllipsisType], [slice(None)] * out_size)
301
310
  if not out_size_specified:
302
311
  result.append(Ellipsis)
303
312
  if qid_shape is None:
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import cmath
16
18
 
17
19
  import numpy as np
@@ -101,10 +103,13 @@ def test_is_hermitian_tolerance():
101
103
 
102
104
 
103
105
  def test_is_unitary():
106
+ assert not cirq.is_unitary(np.empty((0,)))
104
107
  assert cirq.is_unitary(np.empty((0, 0)))
105
108
  assert not cirq.is_unitary(np.empty((1, 0)))
106
109
  assert not cirq.is_unitary(np.empty((0, 1)))
110
+ assert not cirq.is_unitary(np.empty((0, 0, 0)))
107
111
 
112
+ assert not cirq.is_unitary(np.array(1))
108
113
  assert cirq.is_unitary(np.array([[1]]))
109
114
  assert cirq.is_unitary(np.array([[-1]]))
110
115
  assert cirq.is_unitary(np.array([[1j]]))
cirq/linalg/tolerance.py CHANGED
@@ -14,7 +14,10 @@
14
14
 
15
15
  """Utility for testing approximate equality of matrices and scalars within
16
16
  tolerances."""
17
- from typing import Iterable, TYPE_CHECKING, Union
17
+
18
+ from __future__ import annotations
19
+
20
+ from typing import Iterable, TYPE_CHECKING
18
21
 
19
22
  import numpy as np
20
23
 
@@ -22,7 +25,7 @@ if TYPE_CHECKING:
22
25
  from numpy.typing import ArrayLike
23
26
 
24
27
 
25
- def all_near_zero(a: 'ArrayLike', *, atol: float = 1e-8) -> bool:
28
+ def all_near_zero(a: ArrayLike, *, atol: float = 1e-8) -> bool:
26
29
  """Checks if the tensor's elements are all near zero.
27
30
 
28
31
  Args:
@@ -33,7 +36,7 @@ def all_near_zero(a: 'ArrayLike', *, atol: float = 1e-8) -> bool:
33
36
 
34
37
 
35
38
  def all_near_zero_mod(
36
- a: Union[float, Iterable[float], np.ndarray], period: float, *, atol: float = 1e-8
39
+ a: float | Iterable[float] | np.ndarray, period: float, *, atol: float = 1e-8
37
40
  ) -> bool:
38
41
  """Checks if the tensor's elements are all near multiples of the period.
39
42
 
@@ -12,10 +12,12 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  from cirq.linalg.tolerance import all_near_zero, all_near_zero_mod, near_zero, near_zero_mod
16
18
 
17
19
 
18
- def test_all_zero():
20
+ def test_all_zero() -> None:
19
21
  atol = 5
20
22
  assert all_near_zero(0, atol=atol)
21
23
  assert all_near_zero(4.5, atol=atol)
@@ -25,7 +27,7 @@ def test_all_zero():
25
27
  assert not all_near_zero([-4.5, 0, 1, 4.5, 30], atol=atol)
26
28
 
27
29
 
28
- def test_all_zero_mod():
30
+ def test_all_zero_mod() -> None:
29
31
  atol = 5
30
32
  assert all_near_zero_mod(0, 100, atol=atol)
31
33
  assert all_near_zero_mod(4.5, 100, atol=atol)
@@ -45,14 +47,14 @@ def test_all_zero_mod():
45
47
  assert not all_near_zero_mod([-4.5, 0, 1, 4.5, 30], 100, atol=atol)
46
48
 
47
49
 
48
- def test_near_zero():
50
+ def test_near_zero() -> None:
49
51
  atol = 5
50
52
  assert near_zero(0, atol=atol)
51
53
  assert near_zero(4.5, atol=atol)
52
54
  assert not near_zero(5.5, atol=atol)
53
55
 
54
56
 
55
- def test_near_zero_mod():
57
+ def test_near_zero_mod() -> None:
56
58
  atol = 5
57
59
  assert near_zero_mod(0, 100, atol=atol)
58
60
  assert near_zero_mod(4.5, 100, atol=atol)
@@ -14,9 +14,12 @@
14
14
 
15
15
  """Utility methods for transforming matrices or vectors."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  import dataclasses
18
20
  import functools
19
- from typing import Any, List, Optional, Sequence, Tuple, Union
21
+ from types import EllipsisType
22
+ from typing import Any, Sequence
20
23
 
21
24
  import numpy as np
22
25
 
@@ -59,7 +62,7 @@ def reflection_matrix_pow(reflection_matrix: np.ndarray, exponent: float):
59
62
  return pos_part_raised + neg_part_raised
60
63
 
61
64
 
62
- def match_global_phase(a: np.ndarray, b: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
65
+ def match_global_phase(a: np.ndarray, b: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
63
66
  """Phases the given matrices so that they agree on the phase of one entry.
64
67
 
65
68
  To maximize precision, the position with the largest entry from one of the
@@ -101,7 +104,7 @@ def targeted_left_multiply(
101
104
  left_matrix: np.ndarray,
102
105
  right_target: np.ndarray,
103
106
  target_axes: Sequence[int],
104
- out: Optional[np.ndarray] = None,
107
+ out: np.ndarray | None = None,
105
108
  ) -> np.ndarray:
106
109
  """Left-multiplies the given axes of the target tensor by the given matrix.
107
110
 
@@ -176,7 +179,7 @@ class _SliceConfig:
176
179
 
177
180
  @dataclasses.dataclass
178
181
  class _BuildFromSlicesArgs:
179
- slices: Tuple[_SliceConfig, ...]
182
+ slices: tuple[_SliceConfig, ...]
180
183
  scale: complex
181
184
 
182
185
 
@@ -234,8 +237,8 @@ def _build_from_slices(
234
237
  d = len(source.shape)
235
238
  out[...] = 0
236
239
  for arg in args:
237
- source_slice: List[Any] = [slice(None)] * d
238
- target_slice: List[Any] = [slice(None)] * d
240
+ source_slice: list[Any] = [slice(None)] * d
241
+ target_slice: list[Any] = [slice(None)] * d
239
242
  for sleis in arg.slices:
240
243
  source_slice[sleis.axis] = sleis.source_index
241
244
  target_slice[sleis.axis] = sleis.target_index
@@ -247,9 +250,9 @@ def targeted_conjugate_about(
247
250
  tensor: np.ndarray,
248
251
  target: np.ndarray,
249
252
  indices: Sequence[int],
250
- conj_indices: Optional[Sequence[int]] = None,
251
- buffer: Optional[np.ndarray] = None,
252
- out: Optional[np.ndarray] = None,
253
+ conj_indices: Sequence[int] | None = None,
254
+ buffer: np.ndarray | None = None,
255
+ out: np.ndarray | None = None,
253
256
  ) -> np.ndarray:
254
257
  r"""Conjugates the given tensor about the target tensor.
255
258
 
@@ -298,8 +301,8 @@ def targeted_conjugate_about(
298
301
  return targeted_left_multiply(np.conjugate(tensor), first_multiply, conj_indices, out=out)
299
302
 
300
303
 
301
- _TSliceAtom = Union[int, slice, 'ellipsis']
302
- _TSlice = Union[_TSliceAtom, Sequence[_TSliceAtom]]
304
+ _TSliceAtom = int | slice | EllipsisType
305
+ _TSlice = _TSliceAtom | Sequence[_TSliceAtom]
303
306
 
304
307
 
305
308
  def apply_matrix_to_slices(
@@ -307,7 +310,7 @@ def apply_matrix_to_slices(
307
310
  matrix: np.ndarray,
308
311
  slices: Sequence[_TSlice],
309
312
  *,
310
- out: Optional[np.ndarray] = None,
313
+ out: np.ndarray | None = None,
311
314
  ) -> np.ndarray:
312
315
  r"""Left-multiplies an NxN matrix onto N slices of a numpy array.
313
316
 
@@ -417,8 +420,8 @@ class EntangledStateError(ValueError):
417
420
 
418
421
 
419
422
  def partial_trace_of_state_vector_as_mixture(
420
- state_vector: np.ndarray, keep_indices: List[int], *, atol: float = 1e-8
421
- ) -> Tuple[Tuple[float, np.ndarray], ...]:
423
+ state_vector: np.ndarray, keep_indices: list[int], *, atol: float = 1e-8
424
+ ) -> tuple[tuple[float, np.ndarray], ...]:
422
425
  """Returns a mixture representing a state vector with only some qubits kept.
423
426
 
424
427
  The input state vector can have any shape, but if it is one-dimensional it
@@ -452,7 +455,7 @@ def partial_trace_of_state_vector_as_mixture(
452
455
  if 2**dims != state_vector.size:
453
456
  raise ValueError(f'Cannot infer underlying shape of {state_vector.shape}.')
454
457
  state_vector = state_vector.reshape((2,) * dims)
455
- ret_shape: Tuple[int, ...] = (2 ** len(keep_indices),)
458
+ ret_shape: tuple[int, ...] = (2 ** len(keep_indices),)
456
459
  else:
457
460
  ret_shape = tuple(state_vector.shape[i] for i in keep_indices)
458
461
 
@@ -473,7 +476,7 @@ def partial_trace_of_state_vector_as_mixture(
473
476
 
474
477
  def sub_state_vector(
475
478
  state_vector: np.ndarray,
476
- keep_indices: List[int],
479
+ keep_indices: list[int],
477
480
  *,
478
481
  default: np.ndarray = RaiseValueErrorIfNotProvided,
479
482
  atol: float = 1e-6,
@@ -533,7 +536,7 @@ def sub_state_vector(
533
536
 
534
537
  n_qubits = int(np.log2(state_vector.size))
535
538
  keep_dims = 1 << len(keep_indices)
536
- ret_shape: Union[Tuple[int], Tuple[int, ...]]
539
+ ret_shape: tuple[int] | tuple[int, ...]
537
540
  if state_vector.shape == (state_vector.size,):
538
541
  ret_shape = (keep_dims,)
539
542
  state_vector = state_vector.reshape((2,) * n_qubits)
@@ -631,7 +634,7 @@ def density_matrix_kronecker_product(t1: np.ndarray, t2: np.ndarray) -> np.ndarr
631
634
 
632
635
  def factor_state_vector(
633
636
  t: np.ndarray, axes: Sequence[int], *, validate=True, atol=1e-07
634
- ) -> Tuple[np.ndarray, np.ndarray]:
637
+ ) -> tuple[np.ndarray, np.ndarray]:
635
638
  """Factors a state vector into two independent state vectors.
636
639
 
637
640
  This function should only be called on state vectors that are known to be
@@ -677,7 +680,7 @@ def factor_state_vector(
677
680
 
678
681
  def factor_density_matrix(
679
682
  t: np.ndarray, axes: Sequence[int], *, validate=True, atol=1e-07
680
- ) -> Tuple[np.ndarray, np.ndarray]:
683
+ ) -> tuple[np.ndarray, np.ndarray]:
681
684
  """Factors a density matrix into two independent density matrices.
682
685
 
683
686
  This function should only be called on density matrices that are known to
@@ -745,7 +748,7 @@ def transpose_density_matrix_to_axis_order(t: np.ndarray, axes: Sequence[int]):
745
748
  return transpose_state_vector_to_axis_order(t, axes)
746
749
 
747
750
 
748
- def _volumes(shape: Sequence[int]) -> List[int]:
751
+ def _volumes(shape: Sequence[int]) -> list[int]:
749
752
  r"""Returns a list of the volume spanned by each dimension.
750
753
 
751
754
  Given a shape=[d_0, d_1, .., d_n] the volume spanned by each dimension is