qiskit 1.4.1__cp39-abi3-macosx_11_0_arm64.whl → 2.0.0rc1__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 (456) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +2 -5
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/circuit/__init__.py +24 -5
  5. qiskit/circuit/{add_control.py → _add_control.py} +32 -12
  6. qiskit/circuit/_classical_resource_map.py +5 -3
  7. qiskit/circuit/barrier.py +3 -7
  8. qiskit/circuit/classical/expr/__init__.py +31 -3
  9. qiskit/circuit/classical/expr/constructors.py +248 -28
  10. qiskit/circuit/classical/expr/expr.py +104 -3
  11. qiskit/circuit/classical/expr/visitors.py +75 -0
  12. qiskit/circuit/classical/types/__init__.py +12 -8
  13. qiskit/circuit/classical/types/ordering.py +14 -7
  14. qiskit/circuit/classical/types/types.py +36 -0
  15. qiskit/circuit/commutation_checker.py +34 -7
  16. qiskit/circuit/controlflow/__init__.py +32 -1
  17. qiskit/circuit/controlflow/_builder_utils.py +9 -5
  18. qiskit/circuit/controlflow/box.py +163 -0
  19. qiskit/circuit/controlflow/break_loop.py +1 -1
  20. qiskit/circuit/controlflow/builder.py +139 -39
  21. qiskit/circuit/controlflow/continue_loop.py +1 -3
  22. qiskit/circuit/controlflow/control_flow.py +10 -0
  23. qiskit/circuit/controlflow/for_loop.py +2 -1
  24. qiskit/circuit/controlflow/if_else.py +3 -16
  25. qiskit/circuit/controlflow/switch_case.py +2 -8
  26. qiskit/circuit/controlflow/while_loop.py +2 -7
  27. qiskit/circuit/controlledgate.py +2 -4
  28. qiskit/circuit/delay.py +40 -11
  29. qiskit/circuit/duration.py +0 -15
  30. qiskit/circuit/gate.py +2 -4
  31. qiskit/circuit/instruction.py +2 -141
  32. qiskit/circuit/instructionset.py +7 -54
  33. qiskit/circuit/library/__init__.py +34 -5
  34. qiskit/circuit/library/arithmetic/__init__.py +16 -10
  35. qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  36. qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +2 -2
  37. qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +1 -1
  38. qiskit/circuit/library/arithmetic/exact_reciprocal.py +64 -21
  39. qiskit/circuit/library/arithmetic/integer_comparator.py +37 -80
  40. qiskit/circuit/library/arithmetic/linear_amplitude_function.py +169 -2
  41. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +59 -5
  42. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +154 -6
  43. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +114 -4
  44. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +191 -15
  45. qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +93 -39
  46. qiskit/circuit/library/arithmetic/quadratic_form.py +168 -2
  47. qiskit/circuit/library/arithmetic/weighted_adder.py +73 -1
  48. qiskit/circuit/library/bit_flip_oracle.py +130 -0
  49. qiskit/circuit/library/blueprintcircuit.py +52 -16
  50. qiskit/circuit/library/data_preparation/initializer.py +1 -1
  51. qiskit/circuit/library/data_preparation/pauli_feature_map.py +4 -4
  52. qiskit/circuit/library/data_preparation/state_preparation.py +1 -1
  53. qiskit/circuit/library/generalized_gates/gms.py +1 -1
  54. qiskit/circuit/library/generalized_gates/isometry.py +1 -1
  55. qiskit/circuit/library/generalized_gates/pauli.py +1 -2
  56. qiskit/circuit/library/generalized_gates/uc.py +97 -7
  57. qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +1 -1
  58. qiskit/circuit/library/generalized_gates/unitary.py +4 -2
  59. qiskit/circuit/library/hamiltonian_gate.py +1 -1
  60. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
  61. qiskit/circuit/library/n_local/n_local.py +1 -1
  62. qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -1
  63. qiskit/circuit/library/overlap.py +2 -2
  64. qiskit/circuit/library/pauli_evolution.py +39 -24
  65. qiskit/circuit/library/phase_oracle.py +130 -51
  66. qiskit/circuit/library/standard_gates/__init__.py +0 -1
  67. qiskit/circuit/library/standard_gates/dcx.py +3 -4
  68. qiskit/circuit/library/standard_gates/ecr.py +3 -4
  69. qiskit/circuit/library/standard_gates/global_phase.py +5 -6
  70. qiskit/circuit/library/standard_gates/h.py +4 -9
  71. qiskit/circuit/library/standard_gates/i.py +2 -2
  72. qiskit/circuit/library/standard_gates/iswap.py +3 -4
  73. qiskit/circuit/library/standard_gates/p.py +15 -34
  74. qiskit/circuit/library/standard_gates/r.py +2 -6
  75. qiskit/circuit/library/standard_gates/rx.py +5 -15
  76. qiskit/circuit/library/standard_gates/rxx.py +3 -6
  77. qiskit/circuit/library/standard_gates/ry.py +5 -17
  78. qiskit/circuit/library/standard_gates/ryy.py +3 -6
  79. qiskit/circuit/library/standard_gates/rz.py +5 -17
  80. qiskit/circuit/library/standard_gates/rzx.py +3 -6
  81. qiskit/circuit/library/standard_gates/rzz.py +3 -6
  82. qiskit/circuit/library/standard_gates/s.py +6 -15
  83. qiskit/circuit/library/standard_gates/swap.py +4 -11
  84. qiskit/circuit/library/standard_gates/sx.py +7 -12
  85. qiskit/circuit/library/standard_gates/t.py +6 -7
  86. qiskit/circuit/library/standard_gates/u.py +2 -10
  87. qiskit/circuit/library/standard_gates/u1.py +5 -16
  88. qiskit/circuit/library/standard_gates/u2.py +2 -6
  89. qiskit/circuit/library/standard_gates/u3.py +3 -11
  90. qiskit/circuit/library/standard_gates/x.py +13 -60
  91. qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -5
  92. qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -5
  93. qiskit/circuit/library/standard_gates/y.py +4 -9
  94. qiskit/circuit/library/standard_gates/z.py +5 -15
  95. qiskit/circuit/measure.py +11 -2
  96. qiskit/circuit/parameterexpression.py +4 -0
  97. qiskit/circuit/quantumcircuit.py +881 -555
  98. qiskit/circuit/random/utils.py +12 -6
  99. qiskit/circuit/reset.py +5 -2
  100. qiskit/circuit/singleton.py +5 -11
  101. qiskit/circuit/store.py +0 -8
  102. qiskit/compiler/__init__.py +1 -7
  103. qiskit/compiler/transpiler.py +38 -196
  104. qiskit/converters/circuit_to_dag.py +4 -2
  105. qiskit/converters/circuit_to_dagdependency.py +0 -2
  106. qiskit/converters/circuit_to_dagdependency_v2.py +0 -1
  107. qiskit/converters/circuit_to_gate.py +1 -1
  108. qiskit/converters/circuit_to_instruction.py +16 -29
  109. qiskit/converters/dag_to_circuit.py +5 -5
  110. qiskit/converters/dag_to_dagdependency.py +0 -1
  111. qiskit/converters/dag_to_dagdependency_v2.py +0 -1
  112. qiskit/converters/dagdependency_to_circuit.py +0 -6
  113. qiskit/converters/dagdependency_to_dag.py +0 -6
  114. qiskit/dagcircuit/collect_blocks.py +32 -20
  115. qiskit/dagcircuit/dagdependency.py +3 -37
  116. qiskit/dagcircuit/dagdependency_v2.py +2 -80
  117. qiskit/dagcircuit/dagnode.py +14 -2
  118. qiskit/passmanager/__init__.py +24 -6
  119. qiskit/passmanager/passmanager.py +26 -24
  120. qiskit/primitives/__init__.py +44 -35
  121. qiskit/primitives/backend_estimator_v2.py +102 -23
  122. qiskit/primitives/backend_sampler_v2.py +5 -20
  123. qiskit/primitives/base/__init__.py +4 -4
  124. qiskit/primitives/base/base_estimator.py +77 -82
  125. qiskit/primitives/base/base_primitive_job.py +2 -2
  126. qiskit/primitives/base/{base_primitive.py → base_primitive_v1.py} +1 -1
  127. qiskit/primitives/base/{base_result.py → base_result_v1.py} +1 -1
  128. qiskit/primitives/base/base_sampler.py +52 -60
  129. qiskit/primitives/base/{estimator_result.py → estimator_result_v1.py} +2 -2
  130. qiskit/primitives/base/{sampler_result.py → sampler_result_v1.py} +2 -2
  131. qiskit/primitives/base/{validation.py → validation_v1.py} +34 -15
  132. qiskit/primitives/containers/bindings_array.py +3 -1
  133. qiskit/primitives/containers/bit_array.py +23 -0
  134. qiskit/primitives/containers/data_bin.py +3 -1
  135. qiskit/primitives/containers/observables_array.py +19 -2
  136. qiskit/primitives/statevector_sampler.py +6 -8
  137. qiskit/primitives/utils.py +14 -189
  138. qiskit/providers/__init__.py +4 -130
  139. qiskit/providers/backend.py +11 -314
  140. qiskit/providers/basic_provider/__init__.py +3 -1
  141. qiskit/providers/basic_provider/basic_provider.py +29 -9
  142. qiskit/providers/basic_provider/basic_simulator.py +158 -298
  143. qiskit/providers/exceptions.py +0 -33
  144. qiskit/providers/fake_provider/__init__.py +0 -37
  145. qiskit/providers/fake_provider/generic_backend_v2.py +32 -693
  146. qiskit/qasm2/__init__.py +21 -6
  147. qiskit/qasm2/export.py +2 -10
  148. qiskit/qasm2/parse.py +11 -25
  149. qiskit/qasm3/__init__.py +5 -1
  150. qiskit/qasm3/ast.py +44 -0
  151. qiskit/qasm3/exporter.py +65 -27
  152. qiskit/qasm3/printer.py +35 -4
  153. qiskit/qpy/__init__.py +141 -19
  154. qiskit/qpy/binary_io/__init__.py +0 -1
  155. qiskit/qpy/binary_io/circuits.py +91 -116
  156. qiskit/qpy/binary_io/schedules.py +61 -388
  157. qiskit/qpy/binary_io/value.py +154 -28
  158. qiskit/qpy/common.py +10 -7
  159. qiskit/qpy/formats.py +41 -0
  160. qiskit/qpy/interface.py +29 -62
  161. qiskit/qpy/type_keys.py +58 -221
  162. qiskit/quantum_info/analysis/distance.py +3 -1
  163. qiskit/quantum_info/operators/dihedral/dihedral.py +3 -1
  164. qiskit/quantum_info/operators/operator.py +6 -2
  165. qiskit/quantum_info/operators/symplectic/clifford.py +3 -1
  166. qiskit/quantum_info/operators/symplectic/pauli.py +4 -2
  167. qiskit/quantum_info/operators/symplectic/pauli_list.py +17 -5
  168. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +40 -6
  169. qiskit/quantum_info/states/densitymatrix.py +16 -6
  170. qiskit/quantum_info/states/stabilizerstate.py +35 -4
  171. qiskit/quantum_info/states/statevector.py +16 -6
  172. qiskit/result/__init__.py +5 -17
  173. qiskit/result/models.py +18 -10
  174. qiskit/result/result.py +28 -126
  175. qiskit/result/sampled_expval.py +1 -2
  176. qiskit/result/utils.py +3 -4
  177. qiskit/synthesis/__init__.py +21 -1
  178. qiskit/synthesis/arithmetic/__init__.py +3 -1
  179. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  180. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +1 -1
  181. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +2 -2
  182. qiskit/{providers/fake_provider/backends_v1/fake_20q → synthesis/arithmetic/comparators}/__init__.py +4 -6
  183. qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
  184. qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
  185. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -1
  186. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +1 -1
  187. qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
  188. qiskit/{result/mitigation → synthesis/boolean}/__init__.py +2 -2
  189. qiskit/synthesis/boolean/boolean_expression.py +231 -0
  190. qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
  191. qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
  192. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +2 -0
  193. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  194. qiskit/synthesis/evolution/product_formula.py +44 -35
  195. qiskit/synthesis/evolution/qdrift.py +17 -24
  196. qiskit/synthesis/evolution/suzuki_trotter.py +20 -27
  197. qiskit/synthesis/linear/linear_depth_lnn.py +6 -221
  198. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +4 -205
  199. qiskit/synthesis/multi_controlled/__init__.py +1 -0
  200. qiskit/synthesis/multi_controlled/mcx_synthesis.py +5 -2
  201. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
  202. qiskit/synthesis/one_qubit/one_qubit_decompose.py +1 -1
  203. qiskit/synthesis/two_qubit/__init__.py +1 -0
  204. qiskit/synthesis/two_qubit/two_qubit_decompose.py +28 -145
  205. qiskit/transpiler/__init__.py +32 -232
  206. qiskit/transpiler/basepasses.py +20 -51
  207. qiskit/transpiler/layout.py +1 -1
  208. qiskit/transpiler/passes/__init__.py +2 -40
  209. qiskit/transpiler/passes/basis/basis_translator.py +4 -3
  210. qiskit/transpiler/passes/basis/decompose.py +1 -15
  211. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -5
  212. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +3 -2
  213. qiskit/transpiler/passes/layout/apply_layout.py +4 -0
  214. qiskit/transpiler/passes/layout/dense_layout.py +2 -39
  215. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +4 -4
  216. qiskit/transpiler/passes/layout/sabre_layout.py +7 -3
  217. qiskit/transpiler/passes/layout/vf2_layout.py +2 -20
  218. qiskit/transpiler/passes/layout/vf2_post_layout.py +60 -125
  219. qiskit/transpiler/passes/layout/vf2_utils.py +2 -26
  220. qiskit/transpiler/passes/optimization/__init__.py +1 -3
  221. qiskit/transpiler/passes/optimization/collect_and_collapse.py +2 -0
  222. qiskit/transpiler/passes/optimization/collect_cliffords.py +5 -0
  223. qiskit/transpiler/passes/optimization/collect_linear_functions.py +5 -0
  224. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +16 -1
  225. qiskit/transpiler/passes/optimization/commutation_analysis.py +3 -3
  226. qiskit/transpiler/passes/optimization/consolidate_blocks.py +41 -19
  227. qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
  228. qiskit/transpiler/passes/optimization/light_cone.py +135 -0
  229. qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +0 -1
  230. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +18 -22
  231. qiskit/transpiler/passes/optimization/optimize_annotated.py +3 -2
  232. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +6 -4
  233. qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +5 -2
  234. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +26 -3
  235. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -0
  236. qiskit/transpiler/passes/routing/__init__.py +0 -1
  237. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -1
  238. qiskit/transpiler/passes/routing/sabre_swap.py +14 -6
  239. qiskit/transpiler/passes/routing/star_prerouting.py +1 -1
  240. qiskit/transpiler/passes/scheduling/__init__.py +1 -7
  241. qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -4
  242. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -9
  243. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +17 -16
  244. qiskit/transpiler/passes/scheduling/padding/base_padding.py +30 -2
  245. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +20 -58
  246. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +11 -3
  247. qiskit/transpiler/passes/scheduling/scheduling/alap.py +5 -39
  248. qiskit/transpiler/passes/scheduling/scheduling/asap.py +4 -35
  249. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +10 -16
  250. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +127 -59
  251. qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
  252. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +176 -601
  253. qiskit/transpiler/passes/synthesis/hls_plugins.py +294 -1
  254. qiskit/transpiler/passes/synthesis/plugin.py +4 -0
  255. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +16 -10
  256. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -697
  257. qiskit/transpiler/passes/utils/__init__.py +0 -1
  258. qiskit/transpiler/passes/utils/check_gate_direction.py +13 -5
  259. qiskit/transpiler/passes/utils/control_flow.py +2 -6
  260. qiskit/transpiler/passes/utils/gate_direction.py +7 -0
  261. qiskit/transpiler/passes/utils/remove_final_measurements.py +40 -33
  262. qiskit/transpiler/passmanager.py +13 -0
  263. qiskit/transpiler/passmanager_config.py +5 -81
  264. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +225 -344
  265. qiskit/transpiler/preset_passmanagers/common.py +140 -167
  266. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +101 -322
  267. qiskit/transpiler/preset_passmanagers/level0.py +2 -11
  268. qiskit/transpiler/preset_passmanagers/level1.py +2 -14
  269. qiskit/transpiler/preset_passmanagers/level2.py +2 -12
  270. qiskit/transpiler/preset_passmanagers/level3.py +2 -11
  271. qiskit/transpiler/preset_passmanagers/plugin.py +5 -3
  272. qiskit/transpiler/target.py +67 -524
  273. qiskit/user_config.py +8 -4
  274. qiskit/utils/__init__.py +13 -12
  275. qiskit/utils/deprecation.py +4 -112
  276. qiskit/utils/optionals.py +11 -4
  277. qiskit/utils/parallel.py +214 -87
  278. qiskit/utils/units.py +4 -1
  279. qiskit/visualization/__init__.py +3 -7
  280. qiskit/visualization/array.py +4 -1
  281. qiskit/visualization/bloch.py +1 -1
  282. qiskit/visualization/circuit/_utils.py +19 -19
  283. qiskit/visualization/circuit/circuit_visualization.py +11 -4
  284. qiskit/visualization/circuit/matplotlib.py +13 -23
  285. qiskit/visualization/circuit/text.py +7 -3
  286. qiskit/visualization/dag_visualization.py +2 -1
  287. qiskit/visualization/gate_map.py +39 -154
  288. qiskit/visualization/pass_manager_visualization.py +6 -2
  289. qiskit/visualization/state_visualization.py +6 -0
  290. qiskit/visualization/timeline/core.py +18 -12
  291. qiskit/visualization/timeline/interface.py +19 -18
  292. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/METADATA +2 -2
  293. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/RECORD +297 -444
  294. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/WHEEL +2 -1
  295. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/entry_points.txt +8 -2
  296. qiskit/assembler/__init__.py +0 -42
  297. qiskit/assembler/assemble_circuits.py +0 -451
  298. qiskit/assembler/assemble_schedules.py +0 -367
  299. qiskit/assembler/disassemble.py +0 -310
  300. qiskit/assembler/run_config.py +0 -77
  301. qiskit/circuit/bit.py +0 -106
  302. qiskit/circuit/classicalfunction/__init__.py +0 -152
  303. qiskit/circuit/classicalfunction/boolean_expression.py +0 -138
  304. qiskit/circuit/classicalfunction/classical_element.py +0 -54
  305. qiskit/circuit/classicalfunction/classical_function_visitor.py +0 -155
  306. qiskit/circuit/classicalfunction/classicalfunction.py +0 -182
  307. qiskit/circuit/classicalfunction/exceptions.py +0 -41
  308. qiskit/circuit/classicalfunction/types.py +0 -18
  309. qiskit/circuit/classicalfunction/utils.py +0 -91
  310. qiskit/circuit/classicalregister.py +0 -57
  311. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +0 -405
  312. qiskit/circuit/quantumregister.py +0 -75
  313. qiskit/circuit/register.py +0 -246
  314. qiskit/compiler/assembler.py +0 -689
  315. qiskit/compiler/scheduler.py +0 -109
  316. qiskit/compiler/sequencer.py +0 -71
  317. qiskit/primitives/backend_estimator.py +0 -486
  318. qiskit/primitives/backend_sampler.py +0 -222
  319. qiskit/primitives/estimator.py +0 -172
  320. qiskit/primitives/sampler.py +0 -162
  321. qiskit/providers/backend_compat.py +0 -507
  322. qiskit/providers/fake_provider/backends_v1/__init__.py +0 -22
  323. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +0 -18
  324. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +0 -1
  325. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +0 -1
  326. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +0 -37
  327. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +0 -1
  328. qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +0 -1
  329. qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +0 -43
  330. qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +0 -1
  331. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +0 -18
  332. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +0 -1
  333. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +0 -1
  334. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +0 -50
  335. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +0 -1
  336. qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +0 -18
  337. qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +0 -1
  338. qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +0 -41
  339. qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +0 -1
  340. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +0 -18
  341. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +0 -1
  342. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +0 -1
  343. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +0 -44
  344. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +0 -1
  345. qiskit/providers/fake_provider/fake_1q.py +0 -91
  346. qiskit/providers/fake_provider/fake_backend.py +0 -165
  347. qiskit/providers/fake_provider/fake_openpulse_2q.py +0 -391
  348. qiskit/providers/fake_provider/fake_openpulse_3q.py +0 -340
  349. qiskit/providers/fake_provider/fake_pulse_backend.py +0 -49
  350. qiskit/providers/fake_provider/fake_qasm_backend.py +0 -77
  351. qiskit/providers/fake_provider/utils/backend_converter.py +0 -150
  352. qiskit/providers/fake_provider/utils/json_decoder.py +0 -109
  353. qiskit/providers/models/__init__.py +0 -89
  354. qiskit/providers/models/backendconfiguration.py +0 -1040
  355. qiskit/providers/models/backendproperties.py +0 -535
  356. qiskit/providers/models/backendstatus.py +0 -104
  357. qiskit/providers/models/jobstatus.py +0 -77
  358. qiskit/providers/models/pulsedefaults.py +0 -305
  359. qiskit/providers/provider.py +0 -95
  360. qiskit/pulse/__init__.py +0 -158
  361. qiskit/pulse/builder.py +0 -2262
  362. qiskit/pulse/calibration_entries.py +0 -381
  363. qiskit/pulse/channels.py +0 -227
  364. qiskit/pulse/configuration.py +0 -245
  365. qiskit/pulse/exceptions.py +0 -45
  366. qiskit/pulse/filters.py +0 -309
  367. qiskit/pulse/instruction_schedule_map.py +0 -424
  368. qiskit/pulse/instructions/__init__.py +0 -67
  369. qiskit/pulse/instructions/acquire.py +0 -150
  370. qiskit/pulse/instructions/delay.py +0 -71
  371. qiskit/pulse/instructions/directives.py +0 -154
  372. qiskit/pulse/instructions/frequency.py +0 -135
  373. qiskit/pulse/instructions/instruction.py +0 -270
  374. qiskit/pulse/instructions/phase.py +0 -152
  375. qiskit/pulse/instructions/play.py +0 -99
  376. qiskit/pulse/instructions/reference.py +0 -100
  377. qiskit/pulse/instructions/snapshot.py +0 -82
  378. qiskit/pulse/library/__init__.py +0 -97
  379. qiskit/pulse/library/continuous.py +0 -430
  380. qiskit/pulse/library/pulse.py +0 -148
  381. qiskit/pulse/library/samplers/__init__.py +0 -15
  382. qiskit/pulse/library/samplers/decorators.py +0 -295
  383. qiskit/pulse/library/samplers/strategies.py +0 -71
  384. qiskit/pulse/library/symbolic_pulses.py +0 -1989
  385. qiskit/pulse/library/waveform.py +0 -136
  386. qiskit/pulse/macros.py +0 -262
  387. qiskit/pulse/parameter_manager.py +0 -445
  388. qiskit/pulse/parser.py +0 -314
  389. qiskit/pulse/reference_manager.py +0 -58
  390. qiskit/pulse/schedule.py +0 -1854
  391. qiskit/pulse/transforms/__init__.py +0 -106
  392. qiskit/pulse/transforms/alignments.py +0 -406
  393. qiskit/pulse/transforms/base_transforms.py +0 -71
  394. qiskit/pulse/transforms/canonicalization.py +0 -498
  395. qiskit/pulse/transforms/dag.py +0 -122
  396. qiskit/pulse/utils.py +0 -149
  397. qiskit/qobj/__init__.py +0 -75
  398. qiskit/qobj/common.py +0 -81
  399. qiskit/qobj/converters/__init__.py +0 -18
  400. qiskit/qobj/converters/lo_config.py +0 -177
  401. qiskit/qobj/converters/pulse_instruction.py +0 -897
  402. qiskit/qobj/pulse_qobj.py +0 -709
  403. qiskit/qobj/qasm_qobj.py +0 -708
  404. qiskit/qobj/utils.py +0 -46
  405. qiskit/result/mitigation/base_readout_mitigator.py +0 -79
  406. qiskit/result/mitigation/correlated_readout_mitigator.py +0 -277
  407. qiskit/result/mitigation/local_readout_mitigator.py +0 -328
  408. qiskit/result/mitigation/utils.py +0 -217
  409. qiskit/scheduler/__init__.py +0 -40
  410. qiskit/scheduler/config.py +0 -37
  411. qiskit/scheduler/lowering.py +0 -187
  412. qiskit/scheduler/methods/__init__.py +0 -15
  413. qiskit/scheduler/methods/basic.py +0 -140
  414. qiskit/scheduler/schedule_circuit.py +0 -69
  415. qiskit/scheduler/sequence.py +0 -104
  416. qiskit/transpiler/passes/calibration/__init__.py +0 -17
  417. qiskit/transpiler/passes/calibration/base_builder.py +0 -79
  418. qiskit/transpiler/passes/calibration/builders.py +0 -20
  419. qiskit/transpiler/passes/calibration/exceptions.py +0 -22
  420. qiskit/transpiler/passes/calibration/pulse_gate.py +0 -100
  421. qiskit/transpiler/passes/calibration/rx_builder.py +0 -164
  422. qiskit/transpiler/passes/calibration/rzx_builder.py +0 -411
  423. qiskit/transpiler/passes/calibration/rzx_templates.py +0 -58
  424. qiskit/transpiler/passes/optimization/cx_cancellation.py +0 -65
  425. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +0 -162
  426. qiskit/transpiler/passes/optimization/normalize_rx_angle.py +0 -157
  427. qiskit/transpiler/passes/routing/stochastic_swap.py +0 -532
  428. qiskit/transpiler/passes/scheduling/alap.py +0 -153
  429. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +0 -255
  430. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -107
  431. qiskit/transpiler/passes/scheduling/asap.py +0 -175
  432. qiskit/transpiler/passes/scheduling/base_scheduler.py +0 -310
  433. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +0 -313
  434. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -93
  435. qiskit/utils/deprecate_pulse.py +0 -119
  436. qiskit/utils/multiprocessing.py +0 -56
  437. qiskit/visualization/pulse_v2/__init__.py +0 -21
  438. qiskit/visualization/pulse_v2/core.py +0 -901
  439. qiskit/visualization/pulse_v2/device_info.py +0 -173
  440. qiskit/visualization/pulse_v2/drawings.py +0 -253
  441. qiskit/visualization/pulse_v2/events.py +0 -254
  442. qiskit/visualization/pulse_v2/generators/__init__.py +0 -40
  443. qiskit/visualization/pulse_v2/generators/barrier.py +0 -76
  444. qiskit/visualization/pulse_v2/generators/chart.py +0 -208
  445. qiskit/visualization/pulse_v2/generators/frame.py +0 -436
  446. qiskit/visualization/pulse_v2/generators/snapshot.py +0 -133
  447. qiskit/visualization/pulse_v2/generators/waveform.py +0 -645
  448. qiskit/visualization/pulse_v2/interface.py +0 -459
  449. qiskit/visualization/pulse_v2/layouts.py +0 -387
  450. qiskit/visualization/pulse_v2/plotters/__init__.py +0 -17
  451. qiskit/visualization/pulse_v2/plotters/base_plotter.py +0 -53
  452. qiskit/visualization/pulse_v2/plotters/matplotlib.py +0 -201
  453. qiskit/visualization/pulse_v2/stylesheet.py +0 -312
  454. qiskit/visualization/pulse_v2/types.py +0 -242
  455. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/LICENSE.txt +0 -0
  456. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,124 @@
