cirq-core 1.4.1__py3-none-any.whl → 1.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cirq-core might be problematic. Click here for more details.

Files changed (590) hide show
  1. cirq/__init__.py +587 -569
  2. cirq/_compat.py +9 -0
  3. cirq/_compat_test.py +11 -9
  4. cirq/_import.py +7 -8
  5. cirq/_version.py +1 -1
  6. cirq/_version_test.py +1 -1
  7. cirq/circuits/__init__.py +15 -9
  8. cirq/circuits/_block_diagram_drawer.py +1 -2
  9. cirq/circuits/_block_diagram_drawer_test.py +3 -3
  10. cirq/circuits/_box_drawing_character_data.py +0 -1
  11. cirq/circuits/_box_drawing_character_data_test.py +2 -2
  12. cirq/circuits/_bucket_priority_queue.py +0 -1
  13. cirq/circuits/_bucket_priority_queue_test.py +1 -1
  14. cirq/circuits/circuit.py +336 -234
  15. cirq/circuits/circuit_operation.py +102 -52
  16. cirq/circuits/circuit_operation_test.py +85 -4
  17. cirq/circuits/circuit_test.py +101 -32
  18. cirq/circuits/frozen_circuit.py +36 -32
  19. cirq/circuits/insert_strategy.py +10 -0
  20. cirq/circuits/insert_strategy_test.py +20 -0
  21. cirq/circuits/moment.py +79 -80
  22. cirq/circuits/moment_test.py +105 -2
  23. cirq/circuits/optimization_pass.py +15 -15
  24. cirq/circuits/optimization_pass_test.py +8 -9
  25. cirq/circuits/qasm_output.py +64 -33
  26. cirq/circuits/qasm_output_test.py +63 -2
  27. cirq/circuits/text_diagram_drawer.py +26 -56
  28. cirq/circuits/text_diagram_drawer_test.py +5 -4
  29. cirq/contrib/__init__.py +2 -2
  30. cirq/contrib/acquaintance/__init__.py +44 -29
  31. cirq/contrib/acquaintance/bipartite.py +8 -7
  32. cirq/contrib/acquaintance/bipartite_test.py +11 -1
  33. cirq/contrib/acquaintance/devices.py +5 -4
  34. cirq/contrib/acquaintance/devices_test.py +5 -1
  35. cirq/contrib/acquaintance/executor.py +18 -21
  36. cirq/contrib/acquaintance/executor_test.py +3 -2
  37. cirq/contrib/acquaintance/gates.py +36 -27
  38. cirq/contrib/acquaintance/gates_test.py +1 -1
  39. cirq/contrib/acquaintance/inspection_utils.py +10 -9
  40. cirq/contrib/acquaintance/inspection_utils_test.py +6 -1
  41. cirq/contrib/acquaintance/mutation_utils.py +10 -10
  42. cirq/contrib/acquaintance/optimizers.py +7 -6
  43. cirq/contrib/acquaintance/optimizers_test.py +1 -1
  44. cirq/contrib/acquaintance/permutation.py +22 -21
  45. cirq/contrib/acquaintance/permutation_test.py +1 -1
  46. cirq/contrib/acquaintance/shift.py +8 -6
  47. cirq/contrib/acquaintance/shift_swap_network.py +6 -4
  48. cirq/contrib/acquaintance/strategies/__init__.py +9 -3
  49. cirq/contrib/acquaintance/strategies/complete.py +4 -3
  50. cirq/contrib/acquaintance/strategies/cubic.py +5 -3
  51. cirq/contrib/acquaintance/strategies/quartic_paired.py +8 -6
  52. cirq/contrib/acquaintance/topological_sort.py +4 -2
  53. cirq/contrib/bayesian_network/__init__.py +3 -1
  54. cirq/contrib/bayesian_network/bayesian_network_gate.py +5 -3
  55. cirq/contrib/circuitdag/__init__.py +1 -1
  56. cirq/contrib/circuitdag/circuit_dag.py +24 -24
  57. cirq/contrib/circuitdag/circuit_dag_test.py +1 -1
  58. cirq/contrib/custom_simulators/custom_state_simulator.py +10 -8
  59. cirq/contrib/custom_simulators/custom_state_simulator_test.py +15 -11
  60. cirq/contrib/graph_device/__init__.py +8 -8
  61. cirq/contrib/graph_device/graph_device.py +8 -8
  62. cirq/contrib/graph_device/graph_device_test.py +0 -1
  63. cirq/contrib/graph_device/hypergraph_test.py +1 -0
  64. cirq/contrib/json.py +1 -2
  65. cirq/contrib/json_test.py +2 -2
  66. cirq/contrib/noise_models/__init__.py +5 -6
  67. cirq/contrib/noise_models/noise_models.py +8 -6
  68. cirq/contrib/paulistring/__init__.py +22 -10
  69. cirq/contrib/paulistring/clifford_optimize.py +1 -1
  70. cirq/contrib/paulistring/clifford_optimize_test.py +0 -1
  71. cirq/contrib/paulistring/clifford_target_gateset.py +15 -12
  72. cirq/contrib/paulistring/optimize.py +2 -2
  73. cirq/contrib/paulistring/optimize_test.py +0 -1
  74. cirq/contrib/paulistring/pauli_string_dag_test.py +0 -1
  75. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +379 -0
  76. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +523 -0
  77. cirq/contrib/paulistring/pauli_string_optimize.py +3 -1
  78. cirq/contrib/paulistring/pauli_string_optimize_test.py +1 -3
  79. cirq/contrib/paulistring/recombine.py +2 -2
  80. cirq/contrib/paulistring/recombine_test.py +2 -2
  81. cirq/contrib/paulistring/separate.py +3 -4
  82. cirq/contrib/qasm_import/__init__.py +2 -2
  83. cirq/contrib/qasm_import/_lexer.py +21 -26
  84. cirq/contrib/qasm_import/_lexer_test.py +90 -6
  85. cirq/contrib/qasm_import/_parser.py +238 -47
  86. cirq/contrib/qasm_import/_parser_test.py +514 -59
  87. cirq/contrib/qasm_import/qasm_test.py +1 -1
  88. cirq/contrib/qcircuit/__init__.py +6 -4
  89. cirq/contrib/qcircuit/qcircuit_diagram.py +5 -2
  90. cirq/contrib/qcircuit/qcircuit_pdf.py +1 -2
  91. cirq/{experiments/grid_parallel_two_qubit_xeb_test.py → contrib/qcircuit/qcircuit_pdf_test.py} +13 -12
  92. cirq/contrib/qcircuit/qcircuit_test.py +1 -1
  93. cirq/contrib/quantum_volume/__init__.py +7 -7
  94. cirq/contrib/quantum_volume/quantum_volume.py +6 -11
  95. cirq/contrib/quantum_volume/quantum_volume_test.py +3 -1
  96. cirq/contrib/quimb/__init__.py +16 -13
  97. cirq/contrib/quimb/density_matrix.py +1 -1
  98. cirq/contrib/quimb/mps_simulator.py +27 -28
  99. cirq/contrib/quimb/mps_simulator_test.py +5 -0
  100. cirq/contrib/quimb/state_vector.py +3 -10
  101. cirq/contrib/quirk/__init__.py +1 -1
  102. cirq/contrib/quirk/export_to_quirk.py +3 -3
  103. cirq/contrib/routing/__init__.py +12 -9
  104. cirq/contrib/routing/device.py +1 -1
  105. cirq/contrib/routing/device_test.py +1 -2
  106. cirq/contrib/routing/greedy.py +7 -5
  107. cirq/contrib/routing/greedy_test.py +5 -3
  108. cirq/contrib/routing/initialization.py +3 -1
  109. cirq/contrib/routing/initialization_test.py +1 -1
  110. cirq/contrib/routing/swap_network.py +6 -6
  111. cirq/contrib/routing/utils.py +6 -4
  112. cirq/contrib/routing/utils_test.py +1 -2
  113. cirq/{type_workarounds.py → contrib/shuffle_circuits/__init__.py} +5 -10
  114. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +250 -0
  115. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +363 -0
  116. cirq/contrib/svg/__init__.py +1 -1
  117. cirq/contrib/svg/svg.py +12 -10
  118. cirq/contrib/svg/svg_test.py +3 -2
  119. cirq/devices/__init__.py +34 -25
  120. cirq/devices/device.py +16 -12
  121. cirq/devices/device_test.py +1 -0
  122. cirq/devices/grid_device_metadata.py +16 -12
  123. cirq/devices/grid_device_metadata_test.py +2 -1
  124. cirq/devices/grid_qubit.py +31 -26
  125. cirq/devices/grid_qubit_test.py +30 -1
  126. cirq/devices/insertion_noise_model.py +6 -6
  127. cirq/devices/insertion_noise_model_test.py +1 -1
  128. cirq/devices/line_qubit.py +28 -20
  129. cirq/devices/line_qubit_test.py +26 -0
  130. cirq/devices/named_topologies.py +12 -10
  131. cirq/devices/named_topologies_test.py +5 -4
  132. cirq/devices/noise_model.py +29 -33
  133. cirq/devices/noise_properties.py +2 -2
  134. cirq/devices/noise_properties_test.py +2 -2
  135. cirq/devices/noise_utils.py +3 -3
  136. cirq/devices/superconducting_qubits_noise_properties.py +2 -2
  137. cirq/devices/superconducting_qubits_noise_properties_test.py +3 -3
  138. cirq/devices/thermal_noise_model.py +2 -1
  139. cirq/devices/unconstrained_device.py +1 -1
  140. cirq/devices/unconstrained_device_test.py +6 -0
  141. cirq/experiments/__init__.py +51 -34
  142. cirq/experiments/qubit_characterizations.py +17 -15
  143. cirq/experiments/qubit_characterizations_test.py +4 -6
  144. cirq/experiments/random_quantum_circuit_generation.py +10 -9
  145. cirq/experiments/random_quantum_circuit_generation_test.py +21 -4
  146. cirq/experiments/readout_confusion_matrix.py +73 -8
  147. cirq/experiments/readout_confusion_matrix_test.py +104 -1
  148. cirq/experiments/single_qubit_readout_calibration.py +8 -6
  149. cirq/experiments/single_qubit_readout_calibration_test.py +1 -1
  150. cirq/experiments/t1_decay_experiment.py +4 -5
  151. cirq/experiments/t1_decay_experiment_test.py +1 -2
  152. cirq/experiments/t2_decay_experiment.py +0 -1
  153. cirq/experiments/t2_decay_experiment_test.py +1 -2
  154. cirq/experiments/two_qubit_xeb.py +157 -33
  155. cirq/experiments/two_qubit_xeb_test.py +38 -22
  156. cirq/experiments/xeb_fitting.py +99 -19
  157. cirq/experiments/xeb_fitting_test.py +64 -25
  158. cirq/experiments/xeb_sampling.py +14 -18
  159. cirq/experiments/xeb_simulation.py +4 -3
  160. cirq/experiments/xeb_simulation_test.py +20 -14
  161. cirq/experiments/z_phase_calibration.py +368 -0
  162. cirq/experiments/z_phase_calibration_test.py +241 -0
  163. cirq/interop/__init__.py +4 -1
  164. cirq/interop/quirk/__init__.py +7 -4
  165. cirq/interop/quirk/cells/__init__.py +17 -6
  166. cirq/interop/quirk/cells/arithmetic_cells.py +8 -8
  167. cirq/interop/quirk/cells/arithmetic_cells_test.py +1 -1
  168. cirq/interop/quirk/cells/cell.py +6 -6
  169. cirq/interop/quirk/cells/composite_cell.py +5 -5
  170. cirq/interop/quirk/cells/composite_cell_test.py +1 -1
  171. cirq/interop/quirk/cells/control_cells.py +1 -1
  172. cirq/interop/quirk/cells/frequency_space_cells.py +2 -2
  173. cirq/interop/quirk/cells/ignored_cells.py +1 -1
  174. cirq/interop/quirk/cells/input_cells.py +1 -1
  175. cirq/interop/quirk/cells/input_cells_test.py +1 -1
  176. cirq/interop/quirk/cells/input_rotation_cells.py +1 -1
  177. cirq/interop/quirk/cells/input_rotation_cells_test.py +1 -1
  178. cirq/interop/quirk/cells/measurement_cells.py +1 -1
  179. cirq/interop/quirk/cells/parse.py +8 -7
  180. cirq/interop/quirk/cells/parse_test.py +2 -2
  181. cirq/interop/quirk/cells/single_qubit_rotation_cells.py +1 -1
  182. cirq/interop/quirk/cells/swap_cell_test.py +1 -1
  183. cirq/interop/quirk/cells/unsupported_cells.py +1 -1
  184. cirq/interop/quirk/url_to_circuit.py +7 -7
  185. cirq/interop/quirk/url_to_circuit_test.py +1 -1
  186. cirq/ion/__init__.py +4 -2
  187. cirq/json_resolver_cache.py +15 -7
  188. cirq/linalg/__init__.py +62 -51
  189. cirq/linalg/combinators.py +4 -4
  190. cirq/linalg/combinators_test.py +4 -1
  191. cirq/linalg/decompositions.py +15 -40
  192. cirq/linalg/decompositions_test.py +16 -22
  193. cirq/linalg/diagonalize.py +1 -1
  194. cirq/linalg/diagonalize_test.py +1 -1
  195. cirq/linalg/operator_spaces.py +20 -4
  196. cirq/linalg/operator_spaces_test.py +15 -2
  197. cirq/linalg/predicates.py +3 -3
  198. cirq/linalg/predicates_test.py +1 -0
  199. cirq/linalg/tolerance.py +2 -2
  200. cirq/linalg/transformations.py +30 -12
  201. cirq/linalg/transformations_test.py +13 -0
  202. cirq/neutral_atoms/__init__.py +2 -2
  203. cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +0 -1
  204. cirq/ops/__init__.py +172 -132
  205. cirq/ops/arithmetic_operation.py +2 -2
  206. cirq/ops/arithmetic_operation_test.py +2 -2
  207. cirq/ops/boolean_hamiltonian.py +3 -2
  208. cirq/ops/classically_controlled_operation.py +39 -12
  209. cirq/ops/classically_controlled_operation_test.py +147 -1
  210. cirq/ops/clifford_gate.py +38 -36
  211. cirq/ops/clifford_gate_test.py +75 -1
  212. cirq/ops/common_channels.py +16 -45
  213. cirq/ops/common_channels_test.py +10 -0
  214. cirq/ops/common_gate_families.py +1 -1
  215. cirq/ops/common_gate_families_test.py +1 -0
  216. cirq/ops/common_gates.py +48 -49
  217. cirq/ops/common_gates_test.py +18 -2
  218. cirq/ops/control_values.py +3 -3
  219. cirq/ops/control_values_test.py +2 -1
  220. cirq/ops/controlled_gate.py +36 -23
  221. cirq/ops/controlled_gate_test.py +70 -3
  222. cirq/ops/controlled_operation.py +6 -5
  223. cirq/ops/controlled_operation_test.py +7 -3
  224. cirq/ops/dense_pauli_string.py +11 -11
  225. cirq/ops/diagonal_gate.py +2 -2
  226. cirq/ops/diagonal_gate_test.py +1 -0
  227. cirq/ops/eigen_gate.py +16 -36
  228. cirq/ops/eigen_gate_test.py +60 -10
  229. cirq/ops/fourier_transform.py +1 -3
  230. cirq/ops/fourier_transform_test.py +2 -1
  231. cirq/ops/fsim_gate.py +42 -3
  232. cirq/ops/fsim_gate_test.py +21 -0
  233. cirq/ops/gate_operation.py +8 -8
  234. cirq/ops/gate_operation_test.py +4 -2
  235. cirq/ops/gateset_test.py +11 -2
  236. cirq/ops/global_phase_op.py +8 -7
  237. cirq/ops/global_phase_op_test.py +1 -1
  238. cirq/ops/greedy_qubit_manager_test.py +5 -0
  239. cirq/ops/identity.py +14 -4
  240. cirq/ops/identity_test.py +24 -0
  241. cirq/ops/kraus_channel.py +1 -0
  242. cirq/ops/kraus_channel_test.py +3 -1
  243. cirq/ops/linear_combinations.py +27 -21
  244. cirq/ops/linear_combinations_test.py +23 -4
  245. cirq/ops/matrix_gates.py +24 -8
  246. cirq/ops/measure_util.py +2 -2
  247. cirq/ops/measurement_gate.py +7 -4
  248. cirq/ops/measurement_gate_test.py +2 -1
  249. cirq/ops/mixed_unitary_channel.py +1 -0
  250. cirq/ops/mixed_unitary_channel_test.py +3 -1
  251. cirq/ops/named_qubit.py +8 -1
  252. cirq/ops/op_tree.py +3 -30
  253. cirq/ops/op_tree_test.py +4 -0
  254. cirq/ops/parallel_gate.py +2 -3
  255. cirq/ops/parallel_gate_test.py +2 -1
  256. cirq/ops/parity_gates.py +7 -8
  257. cirq/ops/parity_gates_test.py +1 -0
  258. cirq/ops/pauli_gates.py +5 -11
  259. cirq/ops/pauli_gates_test.py +1 -0
  260. cirq/ops/pauli_interaction_gate.py +11 -5
  261. cirq/ops/pauli_interaction_gate_test.py +2 -3
  262. cirq/ops/pauli_measurement_gate.py +6 -5
  263. cirq/ops/pauli_measurement_gate_test.py +1 -0
  264. cirq/ops/pauli_string.py +115 -130
  265. cirq/ops/pauli_string_phasor.py +21 -20
  266. cirq/ops/pauli_string_phasor_test.py +13 -3
  267. cirq/ops/pauli_string_raw_types.py +1 -0
  268. cirq/ops/pauli_string_test.py +192 -55
  269. cirq/ops/pauli_sum_exponential.py +3 -4
  270. cirq/ops/pauli_sum_exponential_test.py +0 -1
  271. cirq/ops/permutation_gate.py +2 -2
  272. cirq/ops/permutation_gate_test.py +1 -1
  273. cirq/ops/phased_iswap_gate.py +6 -7
  274. cirq/ops/phased_iswap_gate_test.py +21 -5
  275. cirq/ops/phased_x_gate.py +11 -25
  276. cirq/ops/phased_x_gate_test.py +19 -3
  277. cirq/ops/phased_x_z_gate.py +12 -11
  278. cirq/ops/projector.py +4 -5
  279. cirq/ops/qubit_manager.py +2 -1
  280. cirq/ops/qubit_manager_test.py +2 -1
  281. cirq/ops/qubit_order.py +1 -1
  282. cirq/ops/random_gate_channel.py +1 -1
  283. cirq/ops/random_gate_channel_test.py +0 -6
  284. cirq/ops/raw_types.py +146 -50
  285. cirq/ops/raw_types_test.py +37 -3
  286. cirq/ops/state_preparation_channel.py +2 -2
  287. cirq/ops/state_preparation_channel_test.py +2 -1
  288. cirq/ops/swap_gates.py +9 -4
  289. cirq/ops/three_qubit_gates.py +8 -8
  290. cirq/ops/three_qubit_gates_test.py +1 -0
  291. cirq/ops/two_qubit_diagonal_gate.py +4 -3
  292. cirq/ops/uniform_superposition_gate.py +4 -4
  293. cirq/ops/uniform_superposition_gate_test.py +1 -0
  294. cirq/ops/wait_gate.py +6 -8
  295. cirq/protocols/__init__.py +135 -83
  296. cirq/protocols/act_on_protocol.py +1 -1
  297. cirq/protocols/act_on_protocol_test.py +1 -1
  298. cirq/protocols/apply_channel_protocol.py +3 -3
  299. cirq/protocols/apply_mixture_protocol.py +15 -9
  300. cirq/protocols/apply_mixture_protocol_test.py +11 -0
  301. cirq/protocols/apply_unitary_protocol.py +2 -2
  302. cirq/protocols/apply_unitary_protocol_test.py +2 -1
  303. cirq/protocols/approximate_equality_protocol.py +7 -8
  304. cirq/protocols/approximate_equality_protocol_test.py +3 -1
  305. cirq/protocols/circuit_diagram_info_protocol.py +8 -6
  306. cirq/protocols/circuit_diagram_info_protocol_test.py +5 -0
  307. cirq/protocols/commutes_protocol.py +6 -6
  308. cirq/protocols/control_key_protocol.py +1 -1
  309. cirq/protocols/decompose_protocol.py +4 -5
  310. cirq/protocols/decompose_protocol_test.py +2 -1
  311. cirq/protocols/equal_up_to_global_phase_protocol.py +3 -3
  312. cirq/protocols/equal_up_to_global_phase_protocol_test.py +7 -0
  313. cirq/protocols/has_stabilizer_effect_protocol.py +5 -5
  314. cirq/protocols/has_unitary_protocol.py +1 -1
  315. cirq/protocols/has_unitary_protocol_test.py +8 -7
  316. cirq/protocols/hash_from_pickle_test.py +120 -0
  317. cirq/protocols/inverse_protocol.py +1 -1
  318. cirq/protocols/json_serialization.py +14 -1
  319. cirq/protocols/json_serialization_test.py +28 -7
  320. cirq/protocols/json_test_data/BitMaskKeyCondition.json +86 -0
  321. cirq/protocols/json_test_data/BitMaskKeyCondition.repr +7 -0
  322. cirq/protocols/json_test_data/Concat.json +19 -0
  323. cirq/protocols/json_test_data/Concat.repr +1 -0
  324. cirq/protocols/json_test_data/README.md +4 -2
  325. cirq/protocols/json_test_data/SympyCondition.json +60 -15
  326. cirq/protocols/json_test_data/SympyCondition.repr +4 -1
  327. cirq/protocols/json_test_data/_InverseCompositeGate.json +10 -0
  328. cirq/protocols/json_test_data/_InverseCompositeGate.repr +1 -0
  329. cirq/protocols/json_test_data/__init__.py +1 -1
  330. cirq/protocols/json_test_data/sympy.And.json +13 -0
  331. cirq/protocols/json_test_data/sympy.And.repr +1 -0
  332. cirq/protocols/json_test_data/sympy.Indexed.json +18 -0
  333. cirq/protocols/json_test_data/sympy.Indexed.repr +1 -0
  334. cirq/protocols/json_test_data/sympy.IndexedBase.json +9 -0
  335. cirq/protocols/json_test_data/sympy.IndexedBase.repr +1 -0
  336. cirq/protocols/json_test_data/sympy.Not.json +9 -0
  337. cirq/protocols/json_test_data/sympy.Not.repr +1 -0
  338. cirq/protocols/json_test_data/sympy.Or.json +13 -0
  339. cirq/protocols/json_test_data/sympy.Or.repr +1 -0
  340. cirq/protocols/json_test_data/sympy.Xor.json +13 -0
  341. cirq/protocols/json_test_data/sympy.Xor.repr +1 -0
  342. cirq/protocols/kraus_protocol.py +8 -8
  343. cirq/protocols/kraus_protocol_test.py +0 -1
  344. cirq/protocols/measurement_key_protocol.py +1 -1
  345. cirq/protocols/measurement_key_protocol_test.py +7 -7
  346. cirq/protocols/mixture_protocol.py +6 -4
  347. cirq/protocols/mixture_protocol_test.py +21 -13
  348. cirq/protocols/pauli_expansion_protocol.py +1 -0
  349. cirq/protocols/pow_protocol.py +1 -1
  350. cirq/protocols/qasm.py +25 -6
  351. cirq/protocols/qasm_test.py +17 -0
  352. cirq/protocols/qid_shape_protocol.py +2 -2
  353. cirq/protocols/resolve_parameters.py +2 -3
  354. cirq/protocols/resolve_parameters_test.py +2 -1
  355. cirq/protocols/trace_distance_bound.py +1 -1
  356. cirq/protocols/trace_distance_bound_test.py +1 -0
  357. cirq/protocols/unitary_protocol.py +3 -3
  358. cirq/protocols/unitary_protocol_test.py +1 -1
  359. cirq/qis/__init__.py +48 -35
  360. cirq/qis/channels_test.py +0 -9
  361. cirq/qis/clifford_tableau.py +46 -26
  362. cirq/qis/clifford_tableau_test.py +2 -1
  363. cirq/qis/entropy.py +115 -0
  364. cirq/qis/entropy_test.py +43 -0
  365. cirq/qis/measures.py +5 -4
  366. cirq/qis/measures_test.py +7 -0
  367. cirq/qis/noise_utils_test.py +4 -4
  368. cirq/qis/quantum_state_representation.py +1 -1
  369. cirq/qis/states.py +7 -7
  370. cirq/sim/__init__.py +55 -37
  371. cirq/sim/classical_simulator.py +7 -6
  372. cirq/sim/classical_simulator_test.py +3 -1
  373. cirq/sim/clifford/__init__.py +17 -9
  374. cirq/sim/clifford/clifford_simulator.py +5 -4
  375. cirq/sim/clifford/clifford_simulator_test.py +32 -9
  376. cirq/sim/clifford/clifford_tableau_simulation_state.py +1 -1
  377. cirq/sim/clifford/stabilizer_simulation_state.py +1 -1
  378. cirq/sim/clifford/stabilizer_state_ch_form.py +4 -3
  379. cirq/sim/density_matrix_simulator.py +3 -2
  380. cirq/sim/density_matrix_simulator_test.py +12 -4
  381. cirq/sim/density_matrix_utils.py +1 -1
  382. cirq/sim/mux.py +2 -2
  383. cirq/sim/simulation_state.py +4 -5
  384. cirq/sim/simulation_state_base.py +2 -2
  385. cirq/sim/simulation_state_test.py +1 -1
  386. cirq/sim/simulation_utils.py +3 -1
  387. cirq/sim/simulation_utils_test.py +2 -3
  388. cirq/sim/simulator.py +7 -6
  389. cirq/sim/simulator_base.py +5 -5
  390. cirq/sim/simulator_test.py +14 -3
  391. cirq/sim/sparse_simulator.py +4 -3
  392. cirq/sim/sparse_simulator_test.py +17 -9
  393. cirq/sim/state_vector.py +2 -2
  394. cirq/sim/state_vector_simulation_state_test.py +1 -1
  395. cirq/sim/state_vector_simulator.py +4 -4
  396. cirq/sim/state_vector_test.py +27 -32
  397. cirq/study/__init__.py +27 -21
  398. cirq/study/flatten_expressions.py +5 -6
  399. cirq/study/flatten_expressions_test.py +1 -1
  400. cirq/study/resolver.py +14 -11
  401. cirq/study/resolver_test.py +10 -1
  402. cirq/study/result.py +3 -3
  403. cirq/study/sweepable.py +15 -9
  404. cirq/study/sweepable_test.py +27 -0
  405. cirq/study/sweeps.py +65 -10
  406. cirq/study/sweeps_test.py +123 -0
  407. cirq/testing/__init__.py +86 -57
  408. cirq/testing/_compat_test_data/module_a/__init__.py +2 -2
  409. cirq/testing/_compat_test_data/module_a/sub/subsub/__init__.py +1 -1
  410. cirq/testing/circuit_compare.py +3 -4
  411. cirq/testing/circuit_compare_test.py +7 -8
  412. cirq/testing/consistent_act_on.py +3 -3
  413. cirq/testing/consistent_channels_test.py +2 -1
  414. cirq/testing/consistent_controlled_gate_op.py +3 -2
  415. cirq/testing/consistent_controlled_gate_op_test.py +2 -3
  416. cirq/testing/consistent_decomposition.py +1 -1
  417. cirq/testing/consistent_decomposition_test.py +1 -2
  418. cirq/testing/consistent_pauli_expansion_test.py +1 -1
  419. cirq/testing/consistent_phase_by.py +1 -1
  420. cirq/testing/consistent_phase_by_test.py +1 -2
  421. cirq/testing/consistent_protocols.py +11 -11
  422. cirq/testing/consistent_protocols_test.py +4 -5
  423. cirq/testing/consistent_qasm.py +8 -12
  424. cirq/testing/consistent_qasm_test.py +1 -1
  425. cirq/testing/consistent_resolve_parameters.py +2 -1
  426. cirq/testing/consistent_specified_has_unitary_test.py +1 -1
  427. cirq/testing/consistent_unitary.py +3 -1
  428. cirq/testing/consistent_unitary_test.py +3 -3
  429. cirq/testing/devices.py +1 -1
  430. cirq/testing/devices_test.py +1 -0
  431. cirq/testing/equals_tester.py +2 -4
  432. cirq/testing/equals_tester_test.py +6 -5
  433. cirq/testing/equivalent_basis_map.py +1 -0
  434. cirq/testing/equivalent_basis_map_test.py +0 -1
  435. cirq/testing/gate_features_test.py +5 -0
  436. cirq/testing/json.py +4 -4
  437. cirq/testing/lin_alg_utils_test.py +1 -1
  438. cirq/testing/order_tester.py +1 -1
  439. cirq/testing/order_tester_test.py +1 -1
  440. cirq/testing/pytest_utils.py +57 -0
  441. cirq/testing/pytest_utils_test.py +35 -0
  442. cirq/testing/random_circuit.py +2 -2
  443. cirq/testing/random_circuit_test.py +2 -2
  444. cirq/testing/routing_devices_test.py +2 -1
  445. cirq/testing/sample_circuits.py +1 -1
  446. cirq/testing/sample_gates.py +5 -4
  447. cirq/testing/sample_gates_test.py +2 -2
  448. cirq/transformers/__init__.py +101 -82
  449. cirq/transformers/align.py +12 -1
  450. cirq/transformers/align_test.py +13 -0
  451. cirq/transformers/analytical_decompositions/__init__.py +27 -24
  452. cirq/transformers/analytical_decompositions/clifford_decomposition.py +2 -1
  453. cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +1 -1
  454. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +1 -1
  455. cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
  456. cirq/transformers/analytical_decompositions/cphase_to_fsim.py +1 -1
  457. cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +1 -1
  458. cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +2 -2
  459. cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +4 -4
  460. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +99 -24
  461. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +105 -14
  462. cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +1 -1
  463. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +1 -1
  464. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +1 -0
  465. cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +3 -4
  466. cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +1 -1
  467. cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +2 -1
  468. cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -1
  469. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +5 -6
  470. cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +2 -2
  471. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +1 -1
  472. cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +1 -2
  473. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +2 -2
  474. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +2 -2
  475. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -1
  476. cirq/transformers/drop_empty_moments.py +1 -0
  477. cirq/transformers/drop_negligible_operations.py +1 -0
  478. cirq/transformers/dynamical_decoupling.py +255 -43
  479. cirq/transformers/dynamical_decoupling_test.py +730 -17
  480. cirq/transformers/eject_phased_paulis.py +29 -15
  481. cirq/transformers/eject_phased_paulis_test.py +3 -8
  482. cirq/transformers/eject_z.py +3 -2
  483. cirq/transformers/eject_z_test.py +3 -3
  484. cirq/transformers/gauge_compiling/__init__.py +25 -9
  485. cirq/transformers/gauge_compiling/cphase_gauge.py +146 -0
  486. cirq/transformers/gauge_compiling/cphase_gauge_test.py +42 -0
  487. cirq/transformers/gauge_compiling/cz_gauge.py +4 -4
  488. cirq/transformers/gauge_compiling/gauge_compiling.py +245 -6
  489. cirq/transformers/gauge_compiling/gauge_compiling_test.py +107 -2
  490. cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +39 -2
  491. cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +10 -1
  492. cirq/transformers/gauge_compiling/iswap_gauge.py +2 -2
  493. cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -2
  494. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +23 -5
  495. cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +3 -2
  496. cirq/transformers/heuristic_decompositions/__init__.py +3 -3
  497. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +2 -1
  498. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +1 -1
  499. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +4 -4
  500. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +4 -4
  501. cirq/transformers/insertion_sort.py +64 -0
  502. cirq/transformers/insertion_sort_test.py +34 -0
  503. cirq/transformers/measurement_transformers.py +14 -1
  504. cirq/transformers/measurement_transformers_test.py +35 -0
  505. cirq/transformers/merge_k_qubit_gates.py +2 -2
  506. cirq/transformers/merge_single_qubit_gates.py +1 -1
  507. cirq/transformers/merge_single_qubit_gates_test.py +1 -1
  508. cirq/transformers/noise_adding.py +115 -0
  509. cirq/transformers/noise_adding_test.py +54 -0
  510. cirq/transformers/optimize_for_target_gateset.py +1 -1
  511. cirq/transformers/optimize_for_target_gateset_test.py +3 -2
  512. cirq/transformers/qubit_management_transformers.py +1 -1
  513. cirq/transformers/randomized_measurements.py +171 -0
  514. cirq/transformers/randomized_measurements_test.py +68 -0
  515. cirq/transformers/routing/__init__.py +14 -5
  516. cirq/transformers/routing/initial_mapper.py +1 -1
  517. cirq/transformers/routing/initial_mapper_test.py +1 -0
  518. cirq/transformers/routing/line_initial_mapper.py +3 -2
  519. cirq/transformers/routing/mapping_manager.py +2 -2
  520. cirq/transformers/routing/mapping_manager_test.py +2 -2
  521. cirq/transformers/routing/route_circuit_cqc.py +3 -2
  522. cirq/transformers/routing/route_circuit_cqc_test.py +2 -1
  523. cirq/transformers/routing/visualize_routed_circuit.py +1 -0
  524. cirq/transformers/routing/visualize_routed_circuit_test.py +1 -0
  525. cirq/transformers/stratify.py +2 -2
  526. cirq/transformers/synchronize_terminal_measurements.py +2 -1
  527. cirq/transformers/target_gatesets/__init__.py +7 -5
  528. cirq/transformers/target_gatesets/compilation_target_gateset.py +16 -3
  529. cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -0
  530. cirq/transformers/target_gatesets/cz_gateset.py +5 -1
  531. cirq/transformers/target_gatesets/cz_gateset_test.py +23 -2
  532. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +1 -1
  533. cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +3 -2
  534. cirq/transformers/transformer_api.py +5 -4
  535. cirq/transformers/transformer_api_test.py +11 -3
  536. cirq/transformers/transformer_primitives.py +9 -31
  537. cirq/transformers/transformer_primitives_test.py +6 -5
  538. cirq/value/__init__.py +51 -30
  539. cirq/value/abc_alt.py +1 -2
  540. cirq/value/angle.py +2 -0
  541. cirq/value/classical_data.py +1 -0
  542. cirq/value/condition.py +149 -3
  543. cirq/value/condition_test.py +254 -0
  544. cirq/value/digits.py +1 -1
  545. cirq/value/duration.py +4 -4
  546. cirq/value/duration_test.py +2 -1
  547. cirq/value/linear_dict.py +85 -24
  548. cirq/value/linear_dict_test.py +94 -3
  549. cirq/value/measurement_key.py +9 -2
  550. cirq/value/periodic_value.py +2 -3
  551. cirq/value/periodic_value_test.py +5 -0
  552. cirq/value/probability.py +1 -0
  553. cirq/value/random_state.py +1 -1
  554. cirq/value/timestamp.py +2 -4
  555. cirq/value/timestamp_test.py +2 -1
  556. cirq/value/type_alias.py +2 -2
  557. cirq/value/value_equality_attr.py +14 -2
  558. cirq/value/value_equality_attr_test.py +1 -1
  559. cirq/vis/__init__.py +9 -6
  560. cirq/vis/density_matrix.py +1 -1
  561. cirq/vis/density_matrix_test.py +2 -5
  562. cirq/vis/heatmap.py +49 -12
  563. cirq/vis/heatmap_test.py +168 -4
  564. cirq/vis/histogram.py +1 -1
  565. cirq/vis/histogram_test.py +1 -2
  566. cirq/vis/state_histogram.py +7 -5
  567. cirq/vis/state_histogram_test.py +2 -2
  568. cirq/work/__init__.py +19 -13
  569. cirq/work/collector.py +2 -2
  570. cirq/work/observable_grouping.py +2 -2
  571. cirq/work/observable_measurement.py +3 -3
  572. cirq/work/observable_measurement_data.py +5 -2
  573. cirq/work/observable_measurement_test.py +8 -8
  574. cirq/work/observable_readout_calibration.py +2 -2
  575. cirq/work/observable_readout_calibration_test.py +2 -1
  576. cirq/work/observable_settings.py +8 -7
  577. cirq/work/observable_settings_test.py +3 -2
  578. cirq/work/pauli_sum_collector.py +1 -1
  579. cirq/work/sampler.py +8 -20
  580. cirq/work/sampler_test.py +4 -3
  581. cirq/work/zeros_sampler.py +1 -1
  582. cirq_core-1.5.0.dist-info/METADATA +125 -0
  583. {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/RECORD +586 -552
  584. {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/WHEEL +1 -1
  585. cirq/experiments/grid_parallel_two_qubit_xeb.py +0 -62
  586. cirq/protocols/json_test_data/GridParallelXEBMetadata.json +0 -119
  587. cirq/protocols/json_test_data/GridParallelXEBMetadata.repr +0 -1
  588. cirq_core-1.4.1.dist-info/METADATA +0 -45
  589. {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/LICENSE +0 -0
  590. {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/top_level.txt +0 -0
cirq/value/linear_dict.py CHANGED
@@ -13,8 +13,9 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Linear combination represented as mapping of things to coefficients."""
16
- import numbers
16
+
17
17
  from typing import (
18
+ AbstractSet,
18
19
  Any,
19
20
  Callable,
20
21
  Dict,
@@ -28,19 +29,44 @@ from typing import (
28
29
  Optional,
29
30
  overload,
30
31
  Tuple,
32
+ TYPE_CHECKING,
31
33
  TypeVar,
32
34
  Union,
33
35
  ValuesView,
34
36
  )
37
+
38
+ import numpy as np
39
+ import sympy
35
40
  from typing_extensions import Self
36
41
 
37
- Scalar = Union[complex, float, numbers.Complex]
42
+ from cirq import protocols
43
+
44
+ if TYPE_CHECKING:
45
+ import cirq
46
+
47
+ Scalar = Union[complex, np.number]
38
48
  TVector = TypeVar('TVector')
39
49
 
40
50
  TDefault = TypeVar('TDefault')
41
51
 
42
52
 
43
- def _format_coefficient(format_spec: str, coefficient: Scalar) -> str:
53
+ class _SympyPrinter(sympy.printing.str.StrPrinter):
54
+ def __init__(self, format_spec: str):
55
+ super().__init__()
56
+ self._format_spec = format_spec
57
+
58
+ def _print(self, expr, **kwargs):
59
+ if expr.is_complex:
60
+ coefficient = complex(expr)
61
+ s = _format_coefficient(self._format_spec, coefficient)
62
+ return s[1:-1] if s.startswith('(') else s
63
+ return super()._print(expr, **kwargs)
64
+
65
+
66
+ def _format_coefficient(format_spec: str, coefficient: 'cirq.TParamValComplex') -> str:
67
+ if isinstance(coefficient, sympy.Basic):
68
+ printer = _SympyPrinter(format_spec)
69
+ return printer.doprint(coefficient)
44
70
  coefficient = complex(coefficient)
45
71
  real_str = f'{coefficient.real:{format_spec}}'
46
72
  imag_str = f'{coefficient.imag:{format_spec}}'
@@ -57,7 +83,7 @@ def _format_coefficient(format_spec: str, coefficient: Scalar) -> str:
57
83
  return f'({real_str}+{imag_str}j)'
58
84
 
59
85
 
60
- def _format_term(format_spec: str, vector: TVector, coefficient: Scalar) -> str:
86
+ def _format_term(format_spec: str, vector: TVector, coefficient: 'cirq.TParamValComplex') -> str:
61
87
  coefficient_str = _format_coefficient(format_spec, coefficient)
62
88
  if not coefficient_str:
63
89
  return coefficient_str
@@ -67,7 +93,7 @@ def _format_term(format_spec: str, vector: TVector, coefficient: Scalar) -> str:
67
93
  return '+' + result
68
94
 
69
95
 
70
- def _format_terms(terms: Iterable[Tuple[TVector, Scalar]], format_spec: str):
96
+ def _format_terms(terms: Iterable[Tuple[TVector, 'cirq.TParamValComplex']], format_spec: str):
71
97
  formatted_terms = [_format_term(format_spec, vector, coeff) for vector, coeff in terms]
72
98
  s = ''.join(formatted_terms)
73
99
  if not s:
@@ -77,7 +103,7 @@ def _format_terms(terms: Iterable[Tuple[TVector, Scalar]], format_spec: str):
77
103
  return s
78
104
 
79
105
 
80
- class LinearDict(Generic[TVector], MutableMapping[TVector, Scalar]):
106
+ class LinearDict(Generic[TVector], MutableMapping[TVector, 'cirq.TParamValComplex']):
81
107
  """Represents linear combination of things.
82
108
 
83
109
  LinearDict implements the basic linear algebraic operations of vector
@@ -94,7 +120,7 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, Scalar]):
94
120
 
95
121
  def __init__(
96
122
  self,
97
- terms: Optional[Mapping[TVector, Scalar]] = None,
123
+ terms: Optional[Mapping[TVector, 'cirq.TParamValComplex']] = None,
98
124
  validator: Optional[Callable[[TVector], bool]] = None,
99
125
  ) -> None:
100
126
  """Initializes linear combination from a collection of terms.
@@ -110,13 +136,18 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, Scalar]):
110
136
  """
111
137
  self._has_validator = validator is not None
112
138
  self._is_valid = validator or (lambda x: True)
113
- self._terms: Dict[TVector, Scalar] = {}
139
+ self._terms: Dict[TVector, 'cirq.TParamValComplex'] = {}
114
140
  if terms is not None:
115
141
  self.update(terms)
116
142
 
117
143
  @classmethod
118
144
  def fromkeys(cls, vectors, coefficient=0):
119
- return LinearDict(dict.fromkeys(vectors, complex(coefficient)))
145
+ return LinearDict(
146
+ dict.fromkeys(
147
+ vectors,
148
+ coefficient if isinstance(coefficient, sympy.Basic) else complex(coefficient),
149
+ )
150
+ )
120
151
 
121
152
  def _check_vector_valid(self, vector: TVector) -> None:
122
153
  if not self._is_valid(vector):
@@ -124,7 +155,11 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, Scalar]):
124
155
 
