cirq-core 1.4.0.dev20240529225110__py3-none-any.whl → 1.5.0__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (590) hide show
  1. cirq/__init__.py +587 -569
  2. cirq/_compat.py +9 -0
  3. cirq/_compat_test.py +11 -9
  4. cirq/_import.py +7 -8
  5. cirq/_version.py +31 -1
  6. cirq/_version_test.py +1 -1
  7. cirq/circuits/__init__.py +15 -9
  8. cirq/circuits/_block_diagram_drawer.py +1 -2
  9. cirq/circuits/_block_diagram_drawer_test.py +3 -3
  10. cirq/circuits/_box_drawing_character_data.py +0 -1
  11. cirq/circuits/_box_drawing_character_data_test.py +2 -2
  12. cirq/circuits/_bucket_priority_queue.py +0 -1
  13. cirq/circuits/_bucket_priority_queue_test.py +1 -1
  14. cirq/circuits/circuit.py +336 -234
  15. cirq/circuits/circuit_operation.py +102 -52
  16. cirq/circuits/circuit_operation_test.py +85 -4
  17. cirq/circuits/circuit_test.py +101 -32
  18. cirq/circuits/frozen_circuit.py +36 -32
  19. cirq/circuits/insert_strategy.py +10 -0
  20. cirq/circuits/insert_strategy_test.py +20 -0
  21. cirq/circuits/moment.py +79 -80
  22. cirq/circuits/moment_test.py +105 -2
  23. cirq/circuits/optimization_pass.py +15 -15
  24. cirq/circuits/optimization_pass_test.py +8 -9
  25. cirq/circuits/qasm_output.py +64 -33
  26. cirq/circuits/qasm_output_test.py +63 -2
  27. cirq/circuits/text_diagram_drawer.py +26 -56
  28. cirq/circuits/text_diagram_drawer_test.py +5 -4
  29. cirq/contrib/__init__.py +2 -2
  30. cirq/contrib/acquaintance/__init__.py +44 -29
  31. cirq/contrib/acquaintance/bipartite.py +8 -7
  32. cirq/contrib/acquaintance/bipartite_test.py +11 -1
  33. cirq/contrib/acquaintance/devices.py +5 -4
  34. cirq/contrib/acquaintance/devices_test.py +5 -1
  35. cirq/contrib/acquaintance/executor.py +18 -21
  36. cirq/contrib/acquaintance/executor_test.py +3 -2
  37. cirq/contrib/acquaintance/gates.py +36 -27
  38. cirq/contrib/acquaintance/gates_test.py +1 -1
  39. cirq/contrib/acquaintance/inspection_utils.py +10 -9
  40. cirq/contrib/acquaintance/inspection_utils_test.py +6 -1
  41. cirq/contrib/acquaintance/mutation_utils.py +10 -10
  42. cirq/contrib/acquaintance/optimizers.py +7 -6
  43. cirq/contrib/acquaintance/optimizers_test.py +1 -1
  44. cirq/contrib/acquaintance/permutation.py +22 -21
  45. cirq/contrib/acquaintance/permutation_test.py +1 -1
  46. cirq/contrib/acquaintance/shift.py +8 -6
  47. cirq/contrib/acquaintance/shift_swap_network.py +6 -4
  48. cirq/contrib/acquaintance/strategies/__init__.py +9 -3
  49. cirq/contrib/acquaintance/strategies/complete.py +4 -3
  50. cirq/contrib/acquaintance/strategies/cubic.py +5 -3
  51. cirq/contrib/acquaintance/strategies/quartic_paired.py +8 -6
  52. cirq/contrib/acquaintance/topological_sort.py +4 -2
  53. cirq/contrib/bayesian_network/__init__.py +3 -1
  54. cirq/contrib/bayesian_network/bayesian_network_gate.py +5 -3
  55. cirq/contrib/circuitdag/__init__.py +1 -1
  56. cirq/contrib/circuitdag/circuit_dag.py +24 -24
  57. cirq/contrib/circuitdag/circuit_dag_test.py +1 -1
  58. cirq/contrib/custom_simulators/custom_state_simulator.py +10 -8
  59. cirq/contrib/custom_simulators/custom_state_simulator_test.py +15 -11
  60. cirq/contrib/graph_device/__init__.py +8 -8
  61. cirq/contrib/graph_device/graph_device.py +8 -8
  62. cirq/contrib/graph_device/graph_device_test.py +0 -1
  63. cirq/contrib/graph_device/hypergraph_test.py +1 -0
  64. cirq/contrib/json.py +1 -2
  65. cirq/contrib/json_test.py +2 -2
  66. cirq/contrib/noise_models/__init__.py +5 -6
  67. cirq/contrib/noise_models/noise_models.py +8 -6
  68. cirq/contrib/paulistring/__init__.py +22 -10
  69. cirq/contrib/paulistring/clifford_optimize.py +1 -1
  70. cirq/contrib/paulistring/clifford_optimize_test.py +0 -1
  71. cirq/contrib/paulistring/clifford_target_gateset.py +15 -12
  72. cirq/contrib/paulistring/optimize.py +2 -2
  73. cirq/contrib/paulistring/optimize_test.py +0 -1
  74. cirq/contrib/paulistring/pauli_string_dag_test.py +0 -1
  75. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +379 -0
  76. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +523 -0
  77. cirq/contrib/paulistring/pauli_string_optimize.py +3 -1
  78. cirq/contrib/paulistring/pauli_string_optimize_test.py +1 -3
  79. cirq/contrib/paulistring/recombine.py +2 -2
  80. cirq/contrib/paulistring/recombine_test.py +2 -2
  81. cirq/contrib/paulistring/separate.py +3 -4
  82. cirq/contrib/qasm_import/__init__.py +2 -2
  83. cirq/contrib/qasm_import/_lexer.py +21 -26
  84. cirq/contrib/qasm_import/_lexer_test.py +90 -6
  85. cirq/contrib/qasm_import/_parser.py +238 -47
  86. cirq/contrib/qasm_import/_parser_test.py +514 -59
  87. cirq/contrib/qasm_import/qasm_test.py +1 -1
  88. cirq/contrib/qcircuit/__init__.py +6 -4
  89. cirq/contrib/qcircuit/qcircuit_diagram.py +5 -2
  90. cirq/contrib/qcircuit/qcircuit_pdf.py +1 -2
  91. cirq/{experiments/grid_parallel_two_qubit_xeb_test.py → contrib/qcircuit/qcircuit_pdf_test.py} +13 -12
  92. cirq/contrib/qcircuit/qcircuit_test.py +1 -1
  93. cirq/contrib/quantum_volume/__init__.py +7 -7
  94. cirq/contrib/quantum_volume/quantum_volume.py +6 -11
  95. cirq/contrib/quantum_volume/quantum_volume_test.py +3 -1
  96. cirq/contrib/quimb/__init__.py +16 -13
  97. cirq/contrib/quimb/density_matrix.py +1 -1
  98. cirq/contrib/quimb/mps_simulator.py +27 -28
  99. cirq/contrib/quimb/mps_simulator_test.py +5 -0
  100. cirq/contrib/quimb/state_vector.py +3 -10
  101. cirq/contrib/quirk/__init__.py +1 -1
  102. cirq/contrib/quirk/export_to_quirk.py +3 -3
  103. cirq/contrib/routing/__init__.py +12 -9
  104. cirq/contrib/routing/device.py +1 -1
  105. cirq/contrib/routing/device_test.py +1 -2
  106. cirq/contrib/routing/greedy.py +7 -5
  107. cirq/contrib/routing/greedy_test.py +5 -3
  108. cirq/contrib/routing/initialization.py +3 -1
  109. cirq/contrib/routing/initialization_test.py +1 -1
  110. cirq/contrib/routing/swap_network.py +6 -6
  111. cirq/contrib/routing/utils.py +6 -4
  112. cirq/contrib/routing/utils_test.py +1 -2
  113. cirq/{type_workarounds.py → contrib/shuffle_circuits/__init__.py} +5 -10
  114. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +250 -0
  115. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +363 -0
  116. cirq/contrib/svg/__init__.py +1 -1
  117. cirq/contrib/svg/svg.py +12 -10
  118. cirq/contrib/svg/svg_test.py +3 -2
  119. cirq/devices/__init__.py +34 -25
  120. cirq/devices/device.py +16 -12
  121. cirq/devices/device_test.py +1 -0
  122. cirq/devices/grid_device_metadata.py +16 -12
  123. cirq/devices/grid_device_metadata_test.py +2 -1
  124. cirq/devices/grid_qubit.py +31 -26
  125. cirq/devices/grid_qubit_test.py +30 -1
  126. cirq/devices/insertion_noise_model.py +6 -6
  127. cirq/devices/insertion_noise_model_test.py +1 -1
  128. cirq/devices/line_qubit.py +28 -20
  129. cirq/devices/line_qubit_test.py +26 -0
  130. cirq/devices/named_topologies.py +12 -10
  131. cirq/devices/named_topologies_test.py +5 -4
  132. cirq/devices/noise_model.py +29 -33
  133. cirq/devices/noise_properties.py +2 -2
  134. cirq/devices/noise_properties_test.py +2 -2
  135. cirq/devices/noise_utils.py +3 -3
  136. cirq/devices/superconducting_qubits_noise_properties.py +2 -2
  137. cirq/devices/superconducting_qubits_noise_properties_test.py +3 -3
  138. cirq/devices/thermal_noise_model.py +2 -1
  139. cirq/devices/unconstrained_device.py +1 -1
  140. cirq/devices/unconstrained_device_test.py +6 -0
  141. cirq/experiments/__init__.py +51 -34
  142. cirq/experiments/qubit_characterizations.py +17 -15
  143. cirq/experiments/qubit_characterizations_test.py +4 -6
  144. cirq/experiments/random_quantum_circuit_generation.py +10 -9
  145. cirq/experiments/random_quantum_circuit_generation_test.py +21 -4
  146. cirq/experiments/readout_confusion_matrix.py +73 -8
  147. cirq/experiments/readout_confusion_matrix_test.py +104 -1
  148. cirq/experiments/single_qubit_readout_calibration.py +8 -6
  149. cirq/experiments/single_qubit_readout_calibration_test.py +1 -1
  150. cirq/experiments/t1_decay_experiment.py +4 -5
  151. cirq/experiments/t1_decay_experiment_test.py +1 -2
  152. cirq/experiments/t2_decay_experiment.py +0 -1
  153. cirq/experiments/t2_decay_experiment_test.py +1 -2
  154. cirq/experiments/two_qubit_xeb.py +157 -33
  155. cirq/experiments/two_qubit_xeb_test.py +38 -22
  156. cirq/experiments/xeb_fitting.py +99 -19
  157. cirq/experiments/xeb_fitting_test.py +64 -25
  158. cirq/experiments/xeb_sampling.py +14 -18
  159. cirq/experiments/xeb_simulation.py +4 -3
  160. cirq/experiments/xeb_simulation_test.py +20 -14
  161. cirq/experiments/z_phase_calibration.py +368 -0
  162. cirq/experiments/z_phase_calibration_test.py +241 -0
  163. cirq/interop/__init__.py +4 -1
  164. cirq/interop/quirk/__init__.py +7 -4
  165. cirq/interop/quirk/cells/__init__.py +17 -6
  166. cirq/interop/quirk/cells/arithmetic_cells.py +8 -8
  167. cirq/interop/quirk/cells/arithmetic_cells_test.py +1 -1
  168. cirq/interop/quirk/cells/cell.py +6 -6
  169. cirq/interop/quirk/cells/composite_cell.py +5 -5
  170. cirq/interop/quirk/cells/composite_cell_test.py +1 -1
  171. cirq/interop/quirk/cells/control_cells.py +1 -1
  172. cirq/interop/quirk/cells/frequency_space_cells.py +2 -2
  173. cirq/interop/quirk/cells/ignored_cells.py +1 -1
  174. cirq/interop/quirk/cells/input_cells.py +1 -1
  175. cirq/interop/quirk/cells/input_cells_test.py +1 -1
  176. cirq/interop/quirk/cells/input_rotation_cells.py +1 -1
  177. cirq/interop/quirk/cells/input_rotation_cells_test.py +1 -1
  178. cirq/interop/quirk/cells/measurement_cells.py +1 -1
  179. cirq/interop/quirk/cells/parse.py +8 -7
  180. cirq/interop/quirk/cells/parse_test.py +2 -2
  181. cirq/interop/quirk/cells/single_qubit_rotation_cells.py +1 -1
  182. cirq/interop/quirk/cells/swap_cell_test.py +1 -1
  183. cirq/interop/quirk/cells/unsupported_cells.py +1 -1
  184. cirq/interop/quirk/url_to_circuit.py +7 -7
  185. cirq/interop/quirk/url_to_circuit_test.py +1 -1
  186. cirq/ion/__init__.py +4 -2
  187. cirq/json_resolver_cache.py +15 -7
  188. cirq/linalg/__init__.py +62 -51
  189. cirq/linalg/combinators.py +4 -4
  190. cirq/linalg/combinators_test.py +4 -1
  191. cirq/linalg/decompositions.py +15 -40
  192. cirq/linalg/decompositions_test.py +16 -22
  193. cirq/linalg/diagonalize.py +1 -1
  194. cirq/linalg/diagonalize_test.py +1 -1
  195. cirq/linalg/operator_spaces.py +20 -4
  196. cirq/linalg/operator_spaces_test.py +15 -2
  197. cirq/linalg/predicates.py +3 -3
  198. cirq/linalg/predicates_test.py +1 -0
  199. cirq/linalg/tolerance.py +2 -2
  200. cirq/linalg/transformations.py +30 -12
  201. cirq/linalg/transformations_test.py +13 -0
  202. cirq/neutral_atoms/__init__.py +2 -2
  203. cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +0 -1
  204. cirq/ops/__init__.py +172 -132
  205. cirq/ops/arithmetic_operation.py +2 -2
  206. cirq/ops/arithmetic_operation_test.py +2 -2
  207. cirq/ops/boolean_hamiltonian.py +3 -2
  208. cirq/ops/classically_controlled_operation.py +39 -12
  209. cirq/ops/classically_controlled_operation_test.py +147 -1
  210. cirq/ops/clifford_gate.py +38 -36
  211. cirq/ops/clifford_gate_test.py +75 -1
  212. cirq/ops/common_channels.py +16 -45
  213. cirq/ops/common_channels_test.py +10 -0
  214. cirq/ops/common_gate_families.py +1 -1
  215. cirq/ops/common_gate_families_test.py +1 -0
  216. cirq/ops/common_gates.py +48 -49
  217. cirq/ops/common_gates_test.py +18 -2
  218. cirq/ops/control_values.py +3 -3
  219. cirq/ops/control_values_test.py +2 -1
  220. cirq/ops/controlled_gate.py +36 -23
  221. cirq/ops/controlled_gate_test.py +70 -3
  222. cirq/ops/controlled_operation.py +6 -5
  223. cirq/ops/controlled_operation_test.py +7 -3
  224. cirq/ops/dense_pauli_string.py +11 -11
  225. cirq/ops/diagonal_gate.py +2 -2
  226. cirq/ops/diagonal_gate_test.py +1 -0
  227. cirq/ops/eigen_gate.py +16 -36
  228. cirq/ops/eigen_gate_test.py +60 -10
  229. cirq/ops/fourier_transform.py +1 -3
  230. cirq/ops/fourier_transform_test.py +2 -1
  231. cirq/ops/fsim_gate.py +42 -3
  232. cirq/ops/fsim_gate_test.py +21 -0
  233. cirq/ops/gate_operation.py +8 -8
  234. cirq/ops/gate_operation_test.py +4 -2
  235. cirq/ops/gateset_test.py +11 -2
  236. cirq/ops/global_phase_op.py +8 -7
  237. cirq/ops/global_phase_op_test.py +1 -1
  238. cirq/ops/greedy_qubit_manager_test.py +5 -0
  239. cirq/ops/identity.py +14 -4
  240. cirq/ops/identity_test.py +24 -0
  241. cirq/ops/kraus_channel.py +1 -0
  242. cirq/ops/kraus_channel_test.py +3 -1
  243. cirq/ops/linear_combinations.py +27 -21
  244. cirq/ops/linear_combinations_test.py +23 -4
  245. cirq/ops/matrix_gates.py +24 -8
  246. cirq/ops/measure_util.py +2 -2
  247. cirq/ops/measurement_gate.py +7 -4
  248. cirq/ops/measurement_gate_test.py +2 -1
  249. cirq/ops/mixed_unitary_channel.py +1 -0
  250. cirq/ops/mixed_unitary_channel_test.py +3 -1
  251. cirq/ops/named_qubit.py +8 -1
  252. cirq/ops/op_tree.py +3 -30
  253. cirq/ops/op_tree_test.py +4 -0
  254. cirq/ops/parallel_gate.py +2 -3
  255. cirq/ops/parallel_gate_test.py +2 -1
  256. cirq/ops/parity_gates.py +7 -8
  257. cirq/ops/parity_gates_test.py +1 -0
  258. cirq/ops/pauli_gates.py +5 -11
  259. cirq/ops/pauli_gates_test.py +1 -0
  260. cirq/ops/pauli_interaction_gate.py +11 -5
  261. cirq/ops/pauli_interaction_gate_test.py +2 -3
  262. cirq/ops/pauli_measurement_gate.py +6 -5
  263. cirq/ops/pauli_measurement_gate_test.py +1 -0
  264. cirq/ops/pauli_string.py +115 -130
  265. cirq/ops/pauli_string_phasor.py +21 -20
  266. cirq/ops/pauli_string_phasor_test.py +13 -3
  267. cirq/ops/pauli_string_raw_types.py +1 -0
  268. cirq/ops/pauli_string_test.py +192 -55
  269. cirq/ops/pauli_sum_exponential.py +3 -4
  270. cirq/ops/pauli_sum_exponential_test.py +0 -1
  271. cirq/ops/permutation_gate.py +2 -2
  272. cirq/ops/permutation_gate_test.py +1 -1
  273. cirq/ops/phased_iswap_gate.py +6 -7
  274. cirq/ops/phased_iswap_gate_test.py +21 -5
  275. cirq/ops/phased_x_gate.py +11 -25
  276. cirq/ops/phased_x_gate_test.py +19 -3
  277. cirq/ops/phased_x_z_gate.py +12 -11
  278. cirq/ops/projector.py +4 -5
  279. cirq/ops/qubit_manager.py +2 -1
  280. cirq/ops/qubit_manager_test.py +2 -1
  281. cirq/ops/qubit_order.py +1 -1
  282. cirq/ops/random_gate_channel.py +1 -1
  283. cirq/ops/random_gate_channel_test.py +0 -6
  284. cirq/ops/raw_types.py +146 -50
  285. cirq/ops/raw_types_test.py +37 -3
  286. cirq/ops/state_preparation_channel.py +2 -2
  287. cirq/ops/state_preparation_channel_test.py +2 -1
  288. cirq/ops/swap_gates.py +9 -4
  289. cirq/ops/three_qubit_gates.py +8 -8
  290. cirq/ops/three_qubit_gates_test.py +1 -0
  291. cirq/ops/two_qubit_diagonal_gate.py +4 -3
  292. cirq/ops/uniform_superposition_gate.py +4 -4
  293. cirq/ops/uniform_superposition_gate_test.py +1 -0
  294. cirq/ops/wait_gate.py +6 -8
  295. cirq/protocols/__init__.py +135 -83
  296. cirq/protocols/act_on_protocol.py +1 -1
  297. cirq/protocols/act_on_protocol_test.py +1 -1
  298. cirq/protocols/apply_channel_protocol.py +3 -3
  299. cirq/protocols/apply_mixture_protocol.py +15 -9
  300. cirq/protocols/apply_mixture_protocol_test.py +11 -0
  301. cirq/protocols/apply_unitary_protocol.py +2 -2
  302. cirq/protocols/apply_unitary_protocol_test.py +2 -1
  303. cirq/protocols/approximate_equality_protocol.py +7 -8
  304. cirq/protocols/approximate_equality_protocol_test.py +3 -1
  305. cirq/protocols/circuit_diagram_info_protocol.py +8 -6
  306. cirq/protocols/circuit_diagram_info_protocol_test.py +5 -0
  307. cirq/protocols/commutes_protocol.py +6 -6
  308. cirq/protocols/control_key_protocol.py +1 -1
  309. cirq/protocols/decompose_protocol.py +4 -5
  310. cirq/protocols/decompose_protocol_test.py +2 -1
  311. cirq/protocols/equal_up_to_global_phase_protocol.py +3 -3
  312. cirq/protocols/equal_up_to_global_phase_protocol_test.py +7 -0
  313. cirq/protocols/has_stabilizer_effect_protocol.py +5 -5
  314. cirq/protocols/has_unitary_protocol.py +1 -1
  315. cirq/protocols/has_unitary_protocol_test.py +8 -7
  316. cirq/protocols/hash_from_pickle_test.py +120 -0
  317. cirq/protocols/inverse_protocol.py +1 -1
  318. cirq/protocols/json_serialization.py +14 -1
  319. cirq/protocols/json_serialization_test.py +28 -7
  320. cirq/protocols/json_test_data/BitMaskKeyCondition.json +86 -0
  321. cirq/protocols/json_test_data/BitMaskKeyCondition.repr +7 -0
  322. cirq/protocols/json_test_data/Concat.json +19 -0
  323. cirq/protocols/json_test_data/Concat.repr +1 -0
  324. cirq/protocols/json_test_data/README.md +4 -2
  325. cirq/protocols/json_test_data/SympyCondition.json +60 -15
  326. cirq/protocols/json_test_data/SympyCondition.repr +4 -1
  327. cirq/protocols/json_test_data/_InverseCompositeGate.json +10 -0
  328. cirq/protocols/json_test_data/_InverseCompositeGate.repr +1 -0
  329. cirq/protocols/json_test_data/__init__.py +1 -1
  330. cirq/protocols/json_test_data/sympy.And.json +13 -0
  331. cirq/protocols/json_test_data/sympy.And.repr +1 -0
  332. cirq/protocols/json_test_data/sympy.Indexed.json +18 -0
  333. cirq/protocols/json_test_data/sympy.Indexed.repr +1 -0
  334. cirq/protocols/json_test_data/sympy.IndexedBase.json +9 -0
  335. cirq/protocols/json_test_data/sympy.IndexedBase.repr +1 -0
  336. cirq/protocols/json_test_data/sympy.Not.json +9 -0
  337. cirq/protocols/json_test_data/sympy.Not.repr +1 -0
  338. cirq/protocols/json_test_data/sympy.Or.json +13 -0
  339. cirq/protocols/json_test_data/sympy.Or.repr +1 -0
  340. cirq/protocols/json_test_data/sympy.Xor.json +13 -0
  341. cirq/protocols/json_test_data/sympy.Xor.repr +1 -0
  342. cirq/protocols/kraus_protocol.py +8 -8
  343. cirq/protocols/kraus_protocol_test.py +0 -1
  344. cirq/protocols/measurement_key_protocol.py +1 -1
  345. cirq/protocols/measurement_key_protocol_test.py +7 -7
  346. cirq/protocols/mixture_protocol.py +6 -4
  347. cirq/protocols/mixture_protocol_test.py +21 -13
  348. cirq/protocols/pauli_expansion_protocol.py +1 -0
  349. cirq/protocols/pow_protocol.py +1 -1
  350. cirq/protocols/qasm.py +25 -6
  351. cirq/protocols/qasm_test.py +17 -0
  352. cirq/protocols/qid_shape_protocol.py +2 -2
  353. cirq/protocols/resolve_parameters.py +2 -3
  354. cirq/protocols/resolve_parameters_test.py +2 -1
  355. cirq/protocols/trace_distance_bound.py +1 -1
  356. cirq/protocols/trace_distance_bound_test.py +1 -0
  357. cirq/protocols/unitary_protocol.py +3 -3
  358. cirq/protocols/unitary_protocol_test.py +1 -1
  359. cirq/qis/__init__.py +48 -35
  360. cirq/qis/channels_test.py +0 -9
  361. cirq/qis/clifford_tableau.py +46 -26
  362. cirq/qis/clifford_tableau_test.py +2 -1
  363. cirq/qis/entropy.py +115 -0
  364. cirq/qis/entropy_test.py +43 -0
  365. cirq/qis/measures.py +5 -4
  366. cirq/qis/measures_test.py +7 -0
  367. cirq/qis/noise_utils_test.py +4 -4
  368. cirq/qis/quantum_state_representation.py +1 -1
  369. cirq/qis/states.py +7 -7
  370. cirq/sim/__init__.py +55 -37
  371. cirq/sim/classical_simulator.py +7 -6
  372. cirq/sim/classical_simulator_test.py +3 -1
  373. cirq/sim/clifford/__init__.py +17 -9
  374. cirq/sim/clifford/clifford_simulator.py +5 -4
  375. cirq/sim/clifford/clifford_simulator_test.py +32 -9
  376. cirq/sim/clifford/clifford_tableau_simulation_state.py +1 -1
  377. cirq/sim/clifford/stabilizer_simulation_state.py +1 -1
  378. cirq/sim/clifford/stabilizer_state_ch_form.py +4 -3
  379. cirq/sim/density_matrix_simulator.py +3 -2
  380. cirq/sim/density_matrix_simulator_test.py +12 -4
  381. cirq/sim/density_matrix_utils.py +1 -1
  382. cirq/sim/mux.py +2 -2
  383. cirq/sim/simulation_state.py +4 -5
  384. cirq/sim/simulation_state_base.py +2 -2
  385. cirq/sim/simulation_state_test.py +1 -1
  386. cirq/sim/simulation_utils.py +3 -1
  387. cirq/sim/simulation_utils_test.py +2 -3
  388. cirq/sim/simulator.py +7 -6
  389. cirq/sim/simulator_base.py +5 -5
  390. cirq/sim/simulator_test.py +14 -3
  391. cirq/sim/sparse_simulator.py +4 -3
  392. cirq/sim/sparse_simulator_test.py +17 -9
  393. cirq/sim/state_vector.py +2 -2
  394. cirq/sim/state_vector_simulation_state_test.py +1 -1
  395. cirq/sim/state_vector_simulator.py +4 -4
  396. cirq/sim/state_vector_test.py +27 -32
  397. cirq/study/__init__.py +27 -21
  398. cirq/study/flatten_expressions.py +5 -6
  399. cirq/study/flatten_expressions_test.py +1 -1
  400. cirq/study/resolver.py +14 -11
  401. cirq/study/resolver_test.py +10 -1
  402. cirq/study/result.py +3 -3
  403. cirq/study/sweepable.py +15 -9
  404. cirq/study/sweepable_test.py +27 -0
  405. cirq/study/sweeps.py +65 -10
  406. cirq/study/sweeps_test.py +123 -0
  407. cirq/testing/__init__.py +86 -57
  408. cirq/testing/_compat_test_data/module_a/__init__.py +2 -2
  409. cirq/testing/_compat_test_data/module_a/sub/subsub/__init__.py +1 -1
  410. cirq/testing/circuit_compare.py +3 -4
  411. cirq/testing/circuit_compare_test.py +7 -8
  412. cirq/testing/consistent_act_on.py +3 -3
  413. cirq/testing/consistent_channels_test.py +2 -1
  414. cirq/testing/consistent_controlled_gate_op.py +3 -2
  415. cirq/testing/consistent_controlled_gate_op_test.py +2 -3
  416. cirq/testing/consistent_decomposition.py +1 -1
  417. cirq/testing/consistent_decomposition_test.py +1 -2
  418. cirq/testing/consistent_pauli_expansion_test.py +1 -1
  419. cirq/testing/consistent_phase_by.py +1 -1
  420. cirq/testing/consistent_phase_by_test.py +1 -2
  421. cirq/testing/consistent_protocols.py +11 -11
  422. cirq/testing/consistent_protocols_test.py +4 -5
  423. cirq/testing/consistent_qasm.py +8 -12
  424. cirq/testing/consistent_qasm_test.py +1 -1
  425. cirq/testing/consistent_resolve_parameters.py +2 -1
  426. cirq/testing/consistent_specified_has_unitary_test.py +1 -1
  427. cirq/testing/consistent_unitary.py +3 -1
  428. cirq/testing/consistent_unitary_test.py +3 -3
  429. cirq/testing/devices.py +1 -1
  430. cirq/testing/devices_test.py +1 -0
  431. cirq/testing/equals_tester.py +2 -4
  432. cirq/testing/equals_tester_test.py +6 -5
  433. cirq/testing/equivalent_basis_map.py +1 -0
  434. cirq/testing/equivalent_basis_map_test.py +0 -1
  435. cirq/testing/gate_features_test.py +5 -0
  436. cirq/testing/json.py +4 -4
  437. cirq/testing/lin_alg_utils_test.py +1 -1
  438. cirq/testing/order_tester.py +1 -1
  439. cirq/testing/order_tester_test.py +1 -1
  440. cirq/testing/pytest_utils.py +57 -0
  441. cirq/testing/pytest_utils_test.py +35 -0
  442. cirq/testing/random_circuit.py +2 -2
  443. cirq/testing/random_circuit_test.py +2 -2
  444. cirq/testing/routing_devices_test.py +2 -1
  445. cirq/testing/sample_circuits.py +1 -1
  446. cirq/testing/sample_gates.py +5 -4
  447. cirq/testing/sample_gates_test.py +2 -2
  448. cirq/transformers/__init__.py +101 -82
  449. cirq/transformers/align.py +12 -1
  450. cirq/transformers/align_test.py +13 -0
  451. cirq/transformers/analytical_decompositions/__init__.py +27 -24
  452. cirq/transformers/analytical_decompositions/clifford_decomposition.py +2 -1
  453. cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +1 -1
  454. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +1 -1
  455. cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
  456. cirq/transformers/analytical_decompositions/cphase_to_fsim.py +1 -1
  457. cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +1 -1
  458. cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +2 -2
  459. cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +4 -4
  460. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +99 -24
  461. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +105 -14
  462. cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +1 -1
  463. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +1 -1
  464. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +1 -0
  465. cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +3 -4
  466. cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +1 -1
  467. cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +2 -1
  468. cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -1
  469. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +5 -6
  470. cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +2 -2
  471. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +1 -1
  472. cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +1 -2
  473. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +2 -2
  474. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +2 -2
  475. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -1
  476. cirq/transformers/drop_empty_moments.py +1 -0
  477. cirq/transformers/drop_negligible_operations.py +1 -0
  478. cirq/transformers/dynamical_decoupling.py +255 -43
  479. cirq/transformers/dynamical_decoupling_test.py +730 -17
  480. cirq/transformers/eject_phased_paulis.py +29 -15
  481. cirq/transformers/eject_phased_paulis_test.py +3 -8
  482. cirq/transformers/eject_z.py +3 -2
  483. cirq/transformers/eject_z_test.py +3 -3
  484. cirq/transformers/gauge_compiling/__init__.py +25 -9
  485. cirq/transformers/gauge_compiling/cphase_gauge.py +146 -0
  486. cirq/transformers/gauge_compiling/cphase_gauge_test.py +42 -0
  487. cirq/transformers/gauge_compiling/cz_gauge.py +4 -4
  488. cirq/transformers/gauge_compiling/gauge_compiling.py +245 -6
  489. cirq/transformers/gauge_compiling/gauge_compiling_test.py +107 -2
  490. cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +39 -2
  491. cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +10 -1
  492. cirq/transformers/gauge_compiling/iswap_gauge.py +2 -2
  493. cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -2
  494. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +23 -5
  495. cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +3 -2
  496. cirq/transformers/heuristic_decompositions/__init__.py +3 -3
  497. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +2 -1
  498. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +1 -1
  499. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +4 -4
  500. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +4 -4
  501. cirq/transformers/insertion_sort.py +64 -0
  502. cirq/transformers/insertion_sort_test.py +34 -0
  503. cirq/transformers/measurement_transformers.py +14 -1
  504. cirq/transformers/measurement_transformers_test.py +35 -0
  505. cirq/transformers/merge_k_qubit_gates.py +2 -2
  506. cirq/transformers/merge_single_qubit_gates.py +1 -1
  507. cirq/transformers/merge_single_qubit_gates_test.py +1 -1
  508. cirq/transformers/noise_adding.py +115 -0
  509. cirq/transformers/noise_adding_test.py +54 -0
  510. cirq/transformers/optimize_for_target_gateset.py +1 -1
  511. cirq/transformers/optimize_for_target_gateset_test.py +3 -2
  512. cirq/transformers/qubit_management_transformers.py +1 -1
  513. cirq/transformers/randomized_measurements.py +171 -0
  514. cirq/transformers/randomized_measurements_test.py +68 -0
  515. cirq/transformers/routing/__init__.py +14 -5
  516. cirq/transformers/routing/initial_mapper.py +1 -1
  517. cirq/transformers/routing/initial_mapper_test.py +1 -0
  518. cirq/transformers/routing/line_initial_mapper.py +3 -2
  519. cirq/transformers/routing/mapping_manager.py +2 -2
  520. cirq/transformers/routing/mapping_manager_test.py +2 -2
  521. cirq/transformers/routing/route_circuit_cqc.py +3 -2
  522. cirq/transformers/routing/route_circuit_cqc_test.py +2 -1
  523. cirq/transformers/routing/visualize_routed_circuit.py +1 -0
  524. cirq/transformers/routing/visualize_routed_circuit_test.py +1 -0
  525. cirq/transformers/stratify.py +2 -2
  526. cirq/transformers/synchronize_terminal_measurements.py +2 -1
  527. cirq/transformers/target_gatesets/__init__.py +7 -5
  528. cirq/transformers/target_gatesets/compilation_target_gateset.py +16 -3
  529. cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -0
  530. cirq/transformers/target_gatesets/cz_gateset.py +5 -1
  531. cirq/transformers/target_gatesets/cz_gateset_test.py +23 -2
  532. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +1 -1
  533. cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +3 -2
  534. cirq/transformers/transformer_api.py +5 -4
  535. cirq/transformers/transformer_api_test.py +11 -3
  536. cirq/transformers/transformer_primitives.py +9 -31
  537. cirq/transformers/transformer_primitives_test.py +6 -5
  538. cirq/value/__init__.py +51 -30
  539. cirq/value/abc_alt.py +1 -2
  540. cirq/value/angle.py +2 -0
  541. cirq/value/classical_data.py +1 -0
  542. cirq/value/condition.py +149 -3
  543. cirq/value/condition_test.py +254 -0
  544. cirq/value/digits.py +1 -1
  545. cirq/value/duration.py +4 -4
  546. cirq/value/duration_test.py +2 -1
  547. cirq/value/linear_dict.py +85 -24
  548. cirq/value/linear_dict_test.py +94 -3
  549. cirq/value/measurement_key.py +9 -2
  550. cirq/value/periodic_value.py +2 -3
  551. cirq/value/periodic_value_test.py +5 -0
  552. cirq/value/probability.py +1 -0
  553. cirq/value/random_state.py +1 -1
  554. cirq/value/timestamp.py +2 -4
  555. cirq/value/timestamp_test.py +2 -1
  556. cirq/value/type_alias.py +2 -2
  557. cirq/value/value_equality_attr.py +14 -2
  558. cirq/value/value_equality_attr_test.py +1 -1
  559. cirq/vis/__init__.py +9 -6
  560. cirq/vis/density_matrix.py +1 -1
  561. cirq/vis/density_matrix_test.py +2 -5
  562. cirq/vis/heatmap.py +49 -12
  563. cirq/vis/heatmap_test.py +168 -4
  564. cirq/vis/histogram.py +1 -1
  565. cirq/vis/histogram_test.py +1 -2
  566. cirq/vis/state_histogram.py +7 -5
  567. cirq/vis/state_histogram_test.py +2 -2
  568. cirq/work/__init__.py +19 -13
  569. cirq/work/collector.py +2 -2
  570. cirq/work/observable_grouping.py +2 -2
  571. cirq/work/observable_measurement.py +3 -3
  572. cirq/work/observable_measurement_data.py +5 -2
  573. cirq/work/observable_measurement_test.py +8 -8
  574. cirq/work/observable_readout_calibration.py +2 -2
  575. cirq/work/observable_readout_calibration_test.py +2 -1
  576. cirq/work/observable_settings.py +8 -7
  577. cirq/work/observable_settings_test.py +3 -2
  578. cirq/work/pauli_sum_collector.py +1 -1
  579. cirq/work/sampler.py +8 -20
  580. cirq/work/sampler_test.py +4 -3
  581. cirq/work/zeros_sampler.py +1 -1
  582. cirq_core-1.5.0.dist-info/METADATA +125 -0
  583. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/RECORD +586 -552
  584. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/WHEEL +1 -1
  585. cirq/experiments/grid_parallel_two_qubit_xeb.py +0 -62
  586. cirq/protocols/json_test_data/GridParallelXEBMetadata.json +0 -119
  587. cirq/protocols/json_test_data/GridParallelXEBMetadata.repr +0 -1
  588. cirq_core-1.4.0.dev20240529225110.dist-info/METADATA +0 -50
  589. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/LICENSE +0 -0
  590. {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/top_level.txt +0 -0
@@ -14,6 +14,7 @@
14
14
 
15
15
  import abc
16
16
  import numbers
17
+ from types import NotImplementedType
17
18
  from typing import (
18
19
  AbstractSet,
19
20
  Any,
@@ -30,15 +31,14 @@ from typing import (
30
31
  TYPE_CHECKING,
31
32
  Union,
32
33
  )
33
- from typing_extensions import Self
34
34
 
35
35
  import numpy as np
36
36
  import sympy
37
+ from typing_extensions import Self
37
38
 
38
- from cirq import protocols, linalg, value
39
+ from cirq import linalg, protocols, value
39
40
  from cirq._compat import proper_repr
40
- from cirq.ops import raw_types, identity, pauli_gates, global_phase_op, pauli_string
41
- from cirq.type_workarounds import NotImplementedType
41
+ from cirq.ops import global_phase_op, identity, pauli_gates, pauli_string, raw_types
42
42
 
43
43
  if TYPE_CHECKING:
44
44
  import cirq
@@ -116,7 +116,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
116
116
  return self._pauli_mask
117
117
 
118
118
  @property
119
- def coefficient(self) -> Union[sympy.Expr, complex]:
119
+ def coefficient(self) -> 'cirq.TParamValComplex':
120
120
  """A complex coefficient or symbol."""
121
121
  return self._coefficient
122
122
 
@@ -203,7 +203,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
203
203
  def __pos__(self):
204
204
  return self
205
205
 
206
- def __pow__(self, power: Union[int, float]) -> Union[NotImplementedType, Self]:
206
+ def __pow__(self, power: float) -> Union[NotImplementedType, Self]:
207
207
  concrete_class = type(self)
208
208
  if isinstance(power, int):
209
209
  i_group = [1, +1j, -1, -1j]
@@ -359,7 +359,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
359
359
  coef = '+'
360
360
  elif self.coefficient == -1:
361
361
  coef = '-'
362
- elif isinstance(self.coefficient, (complex, sympy.Symbol)):
362
+ elif isinstance(self.coefficient, (numbers.Complex, sympy.Symbol)):
363
363
  coef = f'{self.coefficient}*'
364
364
  else:
365
365
  coef = f'({self.coefficient})*'
@@ -403,7 +403,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
403
403
  @abc.abstractmethod
404
404
  def copy(
405
405
  self,
406
- coefficient: Optional[Union[sympy.Expr, int, float, complex]] = None,
406
+ coefficient: Optional['cirq.TParamValComplex'] = None,
407
407
  pauli_mask: Union[None, str, Iterable[int], np.ndarray] = None,
408
408
  ) -> Self:
409
409
  """Returns a copy with possibly modified contents.
@@ -459,7 +459,7 @@ class DensePauliString(BaseDensePauliString):
459
459
 
460
460
  def copy(
461
461
  self,
462
- coefficient: Optional[Union[sympy.Expr, int, float, complex]] = None,
462
+ coefficient: Optional['cirq.TParamValComplex'] = None,
463
463
  pauli_mask: Union[None, str, Iterable[int], np.ndarray] = None,
464
464
  ) -> 'DensePauliString':
465
465
  if pauli_mask is None and (coefficient is None or coefficient == self.coefficient):
@@ -559,7 +559,7 @@ class MutableDensePauliString(BaseDensePauliString):
559
559
 
560
560
  def copy(
561
561
  self,
562
- coefficient: Optional[Union[sympy.Expr, int, float, complex]] = None,
562
+ coefficient: Optional['cirq.TParamValComplex'] = None,
563
563
  pauli_mask: Union[None, str, Iterable[int], np.ndarray] = None,
564
564
  ) -> 'MutableDensePauliString':
565
565
  return MutableDensePauliString(
@@ -627,7 +627,7 @@ def _attempt_value_to_pauli_index(v: 'cirq.Operation') -> Optional[Tuple[int, in
627
627
  return None
628
628
 
629
629
  if not isinstance(v.gate, pauli_gates.Pauli):
630
- return None
630
+ return None # pragma: no cover
631
631
 
632
632
  q = v.qubits[0]
633
633
  from cirq import devices
cirq/ops/diagonal_gate.py CHANGED
@@ -36,7 +36,7 @@ import sympy
36
36
 
37
37
  from cirq import protocols, value
38
38
  from cirq._compat import proper_repr
39
- from cirq.ops import common_gates, raw_types, global_phase_op
39
+ from cirq.ops import common_gates, global_phase_op, raw_types
40
40
 
41
41
  if TYPE_CHECKING:
42
42
  import cirq
@@ -166,7 +166,7 @@ class DiagonalGate(raw_types.Gate):
166
166
  self, index: int, bit_flip: int, theta: 'cirq.TParamVal', qubits: Sequence['cirq.Qid']
167
167
  ) -> Iterator[Union['cirq.ZPowGate', 'cirq.CXPowGate']]:
168
168
  if index == 0:
169
- return []
169
+ return
170
170
  largest_digit = self._num_qubits_() - (len(bin(index)) - 2)
171
171
  yield common_gates.rz(2 * theta)(qubits[largest_digit])
172
172
  _flip_bit = self._num_qubits_() - bit_flip - 1
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  from typing import List
16
+
16
17
  import numpy as np
17
18
  import pytest
18
19
  import sympy
cirq/ops/eigen_gate.py CHANGED
@@ -15,6 +15,7 @@ import abc
15
15
  import fractions
16
16
  import math
17
17
  import numbers
18
+ from types import NotImplementedType
18
19
  from typing import (
19
20
  AbstractSet,
20
21
  Any,
@@ -32,10 +33,8 @@ from typing import (
32
33
  import numpy as np
33
34
  import sympy
34
35
 
35
- from cirq import value, protocols
36
- from cirq.linalg import tolerance
36
+ from cirq import protocols, value
37
37
  from cirq.ops import raw_types
38
- from cirq.type_workarounds import NotImplementedType
39
38
 
40
39
  if TYPE_CHECKING:
41
40
  import cirq
@@ -122,7 +121,6 @@ class EigenGate(raw_types.Gate):
122
121
  exponent = exponent.real
123
122
  self._exponent = exponent
124
123
  self._global_shift = global_shift
125
- self._canonical_exponent_cached = None
126
124
 
127
125
  @property
128
126
  def exponent(self) -> value.TParamVal:
@@ -302,29 +300,22 @@ class EigenGate(raw_types.Gate):
302
300
  def __pow__(self, exponent: Union[float, sympy.Symbol]) -> 'EigenGate':
303
301
  new_exponent = protocols.mul(self._exponent, exponent, NotImplemented)
304
302
  if new_exponent is NotImplemented:
305
- return NotImplemented
303
+ return NotImplemented # pragma: no cover
306
304
  return self._with_exponent(exponent=new_exponent)
307
305
 
308
- @property
309
- def _canonical_exponent(self):
310
- if self._canonical_exponent_cached is None:
311
- period = self._period()
312
- if not period or protocols.is_parameterized(self._exponent):
313
- self._canonical_exponent_cached = self._exponent
314
- else:
315
- self._canonical_exponent_cached = self._exponent % period
316
- return self._canonical_exponent_cached
317
-
318
306
  def _value_equality_values_(self):
319
- return self._canonical_exponent, self._global_shift
307
+ """The phases by which we multiply the eigenspaces.
320
308
 
321
- def _value_equality_approximate_values_(self):
322
- period = self._period()
323
- if not period or protocols.is_parameterized(self._exponent):
324
- exponent = self._exponent
325
- else:
326
- exponent = value.PeriodicValue(self._exponent, period)
327
- return exponent, self._global_shift
309
+ The default implementation assumes that the eigenspaces are constant
310
+ for the class, and the eigenphases are the only distinguishing
311
+ characteristics. For gates whose eigenspaces can change, such as
312
+ `PhasedISwapPowGate`, this must be overridden to provide the additional
313
+ fields that affect the eigenspaces.
314
+ """
315
+ symbolic = lambda x: isinstance(x, sympy.Expr) and x.free_symbols
316
+ f = lambda x: x if symbolic(x) else float(x)
317
+ shifts = (f(self._exponent) * f(self._global_shift + e) for e in self._eigen_shifts())
318
+ return tuple(s if symbolic(s) else value.PeriodicValue(f(s), 2) for s in shifts)
328
319
 
329
320
  def _trace_distance_bound_(self) -> Optional[float]:
330
321
  if protocols.is_parameterized(self._exponent):
@@ -355,7 +346,7 @@ class EigenGate(raw_types.Gate):
355
346
 
356
347
  def _resolve_parameters_(self, resolver: 'cirq.ParamResolver', recursive: bool) -> 'EigenGate':
357
348
  exponent = resolver.value_of(self._exponent, recursive)
358
- if isinstance(exponent, (complex, numbers.Complex)):
349
+ if isinstance(exponent, numbers.Complex):
359
350
  if isinstance(exponent, numbers.Real):
360
351
  exponent = float(exponent)
361
352
  else:
@@ -374,20 +365,9 @@ class EigenGate(raw_types.Gate):
374
365
  return False
375
366
  self_without_phase = self._with_exponent(self.exponent)
376
367
  self_without_phase._global_shift = 0
377
- self_without_exp_or_phase = self_without_phase._with_exponent(0)
378
- self_without_exp_or_phase._global_shift = 0
379
368
  other_without_phase = other._with_exponent(other.exponent)
380
369
  other_without_phase._global_shift = 0
381
- other_without_exp_or_phase = other_without_phase._with_exponent(0)
382
- other_without_exp_or_phase._global_shift = 0
383
- if not protocols.approx_eq(
384
- self_without_exp_or_phase, other_without_exp_or_phase, atol=atol
385
- ):
386
- return False
387
-
388
- period = self_without_phase._period()
389
- exponents_diff = exponents[0] - exponents[1]
390
- return tolerance.near_zero_mod(exponents_diff, period, atol=atol)
370
+ return protocols.approx_eq(self_without_phase, other_without_phase, atol=atol)
391
371
 
392
372
  def _json_dict_(self) -> Dict[str, Any]:
393
373
  return protocols.obj_to_dict_helper(self, ['exponent', 'global_shift'])
@@ -13,7 +13,6 @@
13
13
  # limitations under the License.
14
14
 
15
15
  from typing import List, Tuple
16
- import re
17
16
 
18
17
  import numpy as np
19
18
  import pytest
@@ -50,7 +49,7 @@ class CExpZinGate(cirq.EigenGate, cirq.testing.TwoQubitGate):
50
49
  ]
51
50
 
52
51
 
53
- class ZGateDef(cirq.EigenGate, cirq.testing.TwoQubitGate):
52
+ class ZGateDef(cirq.EigenGate, cirq.testing.SingleQubitGate):
54
53
  @property
55
54
  def exponent(self):
56
55
  return self._exponent
@@ -97,7 +96,6 @@ def test_eq():
97
96
  eq.make_equality_group(lambda: CExpZinGate(quarter_turns=0.1))
98
97
  eq.add_equality_group(CExpZinGate(0), CExpZinGate(4), CExpZinGate(-4))
99
98
 
100
- # Equates by canonicalized period.
101
99
  eq.add_equality_group(CExpZinGate(1.5), CExpZinGate(41.5))
102
100
  eq.add_equality_group(CExpZinGate(3.5), CExpZinGate(-0.5))
103
101
 
@@ -109,6 +107,64 @@ def test_eq():
109
107
  eq.add_equality_group(ZGateDef(exponent=0.5, global_shift=0.5))
110
108
  eq.add_equality_group(ZGateDef(exponent=1.0, global_shift=0.5))
111
109
 
110
+ # All variants of (0,0) == (0*a,0*a) == (0, 2) == (2, 2)
111
+ a, b = sympy.symbols('a, b')
112
+ eq.add_equality_group(
113
+ WeightedZPowGate(0),
114
+ WeightedZPowGate(0) ** 1.1,
115
+ WeightedZPowGate(0) ** a,
116
+ (WeightedZPowGate(0) ** a) ** 1.2,
117
+ WeightedZPowGate(0) ** (a + 1.3),
118
+ WeightedZPowGate(0) ** b,
119
+ WeightedZPowGate(1) ** 2,
120
+ WeightedZPowGate(0, global_shift=1) ** 2,
121
+ WeightedZPowGate(1, global_shift=1) ** 2,
122
+ WeightedZPowGate(2),
123
+ WeightedZPowGate(0, global_shift=2),
124
+ WeightedZPowGate(2, global_shift=2),
125
+ )
126
+ # WeightedZPowGate(2) is identity, but non-integer exponent would make it different, similar to
127
+ # how we treat (X**2)**0.5==X. So these are in their own equality group. (0, 2*a)
128
+ eq.add_equality_group(
129
+ WeightedZPowGate(2) ** a,
130
+ (WeightedZPowGate(1) ** 2) ** a,
131
+ (WeightedZPowGate(1) ** a) ** 2,
132
+ WeightedZPowGate(1) ** (a * 2),
133
+ WeightedZPowGate(1) ** (a + a),
134
+ )
135
+ # Similarly, these are identity without the exponent, but global_shift affects both phases
136
+ # instead of just the one, so will have a different effect from the above depending on the
137
+ # exponent. (2*a, 0)
138
+ eq.add_equality_group(
139
+ WeightedZPowGate(0, global_shift=2) ** a,
140
+ (WeightedZPowGate(0, global_shift=1) ** 2) ** a,
141
+ (WeightedZPowGate(0, global_shift=1) ** a) ** 2,
142
+ WeightedZPowGate(0, global_shift=1) ** (a * 2),
143
+ WeightedZPowGate(0, global_shift=1) ** (a + a),
144
+ )
145
+ # Symbolic exponents that cancel (0, 1) == (0, a/a)
146
+ eq.add_equality_group(
147
+ WeightedZPowGate(1),
148
+ WeightedZPowGate(a) ** (1 / a),
149
+ WeightedZPowGate(b) ** (1 / b),
150
+ WeightedZPowGate(1 / a) ** a,
151
+ WeightedZPowGate(1 / b) ** b,
152
+ )
153
+ # Symbol in one phase and constant off by period in another (0, a) == (2, a)
154
+ eq.add_equality_group(
155
+ WeightedZPowGate(a),
156
+ WeightedZPowGate(a - 2, global_shift=2),
157
+ WeightedZPowGate(1 - 2 / a, global_shift=2 / a) ** a,
158
+ )
159
+ # Different symbol, different equality group (0, b)
160
+ eq.add_equality_group(WeightedZPowGate(b))
161
+ # Various number types
162
+ eq.add_equality_group(
163
+ WeightedZPowGate(np.int64(3), global_shift=sympy.Number(5)) ** 7.0,
164
+ WeightedZPowGate(sympy.Number(3), global_shift=5.0) ** np.int64(7),
165
+ WeightedZPowGate(3.0, global_shift=np.int64(5)) ** sympy.Number(7),
166
+ )
167
+
112
168
 
113
169
  def test_approx_eq():
114
170
  assert cirq.approx_eq(CExpZinGate(1.5), CExpZinGate(1.5), atol=0.1)
@@ -118,8 +174,7 @@ def test_approx_eq():
118
174
  assert cirq.approx_eq(ZGateDef(exponent=1.5), ZGateDef(exponent=1.5), atol=0.1)
119
175
  assert not cirq.approx_eq(CExpZinGate(1.5), ZGateDef(exponent=1.5), atol=0.1)
120
176
  with pytest.raises(
121
- TypeError,
122
- match=re.escape("unsupported operand type(s) for -: 'Symbol' and 'PeriodicValue'"),
177
+ TypeError, match="unsupported operand type\\(s\\) for -: '.*' and 'PeriodicValue'"
123
178
  ):
124
179
  cirq.approx_eq(ZGateDef(exponent=1.5), ZGateDef(exponent=sympy.Symbol('a')), atol=0.1)
125
180
  assert cirq.approx_eq(CExpZinGate(sympy.Symbol('a')), CExpZinGate(sympy.Symbol('a')), atol=0.1)
@@ -333,11 +388,6 @@ class WeightedZPowGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
333
388
  self.weight = weight
334
389
  super().__init__(**kwargs)
335
390
 
336
- def _value_equality_values_(self):
337
- return self.weight, self._canonical_exponent, self._global_shift
338
-
339
- _value_equality_approximate_values_ = _value_equality_values_
340
-
341
391
  def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
342
392
  return [(0, np.diag([1, 0])), (self.weight, np.diag([0, 1]))]
343
393
 
@@ -18,7 +18,7 @@ import numpy as np
18
18
  import sympy
19
19
 
20
20
  import cirq
21
- from cirq import value, _compat
21
+ from cirq import _compat, value
22
22
  from cirq.ops import raw_types
23
23
 
24
24
 
@@ -170,8 +170,6 @@ class PhaseGradientGate(raw_types.Gate):
170
170
  self, resolver: 'cirq.ParamResolver', recursive: bool
171
171
  ) -> 'PhaseGradientGate':
172
172
  new_exponent = cirq.resolve_parameters(self.exponent, resolver, recursive)
173
- if new_exponent is self.exponent:
174
- return self
175
173
  return PhaseGradientGate(num_qubits=self._num_qubits, exponent=new_exponent)
176
174
 
177
175
  def __str__(self) -> str:
@@ -13,7 +13,8 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import numpy as np
16
- import pytest, sympy
16
+ import pytest
17
+ import sympy
17
18
 
18
19
  import cirq
19
20
 
cirq/ops/fsim_gate.py CHANGED
@@ -23,7 +23,7 @@ applies more generally to fermions, thus the name of the gate.
23
23
 
24
24
  import cmath
25
25
  import math
26
- from typing import AbstractSet, Any, Dict, Optional, Tuple
26
+ from typing import AbstractSet, Any, Dict, Iterator, Optional, Tuple
27
27
 
28
28
  import numpy as np
29
29
  import sympy
@@ -187,7 +187,7 @@ class FSimGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
187
187
  out[ii] *= cmath.exp(-1j * self.phi)
188
188
  return out
189
189
 
190
- def _decompose_(self, qubits) -> 'cirq.OP_TREE':
190
+ def _decompose_(self, qubits) -> Iterator['cirq.OP_TREE']:
191
191
  a, b = qubits
192
192
  xx = cirq.XXPowGate(exponent=self.theta / np.pi, global_shift=-0.5)
193
193
  yy = cirq.YYPowGate(exponent=self.theta / np.pi, global_shift=-0.5)
@@ -347,6 +347,45 @@ class PhasedFSimGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
347
347
  chi = (b0 - b1 - a0 + a1) / 2.0
348
348
  return PhasedFSimGate(theta, zeta, chi, gamma, phi)
349
349
 
350
+ @staticmethod
351
+ def from_matrix(u: np.ndarray) -> Optional['PhasedFSimGate']:
352
+ """Contruct a PhasedFSimGate from unitary.
353
+
354
+ Args:
355
+ u: A unitary matrix representing a PhasedFSimGate.
356
+
357
+ Returns:
358
+ - Either PhasedFSimGate with the given unitary or None if
359
+ the matrix is not unitary or if doesn't represent a PhasedFSimGate.
360
+ """
361
+
362
+ gamma = np.angle(u[1, 1] * u[2, 2] - u[1, 2] * u[2, 1]) / -2
363
+ phi = -np.angle(u[3, 3]) - 2 * gamma
364
+ phased_cos_theta_2 = u[1, 1] * u[2, 2]
365
+ if phased_cos_theta_2 == 0:
366
+ # The zeta phase is multiplied with cos(theta),
367
+ # so if cos(theta) is zero then any value is possible.
368
+ zeta = 0
369
+ else:
370
+ zeta = np.angle(u[2, 2] / u[1, 1]) / 2
371
+
372
+ phased_sin_theta_2 = u[1, 2] * u[2, 1]
373
+ if phased_sin_theta_2 == 0:
374
+ # The chi phase is multiplied with sin(theta),
375
+ # so if sin(theta) is zero then any value is possible.
376
+ chi = 0
377
+ else:
378
+ chi = np.angle(u[1, 2] / u[2, 1]) / 2
379
+
380
+ theta = np.angle(
381
+ np.exp(1j * (gamma + zeta)) * u[1, 1] - np.exp(1j * (gamma - chi)) * u[1, 2]
382
+ )
383
+
384
+ gate = PhasedFSimGate(theta=theta, phi=phi, chi=chi, zeta=zeta, gamma=gamma)
385
+ if np.allclose(u, protocols.unitary(gate)):
386
+ return gate
387
+ return None
388
+
350
389
  @property
351
390
  def rz_angles_before(self) -> Tuple['cirq.TParamVal', 'cirq.TParamVal']:
352
391
  """Returns 2-tuple of phase angles applied to qubits before FSimGate."""
@@ -452,7 +491,7 @@ class PhasedFSimGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
452
491
  out[ii] *= f * f
453
492
  return out
454
493
 
455
- def _decompose_(self, qubits) -> 'cirq.OP_TREE':
494
+ def _decompose_(self, qubits) -> Iterator['cirq.OP_TREE']:
456
495
  """Decomposes self into Z rotations and FSimGate.
457
496
 
458
497
  Note that Z rotations returned by this method have unusual global phase
@@ -797,3 +797,24 @@ def test_phased_fsim_json_dict():
797
797
  assert cirq.PhasedFSimGate(
798
798
  theta=0.12, zeta=0.34, chi=0.56, gamma=0.78, phi=0.9
799
799
  )._json_dict_() == {'theta': 0.12, 'zeta': 0.34, 'chi': 0.56, 'gamma': 0.78, 'phi': 0.9}
800
+
801
+
802
+ @pytest.mark.parametrize(
803
+ 'gate',
804
+ [
805
+ cirq.CZ,
806
+ cirq.SQRT_ISWAP,
807
+ cirq.SQRT_ISWAP_INV,
808
+ cirq.ISWAP,
809
+ cirq.ISWAP_INV,
810
+ cirq.cphase(0.1),
811
+ cirq.CZ**0.2,
812
+ ],
813
+ )
814
+ def test_phase_fsim_from_matrix(gate):
815
+ u = cirq.unitary(gate)
816
+ np.testing.assert_allclose(cirq.unitary(cirq.PhasedFSimGate.from_matrix(u)), u, atol=1e-8)
817
+
818
+
819
+ def test_phase_fsim_from_matrix_not_fsim_returns_none():
820
+ assert cirq.PhasedFSimGate.from_matrix(np.ones((4, 4))) is None
@@ -16,29 +16,29 @@
16
16
 
17
17
  import re
18
18
  import warnings
19
+ from types import NotImplementedType
19
20
  from typing import (
20
21
  AbstractSet,
21
22
  Any,
22
- Mapping,
23
23
  cast,
24
24
  Collection,
25
25
  Dict,
26
26
  FrozenSet,
27
+ List,
28
+ Mapping,
27
29
  Optional,
28
30
  Sequence,
29
31
  Tuple,
30
- TypeVar,
31
32
  TYPE_CHECKING,
33
+ TypeVar,
32
34
  Union,
33
- List,
34
35
  )
35
- from typing_extensions import Self
36
36
 
37
37
  import numpy as np
38
+ from typing_extensions import Self
38
39
 
39
40
  from cirq import ops, protocols, value
40
- from cirq.ops import raw_types, gate_features, control_values as cv
41
- from cirq.type_workarounds import NotImplementedType
41
+ from cirq.ops import control_values as cv, gate_features, raw_types
42
42
 
43
43
  if TYPE_CHECKING:
44
44
  import cirq
@@ -302,7 +302,7 @@ class GateOperation(raw_types.Operation):
302
302
  def _decompose_into_clifford_(self):
303
303
  sub = getattr(self.gate, '_decompose_into_clifford_with_qubits_', None)
304
304
  if sub is None:
305
- return NotImplemented
305
+ return NotImplemented # pragma: no cover
306
306
  return sub(self.qubits)
307
307
 
308
308
  def _trace_distance_bound_(self) -> float:
@@ -360,7 +360,7 @@ class GateOperation(raw_types.Operation):
360
360
  return protocols.qasm(self.gate, args=args, qubits=self.qubits, default=None)
361
361
 
362
362
  def _equal_up_to_global_phase_(
363
- self, other: Any, atol: Union[int, float] = 1e-8
363
+ self, other: Any, atol: float = 1e-8
364
364
  ) -> Union[NotImplementedType, bool]:
365
365
  if not isinstance(other, type(self)):
366
366
  return NotImplemented
@@ -454,6 +454,7 @@ def test_is_parameterized():
454
454
  return True
455
455
 
456
456
  q = cirq.LineQubit(0)
457
+ assert No1().num_qubits() == 1
457
458
  assert not cirq.is_parameterized(No1().on(q))
458
459
  assert not cirq.is_parameterized(No2().on(q))
459
460
  assert cirq.is_parameterized(Yes().on(q))
@@ -490,7 +491,9 @@ def test_gate_to_operation_to_gate_round_trips():
490
491
  gate_subclasses = {
491
492
  g
492
493
  for g in all_subclasses(cirq.Gate)
493
- if "cirq." in g.__module__ and "contrib" not in g.__module__ and "test" not in g.__module__
494
+ if g.__module__.startswith("cirq.")
495
+ and "contrib" not in g.__module__
496
+ and "test" not in g.__module__
494
497
  }
495
498
 
496
499
  test_module_spec = cirq.testing.json.spec_for("cirq.protocols")
@@ -506,7 +509,6 @@ def test_gate_to_operation_to_gate_round_trips():
506
509
  cirq.transformers.measurement_transformers._ConfusionChannel,
507
510
  cirq.transformers.measurement_transformers._ModAdd,
508
511
  cirq.transformers.routing.visualize_routed_circuit._SwapPrintGate,
509
- cirq.ops.raw_types._InverseCompositeGate,
510
512
  cirq.circuits.qasm_output.QasmTwoQubitGate,
511
513
  cirq.ops.MSGate,
512
514
  # Interop gates
cirq/ops/gateset_test.py CHANGED
@@ -12,13 +12,15 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import Tuple, List, cast
16
15
  import re
16
+ from typing import cast, List, Tuple
17
+
18
+ import numpy as np
17
19
  import pytest
18
20
  import sympy
21
+
19
22
  import cirq
20
23
  from cirq._compat import proper_repr
21
- import numpy as np
22
24
 
23
25
 
24
26
  class CustomXPowGate(cirq.EigenGate):
@@ -441,3 +443,10 @@ def test_gateset_contains_with_tags():
441
443
  # Both tags to accept and tags to ignore
442
444
  assert op in cirq.Gateset(gf_accept, gf_ignore)
443
445
  assert op_with_tag in cirq.Gateset(gf_accept, gf_ignore)
446
+
447
+
448
+ def test_gateset_contains_op_with_no_gate():
449
+ gf = cirq.GateFamily(cirq.ZPowGate)
450
+ op = cirq.X(cirq.q(1)).with_classical_controls('a')
451
+ assert op.gate is None
452
+ assert op not in gf
@@ -13,22 +13,23 @@
13
13
  # limitations under the License.
14
14
  """A no-qubit global phase operation."""
15
15
 
16
- from typing import AbstractSet, Any, cast, Dict, Sequence, Tuple, Union, Optional, Collection
16
+ from types import NotImplementedType
17
+ from typing import AbstractSet, Any, cast, Collection, Dict, Optional, Sequence, Tuple, Union
17
18
 
18
19
  import numpy as np
19
20
  import sympy
20
21
 
21
22
  import cirq
22
- from cirq import value, protocols
23
- from cirq.ops import raw_types, controlled_gate, control_values as cv
24
- from cirq.type_workarounds import NotImplementedType
23
+ from cirq import protocols, value
24
+ from cirq._compat import proper_repr
25
+ from cirq.ops import control_values as cv, controlled_gate, raw_types
25
26
 
26
27
 
27
28
  @value.value_equality(approximate=True)
28
29
  class GlobalPhaseGate(raw_types.Gate):
29
30
  def __init__(self, coefficient: 'cirq.TParamValComplex', atol: float = 1e-8) -> None:
30
31
  if not isinstance(coefficient, sympy.Basic):
31
- if abs(1 - abs(coefficient)) > atol: # type: ignore[operator]
32
+ if abs(1 - abs(coefficient)) > atol:
32
33
  raise ValueError(f'Coefficient is not unitary: {coefficient!r}')
33
34
  self._coefficient = coefficient
34
35
 
@@ -68,10 +69,10 @@ class GlobalPhaseGate(raw_types.Gate):
68
69
  return str(self.coefficient)
69
70
 
70
71
  def __repr__(self) -> str:
71
- return f'cirq.GlobalPhaseGate({self.coefficient!r})'
72
+ return f'cirq.GlobalPhaseGate({proper_repr(self.coefficient)})'
72
73
 
73
74
  def _op_repr_(self, qubits: Sequence['cirq.Qid']) -> str:
74
- return f'cirq.global_phase_operation({self.coefficient!r})'
75
+ return f'cirq.global_phase_operation({proper_repr(self.coefficient)})'
75
76
 
76
77
  def _json_dict_(self) -> Dict[str, Any]:
77
78
  return protocols.obj_to_dict_helper(self, ['coefficient'])
@@ -33,7 +33,7 @@ def test_init():
33
33
 
34
34
 
35
35
  def test_protocols():
36
- for p in [1, 1j, -1]:
36
+ for p in [1, 1j, -1, sympy.Symbol('s')]:
37
37
  cirq.testing.assert_implements_consistent_protocols(cirq.global_phase_operation(p))
38
38
 
39
39
  np.testing.assert_allclose(
@@ -90,6 +90,11 @@ ancilla_1: ───X───X───
90
90
  )
91
91
 
92
92
 
93
+ def test_empty_qubits():
94
+ qm = cirq.GreedyQubitManager(prefix="anc")
95
+ assert qm.qalloc(0) == []
96
+
97
+
93
98
  def test_greedy_qubit_manager_preserves_order():
94
99
  qm = cirq.GreedyQubitManager(prefix="anc")
95
100
  ancillae = [cirq.q(f"anc_{i}") for i in range(100)]