1
+ # This code is part of Qiskit.
2
+ #
3
+ # (C) Copyright IBM 2025.
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
+ """Circuit synthesizers and related classes for boolean expressions"""
13
+
14
+ import itertools
15
+ from qiskit.circuit import QuantumCircuit
16
+ from qiskit.circuit.library import ZGate, XGate
17
+
18
+
19
+ class EsopGenerator:
20
+ """Generates an ESOP (Exlusive-sum-of-products) representation
21
+ for a boolean function given by its truth table"""
22
+
23
+ def __init__(self, truth_table):
24
+ self.truth_table = truth_table
25
+ self.cofactor_table = {}
26
+ self.esop = self.generate_esop(assignment=())
27
+
28
+ def clause_diff(self, clause1, clause2):
29
+ """The indices of variables where the clauses differ"""
30
+ return [i for i in range(len(clause1)) if clause1[i] != clause2[i]]
31
+
32
+ def combine_and_optimize(self, clauses_1, clauses_2):
33
+ """Combining clauses of distance 1 until no more combinations can be performed"""
34
+ something_changed = True
35
+ combined_clauses = clauses_1 + clauses_2
36
+ while something_changed:
37
+ something_changed = False
38
+ for clause_1, clause_2 in itertools.combinations(combined_clauses, 2):
39
+ diff = self.clause_diff(clause_1, clause_2)
40
+ if len(diff) == 1:
41
+ new_clause = clause_1[: diff[0]] + "-" + clause_1[diff[0] + 1 :]
42
+ if new_clause not in combined_clauses:
43
+ combined_clauses.remove(clause_1)
44
+ combined_clauses.remove(clause_2)
45
+ combined_clauses.append(new_clause)
46
+ something_changed = True
47
+ break
48
+ return combined_clauses
49
+
50
+ def generate_esop(self, assignment):
51
+ """Recursively generates an ESOP for a partially determined boolean expression
52
+ 'assignment' is a partial assignment to the expression's variables
53
+ """
54
+ # this base case is non-optimized;
55
+ # we may be able to terminate even before having a full assignment
56
+ if len(assignment) == self.truth_table.num_bits:
57
+ if self.truth_table[assignment]:
58
+ return ["-" * self.truth_table.num_bits] # True; a don't care clause
59
+ else:
60
+ return [] # False
61
+ i = len(assignment) # current variable
62
+ negative_esop = self.generate_esop(assignment + (False,))
63
+ positive_esop = self.generate_esop(assignment + (True,))
64
+ # Shannon's expansion
65
+ negative_esop_bool_expanded = [
66
+ clause[:i] + "0" + clause[i + 1 :] for clause in negative_esop
67
+ ]
68
+ positive_esop_bool_expanded = [
69
+ clause[:i] + "1" + clause[i + 1 :] for clause in positive_esop
70
+ ]
71
+ self.cofactor_table[assignment] = self.combine_and_optimize(
72
+ negative_esop_bool_expanded, positive_esop_bool_expanded
73
+ )
74
+ return self.cofactor_table[assignment]
75
+
76
+
77
+ def synth_phase_oracle_from_esop(esop, num_qubits):
78
+ """
79
+ Generates a phase oracle for the boolean function f given in ESOP (Exlusive sum of products) form
80
+ esop is of the form ('01-1', '11-0', ...) etc
81
+ where 1 is the variable, 0 is negated variable and - is don't care
82
+ """
83
+ qc = QuantumCircuit(num_qubits)
84
+ clause_data = [
85
+ (zip(*[qubit_data for qubit_data in enumerate(clause) if qubit_data[1] != "-"]))
86
+ for clause in esop
87
+ ]
88
+ for qubit_indices, control_data in clause_data:
89
+ control_state = "".join(control_data)
90
+ if len(control_state) == 1: # single qubit; either Z or XZX
91
+ if control_state == "0":
92
+ qc.x(qubit_indices[0])
93
+ qc.z(qubit_indices[0])
94
+ if control_state == "0":
95
+ qc.x(qubit_indices[0])
96
+ else: # use custom controlled-Z gate
97
+ # we use the last qubit as the target, flipping it if the control is 0 for that qubit
98
+ gate = ZGate().control(len(qubit_indices) - 1, ctrl_state=control_state[:-1][::-1])
99
+ if control_state[-1] == "0":
100
+ qc.x(qubit_indices[-1])
101
+ qc.append(gate, qubit_indices)
102
+ if control_state[-1] == "0":
103
+ qc.x(qubit_indices[-1])
104
+ return qc
105
+
106
+
107
+ def synth_bit_oracle_from_esop(esop, num_qubits):
108
+ """
109
+ Generates a bit-flip oracle for the boolean function f given in ESOP (Exlusive sum of products) form
110
+ esop is of the form ('01-1', '11-0', ...) etc
111
+ where 1 is the variable, 0 is negated variable and - is don't care
112
+ """
113
+ output_index = num_qubits - 1
114
+ qc = QuantumCircuit(num_qubits)
115
+ clause_data = [
116
+ (zip(*[qubit_data for qubit_data in enumerate(clause) if qubit_data[1] != "-"]))
117
+ for clause in esop
118
+ ]
119
+ for qubit_indices, control_data in clause_data:
120
+ control_state = "".join(control_data)
121
+ # use custom controlled-X gate
122
+ gate = XGate().control(len(qubit_indices), ctrl_state=control_state[::-1])
123
+ qc.append(gate, qubit_indices + (output_index,))
124
+ return qc
@@ -0,0 +1,96 @@
1
+ # This code is part of Qiskit.
2
+ #
3
+ # (C) Copyright IBM 2025.
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
+ """Node visitor as defined in https://docs.python.org/3/library/ast.html#ast.NodeVisitor
14
+ This module is used internally by ``qiskit.synthesis.boolean.BooleanExpression``.
15
+ """
16
+
17
+ import ast
18
+ import _ast
19
+
20
+
21
+ class BooleanExpressionEvalVisitor(ast.NodeVisitor):
22
+ """Node visitor to compute the value of the expression, given the boolean values of the args
23
+ as defined in https://docs.python.org/3/library/ast.html#ast.NodeVisitor"""
24
+
25
+ # pylint: disable=invalid-name
26
+ bitops = {
27
+ _ast.BitAnd: lambda values: values[0] and values[1],
28
+ _ast.And: lambda values: values[0] and values[1],
29
+ _ast.BitOr: lambda values: values[0] or values[1],
30
+ _ast.Or: lambda values: values[0] or values[1],
31
+ _ast.BitXor: lambda values: values[0] ^ values[1],
32
+ _ast.Not: lambda values: not values[0],
33
+ _ast.Invert: lambda values: not values[0],
34
+ }
35
+
36
+ def __init__(self):
37
+ self.arg_values = {}
38
+ super().__init__()
39
+
40
+ def bit_binop(self, op, values):
41
+ """Performs the operation, if it is recognized"""
42
+ op_type = type(op)
43
+ if op_type not in self.bitops:
44
+ raise ValueError(f"Unknown op: {op_type}")
45
+ return self.bitops[op_type](values)
46
+
47
+ def visit_BinOp(self, node):
48
+ """Handles ``&``, ``^``, and ``|``."""
49
+ return self.bit_binop(node.op, [self.visit(node.left), self.visit(node.right)])
50
+
51
+ def visit_UnaryOp(self, node):
52
+ """Handles ``~``."""
53
+ return self.bit_binop(node.op, [self.visit(node.operand)])
54
+
55
+ def visit_Name(self, node):
56
+ """Reduce variable names."""
57
+ if node.id not in self.arg_values:
58
+ raise ValueError(f"Undefined value for {node.id}")
59
+ return self.arg_values[node.id]
60
+
61
+ def visit_Module(self, node):
62
+ """Returns the value of the single expression comprising the boolean expression"""
63
+ if len(node.body) != 1 or not isinstance(node.body[0], ast.Expr):
64
+ raise ValueError("Incorrectly formatted boolean expression")
65
+ return self.visit(node.body[0])
66
+
67
+ def visit_Expr(self, node):
68
+ """Returns the value of the expression"""
69
+ return self.visit(node.value)
70
+
71
+ def generic_visit(self, node):
72
+ """Catch all for the unhandled nodes."""
73
+ raise ValueError(f"Unknown node: {type(node)}")
74
+
75
+
76
+ class BooleanExpressionArgsCollectorVisitor(ast.NodeVisitor):
77
+ """Node visitor to collect the name of the args of the expression
78
+ as defined in https://docs.python.org/3/library/ast.html#ast.NodeVisitor"""
79
+
80
+ # pylint: disable=invalid-name
81
+ def __init__(self):
82
+ self.args = set()
83
+ self.args_pos = {}
84
+ super().__init__()
85
+
86
+ def visit_Name(self, node):
87
+ """Collect arg name."""
88
+ self.args.add(node.id)
89
+ if node.id not in self.args_pos or (
90
+ self.args_pos[node.id] > (node.lineno, node.col_offset)
91
+ ):
92
+ self.args_pos[node.id] = (node.lineno, node.col_offset)
93
+
94
+ def get_sorted_args(self):
95
+ """Returns a list of the args, sorted by their appearance locations"""
96
+ return sorted(self.args, key=lambda arg: self.args_pos[arg])
@@ -37,6 +37,8 @@ _1q_inverses = {
37
37
  "tdg": "t",
38
38
  "s": "sdg",
39
39
  "sdg": "s",
40
+ "sx": "sxdg",
41
+ "sxdg": "sx",
40
42
  }