125
156
  def clean(self, *, atol: float = 1e-9) -> Self:
126
157
  """Remove terms with coefficients of absolute value atol or less."""
127
- negligible = [v for v, c in self._terms.items() if abs(c) <= atol] # type: ignore[operator]
158
+ negligible = [
159
+ v
160
+ for v, c in self._terms.items()
161
+ if not isinstance(c, sympy.Basic) and abs(complex(c)) <= atol
162
+ ]
128
163
  for v in negligible:
129
164
  del self._terms[v]
130
165
  return self
@@ -137,40 +172,50 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, Scalar]):
137
172
  snapshot = self.copy().clean(atol=0)
138
173
  return snapshot._terms.keys()
139
174
 
140
- def values(self) -> ValuesView[Scalar]:
175
+ def values(self) -> ValuesView['cirq.TParamValComplex']:
141
176
  snapshot = self.copy().clean(atol=0)
142
177
  return snapshot._terms.values()
143
178
 
144
- def items(self) -> ItemsView[TVector, Scalar]:
179
+ def items(self) -> ItemsView[TVector, 'cirq.TParamValComplex']:
145
180
  snapshot = self.copy().clean(atol=0)
146
181
  return snapshot._terms.items()
147
182
 
148
183
  # pylint: disable=function-redefined
