qiskit 1.3.0__cp39-abi3-macosx_11_0_arm64.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.
Files changed (836) hide show
  1. qiskit/VERSION.txt +1 -0
  2. qiskit/__init__.py +146 -0
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/_numpy_compat.py +73 -0
  5. qiskit/assembler/__init__.py +42 -0
  6. qiskit/assembler/assemble_circuits.py +451 -0
  7. qiskit/assembler/assemble_schedules.py +367 -0
  8. qiskit/assembler/disassemble.py +310 -0
  9. qiskit/assembler/run_config.py +77 -0
  10. qiskit/circuit/__init__.py +1313 -0
  11. qiskit/circuit/_classical_resource_map.py +148 -0
  12. qiskit/circuit/_standard_gates_commutations.py +3849 -0
  13. qiskit/circuit/_utils.py +167 -0
  14. qiskit/circuit/add_control.py +274 -0
  15. qiskit/circuit/annotated_operation.py +279 -0
  16. qiskit/circuit/barrier.py +50 -0
  17. qiskit/circuit/bit.py +94 -0
  18. qiskit/circuit/classical/__init__.py +41 -0
  19. qiskit/circuit/classical/expr/__init__.py +238 -0
  20. qiskit/circuit/classical/expr/constructors.py +556 -0
  21. qiskit/circuit/classical/expr/expr.py +397 -0
  22. qiskit/circuit/classical/expr/visitors.py +300 -0
  23. qiskit/circuit/classical/types/__init__.py +109 -0
  24. qiskit/circuit/classical/types/ordering.py +222 -0
  25. qiskit/circuit/classical/types/types.py +117 -0
  26. qiskit/circuit/classicalfunction/__init__.py +140 -0
  27. qiskit/circuit/classicalfunction/boolean_expression.py +129 -0
  28. qiskit/circuit/classicalfunction/classical_element.py +54 -0
  29. qiskit/circuit/classicalfunction/classical_function_visitor.py +155 -0
  30. qiskit/circuit/classicalfunction/classicalfunction.py +173 -0
  31. qiskit/circuit/classicalfunction/exceptions.py +35 -0
  32. qiskit/circuit/classicalfunction/types.py +18 -0
  33. qiskit/circuit/classicalfunction/utils.py +91 -0
  34. qiskit/circuit/classicalregister.py +57 -0
  35. qiskit/circuit/commutation_checker.py +106 -0
  36. qiskit/circuit/commutation_library.py +20 -0
  37. qiskit/circuit/controlflow/__init__.py +28 -0
  38. qiskit/circuit/controlflow/_builder_utils.py +207 -0
  39. qiskit/circuit/controlflow/break_loop.py +56 -0
  40. qiskit/circuit/controlflow/builder.py +691 -0
  41. qiskit/circuit/controlflow/continue_loop.py +58 -0
  42. qiskit/circuit/controlflow/control_flow.py +84 -0
  43. qiskit/circuit/controlflow/for_loop.py +217 -0
  44. qiskit/circuit/controlflow/if_else.py +511 -0
  45. qiskit/circuit/controlflow/switch_case.py +417 -0
  46. qiskit/circuit/controlflow/while_loop.py +171 -0
  47. qiskit/circuit/controlledgate.py +274 -0
  48. qiskit/circuit/delay.py +123 -0
  49. qiskit/circuit/duration.py +95 -0
  50. qiskit/circuit/equivalence.py +94 -0
  51. qiskit/circuit/equivalence_library.py +18 -0
  52. qiskit/circuit/exceptions.py +19 -0
  53. qiskit/circuit/gate.py +263 -0
  54. qiskit/circuit/instruction.py +697 -0
  55. qiskit/circuit/instructionset.py +179 -0
  56. qiskit/circuit/library/__init__.py +668 -0
  57. qiskit/circuit/library/arithmetic/__init__.py +34 -0
  58. qiskit/circuit/library/arithmetic/adders/__init__.py +18 -0
  59. qiskit/circuit/library/arithmetic/adders/adder.py +210 -0
  60. qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +123 -0
  61. qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +129 -0
  62. qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +95 -0
  63. qiskit/circuit/library/arithmetic/exact_reciprocal.py +88 -0
  64. qiskit/circuit/library/arithmetic/functional_pauli_rotations.py +114 -0
  65. qiskit/circuit/library/arithmetic/integer_comparator.py +243 -0
  66. qiskit/circuit/library/arithmetic/linear_amplitude_function.py +196 -0
  67. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +189 -0
  68. qiskit/circuit/library/arithmetic/multipliers/__init__.py +17 -0
  69. qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +145 -0
  70. qiskit/circuit/library/arithmetic/multipliers/multiplier.py +192 -0
  71. qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +108 -0
  72. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +353 -0
  73. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +277 -0
  74. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +317 -0
  75. qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +335 -0
  76. qiskit/circuit/library/arithmetic/quadratic_form.py +198 -0
  77. qiskit/circuit/library/arithmetic/weighted_adder.py +337 -0
  78. qiskit/circuit/library/basis_change/__init__.py +15 -0
  79. qiskit/circuit/library/basis_change/qft.py +313 -0
  80. qiskit/circuit/library/blueprintcircuit.py +280 -0
  81. qiskit/circuit/library/boolean_logic/__init__.py +18 -0
  82. qiskit/circuit/library/boolean_logic/inner_product.py +155 -0
  83. qiskit/circuit/library/boolean_logic/quantum_and.py +200 -0
  84. qiskit/circuit/library/boolean_logic/quantum_or.py +202 -0
  85. qiskit/circuit/library/boolean_logic/quantum_xor.py +165 -0
  86. qiskit/circuit/library/data_preparation/__init__.py +57 -0
  87. qiskit/circuit/library/data_preparation/_z_feature_map.py +115 -0
  88. qiskit/circuit/library/data_preparation/_zz_feature_map.py +150 -0
  89. qiskit/circuit/library/data_preparation/initializer.py +107 -0
  90. qiskit/circuit/library/data_preparation/pauli_feature_map.py +656 -0
  91. qiskit/circuit/library/data_preparation/state_preparation.py +336 -0
  92. qiskit/circuit/library/fourier_checking.py +158 -0
  93. qiskit/circuit/library/generalized_gates/__init__.py +30 -0
  94. qiskit/circuit/library/generalized_gates/diagonal.py +159 -0
  95. qiskit/circuit/library/generalized_gates/gms.py +174 -0
  96. qiskit/circuit/library/generalized_gates/gr.py +215 -0
  97. qiskit/circuit/library/generalized_gates/isometry.py +370 -0
  98. qiskit/circuit/library/generalized_gates/linear_function.py +318 -0
  99. qiskit/circuit/library/generalized_gates/mcg_up_to_diagonal.py +143 -0
  100. qiskit/circuit/library/generalized_gates/mcmt.py +316 -0
  101. qiskit/circuit/library/generalized_gates/pauli.py +85 -0
  102. qiskit/circuit/library/generalized_gates/permutation.py +194 -0
  103. qiskit/circuit/library/generalized_gates/rv.py +96 -0
  104. qiskit/circuit/library/generalized_gates/uc.py +213 -0
  105. qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +164 -0
  106. qiskit/circuit/library/generalized_gates/ucrx.py +32 -0
  107. qiskit/circuit/library/generalized_gates/ucry.py +32 -0
  108. qiskit/circuit/library/generalized_gates/ucrz.py +32 -0
  109. qiskit/circuit/library/generalized_gates/unitary.py +215 -0
  110. qiskit/circuit/library/graph_state.py +169 -0
  111. qiskit/circuit/library/grover_operator.py +579 -0
  112. qiskit/circuit/library/hamiltonian_gate.py +142 -0
  113. qiskit/circuit/library/hidden_linear_function.py +161 -0
  114. qiskit/circuit/library/iqp.py +175 -0
  115. qiskit/circuit/library/n_local/__init__.py +45 -0
  116. qiskit/circuit/library/n_local/efficient_su2.py +277 -0
  117. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +515 -0
  118. qiskit/circuit/library/n_local/excitation_preserving.py +297 -0
  119. qiskit/circuit/library/n_local/n_local.py +1472 -0
  120. qiskit/circuit/library/n_local/pauli_two_design.py +243 -0
  121. qiskit/circuit/library/n_local/qaoa_ansatz.py +366 -0
  122. qiskit/circuit/library/n_local/real_amplitudes.py +306 -0
  123. qiskit/circuit/library/n_local/two_local.py +289 -0
  124. qiskit/circuit/library/overlap.py +182 -0
  125. qiskit/circuit/library/pauli_evolution.py +186 -0
  126. qiskit/circuit/library/phase_estimation.py +175 -0
  127. qiskit/circuit/library/phase_oracle.py +153 -0
  128. qiskit/circuit/library/quantum_volume.py +167 -0
  129. qiskit/circuit/library/standard_gates/__init__.py +142 -0
  130. qiskit/circuit/library/standard_gates/dcx.py +78 -0
  131. qiskit/circuit/library/standard_gates/ecr.py +130 -0
  132. qiskit/circuit/library/standard_gates/equivalence_library.py +1800 -0
  133. qiskit/circuit/library/standard_gates/global_phase.py +85 -0
  134. qiskit/circuit/library/standard_gates/h.py +258 -0
  135. qiskit/circuit/library/standard_gates/i.py +76 -0
  136. qiskit/circuit/library/standard_gates/iswap.py +134 -0
  137. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +405 -0
  138. qiskit/circuit/library/standard_gates/p.py +441 -0
  139. qiskit/circuit/library/standard_gates/r.py +117 -0
  140. qiskit/circuit/library/standard_gates/rx.py +303 -0
  141. qiskit/circuit/library/standard_gates/rxx.py +183 -0
  142. qiskit/circuit/library/standard_gates/ry.py +298 -0
  143. qiskit/circuit/library/standard_gates/ryy.py +183 -0
  144. qiskit/circuit/library/standard_gates/rz.py +319 -0
  145. qiskit/circuit/library/standard_gates/rzx.py +229 -0
  146. qiskit/circuit/library/standard_gates/rzz.py +196 -0
  147. qiskit/circuit/library/standard_gates/s.py +428 -0
  148. qiskit/circuit/library/standard_gates/swap.py +288 -0
  149. qiskit/circuit/library/standard_gates/sx.py +315 -0
  150. qiskit/circuit/library/standard_gates/t.py +179 -0
  151. qiskit/circuit/library/standard_gates/u.py +403 -0
  152. qiskit/circuit/library/standard_gates/u1.py +501 -0
  153. qiskit/circuit/library/standard_gates/u2.py +149 -0
  154. qiskit/circuit/library/standard_gates/u3.py +436 -0
  155. qiskit/circuit/library/standard_gates/x.py +1529 -0
  156. qiskit/circuit/library/standard_gates/xx_minus_yy.py +235 -0
  157. qiskit/circuit/library/standard_gates/xx_plus_yy.py +239 -0
  158. qiskit/circuit/library/standard_gates/y.py +262 -0
  159. qiskit/circuit/library/standard_gates/z.py +348 -0
  160. qiskit/circuit/library/templates/__init__.py +92 -0
  161. qiskit/circuit/library/templates/clifford/__init__.py +33 -0
  162. qiskit/circuit/library/templates/clifford/clifford_2_1.py +34 -0
  163. qiskit/circuit/library/templates/clifford/clifford_2_2.py +35 -0
  164. qiskit/circuit/library/templates/clifford/clifford_2_3.py +34 -0
  165. qiskit/circuit/library/templates/clifford/clifford_2_4.py +34 -0
  166. qiskit/circuit/library/templates/clifford/clifford_3_1.py +35 -0
  167. qiskit/circuit/library/templates/clifford/clifford_4_1.py +38 -0
  168. qiskit/circuit/library/templates/clifford/clifford_4_2.py +37 -0
  169. qiskit/circuit/library/templates/clifford/clifford_4_3.py +38 -0
  170. qiskit/circuit/library/templates/clifford/clifford_4_4.py +37 -0
  171. qiskit/circuit/library/templates/clifford/clifford_5_1.py +40 -0
  172. qiskit/circuit/library/templates/clifford/clifford_6_1.py +40 -0
  173. qiskit/circuit/library/templates/clifford/clifford_6_2.py +40 -0
  174. qiskit/circuit/library/templates/clifford/clifford_6_3.py +40 -0
  175. qiskit/circuit/library/templates/clifford/clifford_6_4.py +38 -0
  176. qiskit/circuit/library/templates/clifford/clifford_6_5.py +40 -0
  177. qiskit/circuit/library/templates/clifford/clifford_8_1.py +42 -0
  178. qiskit/circuit/library/templates/clifford/clifford_8_2.py +42 -0
  179. qiskit/circuit/library/templates/clifford/clifford_8_3.py +41 -0
  180. qiskit/circuit/library/templates/nct/__init__.py +67 -0
  181. qiskit/circuit/library/templates/nct/template_nct_2a_1.py +34 -0
  182. qiskit/circuit/library/templates/nct/template_nct_2a_2.py +35 -0
  183. qiskit/circuit/library/templates/nct/template_nct_2a_3.py +37 -0
  184. qiskit/circuit/library/templates/nct/template_nct_4a_1.py +43 -0
  185. qiskit/circuit/library/templates/nct/template_nct_4a_2.py +41 -0
  186. qiskit/circuit/library/templates/nct/template_nct_4a_3.py +39 -0
  187. qiskit/circuit/library/templates/nct/template_nct_4b_1.py +41 -0
  188. qiskit/circuit/library/templates/nct/template_nct_4b_2.py +39 -0
  189. qiskit/circuit/library/templates/nct/template_nct_5a_1.py +40 -0
  190. qiskit/circuit/library/templates/nct/template_nct_5a_2.py +40 -0
  191. qiskit/circuit/library/templates/nct/template_nct_5a_3.py +40 -0
  192. qiskit/circuit/library/templates/nct/template_nct_5a_4.py +39 -0
  193. qiskit/circuit/library/templates/nct/template_nct_6a_1.py +40 -0
  194. qiskit/circuit/library/templates/nct/template_nct_6a_2.py +41 -0
  195. qiskit/circuit/library/templates/nct/template_nct_6a_3.py +41 -0
  196. qiskit/circuit/library/templates/nct/template_nct_6a_4.py +41 -0
  197. qiskit/circuit/library/templates/nct/template_nct_6b_1.py +41 -0
  198. qiskit/circuit/library/templates/nct/template_nct_6b_2.py +41 -0
  199. qiskit/circuit/library/templates/nct/template_nct_6c_1.py +41 -0
  200. qiskit/circuit/library/templates/nct/template_nct_7a_1.py +43 -0
  201. qiskit/circuit/library/templates/nct/template_nct_7b_1.py +43 -0
  202. qiskit/circuit/library/templates/nct/template_nct_7c_1.py +43 -0
  203. qiskit/circuit/library/templates/nct/template_nct_7d_1.py +43 -0
  204. qiskit/circuit/library/templates/nct/template_nct_7e_1.py +43 -0
  205. qiskit/circuit/library/templates/nct/template_nct_9a_1.py +45 -0
  206. qiskit/circuit/library/templates/nct/template_nct_9c_1.py +43 -0
  207. qiskit/circuit/library/templates/nct/template_nct_9c_10.py +44 -0
  208. qiskit/circuit/library/templates/nct/template_nct_9c_11.py +44 -0
  209. qiskit/circuit/library/templates/nct/template_nct_9c_12.py +44 -0
  210. qiskit/circuit/library/templates/nct/template_nct_9c_2.py +44 -0
  211. qiskit/circuit/library/templates/nct/template_nct_9c_3.py +44 -0
  212. qiskit/circuit/library/templates/nct/template_nct_9c_4.py +44 -0
  213. qiskit/circuit/library/templates/nct/template_nct_9c_5.py +44 -0
  214. qiskit/circuit/library/templates/nct/template_nct_9c_6.py +44 -0
  215. qiskit/circuit/library/templates/nct/template_nct_9c_7.py +44 -0
  216. qiskit/circuit/library/templates/nct/template_nct_9c_8.py +44 -0
  217. qiskit/circuit/library/templates/nct/template_nct_9c_9.py +44 -0
  218. qiskit/circuit/library/templates/nct/template_nct_9d_1.py +43 -0
  219. qiskit/circuit/library/templates/nct/template_nct_9d_10.py +44 -0
  220. qiskit/circuit/library/templates/nct/template_nct_9d_2.py +44 -0
  221. qiskit/circuit/library/templates/nct/template_nct_9d_3.py +44 -0
  222. qiskit/circuit/library/templates/nct/template_nct_9d_4.py +44 -0
  223. qiskit/circuit/library/templates/nct/template_nct_9d_5.py +44 -0
  224. qiskit/circuit/library/templates/nct/template_nct_9d_6.py +44 -0
  225. qiskit/circuit/library/templates/nct/template_nct_9d_7.py +44 -0
  226. qiskit/circuit/library/templates/nct/template_nct_9d_8.py +44 -0
  227. qiskit/circuit/library/templates/nct/template_nct_9d_9.py +44 -0
  228. qiskit/circuit/library/templates/rzx/__init__.py +25 -0
  229. qiskit/circuit/library/templates/rzx/rzx_cy.py +47 -0
  230. qiskit/circuit/library/templates/rzx/rzx_xz.py +54 -0
  231. qiskit/circuit/library/templates/rzx/rzx_yz.py +45 -0
  232. qiskit/circuit/library/templates/rzx/rzx_zz1.py +69 -0
  233. qiskit/circuit/library/templates/rzx/rzx_zz2.py +59 -0
  234. qiskit/circuit/library/templates/rzx/rzx_zz3.py +59 -0
  235. qiskit/circuit/measure.py +44 -0
  236. qiskit/circuit/operation.py +67 -0
  237. qiskit/circuit/parameter.py +178 -0
  238. qiskit/circuit/parameterexpression.py +692 -0
  239. qiskit/circuit/parametertable.py +119 -0
  240. qiskit/circuit/parametervector.py +120 -0
  241. qiskit/circuit/quantumcircuit.py +6829 -0
  242. qiskit/circuit/quantumcircuitdata.py +136 -0
  243. qiskit/circuit/quantumregister.py +75 -0
  244. qiskit/circuit/random/__init__.py +15 -0
  245. qiskit/circuit/random/utils.py +358 -0
  246. qiskit/circuit/register.py +233 -0
  247. qiskit/circuit/reset.py +34 -0
  248. qiskit/circuit/singleton.py +606 -0
  249. qiskit/circuit/store.py +97 -0
  250. qiskit/circuit/tools/__init__.py +16 -0
  251. qiskit/circuit/tools/pi_check.py +190 -0
  252. qiskit/circuit/twirling.py +145 -0
  253. qiskit/compiler/__init__.py +33 -0
  254. qiskit/compiler/assembler.py +681 -0
  255. qiskit/compiler/scheduler.py +109 -0
  256. qiskit/compiler/sequencer.py +71 -0
  257. qiskit/compiler/transpiler.py +533 -0
  258. qiskit/converters/__init__.py +74 -0
  259. qiskit/converters/circuit_to_dag.py +78 -0
  260. qiskit/converters/circuit_to_dagdependency.py +51 -0
  261. qiskit/converters/circuit_to_dagdependency_v2.py +47 -0
  262. qiskit/converters/circuit_to_gate.py +107 -0
  263. qiskit/converters/circuit_to_instruction.py +155 -0
  264. qiskit/converters/dag_to_circuit.py +79 -0
  265. qiskit/converters/dag_to_dagdependency.py +55 -0
  266. qiskit/converters/dag_to_dagdependency_v2.py +44 -0
  267. qiskit/converters/dagdependency_to_circuit.py +46 -0
  268. qiskit/converters/dagdependency_to_dag.py +54 -0
  269. qiskit/dagcircuit/__init__.py +44 -0
  270. qiskit/dagcircuit/collect_blocks.py +391 -0
  271. qiskit/dagcircuit/dagcircuit.py +24 -0
  272. qiskit/dagcircuit/dagdependency.py +646 -0
  273. qiskit/dagcircuit/dagdependency_v2.py +641 -0
  274. qiskit/dagcircuit/dagdepnode.py +160 -0
  275. qiskit/dagcircuit/dagnode.py +176 -0
  276. qiskit/dagcircuit/exceptions.py +42 -0
  277. qiskit/exceptions.py +153 -0
  278. qiskit/passmanager/__init__.py +240 -0
  279. qiskit/passmanager/base_tasks.py +230 -0
  280. qiskit/passmanager/compilation_status.py +74 -0
  281. qiskit/passmanager/exceptions.py +19 -0
  282. qiskit/passmanager/flow_controllers.py +116 -0
  283. qiskit/passmanager/passmanager.py +333 -0
  284. qiskit/primitives/__init__.py +481 -0
  285. qiskit/primitives/backend_estimator.py +486 -0
  286. qiskit/primitives/backend_estimator_v2.py +434 -0
  287. qiskit/primitives/backend_sampler.py +222 -0
  288. qiskit/primitives/backend_sampler_v2.py +339 -0
  289. qiskit/primitives/base/__init__.py +20 -0
  290. qiskit/primitives/base/base_estimator.py +252 -0
  291. qiskit/primitives/base/base_primitive.py +45 -0
  292. qiskit/primitives/base/base_primitive_job.py +78 -0
  293. qiskit/primitives/base/base_result.py +65 -0
  294. qiskit/primitives/base/base_sampler.py +204 -0
  295. qiskit/primitives/base/estimator_result.py +46 -0
  296. qiskit/primitives/base/sampler_result.py +45 -0
  297. qiskit/primitives/base/validation.py +231 -0
  298. qiskit/primitives/containers/__init__.py +26 -0
  299. qiskit/primitives/containers/bindings_array.py +389 -0
  300. qiskit/primitives/containers/bit_array.py +741 -0
  301. qiskit/primitives/containers/data_bin.py +173 -0
  302. qiskit/primitives/containers/estimator_pub.py +222 -0
  303. qiskit/primitives/containers/object_array.py +94 -0
  304. qiskit/primitives/containers/observables_array.py +279 -0
  305. qiskit/primitives/containers/primitive_result.py +53 -0
  306. qiskit/primitives/containers/pub_result.py +51 -0
  307. qiskit/primitives/containers/sampler_pub.py +193 -0
  308. qiskit/primitives/containers/sampler_pub_result.py +74 -0
  309. qiskit/primitives/containers/shape.py +129 -0
  310. qiskit/primitives/estimator.py +172 -0
  311. qiskit/primitives/primitive_job.py +81 -0
  312. qiskit/primitives/sampler.py +162 -0
  313. qiskit/primitives/statevector_estimator.py +174 -0
  314. qiskit/primitives/statevector_sampler.py +292 -0
  315. qiskit/primitives/utils.py +247 -0
  316. qiskit/providers/__init__.py +803 -0
  317. qiskit/providers/backend.py +667 -0
  318. qiskit/providers/backend_compat.py +472 -0
  319. qiskit/providers/basic_provider/__init__.py +45 -0
  320. qiskit/providers/basic_provider/basic_provider.py +101 -0
  321. qiskit/providers/basic_provider/basic_provider_job.py +65 -0
  322. qiskit/providers/basic_provider/basic_provider_tools.py +218 -0
  323. qiskit/providers/basic_provider/basic_simulator.py +821 -0
  324. qiskit/providers/basic_provider/exceptions.py +30 -0
  325. qiskit/providers/exceptions.py +45 -0
  326. qiskit/providers/fake_provider/__init__.py +105 -0
  327. qiskit/providers/fake_provider/backends_v1/__init__.py +22 -0
  328. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +18 -0
  329. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +1 -0
  330. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +1 -0
  331. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +37 -0
  332. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +1 -0
  333. qiskit/providers/fake_provider/backends_v1/fake_20q/__init__.py +18 -0
  334. qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +1 -0
  335. qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +43 -0
  336. qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +1 -0
  337. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +18 -0
  338. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +1 -0
  339. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +1 -0
  340. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +50 -0
  341. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +1 -0
  342. qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +18 -0
  343. qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +1 -0
  344. qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +41 -0
  345. qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +1 -0
  346. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +18 -0
  347. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +1 -0
  348. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +1 -0
  349. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +44 -0
  350. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +1 -0
  351. qiskit/providers/fake_provider/fake_1q.py +91 -0
  352. qiskit/providers/fake_provider/fake_backend.py +165 -0
  353. qiskit/providers/fake_provider/fake_openpulse_2q.py +391 -0
  354. qiskit/providers/fake_provider/fake_openpulse_3q.py +340 -0
  355. qiskit/providers/fake_provider/fake_pulse_backend.py +49 -0
  356. qiskit/providers/fake_provider/fake_qasm_backend.py +77 -0
  357. qiskit/providers/fake_provider/generic_backend_v2.py +1035 -0
  358. qiskit/providers/fake_provider/utils/__init__.py +15 -0
  359. qiskit/providers/fake_provider/utils/backend_converter.py +150 -0
  360. qiskit/providers/fake_provider/utils/json_decoder.py +109 -0
  361. qiskit/providers/job.py +147 -0
  362. qiskit/providers/jobstatus.py +30 -0
  363. qiskit/providers/models/__init__.py +89 -0
  364. qiskit/providers/models/backendconfiguration.py +1040 -0
  365. qiskit/providers/models/backendproperties.py +517 -0
  366. qiskit/providers/models/backendstatus.py +94 -0
  367. qiskit/providers/models/jobstatus.py +66 -0
  368. qiskit/providers/models/pulsedefaults.py +305 -0
  369. qiskit/providers/options.py +273 -0
  370. qiskit/providers/provider.py +95 -0
  371. qiskit/providers/providerutils.py +110 -0
  372. qiskit/pulse/__init__.py +158 -0
  373. qiskit/pulse/builder.py +2254 -0
  374. qiskit/pulse/calibration_entries.py +381 -0
  375. qiskit/pulse/channels.py +227 -0
  376. qiskit/pulse/configuration.py +245 -0
  377. qiskit/pulse/exceptions.py +45 -0
  378. qiskit/pulse/filters.py +309 -0
  379. qiskit/pulse/instruction_schedule_map.py +424 -0
  380. qiskit/pulse/instructions/__init__.py +67 -0
  381. qiskit/pulse/instructions/acquire.py +150 -0
  382. qiskit/pulse/instructions/delay.py +71 -0
  383. qiskit/pulse/instructions/directives.py +154 -0
  384. qiskit/pulse/instructions/frequency.py +135 -0
  385. qiskit/pulse/instructions/instruction.py +270 -0
  386. qiskit/pulse/instructions/phase.py +152 -0
  387. qiskit/pulse/instructions/play.py +99 -0
  388. qiskit/pulse/instructions/reference.py +100 -0
  389. qiskit/pulse/instructions/snapshot.py +82 -0
  390. qiskit/pulse/library/__init__.py +97 -0
  391. qiskit/pulse/library/continuous.py +430 -0
  392. qiskit/pulse/library/pulse.py +148 -0
  393. qiskit/pulse/library/samplers/__init__.py +15 -0
  394. qiskit/pulse/library/samplers/decorators.py +295 -0
  395. qiskit/pulse/library/samplers/strategies.py +71 -0
  396. qiskit/pulse/library/symbolic_pulses.py +1988 -0
  397. qiskit/pulse/library/waveform.py +136 -0
  398. qiskit/pulse/macros.py +262 -0
  399. qiskit/pulse/parameter_manager.py +445 -0
  400. qiskit/pulse/parser.py +314 -0
  401. qiskit/pulse/reference_manager.py +58 -0
  402. qiskit/pulse/schedule.py +1854 -0
  403. qiskit/pulse/transforms/__init__.py +106 -0
  404. qiskit/pulse/transforms/alignments.py +406 -0
  405. qiskit/pulse/transforms/base_transforms.py +71 -0
  406. qiskit/pulse/transforms/canonicalization.py +498 -0
  407. qiskit/pulse/transforms/dag.py +122 -0
  408. qiskit/pulse/utils.py +149 -0
  409. qiskit/qasm/libs/dummy/stdgates.inc +75 -0
  410. qiskit/qasm/libs/qelib1.inc +266 -0
  411. qiskit/qasm/libs/stdgates.inc +82 -0
  412. qiskit/qasm2/__init__.py +654 -0
  413. qiskit/qasm2/exceptions.py +27 -0
  414. qiskit/qasm2/export.py +372 -0
  415. qiskit/qasm2/parse.py +452 -0
  416. qiskit/qasm3/__init__.py +367 -0
  417. qiskit/qasm3/ast.py +738 -0
  418. qiskit/qasm3/exceptions.py +27 -0
  419. qiskit/qasm3/experimental.py +70 -0
  420. qiskit/qasm3/exporter.py +1299 -0
  421. qiskit/qasm3/printer.py +577 -0
  422. qiskit/qobj/__init__.py +75 -0
  423. qiskit/qobj/common.py +81 -0
  424. qiskit/qobj/converters/__init__.py +18 -0
  425. qiskit/qobj/converters/lo_config.py +177 -0
  426. qiskit/qobj/converters/pulse_instruction.py +897 -0
  427. qiskit/qobj/pulse_qobj.py +709 -0
  428. qiskit/qobj/qasm_qobj.py +708 -0
  429. qiskit/qobj/utils.py +46 -0
  430. qiskit/qpy/__init__.py +1822 -0
  431. qiskit/qpy/binary_io/__init__.py +36 -0
  432. qiskit/qpy/binary_io/circuits.py +1475 -0
  433. qiskit/qpy/binary_io/schedules.py +635 -0
  434. qiskit/qpy/binary_io/value.py +1025 -0
  435. qiskit/qpy/common.py +350 -0
  436. qiskit/qpy/exceptions.py +53 -0
  437. qiskit/qpy/formats.py +401 -0
  438. qiskit/qpy/interface.py +377 -0
  439. qiskit/qpy/type_keys.py +572 -0
  440. qiskit/quantum_info/__init__.py +162 -0
  441. qiskit/quantum_info/analysis/__init__.py +17 -0
  442. qiskit/quantum_info/analysis/average.py +47 -0
  443. qiskit/quantum_info/analysis/distance.py +102 -0
  444. qiskit/quantum_info/analysis/make_observable.py +44 -0
  445. qiskit/quantum_info/analysis/z2_symmetries.py +484 -0
  446. qiskit/quantum_info/operators/__init__.py +28 -0
  447. qiskit/quantum_info/operators/base_operator.py +145 -0
  448. qiskit/quantum_info/operators/channel/__init__.py +29 -0
  449. qiskit/quantum_info/operators/channel/chi.py +191 -0
  450. qiskit/quantum_info/operators/channel/choi.py +218 -0
  451. qiskit/quantum_info/operators/channel/kraus.py +337 -0
  452. qiskit/quantum_info/operators/channel/ptm.py +204 -0
  453. qiskit/quantum_info/operators/channel/quantum_channel.py +348 -0
  454. qiskit/quantum_info/operators/channel/stinespring.py +296 -0
  455. qiskit/quantum_info/operators/channel/superop.py +377 -0
  456. qiskit/quantum_info/operators/channel/transformations.py +475 -0
  457. qiskit/quantum_info/operators/custom_iterator.py +48 -0
  458. qiskit/quantum_info/operators/dihedral/__init__.py +18 -0
  459. qiskit/quantum_info/operators/dihedral/dihedral.py +509 -0
  460. qiskit/quantum_info/operators/dihedral/dihedral_circuits.py +216 -0
  461. qiskit/quantum_info/operators/dihedral/polynomial.py +313 -0
  462. qiskit/quantum_info/operators/dihedral/random.py +64 -0
  463. qiskit/quantum_info/operators/linear_op.py +25 -0
  464. qiskit/quantum_info/operators/measures.py +418 -0
  465. qiskit/quantum_info/operators/mixins/__init__.py +52 -0
  466. qiskit/quantum_info/operators/mixins/adjoint.py +52 -0
  467. qiskit/quantum_info/operators/mixins/group.py +171 -0
  468. qiskit/quantum_info/operators/mixins/linear.py +84 -0
  469. qiskit/quantum_info/operators/mixins/multiply.py +62 -0
  470. qiskit/quantum_info/operators/mixins/tolerances.py +72 -0
  471. qiskit/quantum_info/operators/op_shape.py +525 -0
  472. qiskit/quantum_info/operators/operator.py +865 -0
  473. qiskit/quantum_info/operators/operator_utils.py +76 -0
  474. qiskit/quantum_info/operators/predicates.py +183 -0
  475. qiskit/quantum_info/operators/random.py +154 -0
  476. qiskit/quantum_info/operators/scalar_op.py +254 -0
  477. qiskit/quantum_info/operators/symplectic/__init__.py +23 -0
  478. qiskit/quantum_info/operators/symplectic/base_pauli.py +719 -0
  479. qiskit/quantum_info/operators/symplectic/clifford.py +1030 -0
  480. qiskit/quantum_info/operators/symplectic/clifford_circuits.py +558 -0
  481. qiskit/quantum_info/operators/symplectic/pauli.py +753 -0
  482. qiskit/quantum_info/operators/symplectic/pauli_list.py +1230 -0
  483. qiskit/quantum_info/operators/symplectic/pauli_utils.py +40 -0
  484. qiskit/quantum_info/operators/symplectic/random.py +117 -0
  485. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +1196 -0
  486. qiskit/quantum_info/operators/utils/__init__.py +20 -0
  487. qiskit/quantum_info/operators/utils/anti_commutator.py +36 -0
  488. qiskit/quantum_info/operators/utils/commutator.py +36 -0
  489. qiskit/quantum_info/operators/utils/double_commutator.py +76 -0
  490. qiskit/quantum_info/quaternion.py +156 -0
  491. qiskit/quantum_info/random.py +26 -0
  492. qiskit/quantum_info/states/__init__.py +28 -0
  493. qiskit/quantum_info/states/densitymatrix.py +845 -0
  494. qiskit/quantum_info/states/measures.py +288 -0
  495. qiskit/quantum_info/states/quantum_state.py +503 -0
  496. qiskit/quantum_info/states/random.py +157 -0
  497. qiskit/quantum_info/states/stabilizerstate.py +773 -0
  498. qiskit/quantum_info/states/statevector.py +958 -0
  499. qiskit/quantum_info/states/utils.py +247 -0
  500. qiskit/result/__init__.py +73 -0
  501. qiskit/result/counts.py +189 -0
  502. qiskit/result/distributions/__init__.py +17 -0
  503. qiskit/result/distributions/probability.py +100 -0
  504. qiskit/result/distributions/quasi.py +154 -0
  505. qiskit/result/exceptions.py +40 -0
  506. qiskit/result/mitigation/__init__.py +13 -0
  507. qiskit/result/mitigation/base_readout_mitigator.py +79 -0
  508. qiskit/result/mitigation/correlated_readout_mitigator.py +277 -0
  509. qiskit/result/mitigation/local_readout_mitigator.py +328 -0
  510. qiskit/result/mitigation/utils.py +217 -0
  511. qiskit/result/models.py +234 -0
  512. qiskit/result/postprocess.py +239 -0
  513. qiskit/result/result.py +392 -0
  514. qiskit/result/sampled_expval.py +75 -0
  515. qiskit/result/utils.py +295 -0
  516. qiskit/scheduler/__init__.py +40 -0
  517. qiskit/scheduler/config.py +37 -0
  518. qiskit/scheduler/lowering.py +187 -0
  519. qiskit/scheduler/methods/__init__.py +15 -0
  520. qiskit/scheduler/methods/basic.py +140 -0
  521. qiskit/scheduler/schedule_circuit.py +69 -0
  522. qiskit/scheduler/sequence.py +104 -0
  523. qiskit/synthesis/__init__.py +220 -0
  524. qiskit/synthesis/arithmetic/__init__.py +16 -0
  525. qiskit/synthesis/arithmetic/adders/__init__.py +17 -0
  526. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +154 -0
  527. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +103 -0
  528. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +161 -0
  529. qiskit/synthesis/arithmetic/multipliers/__init__.py +16 -0
  530. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +102 -0
  531. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +99 -0
  532. qiskit/synthesis/clifford/__init__.py +19 -0
  533. qiskit/synthesis/clifford/clifford_decompose_ag.py +178 -0
  534. qiskit/synthesis/clifford/clifford_decompose_bm.py +46 -0
  535. qiskit/synthesis/clifford/clifford_decompose_full.py +64 -0
  536. qiskit/synthesis/clifford/clifford_decompose_greedy.py +58 -0
  537. qiskit/synthesis/clifford/clifford_decompose_layers.py +447 -0
  538. qiskit/synthesis/cnotdihedral/__init__.py +17 -0
  539. qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_full.py +52 -0
  540. qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_general.py +141 -0
  541. qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_two_qubits.py +266 -0
  542. qiskit/synthesis/discrete_basis/__init__.py +16 -0
  543. qiskit/synthesis/discrete_basis/commutator_decompose.py +241 -0
  544. qiskit/synthesis/discrete_basis/gate_sequence.py +415 -0
  545. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +163 -0
  546. qiskit/synthesis/discrete_basis/solovay_kitaev.py +217 -0
  547. qiskit/synthesis/evolution/__init__.py +21 -0
  548. qiskit/synthesis/evolution/evolution_synthesis.py +48 -0
  549. qiskit/synthesis/evolution/lie_trotter.py +117 -0
  550. qiskit/synthesis/evolution/matrix_synthesis.py +47 -0
  551. qiskit/synthesis/evolution/pauli_network.py +80 -0
  552. qiskit/synthesis/evolution/product_formula.py +311 -0
  553. qiskit/synthesis/evolution/qdrift.py +138 -0
  554. qiskit/synthesis/evolution/suzuki_trotter.py +215 -0
  555. qiskit/synthesis/linear/__init__.py +26 -0
  556. qiskit/synthesis/linear/cnot_synth.py +69 -0
  557. qiskit/synthesis/linear/linear_circuits_utils.py +128 -0
  558. qiskit/synthesis/linear/linear_depth_lnn.py +276 -0
  559. qiskit/synthesis/linear/linear_matrix_utils.py +27 -0
  560. qiskit/synthesis/linear_phase/__init__.py +17 -0
  561. qiskit/synthesis/linear_phase/cnot_phase_synth.py +206 -0
  562. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +262 -0
  563. qiskit/synthesis/linear_phase/cz_depth_lnn.py +58 -0
  564. qiskit/synthesis/multi_controlled/__init__.py +24 -0
  565. qiskit/synthesis/multi_controlled/mcmt_vchain.py +52 -0
  566. qiskit/synthesis/multi_controlled/mcx_synthesis.py +356 -0
  567. qiskit/synthesis/one_qubit/__init__.py +15 -0
  568. qiskit/synthesis/one_qubit/one_qubit_decompose.py +288 -0
  569. qiskit/synthesis/permutation/__init__.py +18 -0
  570. qiskit/synthesis/permutation/permutation_full.py +78 -0
  571. qiskit/synthesis/permutation/permutation_lnn.py +54 -0
  572. qiskit/synthesis/permutation/permutation_reverse_lnn.py +93 -0
  573. qiskit/synthesis/permutation/permutation_utils.py +16 -0
  574. qiskit/synthesis/qft/__init__.py +16 -0
  575. qiskit/synthesis/qft/qft_decompose_full.py +97 -0
  576. qiskit/synthesis/qft/qft_decompose_lnn.py +79 -0
  577. qiskit/synthesis/stabilizer/__init__.py +16 -0
  578. qiskit/synthesis/stabilizer/stabilizer_circuit.py +149 -0
  579. qiskit/synthesis/stabilizer/stabilizer_decompose.py +194 -0
  580. qiskit/synthesis/two_qubit/__init__.py +19 -0
  581. qiskit/synthesis/two_qubit/local_invariance.py +63 -0
  582. qiskit/synthesis/two_qubit/two_qubit_decompose.py +700 -0
  583. qiskit/synthesis/two_qubit/xx_decompose/__init__.py +19 -0
  584. qiskit/synthesis/two_qubit/xx_decompose/circuits.py +300 -0
  585. qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +324 -0
  586. qiskit/synthesis/two_qubit/xx_decompose/embodiments.py +163 -0
  587. qiskit/synthesis/two_qubit/xx_decompose/paths.py +412 -0
  588. qiskit/synthesis/two_qubit/xx_decompose/polytopes.py +262 -0
  589. qiskit/synthesis/two_qubit/xx_decompose/utilities.py +40 -0
  590. qiskit/synthesis/two_qubit/xx_decompose/weyl.py +133 -0
  591. qiskit/synthesis/unitary/__init__.py +13 -0
  592. qiskit/synthesis/unitary/aqc/__init__.py +177 -0
  593. qiskit/synthesis/unitary/aqc/approximate.py +116 -0
  594. qiskit/synthesis/unitary/aqc/aqc.py +175 -0
  595. qiskit/synthesis/unitary/aqc/cnot_structures.py +300 -0
  596. qiskit/synthesis/unitary/aqc/cnot_unit_circuit.py +103 -0
  597. qiskit/synthesis/unitary/aqc/cnot_unit_objective.py +299 -0
  598. qiskit/synthesis/unitary/aqc/elementary_operations.py +108 -0
  599. qiskit/synthesis/unitary/aqc/fast_gradient/__init__.py +164 -0
  600. qiskit/synthesis/unitary/aqc/fast_gradient/fast_grad_utils.py +237 -0
  601. qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +226 -0
  602. qiskit/synthesis/unitary/aqc/fast_gradient/layer.py +370 -0
  603. qiskit/synthesis/unitary/aqc/fast_gradient/pmatrix.py +312 -0
  604. qiskit/synthesis/unitary/qsd.py +288 -0
  605. qiskit/transpiler/__init__.py +1290 -0
  606. qiskit/transpiler/basepasses.py +221 -0
  607. qiskit/transpiler/coupling.py +500 -0
  608. qiskit/transpiler/exceptions.py +59 -0
  609. qiskit/transpiler/instruction_durations.py +281 -0
  610. qiskit/transpiler/layout.py +737 -0
  611. qiskit/transpiler/passes/__init__.py +312 -0
  612. qiskit/transpiler/passes/analysis/__init__.py +23 -0
  613. qiskit/transpiler/passes/analysis/count_ops.py +30 -0
  614. qiskit/transpiler/passes/analysis/count_ops_longest_path.py +26 -0
  615. qiskit/transpiler/passes/analysis/dag_longest_path.py +24 -0
  616. qiskit/transpiler/passes/analysis/depth.py +33 -0
  617. qiskit/transpiler/passes/analysis/num_qubits.py +26 -0
  618. qiskit/transpiler/passes/analysis/num_tensor_factors.py +26 -0
  619. qiskit/transpiler/passes/analysis/resource_estimation.py +41 -0
  620. qiskit/transpiler/passes/analysis/size.py +36 -0
  621. qiskit/transpiler/passes/analysis/width.py +27 -0
  622. qiskit/transpiler/passes/basis/__init__.py +19 -0
  623. qiskit/transpiler/passes/basis/basis_translator.py +137 -0
  624. qiskit/transpiler/passes/basis/decompose.py +131 -0
  625. qiskit/transpiler/passes/basis/translate_parameterized.py +175 -0
  626. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +88 -0
  627. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +109 -0
  628. qiskit/transpiler/passes/calibration/__init__.py +17 -0
  629. qiskit/transpiler/passes/calibration/base_builder.py +79 -0
  630. qiskit/transpiler/passes/calibration/builders.py +20 -0
  631. qiskit/transpiler/passes/calibration/exceptions.py +22 -0
  632. qiskit/transpiler/passes/calibration/pulse_gate.py +100 -0
  633. qiskit/transpiler/passes/calibration/rx_builder.py +164 -0
  634. qiskit/transpiler/passes/calibration/rzx_builder.py +411 -0
  635. qiskit/transpiler/passes/calibration/rzx_templates.py +51 -0
  636. qiskit/transpiler/passes/layout/__init__.py +26 -0
  637. qiskit/transpiler/passes/layout/_csp_custom_solver.py +65 -0
  638. qiskit/transpiler/passes/layout/apply_layout.py +123 -0
  639. qiskit/transpiler/passes/layout/csp_layout.py +132 -0
  640. qiskit/transpiler/passes/layout/dense_layout.py +202 -0
  641. qiskit/transpiler/passes/layout/disjoint_utils.py +219 -0
  642. qiskit/transpiler/passes/layout/enlarge_with_ancilla.py +49 -0
  643. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +117 -0
  644. qiskit/transpiler/passes/layout/layout_2q_distance.py +77 -0
  645. qiskit/transpiler/passes/layout/sabre_layout.py +487 -0
  646. qiskit/transpiler/passes/layout/sabre_pre_layout.py +225 -0
  647. qiskit/transpiler/passes/layout/set_layout.py +69 -0
  648. qiskit/transpiler/passes/layout/trivial_layout.py +66 -0
  649. qiskit/transpiler/passes/layout/vf2_layout.py +263 -0
  650. qiskit/transpiler/passes/layout/vf2_post_layout.py +419 -0
  651. qiskit/transpiler/passes/layout/vf2_utils.py +260 -0
  652. qiskit/transpiler/passes/optimization/__init__.py +43 -0
  653. qiskit/transpiler/passes/optimization/_gate_extension.py +80 -0
  654. qiskit/transpiler/passes/optimization/collect_1q_runs.py +31 -0
  655. qiskit/transpiler/passes/optimization/collect_2q_blocks.py +35 -0
  656. qiskit/transpiler/passes/optimization/collect_and_collapse.py +115 -0
  657. qiskit/transpiler/passes/optimization/collect_cliffords.py +104 -0
  658. qiskit/transpiler/passes/optimization/collect_linear_functions.py +80 -0
  659. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +227 -0
  660. qiskit/transpiler/passes/optimization/commutation_analysis.py +44 -0
  661. qiskit/transpiler/passes/optimization/commutative_cancellation.py +82 -0
  662. qiskit/transpiler/passes/optimization/commutative_inverse_cancellation.py +140 -0
  663. qiskit/transpiler/passes/optimization/consolidate_blocks.py +149 -0
  664. qiskit/transpiler/passes/optimization/cx_cancellation.py +65 -0
  665. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +162 -0
  666. qiskit/transpiler/passes/optimization/elide_permutations.py +91 -0
  667. qiskit/transpiler/passes/optimization/hoare_opt.py +420 -0
  668. qiskit/transpiler/passes/optimization/inverse_cancellation.py +95 -0
  669. qiskit/transpiler/passes/optimization/normalize_rx_angle.py +149 -0
  670. qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +268 -0
  671. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +254 -0
  672. qiskit/transpiler/passes/optimization/optimize_1q_gates.py +384 -0
  673. qiskit/transpiler/passes/optimization/optimize_annotated.py +448 -0
  674. qiskit/transpiler/passes/optimization/optimize_cliffords.py +89 -0
  675. qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py +71 -0
  676. qiskit/transpiler/passes/optimization/remove_diagonal_gates_before_measure.py +41 -0
  677. qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
  678. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +69 -0
  679. qiskit/transpiler/passes/optimization/remove_reset_in_zero_state.py +37 -0
  680. qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +47 -0
  681. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +40 -0
  682. qiskit/transpiler/passes/optimization/template_matching/__init__.py +19 -0
  683. qiskit/transpiler/passes/optimization/template_matching/backward_match.py +749 -0
  684. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +452 -0
  685. qiskit/transpiler/passes/optimization/template_matching/maximal_matches.py +77 -0
  686. qiskit/transpiler/passes/optimization/template_matching/template_matching.py +370 -0
  687. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +638 -0
  688. qiskit/transpiler/passes/optimization/template_optimization.py +158 -0
  689. qiskit/transpiler/passes/routing/__init__.py +22 -0
  690. qiskit/transpiler/passes/routing/algorithms/__init__.py +33 -0
  691. qiskit/transpiler/passes/routing/algorithms/token_swapper.py +105 -0
  692. qiskit/transpiler/passes/routing/algorithms/types.py +46 -0
  693. qiskit/transpiler/passes/routing/algorithms/util.py +103 -0
  694. qiskit/transpiler/passes/routing/basic_swap.py +166 -0
  695. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/__init__.py +25 -0
  696. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_block.py +60 -0
  697. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +395 -0
  698. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/pauli_2q_evolution_commutation.py +145 -0
  699. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +306 -0
  700. qiskit/transpiler/passes/routing/layout_transformation.py +119 -0
  701. qiskit/transpiler/passes/routing/lookahead_swap.py +390 -0
  702. qiskit/transpiler/passes/routing/sabre_swap.py +447 -0
  703. qiskit/transpiler/passes/routing/star_prerouting.py +392 -0
  704. qiskit/transpiler/passes/routing/stochastic_swap.py +532 -0
  705. qiskit/transpiler/passes/routing/utils.py +35 -0
  706. qiskit/transpiler/passes/scheduling/__init__.py +27 -0
  707. qiskit/transpiler/passes/scheduling/alap.py +153 -0
  708. qiskit/transpiler/passes/scheduling/alignments/__init__.py +81 -0
  709. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +255 -0
  710. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +78 -0
  711. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +107 -0
  712. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +250 -0
  713. qiskit/transpiler/passes/scheduling/asap.py +175 -0
  714. qiskit/transpiler/passes/scheduling/base_scheduler.py +310 -0
  715. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +312 -0
  716. qiskit/transpiler/passes/scheduling/padding/__init__.py +16 -0
  717. qiskit/transpiler/passes/scheduling/padding/base_padding.py +256 -0
  718. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +452 -0
  719. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +82 -0
  720. qiskit/transpiler/passes/scheduling/scheduling/__init__.py +17 -0
  721. qiskit/transpiler/passes/scheduling/scheduling/alap.py +127 -0
  722. qiskit/transpiler/passes/scheduling/scheduling/asap.py +131 -0
  723. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +94 -0
  724. qiskit/transpiler/passes/scheduling/scheduling/set_io_latency.py +64 -0
  725. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +165 -0
  726. qiskit/transpiler/passes/synthesis/__init__.py +20 -0
  727. qiskit/transpiler/passes/synthesis/aqc_plugin.py +153 -0
  728. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +854 -0
  729. qiskit/transpiler/passes/synthesis/hls_plugins.py +1559 -0
  730. qiskit/transpiler/passes/synthesis/linear_functions_synthesis.py +41 -0
  731. qiskit/transpiler/passes/synthesis/plugin.py +734 -0
  732. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +297 -0
  733. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +1076 -0
  734. qiskit/transpiler/passes/utils/__init__.py +33 -0
  735. qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +41 -0
  736. qiskit/transpiler/passes/utils/check_gate_direction.py +52 -0
  737. qiskit/transpiler/passes/utils/check_map.py +78 -0
  738. qiskit/transpiler/passes/utils/contains_instruction.py +45 -0
  739. qiskit/transpiler/passes/utils/control_flow.py +65 -0
  740. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +93 -0
  741. qiskit/transpiler/passes/utils/dag_fixed_point.py +36 -0
  742. qiskit/transpiler/passes/utils/error.py +69 -0
  743. qiskit/transpiler/passes/utils/filter_op_nodes.py +65 -0
  744. qiskit/transpiler/passes/utils/fixed_point.py +48 -0
  745. qiskit/transpiler/passes/utils/gate_direction.py +86 -0
  746. qiskit/transpiler/passes/utils/gates_basis.py +51 -0
  747. qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +163 -0
  748. qiskit/transpiler/passes/utils/minimum_point.py +118 -0
  749. qiskit/transpiler/passes/utils/remove_barriers.py +49 -0
  750. qiskit/transpiler/passes/utils/remove_final_measurements.py +114 -0
  751. qiskit/transpiler/passes/utils/unroll_forloops.py +81 -0
  752. qiskit/transpiler/passmanager.py +490 -0
  753. qiskit/transpiler/passmanager_config.py +216 -0
  754. qiskit/transpiler/preset_passmanagers/__init__.py +73 -0
  755. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +1045 -0
  756. qiskit/transpiler/preset_passmanagers/common.py +649 -0
  757. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +626 -0
  758. qiskit/transpiler/preset_passmanagers/level0.py +113 -0
  759. qiskit/transpiler/preset_passmanagers/level1.py +120 -0
  760. qiskit/transpiler/preset_passmanagers/level2.py +119 -0
  761. qiskit/transpiler/preset_passmanagers/level3.py +119 -0
  762. qiskit/transpiler/preset_passmanagers/plugin.py +353 -0
  763. qiskit/transpiler/target.py +1319 -0
  764. qiskit/transpiler/timing_constraints.py +59 -0
  765. qiskit/user_config.py +262 -0
  766. qiskit/utils/__init__.py +89 -0
  767. qiskit/utils/classtools.py +146 -0
  768. qiskit/utils/deprecate_pulse.py +119 -0
  769. qiskit/utils/deprecation.py +490 -0
  770. qiskit/utils/lazy_tester.py +363 -0
  771. qiskit/utils/multiprocessing.py +56 -0
  772. qiskit/utils/optionals.py +347 -0
  773. qiskit/utils/parallel.py +191 -0
  774. qiskit/utils/units.py +143 -0
  775. qiskit/version.py +84 -0
  776. qiskit/visualization/__init__.py +288 -0
  777. qiskit/visualization/array.py +204 -0
  778. qiskit/visualization/bloch.py +778 -0
  779. qiskit/visualization/circuit/__init__.py +15 -0
  780. qiskit/visualization/circuit/_utils.py +675 -0
  781. qiskit/visualization/circuit/circuit_visualization.py +727 -0
  782. qiskit/visualization/circuit/latex.py +661 -0
  783. qiskit/visualization/circuit/matplotlib.py +2029 -0
  784. qiskit/visualization/circuit/qcstyle.py +278 -0
  785. qiskit/visualization/circuit/styles/__init__.py +13 -0
  786. qiskit/visualization/circuit/styles/bw.json +202 -0
  787. qiskit/visualization/circuit/styles/clifford.json +202 -0
  788. qiskit/visualization/circuit/styles/iqp-dark.json +214 -0
  789. qiskit/visualization/circuit/styles/iqp.json +214 -0
  790. qiskit/visualization/circuit/styles/textbook.json +202 -0
  791. qiskit/visualization/circuit/text.py +1844 -0
  792. qiskit/visualization/circuit_visualization.py +19 -0
  793. qiskit/visualization/counts_visualization.py +481 -0
  794. qiskit/visualization/dag_visualization.py +316 -0
  795. qiskit/visualization/exceptions.py +21 -0
  796. qiskit/visualization/gate_map.py +1485 -0
  797. qiskit/visualization/library.py +37 -0
  798. qiskit/visualization/pass_manager_visualization.py +308 -0
  799. qiskit/visualization/pulse_v2/__init__.py +21 -0
  800. qiskit/visualization/pulse_v2/core.py +901 -0
  801. qiskit/visualization/pulse_v2/device_info.py +173 -0
  802. qiskit/visualization/pulse_v2/drawings.py +253 -0
  803. qiskit/visualization/pulse_v2/events.py +254 -0
  804. qiskit/visualization/pulse_v2/generators/__init__.py +40 -0
  805. qiskit/visualization/pulse_v2/generators/barrier.py +76 -0
  806. qiskit/visualization/pulse_v2/generators/chart.py +208 -0
  807. qiskit/visualization/pulse_v2/generators/frame.py +436 -0
  808. qiskit/visualization/pulse_v2/generators/snapshot.py +133 -0
  809. qiskit/visualization/pulse_v2/generators/waveform.py +645 -0
  810. qiskit/visualization/pulse_v2/interface.py +458 -0
  811. qiskit/visualization/pulse_v2/layouts.py +387 -0
  812. qiskit/visualization/pulse_v2/plotters/__init__.py +17 -0
  813. qiskit/visualization/pulse_v2/plotters/base_plotter.py +53 -0
  814. qiskit/visualization/pulse_v2/plotters/matplotlib.py +201 -0
  815. qiskit/visualization/pulse_v2/stylesheet.py +312 -0
  816. qiskit/visualization/pulse_v2/types.py +242 -0
  817. qiskit/visualization/state_visualization.py +1518 -0
  818. qiskit/visualization/timeline/__init__.py +21 -0
  819. qiskit/visualization/timeline/core.py +480 -0
  820. qiskit/visualization/timeline/drawings.py +260 -0
  821. qiskit/visualization/timeline/generators.py +506 -0
  822. qiskit/visualization/timeline/interface.py +436 -0
  823. qiskit/visualization/timeline/layouts.py +115 -0
  824. qiskit/visualization/timeline/plotters/__init__.py +16 -0
  825. qiskit/visualization/timeline/plotters/base_plotter.py +58 -0
  826. qiskit/visualization/timeline/plotters/matplotlib.py +192 -0
  827. qiskit/visualization/timeline/stylesheet.py +301 -0
  828. qiskit/visualization/timeline/types.py +148 -0
  829. qiskit/visualization/transition_visualization.py +369 -0
  830. qiskit/visualization/utils.py +49 -0
  831. qiskit-1.3.0.dist-info/LICENSE.txt +203 -0
  832. qiskit-1.3.0.dist-info/METADATA +222 -0
  833. qiskit-1.3.0.dist-info/RECORD +836 -0
  834. qiskit-1.3.0.dist-info/WHEEL +5 -0
  835. qiskit-1.3.0.dist-info/entry_points.txt +76 -0
  836. qiskit-1.3.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1196 @@