41
43
 
42
44
  _1q_gates = {
@@ -55,14 +55,14 @@ class LieTrotter(SuzukiTrotter):
55
55
  insert_barriers: bool = False,
56
56
  cx_structure: str = "chain",
57
57
  atomic_evolution: (
58
- Callable[[Pauli | SparsePauliOp, float], QuantumCircuit]
59
- | Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None]
60
- | None
58
+ Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None] | None
61
59
  ) = None,
62
60
  wrap: bool = False,
63
61
  preserve_order: bool = True,
62
+ *,
63
+ atomic_evolution_sparse_observable: bool = False,
64
64
  ) -> None:
65
- """
65
+ r"""
66
66
  Args:
67
67
  reps: The number of time steps.
68
68
  insert_barriers: Whether to insert barriers between the atomic evolutions.
@@ -75,14 +75,16 @@ class LieTrotter(SuzukiTrotter):
75
75
  three arguments: the circuit to append the evolution to, the Pauli operator to
76
76
  evolve, and the evolution time. By default, a single Pauli evolution is decomposed
77
77
  into a chain of ``CX`` gates and a single ``RZ`` gate.
78
- Alternatively, the function can also take Pauli operator and evolution time as
79
- inputs and returns the circuit that will be appended to the overall circuit being
80
- built.
81
78
  wrap: Whether to wrap the atomic evolutions into custom gate objects. This only takes