149
184
  @overload
150
- def update(self, other: Mapping[TVector, Scalar], **kwargs: Scalar) -> None:
185
+ def update(
186
+ self, other: Mapping[TVector, 'cirq.TParamValComplex'], **kwargs: 'cirq.TParamValComplex'
187
+ ) -> None:
151
188
  pass
152
189
 
153
190
  @overload
154
- def update(self, other: Iterable[Tuple[TVector, Scalar]], **kwargs: Scalar) -> None:
191
+ def update(
192
+ self,
193
+ other: Iterable[Tuple[TVector, 'cirq.TParamValComplex']],
194
+ **kwargs: 'cirq.TParamValComplex',
195
+ ) -> None:
155
196
  pass
156
197
 
157
198
  @overload
158
- def update(self, *args: Any, **kwargs: Scalar) -> None:
199
+ def update(self, *args: Any, **kwargs: 'cirq.TParamValComplex') -> None:
159
200
  pass
160
201
 
161
202
  def update(self, *args, **kwargs):
162
203
  terms = dict()
163
204
  terms.update(*args, **kwargs)
164
205
  for vector, coefficient in terms.items():
206
+ if isinstance(coefficient, sympy.Basic):
207
+ coefficient = sympy.simplify(coefficient)
208
+ if coefficient.is_complex:
209
+ coefficient = complex(coefficient)
165
210
  self[vector] = coefficient