1
+ # This code is part of Qiskit.
2
+ #
3
+ # (C) Copyright IBM 2017, 2022.
4
+ #
5
+ # This code is licensed under the Apache License, Version 2.0. You may
6
+ # obtain a copy of this license in the LICENSE.txt file in the root directory
7
+ # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8
+ #
9
+ # Any modifications or derivative works of this code must retain this
10
+ # copyright notice, and modified files need to carry a notice indicating
11
+ # that they have been altered from the originals.
12
+ """
13
+ N-Qubit Sparse Pauli Operator class.
14
+ """
15
+
16
+ from __future__ import annotations
17
+ from typing import TYPE_CHECKING, List
18
+
19
+ from collections.abc import Mapping, Sequence, Iterable
20
+ from numbers import Number
21
+ from copy import deepcopy
22
+
23
+ import numpy as np
24
+ import rustworkx as rx
25
+
26
+ from qiskit._accelerate.sparse_pauli_op import (
27
+ ZXPaulis,
28
+ decompose_dense,
29
+ to_matrix_dense,
30
+ to_matrix_sparse,
31
+ unordered_unique,
32
+ )
33
+ from qiskit.circuit.parameter import Parameter
34
+ from qiskit.circuit.parameterexpression import ParameterExpression
35
+ from qiskit.circuit.parametertable import ParameterView
36
+ from qiskit.exceptions import QiskitError
37
+ from qiskit.quantum_info.operators.custom_iterator import CustomIterator
38
+ from qiskit.quantum_info.operators.linear_op import LinearOp
39
+ from qiskit.quantum_info.operators.mixins import generate_apidocs
40
+ from qiskit.quantum_info.operators.operator import Operator
41
+ from qiskit.quantum_info.operators.symplectic.pauli import BasePauli
42
+ from qiskit.quantum_info.operators.symplectic.pauli_list import PauliList
43
+ from qiskit.quantum_info.operators.symplectic.pauli import Pauli
44
+
45
+
46
+ if TYPE_CHECKING:
47
+ from qiskit.transpiler.layout import TranspileLayout
48
+
49
+
50
+ class SparsePauliOp(LinearOp):
51
+ """Sparse N-qubit operator in a Pauli basis representation.
52
+
53
+ This is a sparse representation of an N-qubit matrix
54
+ :class:`~qiskit.quantum_info.Operator` in terms of N-qubit
55
+ :class:`~qiskit.quantum_info.PauliList` and complex coefficients.
56
+
57
+ It can be used for performing operator arithmetic for hundreds of qubits
58
+ if the number of non-zero Pauli basis terms is sufficiently small.
59
+
60
+ The Pauli basis components are stored as a
61
+ :class:`~qiskit.quantum_info.PauliList` object and can be accessed
62
+ using the :attr:`~SparsePauliOp.paulis` attribute. The coefficients
63
+ are stored as a complex Numpy array vector and can be accessed using
64
+ the :attr:`~SparsePauliOp.coeffs` attribute.
65
+
66
+ .. rubric:: Data type of coefficients
67
+
68
+ The default ``dtype`` of the internal ``coeffs`` Numpy array is ``complex128``. Users can
69
+ configure this by passing ``np.ndarray`` with a different dtype. For example, a parameterized
70
+ :class:`SparsePauliOp` can be made as follows:
71
+
72
+ .. code-block:: python
73
+
74
+ >>> import numpy as np
75
+ >>> from qiskit.circuit import ParameterVector
76
+ >>> from qiskit.quantum_info import SparsePauliOp
77
+
78
+ >>> SparsePauliOp(["II", "XZ"], np.array(ParameterVector("a", 2)))
79
+ SparsePauliOp(['II', 'XZ'],
80
+ coeffs=[ParameterExpression(1.0*a[0]), ParameterExpression(1.0*a[1])])
81
+
82
+ .. note::
83
+
84
+ Parameterized :class:`SparsePauliOp` does not support the following methods:
85
+
86
+ - ``to_matrix(sparse=True)`` since ``scipy.sparse`` cannot have objects as elements.
87
+ - ``to_operator()`` since :class:`~.quantum_info.Operator` does not support objects.
88
+ - ``sort``, ``argsort`` since :class:`.ParameterExpression` does not support comparison.
89
+ - ``equiv`` since :class:`.ParameterExpression` cannot be converted into complex.
90
+ - ``chop`` since :class:`.ParameterExpression` does not support absolute value.
91
+ """
92
+
93
+ def __init__(
94
+ self,
95
+ data: PauliList | SparsePauliOp | Pauli | list | str,
96
+ coeffs: np.ndarray | None = None,
97
+ *,
98
+ ignore_pauli_phase: bool = False,
99
+ copy: bool = True,
100
+ ):
101
+ """Initialize an operator object.
102
+
103
+ Args:
104
+ data (PauliList or SparsePauliOp or Pauli or list or str): Pauli list of
105
+ terms. A list of Pauli strings or a Pauli string is also allowed.
106
+ coeffs (np.ndarray): complex coefficients for Pauli terms.
107
+
108
+ .. note::
109
+
110
+ If ``data`` is a :obj:`~SparsePauliOp` and ``coeffs`` is not ``None``, the value
111
+ of the ``SparsePauliOp.coeffs`` will be ignored, and only the passed keyword
112
+ argument ``coeffs`` will be used.
113
+
114
+ ignore_pauli_phase (bool): if true, any ``phase`` component of a given :obj:`~PauliList`
115
+ will be assumed to be zero. This is more efficient in cases where a
116
+ :obj:`~PauliList` has been constructed purely for this object, and it is already
117
+ known that the phases in the ZX-convention are zero. It only makes sense to pass
118
+ this option when giving :obj:`~PauliList` data. (Default: False)
119
+ copy (bool): copy the input data if True, otherwise assign it directly, if possible.
120
+ (Default: True)
121
+
122
+ Raises:
123
+ QiskitError: If the input data or coeffs are invalid.
124
+ """
125
+ if ignore_pauli_phase and not isinstance(data, PauliList):
126
+ raise QiskitError("ignore_pauli_phase=True is only valid with PauliList data")
127
+
128
+ if isinstance(data, SparsePauliOp):
129
+ if coeffs is None:
130
+ coeffs = data.coeffs
131
+ data = data._pauli_list
132
+ # `SparsePauliOp._pauli_list` is already compatible with the internal ZX-phase
133
+ # convention. See `BasePauli._from_array` for the internal ZX-phase convention.
134
+ ignore_pauli_phase = True
135
+
136
+ pauli_list = PauliList(data.copy() if copy and hasattr(data, "copy") else data)
137
+
138
+ if coeffs is None:
139
+ coeffs = np.ones(pauli_list.size, dtype=complex)
140
+ else:
141
+ if isinstance(coeffs, np.ndarray):
142
+ dtype = object if coeffs.dtype == object else complex
143
+ else:
144
+ if not isinstance(coeffs, Sequence):
145
+ coeffs = [coeffs]
146
+ if any(isinstance(coeff, ParameterExpression) for coeff in coeffs):
147
+ dtype = object
148
+ else:
149
+ dtype = complex
150
+
151
+ coeffs_asarray = np.asarray(coeffs, dtype=dtype)
152
+ coeffs = (
153
+ coeffs_asarray.copy()
154
+ if copy and np.may_share_memory(coeffs, coeffs_asarray)
155
+ else coeffs_asarray
156
+ )
157
+
158
+ if ignore_pauli_phase:
159
+ # Fast path used in copy operations, where the phase of the PauliList is already known
160
+ # to be zero. This path only works if the input data is compatible with the internal
161
+ # ZX-phase convention.
162
+ self._pauli_list = pauli_list
163
+ self._coeffs = coeffs
164
+ else:
165
+ # move the phase of `pauli_list` to `self._coeffs`
166
+ phase = pauli_list._phase
167
+ count_y = pauli_list._count_y()
168
+ self._coeffs = np.asarray((-1j) ** (phase - count_y) * coeffs, dtype=coeffs.dtype)
169
+ pauli_list._phase = np.mod(count_y, 4)
170
+ self._pauli_list = pauli_list
171
+
172
+ if self._coeffs.shape != (self._pauli_list.size,):
173
+ raise QiskitError(
174
+ "coeff vector is incorrect shape for number"
175
+ f" of Paulis {self._coeffs.shape} != {self._pauli_list.size}"
176
+ )
177
+ # Initialize LinearOp
178
+ super().__init__(num_qubits=self._pauli_list.num_qubits)
179
+
180
+ def __array__(self, dtype=None, copy=None):
181
+ if copy is False:
182
+ raise ValueError("unable to avoid copy while creating an array as requested")
183
+ arr = self.to_matrix()
184
+ return arr if dtype is None else arr.astype(dtype, copy=False)
185
+
186
+ def __repr__(self):
187
+ prefix = "SparsePauliOp("
188
+ pad = len(prefix) * " "
189
+ return (
190
+ f"{prefix}{self.paulis.to_labels()},\n{pad}"
191
+ f"coeffs={np.array2string(self.coeffs, separator=', ')})"
192
+ )
193
+
194
+ def __eq__(self, other):
195
+ """Entrywise comparison of two SparsePauliOp operators"""
196
+ return (
197
+ super().__eq__(other)
198
+ and self.coeffs.dtype == other.coeffs.dtype
199
+ and self.coeffs.shape == other.coeffs.shape
200
+ and self.paulis == other.paulis
201
+ and (
202
+ np.allclose(self.coeffs, other.coeffs)
203
+ if self.coeffs.dtype != object
204
+ else (self.coeffs == other.coeffs).all()
205
+ )
206
+ )
207
+
208
+ def equiv(self, other: SparsePauliOp, atol: float | None = None) -> bool:
209
+ """Check if two SparsePauliOp operators are equivalent.
210
+
211
+ Args:
212
+ other (SparsePauliOp): an operator object.
213
+ atol: Absolute numerical tolerance for checking equivalence.
214
+
215
+ Returns:
216
+ bool: True if the operator is equivalent to ``self``.
217
+ """
218
+ if not super().__eq__(other):
219
+ return False
220
+ if atol is None:
221
+ atol = self.atol
222
+ return np.allclose((self - other).simplify().coeffs, 0.0, atol=atol)
223
+
224
+ @property
225
+ def settings(self) -> dict:
226
+ """Return settings."""
227
+ return {"data": self._pauli_list, "coeffs": self._coeffs}
228
+
229
+ # ---------------------------------------------------------------------
230
+ # Data accessors
231
+ # ---------------------------------------------------------------------
232
+
233
+ @property
234
+ def size(self):
235
+ """The number of Pauli of Pauli terms in the operator."""
236
+ return self._pauli_list.size
237
+
238
+ def __len__(self):
239
+ """Return the size."""
240
+ return self.size
241
+
242
+ @property
243
+ def paulis(self):
244
+ """Return the PauliList."""
245
+ return self._pauli_list
246
+
247
+ @paulis.setter
248
+ def paulis(self, value):
249
+ if not isinstance(value, PauliList):
250
+ value = PauliList(value)
251
+ if value.num_qubits != self.num_qubits:
252
+ raise ValueError(
253
+ f"incorrect number of qubits: expected {self.num_qubits}, got {value.num_qubits}"
254
+ )
255
+ if len(value) != len(self.paulis):
256
+ raise ValueError(
257
+ f"incorrect number of operators: expected {len(self.paulis)}, got {len(value)}"
258
+ )
259
+ self.coeffs *= (-1j) ** value.phase
260
+ value.phase = 0
261
+ self._pauli_list = value
262
+
263
+ @property
264
+ def coeffs(self):
265
+ """Return the Pauli coefficients."""
266
+ return self._coeffs
267
+
268
+ @coeffs.setter
269
+ def coeffs(self, value):
270
+ """Set Pauli coefficients."""
271
+ self._coeffs[:] = value
272
+
273
+ def __getitem__(self, key):
274
+ """Return a view of the SparsePauliOp."""
275
+ # Returns a view of specified rows of the PauliList
276
+ # This supports all slicing operations the underlying array supports.
277
+ if isinstance(key, (int, np.integer)):
278
+ key = [key]
279
+ return SparsePauliOp(self.paulis[key], self.coeffs[key])
280
+
281
+ def __setitem__(self, key, value):
282
+ """Update SparsePauliOp."""
283
+ # Modify specified rows of the PauliList
284
+ if not isinstance(value, SparsePauliOp):
285
+ value = SparsePauliOp(value)
286
+ self.paulis[key] = value.paulis
287
+ self.coeffs[key] = value.coeffs
288
+
289
+ # ---------------------------------------------------------------------
290
+ # LinearOp Methods
291
+ # ---------------------------------------------------------------------
292
+
293
+ def conjugate(self):
294
+ # Conjugation conjugates phases and also Y.conj() = -Y
295
+ # Hence we need to multiply conjugated coeffs by -1
296
+ # for rows with an odd number of Y terms.
297
+ # Find rows with Ys
298
+ ret = self.transpose()
299
+ ret._coeffs = ret._coeffs.conj()
300
+ return ret
301
+
302
+ def transpose(self):
303
+ # The only effect transposition has is Y.T = -Y
304
+ # Hence we need to multiply coeffs by -1 for rows with an
305
+ # odd number of Y terms.
306
+ ret = self.copy()
307
+ minus = (-1) ** ret.paulis._count_y()
308
+ ret._coeffs *= minus
309
+ return ret
310
+
311
+ def adjoint(self):
312
+ # Pauli's are self adjoint, so we only need to
313
+ # conjugate the phases
314
+ ret = self.copy()
315
+ ret._coeffs = ret._coeffs.conj()
316
+ return ret
317
+
318
+ def compose(
319
+ self, other: SparsePauliOp, qargs: list | None = None, front: bool = False
320
+ ) -> SparsePauliOp:
321
+ if qargs is None:
322
+ qargs = getattr(other, "qargs", None)
323
+
324
+ if not isinstance(other, SparsePauliOp):
325
+ other = SparsePauliOp(other)
326
+
327
+ # Validate composition dimensions and qargs match
328
+ self._op_shape.compose(other._op_shape, qargs, front)
329
+
330
+ if qargs is not None:
331
+ x1, z1 = self.paulis.x[:, qargs], self.paulis.z[:, qargs]
332
+ else:
333
+ x1, z1 = self.paulis.x, self.paulis.z
334
+ x2, z2 = other.paulis.x, other.paulis.z
335
+ num_qubits = other.num_qubits
336
+
337
+ # This method is the outer version of `BasePauli.compose`.
338
+ # `x1` and `z1` have shape `(self.size, num_qubits)`.
339
+ # `x2` and `z2` have shape `(other.size, num_qubits)`.
340
+ # `x1[:, no.newaxis]` results in shape `(self.size, 1, num_qubits)`.
341
+ # `ar = ufunc(x1[:, np.newaxis], x2)` will be in shape `(self.size, other.size, num_qubits)`.
342
+ # So, `ar.reshape((-1, num_qubits))` will be in shape `(self.size * other.size, num_qubits)`.
343
+ # Ref: https://numpy.org/doc/stable/user/theory.broadcasting.html
344
+
345
+ phase = np.add.outer(self.paulis._phase, other.paulis._phase).reshape(-1)
346
+ if front:
347
+ q = np.logical_and(x1[:, np.newaxis], z2).reshape((-1, num_qubits))
348
+ else:
349
+ q = np.logical_and(z1[:, np.newaxis], x2).reshape((-1, num_qubits))
350
+ # `np.mod` will be applied to `phase` in `SparsePauliOp.__init__`
351
+ phase = phase + 2 * q.sum(axis=1, dtype=np.uint8)
352
+
353
+ x3 = np.logical_xor(x1[:, np.newaxis], x2).reshape((-1, num_qubits))
354
+ z3 = np.logical_xor(z1[:, np.newaxis], z2).reshape((-1, num_qubits))
355
+
356
+ if qargs is None:
357
+ pauli_list = PauliList(BasePauli(z3, x3, phase))
358
+ else:
359
+ x4 = np.repeat(self.paulis.x, other.size, axis=0)
360
+ z4 = np.repeat(self.paulis.z, other.size, axis=0)
361
+ x4[:, qargs] = x3
362
+ z4[:, qargs] = z3
363
+ pauli_list = PauliList(BasePauli(z4, x4, phase))
364
+
365
+ # note: the following is a faster code equivalent to
366
+ # `coeffs = np.kron(self.coeffs, other.coeffs)`
367
+ # since `self.coeffs` and `other.coeffs` are both 1d arrays.
368
+ coeffs = np.multiply.outer(self.coeffs, other.coeffs).ravel()
369
+ return SparsePauliOp(pauli_list, coeffs, copy=False)
370
+
371
+ def tensor(self, other: SparsePauliOp) -> SparsePauliOp:
372
+ if not isinstance(other, SparsePauliOp):
373
+ other = SparsePauliOp(other)
374
+ return self._tensor(self, other)
375
+
376
+ def expand(self, other: SparsePauliOp) -> SparsePauliOp:
377
+ if not isinstance(other, SparsePauliOp):
378
+ other = SparsePauliOp(other)
379
+ return self._tensor(other, self)
380
+
381
+ @classmethod
382
+ def _tensor(cls, a, b):
383
+ paulis = a.paulis.tensor(b.paulis)
384
+ coeffs = np.kron(a.coeffs, b.coeffs)
385
+ return SparsePauliOp(paulis, coeffs, ignore_pauli_phase=True, copy=False)
386
+
387
+ def _add(self, other, qargs=None):
388
+ if qargs is None:
389
+ qargs = getattr(other, "qargs", None)
390
+
391
+ if not isinstance(other, SparsePauliOp):
392
+ other = SparsePauliOp(other)
393
+
394
+ self._op_shape._validate_add(other._op_shape, qargs)
395
+
396
+ paulis = self.paulis._add(other.paulis, qargs=qargs)
397
+ coeffs = np.hstack((self.coeffs, other.coeffs))
398
+ return SparsePauliOp(paulis, coeffs, ignore_pauli_phase=True, copy=False)
399
+
400
+ def _multiply(self, other):
401
+ if not isinstance(other, (Number, ParameterExpression)):
402
+ raise QiskitError("other is neither a Number nor a Parameter/ParameterExpression")
403
+ if other == 0:
404
+ # Check edge case that we deleted all Paulis
405
+ # In this case we return an identity Pauli with a zero coefficient
406
+ paulis = PauliList.from_symplectic(
407
+ np.zeros((1, self.num_qubits), dtype=bool),
408
+ np.zeros((1, self.num_qubits), dtype=bool),
409
+ )
410
+ coeffs = np.array([0j])
411
+ return SparsePauliOp(paulis, coeffs, ignore_pauli_phase=True, copy=False)
412
+ # Otherwise we just update the phases
413
+ return SparsePauliOp(
414
+ self.paulis.copy(), other * self.coeffs, ignore_pauli_phase=True, copy=False
415
+ )
416
+
417
+ # ---------------------------------------------------------------------
418
+ # Utility Methods
419
+ # ---------------------------------------------------------------------
420
+
421
+ def is_unitary(self, atol: float | None = None, rtol: float | None = None) -> bool:
422
+ """Return True if operator is a unitary matrix.
423
+
424
+ Args:
425
+ atol (float): Optional. Absolute tolerance for checking if
426
+ coefficients are zero (Default: 1e-8).
427
+ rtol (float): Optional. relative tolerance for checking if
428
+ coefficients are zero (Default: 1e-5).
429
+
430
+ Returns:
431
+ bool: True if the operator is unitary, False otherwise.
432
+ """
433
+ # Get default atol and rtol
434
+ if atol is None:
435
+ atol = self.atol
436
+ if rtol is None:
437
+ rtol = self.rtol
438
+
439
+ # Compose with adjoint
440
+ val = self.compose(self.adjoint()).simplify()
441
+ # See if the result is an identity
442
+ return (
443
+ val.size == 1
444
+ and np.isclose(val.coeffs[0], 1.0, atol=atol, rtol=rtol)
445
+ and not np.any(val.paulis.x)
446
+ and not np.any(val.paulis.z)
447
+ )
448
+
449
+ def simplify(self, atol: float | None = None, rtol: float | None = None) -> SparsePauliOp:
450
+ """Simplify PauliList by combining duplicates and removing zeros.
451
+
452
+ Args:
453
+ atol (float): Optional. Absolute tolerance for checking if
454
+ coefficients are zero (Default: 1e-8).
455
+ rtol (float): Optional. relative tolerance for checking if
456
+ coefficients are zero (Default: 1e-5).
457
+
458
+ Returns:
459
+ SparsePauliOp: the simplified SparsePauliOp operator.
460
+ """
461
+ # Get default atol and rtol
462
+ if atol is None:
463
+ atol = self.atol
464
+ if rtol is None:
465
+ rtol = self.rtol
466
+
467
+ # Filter non-zero coefficients
468
+ if self.coeffs.dtype == object:
469
+
470
+ def to_complex(coeff):
471
+ if not hasattr(coeff, "sympify"):
472
+ return coeff
473
+ sympified = coeff.sympify()
474
+ return complex(sympified) if sympified.is_Number else np.nan
475
+
476
+ non_zero = np.logical_not(
477
+ np.isclose([to_complex(x) for x in self.coeffs], 0, atol=atol, rtol=rtol)
478
+ )
479
+ else:
480
+ non_zero = np.logical_not(np.isclose(self.coeffs, 0, atol=atol, rtol=rtol))
481
+ paulis_x = self.paulis.x[non_zero]
482
+ paulis_z = self.paulis.z[non_zero]
483
+ nz_coeffs = self.coeffs[non_zero]
484
+
485
+ array = np.packbits(paulis_x, axis=1).astype(np.uint16) * 256 + np.packbits(
486
+ paulis_z, axis=1
487
+ )
488
+ indexes, inverses = unordered_unique(array)
489
+
490
+ if np.all(non_zero) and indexes.shape[0] == array.shape[0]:
491
+ # No zero operator or duplicate operator
492
+ return self.copy()
493
+
494
+ coeffs = np.zeros(indexes.shape[0], dtype=self.coeffs.dtype)
495
+ np.add.at(coeffs, inverses, nz_coeffs)
496
+ # Delete zero coefficient rows
497
+ if self.coeffs.dtype == object:
498
+ is_zero = np.array(
499
+ [np.isclose(to_complex(coeff), 0, atol=atol, rtol=rtol) for coeff in coeffs]
500
+ )
501
+ else:
502
+ is_zero = np.isclose(coeffs, 0, atol=atol, rtol=rtol)
503
+ # Check edge case that we deleted all Paulis
504
+ # In this case we return an identity Pauli with a zero coefficient
505
+ if np.all(is_zero):
506
+ x = np.zeros((1, self.num_qubits), dtype=bool)
507
+ z = np.zeros((1, self.num_qubits), dtype=bool)
508
+ coeffs = np.array([0j], dtype=self.coeffs.dtype)
509
+ else:
510
+ non_zero = np.logical_not(is_zero)
511
+ non_zero_indexes = indexes[non_zero]
512
+ x = paulis_x[non_zero_indexes]
513
+ z = paulis_z[non_zero_indexes]
514
+ coeffs = coeffs[non_zero]
515
+
516
+ return SparsePauliOp(
517
+ PauliList.from_symplectic(z, x), coeffs, ignore_pauli_phase=True, copy=False
518
+ )
519
+
520
+ def argsort(self, weight: bool = False):
521
+ """Return indices for sorting the rows of the table.
522
+
523
+ Returns the composition of permutations in the order of sorting
524
+ by coefficient and sorting by Pauli.
525
+ By using the `weight` kwarg the output can additionally be sorted
526
+ by the number of non-identity terms in the Pauli, where the set of
527
+ all Pauli's of a given weight are still ordered lexicographically.
528
+
529
+ **Example**
530
+
531
+ Here is an example of how to use SparsePauliOp argsort.
532
+
533
+ .. code-block::
534
+
535
+ import numpy as np
536
+ from qiskit.quantum_info import SparsePauliOp
537
+
538
+ # 2-qubit labels
539
+ labels = ["XX", "XX", "XX", "YI", "II", "XZ", "XY", "XI"]
540
+ # coeffs
541
+ coeffs = [2.+1.j, 2.+2.j, 3.+0.j, 3.+0.j, 4.+0.j, 5.+0.j, 6.+0.j, 7.+0.j]
542
+
543
+ # init
544
+ spo = SparsePauliOp(labels, coeffs)
545
+ print('Initial Ordering')
546
+ print(spo)
547
+
548
+ # Lexicographic Ordering
549
+ srt = spo.argsort()
550
+ print('Lexicographically sorted')
551
+ print(srt)
552
+
553
+ # Lexicographic Ordering
554
+ srt = spo.argsort(weight=False)
555
+ print('Lexicographically sorted')
556
+ print(srt)
557
+
558
+ # Weight Ordering
559
+ srt = spo.argsort(weight=True)
560
+ print('Weight sorted')
561
+ print(srt)
562
+
563
+ .. code-block:: text
564
+
565
+ Initial Ordering
566
+ SparsePauliOp(['XX', 'XX', 'XX', 'YI', 'II', 'XZ', 'XY', 'XI'],
567
+ coeffs=[2.+1.j, 2.+2.j, 3.+0.j, 3.+0.j, 4.+0.j, 5.+0.j, 6.+0.j, 7.+0.j])
568
+ Lexicographically sorted
569
+ [4 7 0 1 2 6 5 3]
570
+ Lexicographically sorted
571
+ [4 7 0 1 2 6 5 3]
572
+ Weight sorted
573
+ [4 7 3 0 1 2 6 5]
574
+
575
+ Args:
576
+ weight (bool): optionally sort by weight if True (Default: False).
577
+ By using the weight kwarg the output can additionally be sorted
578
+ by the number of non-identity terms in the Pauli.
579
+
580
+ Returns:
581
+ array: the indices for sorting the table.
582
+ """
583
+ sort_coeffs_inds = np.argsort(self._coeffs, kind="stable")
584
+ pauli_list = self._pauli_list[sort_coeffs_inds]
585
+ sort_pauli_inds = pauli_list.argsort(weight=weight, phase=False)
586
+ return sort_coeffs_inds[sort_pauli_inds]
587
+
588
+ def sort(self, weight: bool = False):
589
+ """Sort the rows of the table.
590
+
591
+ After sorting the coefficients using numpy's argsort, sort by Pauli.
592
+ Pauli sort takes precedence.
593
+ If Pauli is the same, it will be sorted by coefficient.
594
+ By using the `weight` kwarg the output can additionally be sorted
595
+ by the number of non-identity terms in the Pauli, where the set of
596
+ all Pauli's of a given weight are still ordered lexicographically.
597
+
598
+ **Example**
599
+
600
+ Here is an example of how to use SparsePauliOp sort.
601
+
602
+ .. code-block::
603
+
604
+ import numpy as np
605
+ from qiskit.quantum_info import SparsePauliOp
606
+
607
+ # 2-qubit labels
608
+ labels = ["XX", "XX", "XX", "YI", "II", "XZ", "XY", "XI"]
609
+ # coeffs
610
+ coeffs = [2.+1.j, 2.+2.j, 3.+0.j, 3.+0.j, 4.+0.j, 5.+0.j, 6.+0.j, 7.+0.j]
611
+
612
+ # init
613
+ spo = SparsePauliOp(labels, coeffs)
614
+ print('Initial Ordering')
615
+ print(spo)
616
+
617
+ # Lexicographic Ordering
618
+ srt = spo.sort()
619
+ print('Lexicographically sorted')
620
+ print(srt)
621
+
622
+ # Lexicographic Ordering
623
+ srt = spo.sort(weight=False)
624
+ print('Lexicographically sorted')
625
+ print(srt)
626
+
627
+ # Weight Ordering
628
+ srt = spo.sort(weight=True)
629
+ print('Weight sorted')
630
+ print(srt)
631
+
632
+ .. code-block:: text
633
+
634
+ Initial Ordering
635
+ SparsePauliOp(['XX', 'XX', 'XX', 'YI', 'II', 'XZ', 'XY', 'XI'],
636
+ coeffs=[2.+1.j, 2.+2.j, 3.+0.j, 3.+0.j, 4.+0.j, 5.+0.j, 6.+0.j, 7.+0.j])
637
+ Lexicographically sorted
638
+ SparsePauliOp(['II', 'XI', 'XX', 'XX', 'XX', 'XY', 'XZ', 'YI'],
639
+ coeffs=[4.+0.j, 7.+0.j, 2.+1.j, 2.+2.j, 3.+0.j, 6.+0.j, 5.+0.j, 3.+0.j])
640
+ Lexicographically sorted
641
+ SparsePauliOp(['II', 'XI', 'XX', 'XX', 'XX', 'XY', 'XZ', 'YI'],
642
+ coeffs=[4.+0.j, 7.+0.j, 2.+1.j, 2.+2.j, 3.+0.j, 6.+0.j, 5.+0.j, 3.+0.j])
643
+ Weight sorted
644
+ SparsePauliOp(['II', 'XI', 'YI', 'XX', 'XX', 'XX', 'XY', 'XZ'],
645
+ coeffs=[4.+0.j, 7.+0.j, 3.+0.j, 2.+1.j, 2.+2.j, 3.+0.j, 6.+0.j, 5.+0.j])
646
+
647
+ Args:
648
+ weight (bool): optionally sort by weight if True (Default: False).
649
+ By using the weight kwarg the output can additionally be sorted
650
+ by the number of non-identity terms in the Pauli.
651
+
652
+ Returns:
653
+ SparsePauliOp: a sorted copy of the original table.
654
+ """
655
+ indices = self.argsort(weight=weight)
656
+ return SparsePauliOp(self._pauli_list[indices], self._coeffs[indices])
657
+
658
+ def chop(self, tol: float = 1e-14) -> SparsePauliOp:
659
+ """Set real and imaginary parts of the coefficients to 0 if ``< tol`` in magnitude.
660
+
661
+ For example, the operator representing ``1+1e-17j X + 1e-17 Y`` with a tolerance larger
662
+ than ``1e-17`` will be reduced to ``1 X`` whereas :meth:`.SparsePauliOp.simplify` would
663
+ return ``1+1e-17j X``.
664
+
665
+ If a both the real and imaginary part of a coefficient is 0 after chopping, the
666
+ corresponding Pauli is removed from the operator.
667
+
668
+ Args:
669
+ tol (float): The absolute tolerance to check whether a real or imaginary part should
670
+ be set to 0.
671
+
672
+ Returns:
673
+ SparsePauliOp: This operator with chopped coefficients.
674
+ """
675
+ realpart_nonzero = np.abs(self.coeffs.real) > tol
676
+ imagpart_nonzero = np.abs(self.coeffs.imag) > tol
677
+
678
+ remaining_indices = np.logical_or(realpart_nonzero, imagpart_nonzero)
679
+ remaining_real = realpart_nonzero[remaining_indices]
680
+ remaining_imag = imagpart_nonzero[remaining_indices]
681
+
682
+ if len(remaining_real) == 0: # if no Paulis are left
683
+ x = np.zeros((1, self.num_qubits), dtype=bool)
684
+ z = np.zeros((1, self.num_qubits), dtype=bool)
685
+ coeffs = np.array([0j], dtype=complex)
686
+ else:
687
+ coeffs = np.zeros(np.count_nonzero(remaining_indices), dtype=complex)
688
+ coeffs.real[remaining_real] = self.coeffs.real[realpart_nonzero]
689
+ coeffs.imag[remaining_imag] = self.coeffs.imag[imagpart_nonzero]
690
+
691
+ x = self.paulis.x[remaining_indices]
692
+ z = self.paulis.z[remaining_indices]
693
+
694
+ return SparsePauliOp(
695
+ PauliList.from_symplectic(z, x), coeffs, ignore_pauli_phase=True, copy=False
696
+ )
697
+
698
+ @staticmethod
699
+ def sum(ops: list[SparsePauliOp]) -> SparsePauliOp:
700
+ """Sum of SparsePauliOps.
701
+
702
+ This is a specialized version of the builtin ``sum`` function for SparsePauliOp
703
+ with smaller overhead.
704
+
705
+ Args:
706
+ ops (list[SparsePauliOp]): a list of SparsePauliOps.
707
+
708
+ Returns:
709
+ SparsePauliOp: the SparsePauliOp representing the sum of the input list.
710
+
711
+ Raises:
712
+ QiskitError: if the input list is empty.
713
+ QiskitError: if the input list includes an object that is not SparsePauliOp.
714
+ QiskitError: if the numbers of qubits of the objects in the input list do not match.
715
+ """
716
+ if len(ops) == 0:
717
+ raise QiskitError("Input list is empty")
718
+ if not all(isinstance(op, SparsePauliOp) for op in ops):
719
+ raise QiskitError("Input list includes an object that is not SparsePauliOp")
720
+ for other in ops[1:]:
721
+ ops[0]._op_shape._validate_add(other._op_shape)
722
+
723
+ z = np.vstack([op.paulis.z for op in ops])
724
+ x = np.vstack([op.paulis.x for op in ops])
725
+ phase = np.hstack([op.paulis._phase for op in ops])
726
+ pauli_list = PauliList(BasePauli(z, x, phase))
727
+ coeffs = np.hstack([op.coeffs for op in ops])
728
+ return SparsePauliOp(pauli_list, coeffs, ignore_pauli_phase=True, copy=False)
729
+
730
+ # ---------------------------------------------------------------------
731
+ # Additional conversions
732
+ # ---------------------------------------------------------------------
733
+
734
+ @staticmethod
735
+ def from_operator(
736
+ obj: Operator, atol: float | None = None, rtol: float | None = None
737
+ ) -> SparsePauliOp:
738
+ """Construct from an Operator objector.
739
+
740
+ Note that the cost of this construction is exponential in general because the number of
741
+ possible Pauli terms in the decomposition is exponential in the number of qubits.
742
+
743
+ Internally this uses an implementation of the "tensorized Pauli decomposition" presented in
744
+ `Hantzko, Binkowski and Gupta (2023) <https://arxiv.org/abs/2310.13421>`__.
745
+
746
+ Args:
747
+ obj (Operator): an N-qubit operator.
748
+ atol (float): Optional. Absolute tolerance for checking if coefficients are zero
749
+ (Default: 1e-8). Since the comparison is to zero, in effect the tolerance used is
750
+ the maximum of ``atol`` and ``rtol``.
751
+ rtol (float): Optional. relative tolerance for checking if coefficients are zero
752
+ (Default: 1e-5). Since the comparison is to zero, in effect the tolerance used is
753
+ the maximum of ``atol`` and ``rtol``.
754
+
755
+ Returns:
756
+ SparsePauliOp: the SparsePauliOp representation of the operator.
757
+
758
+ Raises:
759
+ QiskitError: if the input operator is not an N-qubit operator.
760
+ """
761
+ # Get default atol and rtol
762
+ if atol is None:
763
+ atol = SparsePauliOp.atol
764
+ if rtol is None:
765
+ rtol = SparsePauliOp.rtol
766
+ tol = max((atol, rtol))
767
+
768
+ if not isinstance(obj, Operator):
769
+ obj = Operator(obj)
770
+
771
+ # Check dimension is N-qubit operator
772
+ num_qubits = obj.num_qubits
773
+ if num_qubits is None:
774
+ raise QiskitError("Input Operator is not an N-qubit operator.")
775
+ zx_paulis = decompose_dense(obj.data, tol)
776
+ # Indirection through `BasePauli` is because we're already supplying the phase in the ZX
777
+ # convention.
778
+ pauli_list = PauliList(BasePauli(zx_paulis.z, zx_paulis.x, zx_paulis.phases))
779
+ return SparsePauliOp(pauli_list, zx_paulis.coeffs, ignore_pauli_phase=True, copy=False)
780
+
781
+ @staticmethod
782
+ def from_list(
783
+ obj: Iterable[tuple[str, complex]], dtype: type = complex, *, num_qubits: int = None
784
+ ) -> SparsePauliOp:
785
+ """Construct from a list of Pauli strings and coefficients.
786
+
787
+ For example, the 5-qubit Hamiltonian
788
+
789
+ .. math::
790
+
791
+ H = Z_1 X_4 + 2 Y_0 Y_3
792
+
793
+ can be constructed as
794
+
795
+ .. code-block:: python
796
+
797
+ from qiskit.quantum_info import SparsePauliOp
798
+
799
+ # via tuples and the full Pauli string
800
+ op = SparsePauliOp.from_list([("XIIZI", 1), ("IYIIY", 2)])
801
+
802
+ Args:
803
+ obj (Iterable[Tuple[str, complex]]): The list of 2-tuples specifying the Pauli terms.
804
+ dtype (type): The dtype of coeffs (Default: complex).
805
+ num_qubits (int): The number of qubits of the operator (Default: None).
806
+
807
+ Returns:
808
+ SparsePauliOp: The SparsePauliOp representation of the Pauli terms.
809
+
810
+ Raises:
811
+ QiskitError: If an empty list is passed and num_qubits is None.
812
+ QiskitError: If num_qubits and the objects in the input list do not match.
813
+ """
814
+ obj = list(obj) # To convert zip or other iterable
815
+ size = len(obj)
816
+
817
+ if size == 0 and num_qubits is None:
818
+ raise QiskitError(
819
+ "Could not determine the number of qubits from an empty list. Try passing num_qubits."
820
+ )
821
+ if size > 0 and num_qubits is not None:
822
+ if len(obj[0][0]) != num_qubits:
823
+ raise QiskitError(
824
+ f"num_qubits ({num_qubits}) and the objects in the input list do not match."
825
+ )
826
+ if num_qubits is None:
827
+ num_qubits = len(obj[0][0])
828
+ if size == 0:
829
+ obj = [("I" * num_qubits, 0)]
830
+ size = len(obj)
831
+
832
+ coeffs = np.zeros(size, dtype=dtype)
833
+ labels = np.zeros(size, dtype=f"<U{num_qubits}")
834
+ for i, item in enumerate(obj):
835
+ labels[i] = item[0]
836
+ coeffs[i] = item[1]
837
+
838
+ paulis = PauliList(labels)
839
+ return SparsePauliOp(paulis, coeffs, copy=False)
840
+
841
+ @staticmethod
842
+ def from_sparse_list(
843
+ obj: Iterable[tuple[str, list[int], complex]],
844
+ num_qubits: int,
845
+ do_checks: bool = True,
846
+ dtype: type = complex,
847
+ ) -> SparsePauliOp:
848
+ """Construct from a list of local Pauli strings and coefficients.
849
+
850
+ Each list element is a 3-tuple of a local Pauli string, indices where to apply it,
851
+ and a coefficient.
852
+
853
+ For example, the 5-qubit Hamiltonian
854
+
855
+ .. math::
856
+
857
+ H = Z_1 X_4 + 2 Y_0 Y_3
858
+
859
+ can be constructed as
860
+
861
+ .. code-block:: python
862
+
863
+ from qiskit.quantum_info import SparsePauliOp
864
+
865
+ # via triples and local Paulis with indices
866
+ op = SparsePauliOp.from_sparse_list([("ZX", [1, 4], 1), ("YY", [0, 3], 2)], num_qubits=5)
867
+
868
+ # equals the following construction from "dense" Paulis
869
+ op = SparsePauliOp.from_list([("XIIZI", 1), ("IYIIY", 2)])
870
+
871
+ Args:
872
+ obj (Iterable[tuple[str, list[int], complex]]): The list 3-tuples specifying the Paulis.
873
+ num_qubits (int): The number of qubits of the operator.
874
+ do_checks (bool): The flag of checking if the input indices are not duplicated
875
+ (Default: True).
876
+ dtype (type): The dtype of coeffs (Default: complex).
877
+
878
+ Returns:
879
+ SparsePauliOp: The SparsePauliOp representation of the Pauli terms.
880
+
881
+ Raises:
882
+ QiskitError: If the number of qubits is incompatible with the indices of the Pauli terms.
883
+ QiskitError: If the designated qubit is already assigned.
884
+ """
885
+ obj = list(obj) # To convert zip or other iterable
886
+ size = len(obj)
887
+
888
+ if size == 0:
889
+ obj = [("I" * num_qubits, range(num_qubits), 0)]
890
+ size = len(obj)
891
+
892
+ coeffs = np.zeros(size, dtype=dtype)
893
+ labels = np.zeros(size, dtype=f"<U{num_qubits}")
894
+
895
+ for i, (paulis, indices, coeff) in enumerate(obj):
896
+ if do_checks and len(indices) != len(set(indices)):
897
+ raise QiskitError("Input indices are duplicated.")
898
+ # construct the full label based off the non-trivial Paulis and indices
899
+ label = ["I"] * num_qubits
900
+ for pauli, index in zip(paulis, indices):
901
+ if index >= num_qubits:
902
+ raise QiskitError(
903
+ f"The number of qubits ({num_qubits}) is smaller than a required index {index}."
904
+ )
905
+ label[~index] = pauli
906
+
907
+ labels[i] = "".join(label)
908
+ coeffs[i] = coeff
909
+
910
+ paulis = PauliList(labels)
911
+ return SparsePauliOp(paulis, coeffs, copy=False)
912
+
913
+ def to_list(self, array: bool = False):
914
+ """Convert to a list Pauli string labels and coefficients.
915
+
916
+ For operators with a lot of terms converting using the ``array=True``
917
+ kwarg will be more efficient since it allocates memory for
918
+ the full Numpy array of labels in advance.
919
+
920
+ Args:
921
+ array (bool): return a Numpy array if True, otherwise
922
+ return a list (Default: False).
923
+
924
+ Returns:
925
+ list or array: List of pairs (label, coeff) for rows of the PauliList.
926
+ """
927
+ # Dtype for a structured array with string labels and complex coeffs
928
+ pauli_labels = self.paulis.to_labels(array=True)
929
+ labels = np.zeros(
930
+ self.size, dtype=[("labels", pauli_labels.dtype), ("coeffs", self.coeffs.dtype)]
931
+ )
932
+ labels["labels"] = pauli_labels
933
+ labels["coeffs"] = self.coeffs
934
+ if array:
935
+ return labels
936
+ return labels.tolist()
937
+
938
+ def to_sparse_list(self):
939
+ """Convert to a sparse Pauli list format with elements (pauli, qubits, coefficient)."""
940
+ pauli_labels = self.paulis.to_labels()
941
+ sparse_list = [
942
+ (*sparsify_label(label), coeff) for label, coeff in zip(pauli_labels, self.coeffs)
943
+ ]
944
+ return sparse_list
945
+
946
+ def to_matrix(self, sparse: bool = False, force_serial: bool = False) -> np.ndarray:
947
+ """Convert to a dense or sparse matrix.
948
+
949
+ Args:
950
+ sparse: if ``True`` return a sparse CSR matrix, otherwise return dense Numpy
951
+ array (the default).
952
+ force_serial: if ``True``, use an unthreaded implementation, regardless of the state of
953
+ the `Qiskit threading-control environment variables
954
+ <https://docs.quantum.ibm.com/guides/configure-qiskit-local#environment-variables>`__.
955
+ By default, this will use threaded parallelism over the available CPUs.
956
+
957
+ Returns:
958
+ array: A dense matrix if `sparse=False`.
959
+ csr_matrix: A sparse matrix in CSR format if `sparse=True`.
960
+ """
961
+ if self.coeffs.dtype == object:
962
+ # Fallback to slow Python-space method.
963
+ return sum(self.matrix_iter(sparse=sparse))
964
+
965
+ pauli_list = self.paulis
966
+ zx = ZXPaulis(
967
+ pauli_list.x.astype(np.bool_),
968
+ pauli_list.z.astype(np.bool_),
969
+ pauli_list.phase.astype(np.uint8),
970
+ self.coeffs.astype(np.complex128),
971
+ )
972
+ if sparse:
973
+ from scipy.sparse import csr_matrix
974
+
975
+ data, indices, indptr = to_matrix_sparse(zx, force_serial=force_serial)
976
+ side = 1 << self.num_qubits
977
+ return csr_matrix((data, indices, indptr), shape=(side, side))
978
+ return to_matrix_dense(zx, force_serial=force_serial)
979
+
980
+ def to_operator(self) -> Operator:
981
+ """Convert to a matrix Operator object"""
982
+ return Operator(self.to_matrix())
983
+
984
+ # ---------------------------------------------------------------------
985
+ # Custom Iterators
986
+ # ---------------------------------------------------------------------
987
+
988
+ def label_iter(self):
989
+ """Return a label representation iterator.
990
+
991
+ This is a lazy iterator that converts each term in the SparsePauliOp
992
+ into a tuple (label, coeff). To convert the entire table to labels
993
+ use the :meth:`to_labels` method.
994
+
995
+ Returns:
996
+ LabelIterator: label iterator object for the SparsePauliOp.
997
+ """
998
+
999
+ class LabelIterator(CustomIterator):
1000
+ """Label representation iteration and item access."""
1001
+
1002
+ def __repr__(self):
1003
+ return f"<SparsePauliOp_label_iterator at {hex(id(self))}>"
1004
+
1005
+ def __getitem__(self, key):
1006
+ coeff = self.obj.coeffs[key]
1007
+ pauli = self.obj.paulis.label_iter()[key]
1008
+ return (pauli, coeff)
1009
+
1010
+ return LabelIterator(self)
1011
+
1012
+ def matrix_iter(self, sparse: bool = False):
1013
+ """Return a matrix representation iterator.
1014
+
1015
+ This is a lazy iterator that converts each term in the SparsePauliOp
1016
+ into a matrix as it is used. To convert to a single matrix use the
1017
+ :meth:`to_matrix` method.
1018
+
1019
+ Args:
1020
+ sparse (bool): optionally return sparse CSR matrices if True,
1021
+ otherwise return Numpy array matrices
1022
+ (Default: False)
1023
+
1024
+ Returns:
1025
+ MatrixIterator: matrix iterator object for the PauliList.
1026
+ """
1027
+
1028
+ class MatrixIterator(CustomIterator):
1029
+ """Matrix representation iteration and item access."""
1030
+
1031
+ def __repr__(self):
1032
+ return f"<SparsePauliOp_matrix_iterator at {hex(id(self))}>"
1033
+
1034
+ def __getitem__(self, key):
1035
+ coeff = self.obj.coeffs[key]
1036
+ mat = self.obj.paulis[key].to_matrix(sparse)
1037
+ return coeff * mat
1038
+
1039
+ return MatrixIterator(self)
1040
+
1041
+ def noncommutation_graph(self, qubit_wise: bool) -> rx.PyGraph:
1042
+ """Create the non-commutation graph of this SparsePauliOp.
1043
+
1044
+ This transforms the measurement operator grouping problem into graph coloring problem. The
1045
+ constructed graph contains one node for each Pauli. The nodes will be connecting for any two
1046
+ Pauli terms that do _not_ commute.
1047
+
1048
+ Args:
1049
+ qubit_wise (bool): whether the commutation rule is applied to the whole operator,
1050
+ or on a per-qubit basis.
1051
+
1052
+ Returns:
1053
+ rustworkx.PyGraph: the non-commutation graph with nodes for each Pauli and edges
1054
+ indicating a non-commutation relation. Each node will hold the index of the Pauli
1055
+ term it corresponds to in its data. The edges of the graph hold no data.
1056
+ """
1057
+ return self.paulis.noncommutation_graph(qubit_wise)
1058
+
1059
+ def group_commuting(self, qubit_wise: bool = False) -> list[SparsePauliOp]:
1060
+ """Partition a SparsePauliOp into sets of commuting Pauli strings.
1061
+
1062
+ Args:
1063
+ qubit_wise (bool): whether the commutation rule is applied to the whole operator,
1064
+ or on a per-qubit basis. For example:
1065
+
1066
+ .. code-block:: python
1067
+
1068
+ >>> from qiskit.quantum_info import SparsePauliOp
1069
+ >>> op = SparsePauliOp.from_list([("XX", 2), ("YY", 1), ("IZ",2j), ("ZZ",1j)])
1070
+ >>> op.group_commuting()
1071
+ [SparsePauliOp(["IZ", "ZZ"], coeffs=[0.+2.j, 0.+1j]),
1072
+ SparsePauliOp(["XX", "YY"], coeffs=[2.+0.j, 1.+0.j])]
1073
+ >>> op.group_commuting(qubit_wise=True)
1074
+ [SparsePauliOp(['XX'], coeffs=[2.+0.j]),
1075
+ SparsePauliOp(['YY'], coeffs=[1.+0.j]),
1076
+ SparsePauliOp(['IZ', 'ZZ'], coeffs=[0.+2.j, 0.+1.j])]
1077
+
1078
+ Returns:
1079
+ list[SparsePauliOp]: List of SparsePauliOp where each SparsePauliOp contains
1080
+ commuting Pauli operators.
1081
+ """
1082
+ groups = self.paulis._commuting_groups(qubit_wise)
1083
+ return [self[group] for group in groups.values()]
1084
+
1085
+ @property
1086
+ def parameters(self) -> ParameterView:
1087
+ r"""Return the free ``Parameter``\s in the coefficients."""
1088
+ ret = set()
1089
+ for coeff in self.coeffs:
1090
+ if isinstance(coeff, ParameterExpression):
1091
+ ret |= coeff.parameters
1092
+ return ParameterView(ret)
1093
+
1094
+ def assign_parameters(
1095
+ self,
1096
+ parameters: (
1097
+ Mapping[Parameter, complex | ParameterExpression]
1098
+ | Sequence[complex | ParameterExpression]
1099
+ ),
1100
+ inplace: bool = False,
1101
+ ) -> SparsePauliOp | None:
1102
+ r"""Bind the free ``Parameter``\s in the coefficients to provided values.
1103
+
1104
+ Args:
1105
+ parameters: The values to bind the parameters to.
1106
+ inplace: If ``False``, a copy of the operator with the bound parameters is returned.
1107
+ If ``True`` the operator itself is modified.
1108
+
1109
+ Returns:
1110
+ A copy of the operator with bound parameters, if ``inplace`` is ``False``, otherwise
1111
+ ``None``.
1112
+ """
1113
+ if inplace:
1114
+ bound = self
1115
+ else:
1116
+ bound = deepcopy(self)
1117
+
1118
+ # turn the parameters to a dictionary
1119
+ if isinstance(parameters, Sequence):
1120
+ free_parameters = bound.parameters
1121
+ if len(parameters) != len(free_parameters):
1122
+ raise ValueError(
1123
+ f"Mismatching number of values ({len(parameters)}) and parameters "
1124
+ f"({len(free_parameters)}). For partial binding please pass a dictionary of "
1125
+ "{parameter: value} pairs."
1126
+ )
1127
+ parameters = dict(zip(free_parameters, parameters))
1128
+
1129
+ for i, coeff in enumerate(bound.coeffs):
1130
+ if isinstance(coeff, ParameterExpression):
1131
+ for key in coeff.parameters & parameters.keys():
1132
+ coeff = coeff.assign(key, parameters[key])
1133
+ if len(coeff.parameters) == 0:
1134
+ coeff = complex(coeff)
1135
+ bound.coeffs[i] = coeff
1136
+
1137
+ return None if inplace else bound
1138
+
1139
+ def apply_layout(
1140
+ self, layout: TranspileLayout | List[int] | None, num_qubits: int | None = None
1141
+ ) -> SparsePauliOp:
1142
+ """Apply a transpiler layout to this :class:`~.SparsePauliOp`
1143
+
1144
+ Args:
1145
+ layout: Either a :class:`~.TranspileLayout`, a list of integers or None.
1146
+ If both layout and num_qubits are none, a copy of the operator is
1147
+ returned.
1148
+ num_qubits: The number of qubits to expand the operator to. If not
1149
+ provided then if ``layout`` is a :class:`~.TranspileLayout` the
1150
+ number of the transpiler output circuit qubits will be used by
1151
+ default. If ``layout`` is a list of integers the permutation
1152
+ specified will be applied without any expansion. If layout is
1153
+ None, the operator will be expanded to the given number of qubits.
1154
+
1155
+ Returns:
1156
+ A new :class:`.SparsePauliOp` with the provided layout applied
1157
+ """
1158
+ from qiskit.transpiler.layout import TranspileLayout
1159
+
1160
+ if layout is None and num_qubits is None:
1161
+ return self.copy()
1162
+
1163
+ n_qubits = self.num_qubits
1164
+ if isinstance(layout, TranspileLayout):
1165
+ n_qubits = len(layout._output_qubit_list)
1166
+ layout = layout.final_index_layout()
1167
+ if num_qubits is not None:
1168
+ if num_qubits < n_qubits:
1169
+ raise QiskitError(
1170
+ f"The input num_qubits is too small, a {num_qubits} qubit layout cannot be "
1171
+ f"applied to a {n_qubits} qubit operator"
1172
+ )
1173
+ n_qubits = num_qubits
1174
+ if layout is None:
1175
+ layout = list(range(self.num_qubits))
1176
+ else:
1177
+ if any(x < 0 or x >= n_qubits for x in layout):
1178
+ raise QiskitError("Provided layout contains indices outside the number of qubits.")
1179
+ if len(set(layout)) != len(layout):
1180
+ raise QiskitError("Provided layout contains duplicate indices.")
1181
+ if self.num_qubits == 0:
1182
+ return type(self)(["I" * n_qubits] * self.size, self.coeffs)
1183
+ new_op = type(self)("I" * n_qubits)
1184
+ return new_op.compose(self, qargs=layout)
1185
+
1186
+
1187
+ def sparsify_label(pauli_string):
1188
+ """Return a sparse format of a Pauli string, e.g. "XIIIZ" -> ("XZ", [0, 4])."""
1189
+ qubits = [i for i, label in enumerate(reversed(pauli_string)) if label != "I"]
1190
+ sparse_label = "".join(pauli_string[~i] for i in qubits)
1191
+
1192
+ return sparse_label, qubits
1193
+
1194
+
1195
+ # Update docstrings for API docs
1196
+ generate_apidocs(SparsePauliOp)