82
79
  effect when ``atomic_evolution is None``.
83
80
  preserve_order: If ``False``, allows reordering the terms of the operator to
84
81
  potentially yield a shallower evolution circuit. Not relevant
85
82
  when synthesizing operator with a single term.
83
+ atomic_evolution_sparse_observable: If a custom ``atomic_evolution`` is passed,
84
+ which does not yet support :class:`.SparseObservable`\ s as input, set this
85
+ argument to ``False`` to automatically apply a conversion to :class:`.SparsePauliOp`.
86
+ This argument is supported until Qiskit 2.2, at which point all atomic evolutions
87
+ are required to support :class:`.SparseObservable`\ s as input.
86
88
  """
87
89
  super().__init__(
88
90
  1,
@@ -92,6 +94,7 @@ class LieTrotter(SuzukiTrotter):
92
94
  atomic_evolution,
93
95
  wrap,
94
96
  preserve_order=preserve_order,
97
+ atomic_evolution_sparse_observable=atomic_evolution_sparse_observable,
95
98
  )
96
99
 
97
100
  @property
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- import inspect
17
+ import warnings
18
18
  import itertools
19
19
  from collections.abc import Callable, Sequence
20
20
  from collections import defaultdict
@@ -24,8 +24,7 @@ import numpy as np
24
24
  import rustworkx as rx
25
25
  from qiskit.circuit.parameterexpression import ParameterExpression
26
26
  from qiskit.circuit.quantumcircuit import QuantumCircuit, ParameterValueType
27
- from qiskit.quantum_info import SparsePauliOp, Pauli
28
- from qiskit.utils.deprecation import deprecate_arg
27
+ from qiskit.quantum_info import SparsePauliOp, Pauli, SparseObservable
29
28
  from qiskit._accelerate.circuit_library import pauli_evolution
30
29
 
31
30
  from .evolution_synthesis import EvolutionSynthesis
@@ -42,20 +41,6 @@ class ProductFormula(EvolutionSynthesis):
42
41
  :obj:`.LieTrotter` and :obj:`.SuzukiTrotter` inherit from this class.
43
42
  """