166
211
  self.clean(atol=0)
167
212
 
168
213
  @overload
169
- def get(self, vector: TVector) -> Scalar:
214
+ def get(self, vector: TVector) -> 'cirq.TParamValComplex':
170
215
  pass
171
216
 
172
217
  @overload
173
- def get(self, vector: TVector, default: TDefault) -> Union[Scalar, TDefault]:
218
+ def get(self, vector: TVector, default: TDefault) -> Union['cirq.TParamValComplex', TDefault]:
174
219
  pass
175
220
 
176
221
  def get(self, vector, default=0):
@@ -183,10 +228,10 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, Scalar]):
183
228
  def __contains__(self, vector: Any) -> bool:
184
229
  return vector in self._terms and self._terms[vector] != 0
185
230
 
186
- def __getitem__(self, vector: TVector) -> Scalar:
231
+ def __getitem__(self, vector: TVector) -> 'cirq.TParamValComplex':
187
232
  return self._terms.get(vector, 0)
188
233
 
189
- def __setitem__(self, vector: TVector, coefficient: Scalar) -> None:
234
+ def __setitem__(self, vector: TVector, coefficient: 'cirq.TParamValComplex') -> None:
190
235
  self._check_vector_valid(vector)
191
236
  if coefficient != 0:
192
237
  self._terms[vector] = coefficient
@@ -234,21 +279,21 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, Scalar]):
234
279
  factory = type(self)
235
280
  return factory({v: -c for v, c in self.items()})
236
281
 
237
- def __imul__(self, a: Scalar) -> Self:
282
+ def __imul__(self, a: 'cirq.TParamValComplex') -> Self:
238
283
  for vector in self:
239
284
  self._terms[vector] *= a
240
285
  self.clean(atol=0)
241
286
  return self
242
287
 
243
- def __mul__(self, a: Scalar) -> Self:
288
+ def __mul__(self, a: 'cirq.TParamValComplex') -> Self:
244
289
  result = self.copy()
245
290
  result *= a
246
- return result
291
+ return result.copy()
247
292
 
248
- def __rmul__(self, a: Scalar) -> Self:
293
+ def __rmul__(self, a: 'cirq.TParamValComplex') -> Self:
249
294
  return self.__mul__(a)
250
295
 
251
- def __truediv__(self, a: Scalar) -> Self:
296
+ def __truediv__(self, a: 'cirq.TParamValComplex') -> Self:
252
297
  return self.__mul__(1 / a)
253
298
 
254
299
  def __bool__(self) -> bool:
@@ -318,3 +363,19 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, Scalar]):
318
363
  @classmethod
319
364
  def _from_json_dict_(cls, keys, values, **kwargs):