44
43
 
45
- @deprecate_arg(
46
- name="atomic_evolution",
47
- since="1.4",
48
- predicate=lambda callable: callable is not None
49
- and len(inspect.signature(callable).parameters) == 2,
50
- deprecation_description=(
51
- "The 'Callable[[Pauli | SparsePauliOp, float], QuantumCircuit]' signature of the "
52
- "'atomic_evolution' argument"
53
- ),
54
- additional_msg=(
55
- "Instead you should update your 'atomic_evolution' function to be of the following "
56
- "type: 'Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None]'."
57
- ),
58
- )
59
44
  def __init__(
60
45
  self,
61
46
  order: int,
@@ -63,14 +48,14 @@ class ProductFormula(EvolutionSynthesis):
63
48
  insert_barriers: bool = False,
64
49
  cx_structure: str = "chain",
65
50
  atomic_evolution: (
66
- Callable[[Pauli | SparsePauliOp, float], QuantumCircuit]
67
- | Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None]
68
- | None
51
+ Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None] | None
69
52
  ) = None,
70
53
  wrap: bool = False,
71
54
  preserve_order: bool = True,
55
+ *,
56
+ atomic_evolution_sparse_observable: bool = False,
72
57
  ) -> None:
73
- """
58
+ r"""
74
59
  Args:
75
60
  order: The order of the product formula.
76
61
  reps: The number of time steps.
@@ -84,15 +69,17 @@ class ProductFormula(EvolutionSynthesis):
84
69
  three arguments: the circuit to append the evolution to, the Pauli operator to
85
70
  evolve, and the evolution time. By default, a single Pauli evolution is decomposed
86
71
  into a chain of ``CX`` gates and a single ``RZ`` gate.
87
- Alternatively, the function can also take Pauli operator and evolution time as
88
- inputs and returns the circuit that will be appended to the overall circuit being
89
- built.
90
72
  wrap: Whether to wrap the atomic evolutions into custom gate objects. Note that setting
91
73
  this to ``True`` is slower than ``False``. This only takes effect when
92
74
  ``atomic_evolution is None``.
93
75
  preserve_order: If ``False``, allows reordering the terms of the operator to
94
76
  potentially yield a shallower evolution circuit. Not relevant
95
77
  when synthesizing operator with a single term.
78
+ atomic_evolution_sparse_observable: If a custom ``atomic_evolution`` is passed,
79
+ which does not yet support :class:`.SparseObservable`\ s as input, set this
80
+ argument to ``False`` to automatically apply a conversion to :class:`.SparsePauliOp`.
81
+ This argument is supported until Qiskit 2.2, at which point all atomic evolutions
82
+ are required to support :class:`.SparseObservable`\ s as input.
96
83
  """
97
84
  super().__init__()
98
85
  self.order = order
@@ -112,17 +99,10 @@ class ProductFormula(EvolutionSynthesis):
112
99
  # if atomic evolution is not provided, set a default
113
100
  if atomic_evolution is None:
114
101
  self.atomic_evolution = None
115
-
116
- elif len(inspect.signature(atomic_evolution).parameters) == 2:
117
-
118
- def wrap_atomic_evolution(output, operator, time):
119
- definition = atomic_evolution(operator, time)
120
- output.compose(definition, wrap=wrap, inplace=True)
121
-
122
- self.atomic_evolution = wrap_atomic_evolution
123
-
124
102
  else:
125
- self.atomic_evolution = atomic_evolution
103
+ self.atomic_evolution = wrap_custom_atomic_evolution(
104
+ atomic_evolution, atomic_evolution_sparse_observable
105
+ )
126
106
 
127
107
  def expand(
128
108
  self, evolution: PauliEvolutionGate
@@ -203,7 +183,7 @@ class ProductFormula(EvolutionSynthesis):
203
183
  for i, pauli_rotation in enumerate(pauli_rotations):
204
184
  if self._atomic_evolution is not None:
205
185
  # use the user-provided evolution with a global operator
206
- operator = SparsePauliOp.from_sparse_list([pauli_rotation], num_qubits)
186
+ operator = SparseObservable.from_sparse_list([pauli_rotation], num_qubits)
207
187
  self.atomic_evolution(circuit, operator, time=1) # time is inside the Pauli coeff
208
188
 
209
189
  else: # this means self._wrap is True
@@ -302,3 +282,32 @@ def reorder_paulis(
302
282
 
303
283
  terms = list(itertools.chain(*terms_by_color.values()))
304
284
  return terms
285
+
286
+
287
+ def wrap_custom_atomic_evolution(atomic_evolution, support_sparse_observable):
288
+ r"""Wrap a custom atomic evolution into compatible format for the product formula.
289
+
290
+ This includes an inplace action, i.e. the signature is (circuit, operator, time) and
291
+ ensuring that ``SparseObservable``\ s are supported.
292
+ """
293
+ # next, enable backward compatible use of atomic evolutions, that did not support
294
+ # SparseObservable inputs
295
+ if support_sparse_observable is False:
296
+ warnings.warn(
297
+ "The atomic_evolution should support SparseObservables as operator input. "
298
+ "Until Qiskit 2.2, an automatic conversion to SparsePauliOp is done, which can "
299
+ "be turned off by passing the argument atomic_evolution_sparse_observable=True.",
300
+ category=PendingDeprecationWarning,
301
+ stacklevel=2,
302
+ )
303
+
304
+ def sparseobs_atomic_evolution(output, operator, time):
305
+ if isinstance(operator, SparseObservable):
306
+ operator = SparsePauliOp.from_sparse_observable(operator)
307
+
308
+ atomic_evolution(output, operator, time)
309
+
310
+ else:
311
+ sparseobs_atomic_evolution = atomic_evolution
312
+
313
+ return sparseobs_atomic_evolution
@@ -14,7 +14,6 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- import inspect
18
17
  import math
19
18
  import typing
20
19
  from itertools import chain
@@ -22,7 +21,6 @@ from collections.abc import Callable
22
21
  import numpy as np
23
22
  from qiskit.circuit.quantumcircuit import QuantumCircuit
24
23
  from qiskit.quantum_info.operators import SparsePauliOp, Pauli
25
- from qiskit.utils.deprecation import deprecate_arg
26
24
  from qiskit.exceptions import QiskitError
27
25
 
28
26
  from .product_formula import ProductFormula, reorder_paulis
@@ -32,7 +30,7 @@ if typing.TYPE_CHECKING:
32
30
 
33
31
 
34
32
  class QDrift(ProductFormula):
35
- r"""The QDrift Trotterization method, which selects each each term in the
33
+ r"""The QDrift Trotterization method, which selects each term in the
36
34
  Trotterization randomly, with a probability proportional to its weight. Based on the work
37
35
  of Earl Campbell in Ref. [1].
38
36
 
@@ -41,33 +39,19 @@ class QDrift(ProductFormula):
41
39
  `arXiv:quant-ph/1811.08017 <https://arxiv.org/abs/1811.08017>`_
42
40
  """