320
365
  return cls(terms=dict(zip(keys, values)))
366
+
367
+ def _is_parameterized_(self) -> bool:
368
+ return any(protocols.is_parameterized(v) for v in self._terms.values())
369
+
370
+ def _parameter_names_(self) -> AbstractSet[str]:
371
+ return set(name for v in self._terms.values() for name in protocols.parameter_names(v))
372
+
373
+ def _resolve_parameters_(self, resolver: 'cirq.ParamResolver', recursive: bool) -> 'LinearDict':
374
+ result = self.copy()
375
+ result.update(
376
+ {
377
+ k: protocols.resolve_parameters(v, resolver, recursive)
378
+ for k, v in self._terms.items()
379
+ }
380
+ )
381
+ return result
@@ -14,6 +14,7 @@
14
14
 
15
15
  import numpy as np
16
16
  import pytest
17
+ import sympy
17
18
 
18
19
  import cirq
19
20
 
@@ -24,6 +25,12 @@ def test_empty_init():
24
25
  assert not v
25
26
 
26
27
 
28
+ sym = sympy.Symbol('sym')
29
+ expr = sym * -(2 + 3j)
30
+ symval = expr.subs({'sym': 5})
31
+ symvalresolved = -10 - 15j
32
+
33
+
27
34
  @pytest.mark.parametrize(
28
35
  'keys, coefficient, terms_expected',
29
36
  (
@@ -31,6 +38,9 @@ def test_empty_init():
31
38
  (('X',), 2, {'X': 2}),
32
39
  (('a', 'b', 'c', 'd'), 0.5, {'a': 0.5, 'b': 0.5, 'c': 0.5, 'd': 0.5}),
33
40
  (('b', 'c', 'd', 'e'), -2j, {'b': -2j, 'c': -2j, 'd': -2j, 'e': -2j}),
41
+ (('b', 'c'), sym, {'b': sym, 'c': sym}),
42
+ (('b', 'c'), expr, {'b': expr, 'c': expr}),
43
+ (('b', 'c'), symval, {'b': symvalresolved, 'c': symvalresolved}),
34
44
  ),
35
45
  )
36
46
  def test_fromkeys(keys, coefficient, terms_expected):
@@ -273,6 +283,9 @@ def test_len(terms, expected_length):
273
283
  ({'X': 1}, {'Y': 2}, {'X': 1, 'Y': 2}),
274
284
  ({'X': 1}, {'X': 1}, {'X': 2}),
275
285
  ({'X': 1, 'Y': 2}, {'Y': -2}, {'X': 1}),
286
+ ({'X': 1}, {'X': sym}, {'X': sym + 1}),
287
+ ({'X': 1}, {'X': expr}, {'X': expr + 1}),
288
+ ({'X': 1}, {'X': symval}, {'X': symvalresolved + 1}),
276
289
  ),
277
290
  )
278
291
  def test_vector_addition(terms_1, terms_2, terms_expected):
@@ -297,6 +310,9 @@ def test_vector_addition(terms_1, terms_2, terms_expected):
297
310
  ({'X': 1}, {'X': 1}, {}),
298
311
  ({'X': 1, 'Y': 2}, {'Y': 2}, {'X': 1}),
299
312
  ({'X': 1, 'Y': 2}, {'Y': 3}, {'X': 1, 'Y': -1}),
313
+ ({'X': 1}, {'X': sym}, {'X': 1 - sym}),
314
+ ({'X': 1}, {'X': expr}, {'X': 1 - expr}),
315
+ ({'X': 1}, {'X': symval}, {'X': 1 - symvalresolved}),
300
316
  ),
301
317
  )
302
318
  def test_vector_subtraction(terms_1, terms_2, terms_expected):
@@ -313,7 +329,14 @@ def test_vector_subtraction(terms_1, terms_2, terms_expected):
313
329
 
314
330
  @pytest.mark.parametrize(
315
331
  'terms, terms_expected',
316
- (({}, {}), ({'key': 1}, {'key': -1}), ({'1': 10, '2': -20}, {'1': -10, '2': 20})),
332
+ (
333
+ ({}, {}),
334
+ ({'key': 1}, {'key': -1}),
335
+ ({'1': 10, '2': -20}, {'1': -10, '2': 20}),
336
+ ({'key': sym}, {'key': -sym}),
337
+ ({'key': expr}, {'key': -expr}),
338
+ ({'key': symval}, {'key': -symvalresolved}),
339
+ ),
317
340
  )
318
341
  def test_vector_negation(terms, terms_expected):
319
342
  linear_dict = cirq.LinearDict(terms)
@@ -331,6 +354,12 @@ def test_vector_negation(terms, terms_expected):
331
354
  (0, {'abc': 10, 'def': 20}, {}),
332
355
  (1j, {'X': 4j}, {'X': -4}),
333
356
  (-1, {'a': 10, 'b': -20}, {'a': -10, 'b': 20}),
357
+ (2, {'X': sym}, {'X': 2 * sym}),
358
+ (2, {'X': expr}, {'X': 2 * expr}),
359
+ (2, {'X': symval}, {'X': 2 * symvalresolved}),
360
+ (sym, {'X': 2}, {'X': 2 * sym}),
361
+ (expr, {'X': 2}, {'X': 2 * expr}),
362
+ (symval, {'X': 2}, {'X': 2 * symvalresolved}),
334
363
  ),
335
364
  )
336
365
  def test_scalar_multiplication(scalar, terms, terms_expected):
@@ -350,6 +379,12 @@ def test_scalar_multiplication(scalar, terms, terms_expected):
350
379
  (2, {'X': 6, 'Y': -2}, {'X': 3, 'Y': -1}),
351
380
  (1j, {'X': 1, 'Y': 1j}, {'X': -1j, 'Y': 1}),
352
381
  (-1, {'a': 10, 'b': -20}, {'a': -10, 'b': 20}),
382
+ (2, {'X': sym}, {'X': 0.5 * sym}),
383
+ (2, {'X': expr}, {'X': 0.5 * expr}),
384
+ (2, {'X': symval}, {'X': 0.5 * symvalresolved}),
385
+ (sym, {'X': 2}, {'X': 2 / sym}),
386
+ (expr, {'X': 2}, {'X': 2 / expr}),
387
+ (symval, {'X': 2}, {'X': 2 / symvalresolved}),
353
388
  ),
354
389
  )
355
390
  def test_scalar_division(scalar, terms, terms_expected):
@@ -387,7 +422,13 @@ def test_bool(terms, bool_value):
387
422
 
388
423
  @pytest.mark.parametrize(
389
424
  'terms_1, terms_2',
390
- (({}, {}), ({}, {'X': 0}), ({'X': 0.0}, {'Y': 0.0}), ({'a': 1}, {'a': 1, 'b': 0})),
425
+ (
426
+ ({}, {}),
427
+ ({}, {'X': 0}),
428
+ ({'X': 0.0}, {'Y': 0.0}),
429
+ ({'a': 1}, {'a': 1, 'b': 0}),
430
+ ({'X': sym}, {'X': sym}),
431
+ ),
391
432
  )
392
433
  def test_equal(terms_1, terms_2):
393
434
  linear_dict_1 = cirq.LinearDict(terms_1)
@@ -405,6 +446,7 @@ def test_equal(terms_1, terms_2):
405
446
  ({'X': 1e-12}, {'X': 0}),
406
447
  ({'X': 0.0}, {'Y': 0.1}),
407
448
  ({'X': 1}, {'X': 1, 'Z': 1e-12}),
449
+ ({'X': sym + 0.1}, {'X': sym}),
408
450
  ),
409
451
  )
410
452
  def test_unequal(terms_1, terms_2):
@@ -423,6 +465,7 @@ def test_unequal(terms_1, terms_2):
423
465
  ({'X': 1e-12}, {'X': 0}),
424
466
  ({'X': 5e-10}, {'Y': 2e-11}),
425
467
  ({'X': 1.000000001}, {'X': 1, 'Z': 0}),
468
+ ({'X': sym + 0.000000001}, {'X': sym}),
426
469
  ),
427
470
  )
428
471
  def test_approximately_equal(terms_1, terms_2):
@@ -476,7 +519,20 @@ def test_format(terms, fmt, expected_string):
476
519
  assert actual_string.replace(' ', '') == expected_string.replace(' ', '')
477
520
 
478
521
 
479
- @pytest.mark.parametrize('terms', (({}, {'X': 1}, {'X': 2, 'Y': 3}, {'X': 1.23456789e-12})))
522
+ @pytest.mark.parametrize(
523
+ 'terms',
524
+ (
525
+ (
526
+ {},
527
+ {'X': 1},
528
+ {'X': 2, 'Y': 3},
529
+ {'X': 1.23456789e-12},
530
+ {'X': sym},
531
+ ({'X': sym * 2}),
532
+ {'X': symval},
533
+ )
534
+ ),
535
+ )
480
536
  def test_repr(terms):
481
537
  original = cirq.LinearDict(terms)
482
538
  recovered = eval(repr(original))
@@ -502,6 +558,10 @@ def test_repr(terms):
502
558
  ({'X': -2, 'Y': -3}, '-2.000*X-3.000*Y'),
503
559
  ({'X': -2j, 'Y': -3}, '-2.000j*X-3.000*Y'),
504
560
  ({'X': -2j, 'Y': -3j}, '-2.000j*X-3.000j*Y'),
561
+ ({'X': sym}, 'sym*X'),
562
+ ({'X': sym * 2}, '2.000*sym*X'),
563
+ ({'X': expr}, '-sym*(2.000+3.000j)*X'),
564
+ ({'X': symval}, '-(10.000+15.000j)*X'),
505
565
  ),
506
566
  )
507
567
  def test_str(terms, string):
@@ -547,3 +607,34 @@ def test_repr_pretty(terms):
547
607
  def test_json_fails_with_validator():
548
608
  with pytest.raises(ValueError, match='not json serializable'):
549
609
  _ = cirq.to_json(cirq.LinearDict({}, validator=lambda: True))
610
+
611
+
612
+ @pytest.mark.parametrize(
613
+ 'terms, names',
614
+ (
615
+ ({'X': sym}, {'sym'}),
616
+ ({'X': sym * sympy.Symbol('a')}, {'sym', 'a'}),
617
+ ({'X': expr}, {'sym'}),
618
+ ({'X': sym, 'Y': sympy.Symbol('a')}, {'sym', 'a'}),
619
+ ({'X': symval}, set()),
620
+ ),
621
+ )
622
+ def test_parameter_names(terms, names):
623
+ linear_dict = cirq.LinearDict(terms)
624
+ assert cirq.parameter_names(linear_dict) == names
625
+
626
+
627
+ @pytest.mark.parametrize(
628
+ 'terms, expected',
629
+ (
630
+ ({'X': sym}, {'X': 2}),
631
+ ({'X': sym * sympy.Symbol('a')}, {'X': 6}),
632
+ ({'X': expr}, {'X': -4 - 6j}),
633
+ ({'X': sym, 'Y': sympy.Symbol('a')}, {'X': 2, 'Y': 3}),
634
+ ({'X': symval}, {'X': symvalresolved}),
635
+ ),
636
+ )
637
+ def test_resolve_parameters(terms, expected):
638
+ linear_dict = cirq.LinearDict(terms)
639
+ expected_dict = cirq.LinearDict(expected)
640
+ assert cirq.resolve_parameters(linear_dict, {'sym': 2, 'a': 3}) == expected_dict
@@ -12,9 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import FrozenSet, Mapping, Optional, Tuple
16
-
17
15
  import dataclasses
16
+ from typing import Any, Dict, FrozenSet, Mapping, Optional, Tuple
18
17
 
19
18
  MEASUREMENT_KEY_SEPARATOR = ':'
20
19
 
@@ -77,6 +76,14 @@ class MeasurementKey:
77
76
  object.__setattr__(self, '_hash', hash(str(self)))
78
77
  return self._hash
79
78
 
79
+ def __getstate__(self) -> Dict[str, Any]:
80
+ # clear cached hash value when pickling, see #6674
81
+ state = self.__dict__
82
+ if "_hash" in state:
83
+ state = state.copy()
84
+ del state["_hash"]
85
+ return state
86
+
80
87
  def __lt__(self, other):
81
88
  if isinstance(other, MeasurementKey):