43
41
 
44
- @deprecate_arg(
45
- name="atomic_evolution",
46
- since="1.4",
47
- predicate=lambda callable: callable is not None
48
- and len(inspect.signature(callable).parameters) == 2,
49
- deprecation_description=(
50
- "The 'Callable[[Pauli | SparsePauliOp, float], QuantumCircuit]' signature of the "
51
- "'atomic_evolution' argument"
52
- ),
53
- additional_msg=(
54
- "Instead you should update your 'atomic_evolution' function to be of the following "
55
- "type: 'Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None]'."
56
- ),
57
- )
58
42
  def __init__(
59
43
  self,
60
44
  reps: int = 1,
61
45
  insert_barriers: bool = False,
62
46
  cx_structure: str = "chain",
63
47
  atomic_evolution: (
64
- Callable[[Pauli | SparsePauliOp, float], QuantumCircuit]
65
- | Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None]
66
- | None
48
+ Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None] | None
67
49
  ) = None,
68
50
  seed: int | None = None,
69
51
  wrap: bool = False,
70
52
  preserve_order: bool = True,
53
+ *,
54
+ atomic_evolution_sparse_observable: bool = False,
71
55
  ) -> None:
72
56
  r"""
73
57
  Args:
@@ -82,18 +66,27 @@ class QDrift(ProductFormula):
82
66
  three arguments: the circuit to append the evolution to, the Pauli operator to
83
67
  evolve, and the evolution time. By default, a single Pauli evolution is decomposed
84
68
  into a chain of ``CX`` gates and a single ``RZ`` gate.
85
- Alternatively, the function can also take Pauli operator and evolution time as
86
- inputs and returns the circuit that will be appended to the overall circuit being
87
- built.
88
69
  seed: An optional seed for reproducibility of the random sampling process.
89
70
  wrap: Whether to wrap the atomic evolutions into custom gate objects. This only takes
90
71
  effect when ``atomic_evolution is None``.
91
72
  preserve_order: If ``False``, allows reordering the terms of the operator to
92
73
  potentially yield a shallower evolution circuit. Not relevant
93
74
  when synthesizing operator with a single term.
75
+ atomic_evolution_sparse_observable: If a custom ``atomic_evolution`` is passed,
76
+ which does not yet support :class:`.SparseObservable`\ s as input, set this
77
+ argument to ``False`` to automatically apply a conversion to :class:`.SparsePauliOp`.
78
+ This argument is supported until Qiskit 2.2, at which point all atomic evolutions
79
+ are required to support :class:`.SparseObservable`\ s as input.
94
80
  """