82
89
  if self.path != other.path:
@@ -12,13 +12,12 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import AbstractSet, Any, TYPE_CHECKING, Union
15
+ from typing import AbstractSet, Any, TYPE_CHECKING
16
16
 
17
17
  import sympy
18
18
 
19
19
  from cirq._compat import proper_repr
20
20
 
21
-
22
21
  if TYPE_CHECKING:
23
22
  import cirq
24
23
 
@@ -36,7 +35,7 @@ class PeriodicValue:
36
35
  interval.
37
36
  """
38
37
 
39
- def __init__(self, value: Union[int, float, sympy.Expr], period: Union[int, float, sympy.Expr]):
38
+ def __init__(self, value: 'cirq.TParamVal', period: 'cirq.TParamVal'):
40
39
  """Initializes the equivalence class.
41
40
 
42
41
  Args:
@@ -42,6 +42,11 @@ def test_periodic_value_approx_eq_basic():
42
42
  assert not cirq.approx_eq(cirq.PeriodicValue(1.0, 2.0), cirq.PeriodicValue(1.0, 2.2), atol=0.1)
43
43
  assert not cirq.approx_eq(cirq.PeriodicValue(1.0, 2.0), cirq.PeriodicValue(1.2, 2.2), atol=0.3)
44
44
  assert not cirq.approx_eq(cirq.PeriodicValue(1.0, 2.0), cirq.PeriodicValue(1.2, 2.2), atol=0.1)
45
+ assert cirq.approx_eq(
46
+ cirq.PeriodicValue(sympy.Symbol('t'), 2.0),
47
+ cirq.PeriodicValue(sympy.Symbol('t'), 2.0),
48
+ atol=0.1,
49
+ )
45
50
 
46
51
 
47
52
  def test_periodic_value_approx_eq_normalized():
cirq/value/probability.py CHANGED
@@ -17,6 +17,7 @@
17
17
  from typing import TYPE_CHECKING
18
18
 
19
19
  import numpy as np
20
+
20
21
  from cirq.qis import to_valid_state_vector
21
22
 
22
23
  if TYPE_CHECKING:
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import cast, Any
15
+ from typing import Any, cast
16
16
 
17
17
  import numpy as np
18
18
 
cirq/value/timestamp.py CHANGED
@@ -14,7 +14,7 @@
14
14
  """A typed location in time that supports picosecond accuracy."""
15
15
 
16
16
  from datetime import timedelta
17
- from typing import Union, overload
17
+ from typing import overload
18
18
 
19
19
  from cirq.value.duration import Duration
20
20
 
@@ -24,9 +24,7 @@ class Timestamp:
24
24
 
25
25
  Supports affine operations against Duration."""
26
26
 
27
- def __init__(
28
- self, *, picos: Union[int, float] = 0, nanos: Union[int, float] = 0 # Forces keyword args.
29
- ) -> None:
27
+ def __init__(self, *, picos: float = 0, nanos: float = 0) -> None: # Forces keyword args.
30
28
  """Initializes a Timestamp with a time specified in ns and/or ps.
31
29
 
32
30
  The time is relative to some unspecified "time zero". If both picos and
@@ -13,10 +13,11 @@
13
13
  # limitations under the License.
14
14
 
15
15
  from datetime import timedelta
16
+
16
17
  import pytest
17
18
 
18
19
  import cirq
19
- from cirq import Timestamp, Duration
20
+ from cirq import Duration, Timestamp
20
21
 
21
22
 
22
23
  def test_init():
cirq/value/type_alias.py CHANGED
@@ -14,10 +14,10 @@
14
14
 
15
15
  from typing import Union
16
16
 
17
+ import numpy as np
17
18
  import sympy
18
19
 
19
20
  from cirq._doc import document
20
- from cirq.value import linear_dict
21
21
 
22
22
  """Supply aliases for commonly used types.
23
23
  """
@@ -28,5 +28,5 @@ document(TParamKey, """A parameter that a parameter resolver may map to a value.
28
28
  TParamVal = Union[float, sympy.Expr]
29
29
  document(TParamVal, """A value that a parameter resolver may return for a parameter.""")
30
30
 
31
- TParamValComplex = Union[linear_dict.Scalar, sympy.Expr]
31
+ TParamValComplex = Union[complex, np.number, sympy.Expr]
32
32
  document(TParamValComplex, """A complex value that parameter resolvers may use for parameters.""")
@@ -13,11 +13,11 @@
13
13
  # limitations under the License.
14
14
  """Defines `@cirq.value_equality`, for easy __eq__/__hash__ methods."""
15
15
 
16
- from typing import Any, Callable, Optional, overload, Union
16
+ from typing import Any, Callable, Dict, Optional, overload, Union
17
17
 
18
18
  from typing_extensions import Protocol
19
19
 
20
- from cirq import protocols, _compat
20
+ from cirq import _compat, protocols
21
21
 
22
22
 
23
23
  class _SupportsValueEquality(Protocol):
@@ -110,6 +110,16 @@ def _value_equality_approx_eq(
110
110
  )
111
111
 
112
112
 
113
+ def _value_equality_getstate(self: _SupportsValueEquality) -> Dict[str, Any]:
114
+ # clear cached hash value when pickling, see #6674
115
+ state = self.__dict__
116
+ hash_attr = _compat._method_cache_name(self.__hash__)
117
+ if hash_attr in state:
118
+ state = state.copy()
119
+ del state[hash_attr]
120
+ return state
121
+
122
+
113
123
  # pylint: disable=function-redefined
114
124
  @overload
115
125
  def value_equality(
@@ -228,6 +238,8 @@ def value_equality(
228
238
  cached_values_getter = values_getter if unhashable else _compat.cached_method(values_getter)
229
239
  setattr(cls, '_value_equality_values_', cached_values_getter)
230
240
  setattr(cls, '__hash__', None if unhashable else _compat.cached_method(_value_equality_hash))
241
+ if not unhashable:
242
+ setattr(cls, '__getstate__', _value_equality_getstate)
231
243
  setattr(cls, '__eq__', _value_equality_eq)
232
244
  setattr(cls, '__ne__', _value_equality_ne)
233
245
 
@@ -94,7 +94,7 @@ class UnhashableD:
94
94
  self.x = x
95
95
 
96
96
  def _value_equality_values_(self):
97
- return self.x
97
+ return self.x # pragma: no cover
98
98
 
99
99
 
100
100
  class UnhashableCa(UnhashableC):
cirq/vis/__init__.py CHANGED
@@ -14,14 +14,17 @@
14
14
 
15
15
  """Classes and methods for visualizing results, quantum states, and devices."""
16
16
 
17
- from cirq.vis.heatmap import Heatmap
17
+ from cirq.vis.heatmap import Heatmap as Heatmap
18
18
 
19
- from cirq.vis.heatmap import TwoQubitInteractionHeatmap
19
+ from cirq.vis.heatmap import TwoQubitInteractionHeatmap as TwoQubitInteractionHeatmap
20
20
 
21
- from cirq.vis.histogram import integrated_histogram
21
+ from cirq.vis.histogram import integrated_histogram as integrated_histogram
22
22
 
23
- from cirq.vis.state_histogram import get_state_histogram, plot_state_histogram
23
+ from cirq.vis.state_histogram import (
24
+ get_state_histogram as get_state_histogram,
25
+ plot_state_histogram as plot_state_histogram,
26
+ )
24
27
 
25
- from cirq.vis.density_matrix import plot_density_matrix
28
+ from cirq.vis.density_matrix import plot_density_matrix as plot_density_matrix
26
29
 
27
- from cirq.vis.vis_utils import relative_luminance
30
+ from cirq.vis.vis_utils import relative_luminance as relative_luminance
@@ -16,8 +16,8 @@
16
16
 
17
17
  from typing import Optional
18
18
 
19
- import numpy as np
20
19
  import matplotlib.pyplot as plt
20
+ import numpy as np
21
21
  from matplotlib import lines, patches
22
22
 
23
23
  from cirq.qis.states import validate_density_matrix
@@ -15,13 +15,10 @@
15
15
 
16
16
  import numpy as np
17
17
  import pytest
18
-
19
- from matplotlib import lines, patches, text, spines, axis
20
- from matplotlib import pyplot as plt
18
+ from matplotlib import axis, lines, patches, pyplot as plt, spines, text
21
19
 
22
20
  import cirq.testing
23
- from cirq.vis.density_matrix import plot_density_matrix
24
- from cirq.vis.density_matrix import _plot_element_of_density_matrix
21
+ from cirq.vis.density_matrix import _plot_element_of_density_matrix, plot_density_matrix
25
22
 
26
23
 
27
24
  @pytest.mark.usefixtures('closefigures')