95
81
  super().__init__(
96
- 1, reps, insert_barriers, cx_structure, atomic_evolution, wrap, preserve_order
82
+ 1,
83
+ reps,
84
+ insert_barriers,
85
+ cx_structure,
86
+ atomic_evolution,
87
+ wrap,
88
+ preserve_order,
89
+ atomic_evolution_sparse_observable=atomic_evolution_sparse_observable,
97
90
  )
98
91
  self.sampled_ops = None
99
92
  self.rng = np.random.default_rng(seed)
@@ -14,7 +14,6 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- import inspect
18
17
  import typing
19
18
  from collections.abc import Callable
20
19
  from itertools import chain
@@ -22,8 +21,7 @@ import numpy as np
22
21
 
23
22
  from qiskit.circuit.parameterexpression import ParameterExpression
24
23
  from qiskit.circuit.quantumcircuit import QuantumCircuit
25
- from qiskit.quantum_info.operators import SparsePauliOp, Pauli
26
- from qiskit.utils.deprecation import deprecate_arg
24
+ from qiskit.quantum_info import SparsePauliOp, Pauli
27
25
 
28
26
  from .product_formula import ProductFormula, reorder_paulis
29
27
 
@@ -60,20 +58,6 @@ class SuzukiTrotter(ProductFormula):
60
58
  `arXiv:math-ph/0506007 <https://arxiv.org/pdf/math-ph/0506007.pdf>`_
61
59
  """
62
60
 
63
- @deprecate_arg(
64
- name="atomic_evolution",
65
- since="1.4",
66
- predicate=lambda callable: callable is not None
67
- and len(inspect.signature(callable).parameters) == 2,
68
- deprecation_description=(
69
- "The 'Callable[[Pauli | SparsePauliOp, float], QuantumCircuit]' signature of the "
70
- "'atomic_evolution' argument"
71
- ),
72
- additional_msg=(
73
- "Instead you should update your 'atomic_evolution' function to be of the following "
74
- "type: 'Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None]'."
75
- ),
76
- )
77
61
  def __init__(
78
62
  self,
79
63
  order: int = 2,
@@ -81,14 +65,14 @@ class SuzukiTrotter(ProductFormula):
81
65
  insert_barriers: bool = False,
82
66
  cx_structure: str = "chain",
83
67
  atomic_evolution: (
84
- Callable[[Pauli | SparsePauliOp, float], QuantumCircuit]
85
- | Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None]
86
- | None
68
+ Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None] | None
87
69
  ) = None,
88
70
  wrap: bool = False,
89
71
  preserve_order: bool = True,
72
+ *,
73
+ atomic_evolution_sparse_observable: bool = False,
90
74
  ) -> None:
91
- """
75
+ r"""
92
76
  Args:
93
77
  order: The order of the product formula.
94
78
  reps: The number of time steps.
@@ -101,23 +85,26 @@ class SuzukiTrotter(ProductFormula):
101
85
  three arguments: the circuit to append the evolution to, the Pauli operator to
102
86
  evolve, and the evolution time. By default, a single Pauli evolution is decomposed
103
87
  into a chain of ``CX`` gates and a single ``RZ`` gate.
104
- Alternatively, the function can also take Pauli operator and evolution time as
105
- inputs and returns the circuit that will be appended to the overall circuit being
106
- built.
107
88
  wrap: Whether to wrap the atomic evolutions into custom gate objects. This only takes
108
89
  effect when ``atomic_evolution is None``.
109
90
  preserve_order: If ``False``, allows reordering the terms of the operator to
110
91
  potentially yield a shallower evolution circuit. Not relevant
111
92
  when synthesizing operator with a single term.
93
+ atomic_evolution_sparse_observable: If a custom ``atomic_evolution`` is passed,
94
+ which does not yet support :class:`.SparseObservable`\ s as input, set this
95
+ argument to ``False`` to automatically apply a conversion to :class:`.SparsePauliOp`.
96
+ This argument is supported until Qiskit 2.2, at which point all atomic evolutions
97
+ are required to support :class:`.SparseObservable`\ s as input.
98
+
112
99
  Raises:
113
100
  ValueError: If order is not even
114
101
  """
115
-
116
102
  if order > 1 and order % 2 == 1:
117
103
  raise ValueError(
118
104
  "Suzuki product formulae are symmetric and therefore only defined "
119
105
  f"for when the order is 1 or even, not {order}."
120
106
  )
107
+
121
108
  super().__init__(
122
109
  order,
123
110
  reps,
@@ -126,6 +113,7 @@ class SuzukiTrotter(ProductFormula):
126
113
  atomic_evolution,
127
114
  wrap,
128
115
  preserve_order=preserve_order,
116
+ atomic_evolution_sparse_observable=atomic_evolution_sparse_observable,
129
117
  )
130
118
 
131
119
  def expand(
@@ -154,13 +142,18 @@ class SuzukiTrotter(ProductFormula):
154
142
  Returns:
155
143
  The Pauli network implementing the Trotter expansion.
156
144
  """
157
- operators = evolution.operator # type: SparsePauliOp | list[SparsePauliOp]
145
+ operators = evolution.operator
158
146
  time = evolution.time
159
147
 
160
148
  def to_sparse_list(operator):
149
+ sparse_list = (
150
+ operator.to_sparse_list()
151
+ if isinstance(operator, SparsePauliOp)
152
+ else operator.to_sparse_list()
153
+ )
161
154
  paulis = [
162
155
  (pauli, indices, real_or_fail(coeff) * time * 2 / self.reps)
163
- for pauli, indices, coeff in operator.to_sparse_list()
156
+ for pauli, indices, coeff in sparse_list
164
157
  ]
165
158
  if not self.preserve_order:
166
159
  return reorder_paulis(paulis)