qiskit 1.1.2__cp38-abi3-macosx_10_9_universal2.whl → 1.2.0__cp38-abi3-macosx_10_9_universal2.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 (343) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +27 -24
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/_numpy_compat.py +1 -1
  5. qiskit/assembler/assemble_circuits.py +107 -64
  6. qiskit/assembler/assemble_schedules.py +5 -12
  7. qiskit/assembler/disassemble.py +10 -1
  8. qiskit/circuit/__init__.py +6 -3
  9. qiskit/circuit/_classical_resource_map.py +5 -5
  10. qiskit/circuit/_utils.py +0 -13
  11. qiskit/circuit/add_control.py +1 -1
  12. qiskit/circuit/annotated_operation.py +23 -1
  13. qiskit/circuit/classical/expr/expr.py +4 -4
  14. qiskit/circuit/classical/expr/visitors.py +1 -1
  15. qiskit/circuit/classical/types/__init__.py +1 -1
  16. qiskit/circuit/classical/types/types.py +2 -2
  17. qiskit/circuit/classicalfunction/boolean_expression.py +1 -1
  18. qiskit/circuit/classicalfunction/classical_function_visitor.py +5 -5
  19. qiskit/circuit/classicalfunction/utils.py +1 -1
  20. qiskit/circuit/classicalregister.py +1 -1
  21. qiskit/circuit/commutation_checker.py +83 -35
  22. qiskit/circuit/controlflow/_builder_utils.py +1 -1
  23. qiskit/circuit/controlflow/builder.py +10 -6
  24. qiskit/circuit/controlflow/if_else.py +2 -2
  25. qiskit/circuit/controlflow/switch_case.py +1 -1
  26. qiskit/circuit/delay.py +1 -1
  27. qiskit/circuit/duration.py +2 -2
  28. qiskit/circuit/equivalence.py +5 -7
  29. qiskit/circuit/gate.py +11 -8
  30. qiskit/circuit/instruction.py +31 -13
  31. qiskit/circuit/instructionset.py +2 -5
  32. qiskit/circuit/library/__init__.py +2 -1
  33. qiskit/circuit/library/arithmetic/linear_amplitude_function.py +1 -1
  34. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +1 -1
  35. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +1 -1
  36. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +1 -1
  37. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +3 -3
  38. qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +1 -1
  39. qiskit/circuit/library/basis_change/__init__.py +1 -1
  40. qiskit/circuit/library/basis_change/qft.py +40 -6
  41. qiskit/circuit/library/blueprintcircuit.py +3 -5
  42. qiskit/circuit/library/data_preparation/__init__.py +9 -2
  43. qiskit/circuit/library/data_preparation/initializer.py +8 -0
  44. qiskit/circuit/library/data_preparation/state_preparation.py +98 -178
  45. qiskit/circuit/library/generalized_gates/isometry.py +8 -8
  46. qiskit/circuit/library/generalized_gates/linear_function.py +3 -2
  47. qiskit/circuit/library/generalized_gates/mcg_up_to_diagonal.py +4 -4
  48. qiskit/circuit/library/generalized_gates/permutation.py +8 -9
  49. qiskit/circuit/library/generalized_gates/uc.py +3 -3
  50. qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +2 -2
  51. qiskit/circuit/library/generalized_gates/unitary.py +13 -11
  52. qiskit/circuit/library/graph_state.py +1 -1
  53. qiskit/circuit/library/hamiltonian_gate.py +1 -2
  54. qiskit/circuit/library/hidden_linear_function.py +1 -1
  55. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +3 -2
  56. qiskit/circuit/library/n_local/n_local.py +4 -5
  57. qiskit/circuit/library/n_local/pauli_two_design.py +1 -1
  58. qiskit/circuit/library/n_local/qaoa_ansatz.py +6 -8
  59. qiskit/circuit/library/n_local/two_local.py +1 -1
  60. qiskit/circuit/library/overlap.py +11 -5
  61. qiskit/circuit/library/pauli_evolution.py +7 -3
  62. qiskit/circuit/library/standard_gates/dcx.py +3 -0
  63. qiskit/circuit/library/standard_gates/ecr.py +3 -0
  64. qiskit/circuit/library/standard_gates/global_phase.py +3 -0
  65. qiskit/circuit/library/standard_gates/h.py +13 -5
  66. qiskit/circuit/library/standard_gates/i.py +3 -0
  67. qiskit/circuit/library/standard_gates/iswap.py +3 -0
  68. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +19 -10
  69. qiskit/circuit/library/standard_gates/p.py +14 -9
  70. qiskit/circuit/library/standard_gates/r.py +3 -0
  71. qiskit/circuit/library/standard_gates/rx.py +21 -6
  72. qiskit/circuit/library/standard_gates/rxx.py +40 -1
  73. qiskit/circuit/library/standard_gates/ry.py +21 -6
  74. qiskit/circuit/library/standard_gates/ryy.py +40 -1
  75. qiskit/circuit/library/standard_gates/rz.py +22 -6
  76. qiskit/circuit/library/standard_gates/rzx.py +40 -1
  77. qiskit/circuit/library/standard_gates/rzz.py +41 -2
  78. qiskit/circuit/library/standard_gates/s.py +77 -0
  79. qiskit/circuit/library/standard_gates/swap.py +12 -5
  80. qiskit/circuit/library/standard_gates/sx.py +14 -5
  81. qiskit/circuit/library/standard_gates/t.py +5 -0
  82. qiskit/circuit/library/standard_gates/u.py +22 -7
  83. qiskit/circuit/library/standard_gates/u1.py +8 -3
  84. qiskit/circuit/library/standard_gates/u2.py +3 -0
  85. qiskit/circuit/library/standard_gates/u3.py +22 -7
  86. qiskit/circuit/library/standard_gates/x.py +156 -92
  87. qiskit/circuit/library/standard_gates/xx_minus_yy.py +40 -1
  88. qiskit/circuit/library/standard_gates/xx_plus_yy.py +52 -11
  89. qiskit/circuit/library/standard_gates/y.py +6 -1
  90. qiskit/circuit/library/standard_gates/z.py +8 -1
  91. qiskit/circuit/operation.py +1 -1
  92. qiskit/circuit/parameter.py +9 -10
  93. qiskit/circuit/parameterexpression.py +16 -13
  94. qiskit/circuit/parametertable.py +1 -190
  95. qiskit/circuit/parametervector.py +1 -1
  96. qiskit/circuit/quantumcircuit.py +395 -387
  97. qiskit/circuit/quantumcircuitdata.py +3 -5
  98. qiskit/circuit/quantumregister.py +1 -1
  99. qiskit/circuit/random/__init__.py +1 -1
  100. qiskit/circuit/random/utils.py +175 -26
  101. qiskit/circuit/register.py +5 -7
  102. qiskit/circuit/singleton.py +3 -3
  103. qiskit/circuit/tools/pi_check.py +4 -4
  104. qiskit/compiler/assembler.py +95 -24
  105. qiskit/compiler/scheduler.py +2 -2
  106. qiskit/compiler/transpiler.py +42 -128
  107. qiskit/converters/circuit_to_dag.py +4 -6
  108. qiskit/converters/circuit_to_gate.py +4 -8
  109. qiskit/converters/circuit_to_instruction.py +5 -17
  110. qiskit/converters/dag_to_circuit.py +2 -6
  111. qiskit/dagcircuit/collect_blocks.py +2 -2
  112. qiskit/dagcircuit/dagcircuit.py +190 -187
  113. qiskit/dagcircuit/dagdependency.py +4 -4
  114. qiskit/dagcircuit/dagdependency_v2.py +4 -4
  115. qiskit/dagcircuit/dagdepnode.py +1 -1
  116. qiskit/dagcircuit/dagnode.py +66 -157
  117. qiskit/passmanager/flow_controllers.py +1 -1
  118. qiskit/passmanager/passmanager.py +3 -3
  119. qiskit/primitives/__init__.py +1 -5
  120. qiskit/primitives/backend_estimator.py +25 -15
  121. qiskit/primitives/backend_estimator_v2.py +31 -7
  122. qiskit/primitives/backend_sampler.py +21 -12
  123. qiskit/primitives/backend_sampler_v2.py +12 -3
  124. qiskit/primitives/base/base_estimator.py +31 -4
  125. qiskit/primitives/base/base_primitive.py +2 -2
  126. qiskit/primitives/base/base_result.py +2 -2
  127. qiskit/primitives/base/base_sampler.py +26 -2
  128. qiskit/primitives/base/estimator_result.py +2 -2
  129. qiskit/primitives/base/sampler_result.py +2 -2
  130. qiskit/primitives/containers/__init__.py +0 -1
  131. qiskit/primitives/containers/bindings_array.py +2 -2
  132. qiskit/primitives/containers/bit_array.py +108 -10
  133. qiskit/primitives/containers/shape.py +3 -3
  134. qiskit/primitives/estimator.py +9 -2
  135. qiskit/primitives/primitive_job.py +1 -1
  136. qiskit/primitives/sampler.py +10 -3
  137. qiskit/primitives/statevector_estimator.py +5 -3
  138. qiskit/primitives/statevector_sampler.py +11 -5
  139. qiskit/primitives/utils.py +16 -0
  140. qiskit/providers/backend.py +15 -6
  141. qiskit/providers/backend_compat.py +7 -4
  142. qiskit/providers/basic_provider/basic_provider_tools.py +1 -1
  143. qiskit/providers/basic_provider/basic_simulator.py +33 -25
  144. qiskit/providers/fake_provider/fake_backend.py +10 -3
  145. qiskit/providers/fake_provider/fake_openpulse_2q.py +157 -149
  146. qiskit/providers/fake_provider/fake_openpulse_3q.py +228 -220
  147. qiskit/providers/fake_provider/fake_pulse_backend.py +2 -1
  148. qiskit/providers/fake_provider/fake_qasm_backend.py +7 -2
  149. qiskit/providers/fake_provider/generic_backend_v2.py +514 -68
  150. qiskit/providers/models/__init__.py +48 -11
  151. qiskit/providers/models/backendconfiguration.py +50 -4
  152. qiskit/providers/models/backendproperties.py +13 -2
  153. qiskit/providers/models/pulsedefaults.py +10 -11
  154. qiskit/providers/options.py +13 -13
  155. qiskit/providers/providerutils.py +3 -1
  156. qiskit/pulse/configuration.py +8 -12
  157. qiskit/pulse/instruction_schedule_map.py +3 -5
  158. qiskit/pulse/instructions/acquire.py +7 -8
  159. qiskit/pulse/instructions/instruction.py +2 -3
  160. qiskit/pulse/library/samplers/decorators.py +5 -9
  161. qiskit/pulse/library/symbolic_pulses.py +4 -7
  162. qiskit/pulse/library/waveform.py +2 -5
  163. qiskit/pulse/macros.py +11 -6
  164. qiskit/pulse/parser.py +8 -10
  165. qiskit/pulse/schedule.py +9 -17
  166. qiskit/pulse/transforms/alignments.py +1 -3
  167. qiskit/pulse/utils.py +1 -2
  168. qiskit/qasm/libs/stdgates.inc +35 -28
  169. qiskit/qasm2/__init__.py +7 -7
  170. qiskit/qasm2/export.py +5 -9
  171. qiskit/qasm2/parse.py +1 -1
  172. qiskit/qasm3/ast.py +9 -25
  173. qiskit/qasm3/exporter.py +582 -479
  174. qiskit/qasm3/printer.py +7 -16
  175. qiskit/qobj/common.py +10 -0
  176. qiskit/qobj/converters/lo_config.py +9 -0
  177. qiskit/qobj/converters/pulse_instruction.py +13 -6
  178. qiskit/qobj/pulse_qobj.py +69 -15
  179. qiskit/qobj/qasm_qobj.py +72 -20
  180. qiskit/qobj/utils.py +9 -0
  181. qiskit/qpy/__init__.py +1 -1
  182. qiskit/qpy/binary_io/circuits.py +8 -5
  183. qiskit/qpy/binary_io/schedules.py +1 -1
  184. qiskit/qpy/binary_io/value.py +3 -3
  185. qiskit/qpy/interface.py +3 -2
  186. qiskit/qpy/type_keys.py +2 -2
  187. qiskit/quantum_info/operators/channel/quantum_channel.py +3 -6
  188. qiskit/quantum_info/operators/channel/superop.py +2 -2
  189. qiskit/quantum_info/operators/channel/transformations.py +1 -1
  190. qiskit/quantum_info/operators/dihedral/dihedral.py +3 -4
  191. qiskit/quantum_info/operators/dihedral/dihedral_circuits.py +1 -3
  192. qiskit/quantum_info/operators/dihedral/random.py +6 -3
  193. qiskit/quantum_info/operators/measures.py +2 -2
  194. qiskit/quantum_info/operators/op_shape.py +12 -20
  195. qiskit/quantum_info/operators/operator.py +14 -21
  196. qiskit/quantum_info/operators/predicates.py +1 -0
  197. qiskit/quantum_info/operators/symplectic/base_pauli.py +7 -11
  198. qiskit/quantum_info/operators/symplectic/clifford.py +1 -1
  199. qiskit/quantum_info/operators/symplectic/pauli.py +3 -3
  200. qiskit/quantum_info/operators/symplectic/pauli_list.py +9 -10
  201. qiskit/quantum_info/operators/symplectic/random.py +1 -1
  202. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +15 -17
  203. qiskit/quantum_info/quaternion.py +1 -1
  204. qiskit/quantum_info/states/densitymatrix.py +5 -8
  205. qiskit/quantum_info/states/stabilizerstate.py +128 -37
  206. qiskit/quantum_info/states/statevector.py +4 -8
  207. qiskit/result/counts.py +2 -2
  208. qiskit/result/mitigation/correlated_readout_mitigator.py +2 -2
  209. qiskit/result/mitigation/local_readout_mitigator.py +2 -2
  210. qiskit/result/mitigation/utils.py +1 -3
  211. qiskit/result/models.py +17 -16
  212. qiskit/result/result.py +15 -20
  213. qiskit/scheduler/lowering.py +2 -2
  214. qiskit/synthesis/__init__.py +2 -1
  215. qiskit/synthesis/clifford/__init__.py +1 -1
  216. qiskit/synthesis/clifford/clifford_decompose_ag.py +2 -2
  217. qiskit/synthesis/clifford/clifford_decompose_bm.py +10 -240
  218. qiskit/synthesis/clifford/clifford_decompose_greedy.py +9 -303
  219. qiskit/synthesis/clifford/clifford_decompose_layers.py +25 -23
  220. qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_full.py +1 -1
  221. qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_general.py +1 -1
  222. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +1 -1
  223. qiskit/synthesis/discrete_basis/solovay_kitaev.py +2 -2
  224. qiskit/synthesis/evolution/evolution_synthesis.py +4 -2
  225. qiskit/synthesis/evolution/lie_trotter.py +46 -19
  226. qiskit/synthesis/evolution/product_formula.py +111 -55
  227. qiskit/synthesis/evolution/qdrift.py +40 -10
  228. qiskit/synthesis/evolution/suzuki_trotter.py +43 -33
  229. qiskit/synthesis/linear/__init__.py +1 -0
  230. qiskit/synthesis/linear/cnot_synth.py +22 -96
  231. qiskit/synthesis/linear/linear_depth_lnn.py +8 -8
  232. qiskit/synthesis/linear/linear_matrix_utils.py +13 -161
  233. qiskit/synthesis/linear_phase/cnot_phase_synth.py +1 -1
  234. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +3 -3
  235. qiskit/synthesis/linear_phase/cz_depth_lnn.py +1 -1
  236. qiskit/synthesis/one_qubit/one_qubit_decompose.py +29 -29
  237. qiskit/synthesis/permutation/permutation_full.py +5 -29
  238. qiskit/synthesis/permutation/permutation_lnn.py +2 -24
  239. qiskit/synthesis/permutation/permutation_utils.py +2 -59
  240. qiskit/synthesis/qft/__init__.py +1 -0
  241. qiskit/synthesis/qft/qft_decompose_full.py +79 -0
  242. qiskit/synthesis/qft/qft_decompose_lnn.py +17 -9
  243. qiskit/synthesis/stabilizer/stabilizer_circuit.py +6 -6
  244. qiskit/synthesis/stabilizer/stabilizer_decompose.py +2 -2
  245. qiskit/synthesis/two_qubit/local_invariance.py +8 -38
  246. qiskit/synthesis/two_qubit/two_qubit_decompose.py +48 -129
  247. qiskit/synthesis/unitary/aqc/cnot_structures.py +1 -1
  248. qiskit/synthesis/unitary/qsd.py +5 -3
  249. qiskit/transpiler/__init__.py +1 -0
  250. qiskit/transpiler/basepasses.py +1 -1
  251. qiskit/transpiler/coupling.py +3 -3
  252. qiskit/transpiler/instruction_durations.py +1 -2
  253. qiskit/transpiler/layout.py +3 -3
  254. qiskit/transpiler/passes/__init__.py +2 -0
  255. qiskit/transpiler/passes/basis/basis_translator.py +84 -64
  256. qiskit/transpiler/passes/basis/translate_parameterized.py +3 -5
  257. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
  258. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +10 -10
  259. qiskit/transpiler/passes/calibration/rx_builder.py +3 -3
  260. qiskit/transpiler/passes/calibration/rzx_builder.py +3 -3
  261. qiskit/transpiler/passes/layout/apply_layout.py +13 -3
  262. qiskit/transpiler/passes/layout/sabre_layout.py +10 -8
  263. qiskit/transpiler/passes/layout/sabre_pre_layout.py +4 -1
  264. qiskit/transpiler/passes/layout/set_layout.py +2 -2
  265. qiskit/transpiler/passes/layout/vf2_layout.py +1 -1
  266. qiskit/transpiler/passes/layout/vf2_utils.py +3 -3
  267. qiskit/transpiler/passes/optimization/__init__.py +1 -0
  268. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +2 -2
  269. qiskit/transpiler/passes/optimization/commutation_analysis.py +7 -10
  270. qiskit/transpiler/passes/optimization/commutative_cancellation.py +35 -19
  271. qiskit/transpiler/passes/optimization/consolidate_blocks.py +17 -8
  272. qiskit/transpiler/passes/optimization/inverse_cancellation.py +6 -6
  273. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +64 -41
  274. qiskit/transpiler/passes/optimization/optimize_1q_gates.py +1 -1
  275. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +83 -0
  276. qiskit/transpiler/passes/optimization/template_matching/backward_match.py +1 -1
  277. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +2 -2
  278. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -1
  279. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -2
  280. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +1 -1
  281. qiskit/transpiler/passes/routing/layout_transformation.py +2 -1
  282. qiskit/transpiler/passes/routing/sabre_swap.py +35 -26
  283. qiskit/transpiler/passes/routing/star_prerouting.py +80 -105
  284. qiskit/transpiler/passes/routing/stochastic_swap.py +1 -3
  285. qiskit/transpiler/passes/scheduling/alap.py +1 -2
  286. qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -2
  287. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
  288. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +2 -2
  289. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +1 -1
  290. qiskit/transpiler/passes/scheduling/asap.py +1 -2
  291. qiskit/transpiler/passes/scheduling/base_scheduler.py +5 -5
  292. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +3 -3
  293. qiskit/transpiler/passes/scheduling/padding/base_padding.py +1 -1
  294. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +20 -14
  295. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +7 -6
  296. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +4 -3
  297. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +211 -36
  298. qiskit/transpiler/passes/synthesis/plugin.py +2 -2
  299. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +80 -40
  300. qiskit/transpiler/passes/utils/__init__.py +0 -1
  301. qiskit/transpiler/passes/utils/check_gate_direction.py +4 -4
  302. qiskit/transpiler/passes/utils/check_map.py +3 -6
  303. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +3 -4
  304. qiskit/transpiler/passes/utils/error.py +2 -2
  305. qiskit/transpiler/passes/utils/fixed_point.py +3 -3
  306. qiskit/transpiler/passes/utils/gate_direction.py +1 -1
  307. qiskit/transpiler/passes/utils/gates_basis.py +1 -2
  308. qiskit/transpiler/passmanager.py +7 -6
  309. qiskit/transpiler/preset_passmanagers/__init__.py +4 -228
  310. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +73 -18
  311. qiskit/transpiler/preset_passmanagers/common.py +3 -6
  312. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +518 -0
  313. qiskit/transpiler/preset_passmanagers/level0.py +1 -1
  314. qiskit/transpiler/target.py +27 -8
  315. qiskit/user_config.py +29 -6
  316. qiskit/utils/classtools.py +3 -3
  317. qiskit/utils/deprecation.py +3 -2
  318. qiskit/utils/lazy_tester.py +2 -2
  319. qiskit/utils/optionals.py +8 -8
  320. qiskit/visualization/bloch.py +18 -23
  321. qiskit/visualization/circuit/_utils.py +34 -10
  322. qiskit/visualization/circuit/circuit_visualization.py +23 -16
  323. qiskit/visualization/circuit/latex.py +29 -27
  324. qiskit/visualization/circuit/matplotlib.py +4 -2
  325. qiskit/visualization/circuit/qcstyle.py +2 -2
  326. qiskit/visualization/circuit/text.py +9 -15
  327. qiskit/visualization/dag_visualization.py +2 -2
  328. qiskit/visualization/pulse_v2/core.py +1 -1
  329. qiskit/visualization/pulse_v2/events.py +1 -1
  330. qiskit/visualization/pulse_v2/generators/frame.py +3 -4
  331. qiskit/visualization/pulse_v2/generators/waveform.py +5 -9
  332. qiskit/visualization/pulse_v2/layouts.py +1 -5
  333. qiskit/visualization/pulse_v2/plotters/matplotlib.py +1 -2
  334. qiskit/visualization/state_visualization.py +5 -6
  335. qiskit/visualization/timeline/plotters/matplotlib.py +1 -2
  336. qiskit/visualization/transition_visualization.py +7 -2
  337. {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/METADATA +12 -12
  338. {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/RECORD +342 -340
  339. {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/entry_points.txt +3 -0
  340. qiskit/transpiler/passes/utils/block_to_matrix.py +0 -47
  341. {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/LICENSE.txt +0 -0
  342. {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/WHEEL +0 -0
  343. {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/top_level.txt +0 -0
@@ -187,7 +187,7 @@ class DAGDependency:
187
187
 
188
188
  duplicate_qubits = set(self.qubits).intersection(qubits)
189
189
  if duplicate_qubits:
190
- raise DAGDependencyError("duplicate qubits %s" % duplicate_qubits)
190
+ raise DAGDependencyError(f"duplicate qubits {duplicate_qubits}")
191
191
 
192
192
  self.qubits.extend(qubits)
193
193
 
@@ -198,7 +198,7 @@ class DAGDependency:
198
198
 
199
199
  duplicate_clbits = set(self.clbits).intersection(clbits)
200
200
  if duplicate_clbits:
201
- raise DAGDependencyError("duplicate clbits %s" % duplicate_clbits)
201
+ raise DAGDependencyError(f"duplicate clbits {duplicate_clbits}")
202
202
 
203
203
  self.clbits.extend(clbits)
204
204
 
@@ -207,7 +207,7 @@ class DAGDependency:
207
207
  if not isinstance(qreg, QuantumRegister):
208
208
  raise DAGDependencyError("not a QuantumRegister instance.")
209
209
  if qreg.name in self.qregs:
210
- raise DAGDependencyError("duplicate register %s" % qreg.name)
210
+ raise DAGDependencyError(f"duplicate register {qreg.name}")
211
211
  self.qregs[qreg.name] = qreg
212
212
  existing_qubits = set(self.qubits)
213
213
  for j in range(qreg.size):
@@ -219,7 +219,7 @@ class DAGDependency:
219
219
  if not isinstance(creg, ClassicalRegister):
220
220
  raise DAGDependencyError("not a ClassicalRegister instance.")
221
221
  if creg.name in self.cregs:
222
- raise DAGDependencyError("duplicate register %s" % creg.name)
222
+ raise DAGDependencyError(f"duplicate register {creg.name}")
223
223
  self.cregs[creg.name] = creg
224
224
  existing_clbits = set(self.clbits)
225
225
  for j in range(creg.size):
@@ -247,7 +247,7 @@ class _DAGDependencyV2:
247
247
 
248
248
  duplicate_qubits = set(self.qubits).intersection(qubits)
249
249
  if duplicate_qubits:
250
- raise DAGDependencyError("duplicate qubits %s" % duplicate_qubits)
250
+ raise DAGDependencyError(f"duplicate qubits {duplicate_qubits}")
251
251
 
252
252
  for qubit in qubits:
253
253
  self.qubits.append(qubit)
@@ -260,7 +260,7 @@ class _DAGDependencyV2:
260
260
 
261
261
  duplicate_clbits = set(self.clbits).intersection(clbits)
262
262
  if duplicate_clbits:
263
- raise DAGDependencyError("duplicate clbits %s" % duplicate_clbits)
263
+ raise DAGDependencyError(f"duplicate clbits {duplicate_clbits}")
264
264
 
265
265
  for clbit in clbits:
266
266
  self.clbits.append(clbit)
@@ -271,7 +271,7 @@ class _DAGDependencyV2:
271
271
  if not isinstance(qreg, QuantumRegister):
272
272
  raise DAGDependencyError("not a QuantumRegister instance.")
273
273
  if qreg.name in self.qregs:
274
- raise DAGDependencyError("duplicate register %s" % qreg.name)
274
+ raise DAGDependencyError(f"duplicate register {qreg.name}")
275
275
  self.qregs[qreg.name] = qreg
276
276
  existing_qubits = set(self.qubits)
277
277
  for j in range(qreg.size):
@@ -288,7 +288,7 @@ class _DAGDependencyV2:
288
288
  if not isinstance(creg, ClassicalRegister):
289
289
  raise DAGDependencyError("not a ClassicalRegister instance.")
290
290
  if creg.name in self.cregs:
291
- raise DAGDependencyError("duplicate register %s" % creg.name)
291
+ raise DAGDependencyError(f"duplicate register {creg.name}")
292
292
  self.cregs[creg.name] = creg
293
293
  existing_clbits = set(self.clbits)
294
294
  for j in range(creg.size):
@@ -83,7 +83,7 @@ class DAGDepNode:
83
83
  def op(self):
84
84
  """Returns the Instruction object corresponding to the op for the node, else None"""
85
85
  if not self.type or self.type != "op":
86
- raise QiskitError("The node %s is not an op node" % (str(self)))
86
+ raise QiskitError(f"The node {str(self)} is not an op node")
87
87
  return self._op
88
88
 
89
89
  @op.setter
@@ -14,14 +14,11 @@
14
14
  """Objects to represent the information at a node in the DAGCircuit."""
15
15
  from __future__ import annotations
16
16
 
17
- import itertools
18
17
  import typing
19
18
  import uuid
20
- from collections.abc import Iterable
21
-
22
19
 
20
+ import qiskit._accelerate.circuit
23
21
  from qiskit.circuit import (
24
- Qubit,
25
22
  Clbit,
26
23
  ClassicalRegister,
27
24
  ControlFlowOp,
@@ -30,7 +27,6 @@ from qiskit.circuit import (
30
27
  SwitchCaseOp,
31
28
  ForLoopOp,
32
29
  Parameter,
33
- Operation,
34
30
  QuantumCircuit,
35
31
  )
36
32
  from qiskit.circuit.classical import expr
@@ -39,6 +35,12 @@ if typing.TYPE_CHECKING:
39
35
  from qiskit.dagcircuit import DAGCircuit
40
36
 
41
37
 
38
+ DAGNode = qiskit._accelerate.circuit.DAGNode
39
+ DAGOpNode = qiskit._accelerate.circuit.DAGOpNode
40
+ DAGInNode = qiskit._accelerate.circuit.DAGInNode
41
+ DAGOutNode = qiskit._accelerate.circuit.DAGOutNode
42
+
43
+
42
44
  def _legacy_condition_eq(cond1, cond2, bit_indices1, bit_indices2) -> bool:
43
45
  if cond1 is cond2 is None:
44
46
  return True
@@ -175,158 +177,65 @@ _SEMANTIC_EQ_CONTROL_FLOW = {
175
177
  _SEMANTIC_EQ_SYMMETRIC = frozenset({"barrier", "swap", "break_loop", "continue_loop"})
176
178
 
177
179
 
178
- class DAGNode:
179
- """Parent class for DAGOpNode, DAGInNode, and DAGOutNode."""
180
-
181
- __slots__ = ["_node_id"]
182
-
183
- def __init__(self, nid=-1):
184
- """Create a node"""
185
- self._node_id = nid
186
-
187
- def __lt__(self, other):
188
- return self._node_id < other._node_id
189
-
190
- def __gt__(self, other):
191
- return self._node_id > other._node_id
192
-
193
- def __str__(self):
194
- # TODO is this used anywhere other than in DAG drawing?
195
- # needs to be unique as it is what pydot uses to distinguish nodes
196
- return str(id(self))
197
-
198
- @staticmethod
199
- def semantic_eq(node1, node2, bit_indices1, bit_indices2):
200
- """
201
- Check if DAG nodes are considered equivalent, e.g., as a node_match for
202
- :func:`rustworkx.is_isomorphic_node_match`.
203
-
204
- Args:
205
- node1 (DAGOpNode, DAGInNode, DAGOutNode): A node to compare.
206
- node2 (DAGOpNode, DAGInNode, DAGOutNode): The other node to compare.
207
- bit_indices1 (dict): Dictionary mapping Bit instances to their index
208
- within the circuit containing node1
209
- bit_indices2 (dict): Dictionary mapping Bit instances to their index
210
- within the circuit containing node2
211
-
212
- Return:
213
- Bool: If node1 == node2
214
- """
215
- if not isinstance(node1, DAGOpNode) or not isinstance(node1, DAGOpNode):
216
- return type(node1) is type(node2) and bit_indices1.get(node1.wire) == bit_indices2.get(
217
- node2.wire
218
- )
219
- if isinstance(node1.op, ControlFlowOp) and isinstance(node2.op, ControlFlowOp):
220
- # While control-flow operations aren't represented natively in the DAG, we have to do
221
- # some unpleasant dispatching and very manual handling. Once they have more first-class
222
- # support we'll still be dispatching, but it'll look more appropriate (like the dispatch
223
- # based on `DAGOpNode`/`DAGInNode`/`DAGOutNode` that already exists) and less like we're
224
- # duplicating code from the `ControlFlowOp` classes.
225
- if type(node1.op) is not type(node2.op):
226
- return False
227
- comparer = _SEMANTIC_EQ_CONTROL_FLOW.get(type(node1.op))
228
- if comparer is None: # pragma: no cover
229
- raise RuntimeError(f"unhandled control-flow operation: {type(node1.op)}")
230
- return comparer(node1, node2, bit_indices1, bit_indices2)
231
-
232
- node1_qargs = [bit_indices1[qarg] for qarg in node1.qargs]
233
- node1_cargs = [bit_indices1[carg] for carg in node1.cargs]
234
-
235
- node2_qargs = [bit_indices2[qarg] for qarg in node2.qargs]
236
- node2_cargs = [bit_indices2[carg] for carg in node2.cargs]
237
-
238
- # For barriers, qarg order is not significant so compare as sets
239
- if node1.op.name == node2.op.name and node1.name in _SEMANTIC_EQ_SYMMETRIC:
240
- node1_qargs = set(node1_qargs)
241
- node1_cargs = set(node1_cargs)
242
- node2_qargs = set(node2_qargs)
243
- node2_cargs = set(node2_cargs)
244
-
245
- return (
246
- node1_qargs == node2_qargs
247
- and node1_cargs == node2_cargs
248
- and _legacy_condition_eq(
249
- getattr(node1.op, "condition", None),
250
- getattr(node2.op, "condition", None),
251
- bit_indices1,
252
- bit_indices2,
253
- )
254
- and node1.op == node2.op
180
+ # Note: called from dag_node.rs.
181
+ def _semantic_eq(node1, node2, bit_indices1, bit_indices2):
182
+ """
183
+ Check if DAG nodes are considered equivalent, e.g., as a node_match for
184
+ :func:`rustworkx.is_isomorphic_node_match`.
185
+
186
+ Args:
187
+ node1 (DAGOpNode, DAGInNode, DAGOutNode): A node to compare.
188
+ node2 (DAGOpNode, DAGInNode, DAGOutNode): The other node to compare.
189
+ bit_indices1 (dict): Dictionary mapping Bit instances to their index
190
+ within the circuit containing node1
191
+ bit_indices2 (dict): Dictionary mapping Bit instances to their index
192
+ within the circuit containing node2
193
+
194
+ Return:
195
+ Bool: If node1 == node2
196
+ """
197
+ if not isinstance(node1, DAGOpNode) or not isinstance(node1, DAGOpNode):
198
+ return type(node1) is type(node2) and bit_indices1.get(node1.wire) == bit_indices2.get(
199
+ node2.wire
255
200
  )
201
+ if isinstance(node1.op, ControlFlowOp) and isinstance(node2.op, ControlFlowOp):
202
+ # While control-flow operations aren't represented natively in the DAG, we have to do
203
+ # some unpleasant dispatching and very manual handling. Once they have more first-class
204
+ # support we'll still be dispatching, but it'll look more appropriate (like the dispatch
205
+ # based on `DAGOpNode`/`DAGInNode`/`DAGOutNode` that already exists) and less like we're
206
+ # duplicating code from the `ControlFlowOp` classes.
207
+ if type(node1.op) is not type(node2.op):
208
+ return False
209
+ comparer = _SEMANTIC_EQ_CONTROL_FLOW.get(type(node1.op))
210
+ if comparer is None: # pragma: no cover
211
+ raise RuntimeError(f"unhandled control-flow operation: {type(node1.op)}")
212
+ return comparer(node1, node2, bit_indices1, bit_indices2)
213
+
214
+ node1_qargs = [bit_indices1[qarg] for qarg in node1.qargs]
215
+ node1_cargs = [bit_indices1[carg] for carg in node1.cargs]
216
+
217
+ node2_qargs = [bit_indices2[qarg] for qarg in node2.qargs]
218
+ node2_cargs = [bit_indices2[carg] for carg in node2.cargs]
219
+
220
+ # For barriers, qarg order is not significant so compare as sets
221
+ if node1.op.name == node2.op.name and node1.name in _SEMANTIC_EQ_SYMMETRIC:
222
+ node1_qargs = set(node1_qargs)
223
+ node1_cargs = set(node1_cargs)
224
+ node2_qargs = set(node2_qargs)
225
+ node2_cargs = set(node2_cargs)
226
+
227
+ return (
228
+ node1_qargs == node2_qargs
229
+ and node1_cargs == node2_cargs
230
+ and _legacy_condition_eq(
231
+ getattr(node1.op, "condition", None),
232
+ getattr(node2.op, "condition", None),
233
+ bit_indices1,
234
+ bit_indices2,
235
+ )
236
+ and node1.op == node2.op
237
+ )
256
238
 
257
239
 
258
- class DAGOpNode(DAGNode):
259
- """Object to represent an Instruction at a node in the DAGCircuit."""
260
-
261
- __slots__ = ["op", "qargs", "cargs", "sort_key"]
262
-
263
- def __init__(
264
- self, op: Operation, qargs: Iterable[Qubit] = (), cargs: Iterable[Clbit] = (), dag=None
265
- ):
266
- """Create an Instruction node"""
267
- super().__init__()
268
- self.op = op
269
- self.qargs = tuple(qargs)
270
- self.cargs = tuple(cargs)
271
- if dag is not None:
272
- cache_key = (self.qargs, self.cargs)
273
- key = dag._key_cache.get(cache_key, None)
274
- if key is not None:
275
- self.sort_key = key
276
- else:
277
- self.sort_key = ",".join(
278
- f"{dag.find_bit(q).index:04d}" for q in itertools.chain(*cache_key)
279
- )
280
- dag._key_cache[cache_key] = self.sort_key
281
- else:
282
- self.sort_key = str(self.qargs)
283
-
284
- @property
285
- def name(self):
286
- """Returns the Instruction name corresponding to the op for this node"""
287
- return self.op.name
288
-
289
- @name.setter
290
- def name(self, new_name):
291
- """Sets the Instruction name corresponding to the op for this node"""
292
- self.op.name = new_name
293
-
294
- def __repr__(self):
295
- """Returns a representation of the DAGOpNode"""
296
- return f"DAGOpNode(op={self.op}, qargs={self.qargs}, cargs={self.cargs})"
297
-
298
-
299
- class DAGInNode(DAGNode):
300
- """Object to represent an incoming wire node in the DAGCircuit."""
301
-
302
- __slots__ = ["wire", "sort_key"]
303
-
304
- def __init__(self, wire):
305
- """Create an incoming node"""
306
- super().__init__()
307
- self.wire = wire
308
- # TODO sort_key which is used in dagcircuit.topological_nodes
309
- # only works as str([]) for DAGInNodes. Need to figure out why.
310
- self.sort_key = str([])
311
-
312
- def __repr__(self):
313
- """Returns a representation of the DAGInNode"""
314
- return f"DAGInNode(wire={self.wire})"
315
-
316
-
317
- class DAGOutNode(DAGNode):
318
- """Object to represent an outgoing wire node in the DAGCircuit."""
319
-
320
- __slots__ = ["wire", "sort_key"]
321
-
322
- def __init__(self, wire):
323
- """Create an outgoing node"""
324
- super().__init__()
325
- self.wire = wire
326
- # TODO sort_key which is used in dagcircuit.topological_nodes
327
- # only works as str([]) for DAGOutNodes. Need to figure out why.
328
- self.sort_key = str([])
329
-
330
- def __repr__(self):
331
- """Returns a representation of the DAGOutNode"""
332
- return f"DAGOutNode(wire={self.wire})"
240
+ # Bind semantic_eq from Python to Rust implementation
241
+ DAGNode.semantic_eq = staticmethod(_semantic_eq)
@@ -84,7 +84,7 @@ class DoWhileController(BaseController):
84
84
  return
85
85
  # Remove stored tasks from the completed task collection for next loop
86
86
  state.workflow_status.completed_passes.difference_update(self.tasks)
87
- raise PassManagerError("Maximum iteration reached. max_iteration=%i" % max_iteration)
87
+ raise PassManagerError(f"Maximum iteration reached. max_iteration={max_iteration}")
88
88
 
89
89
 
90
90
  class ConditionalController(BaseController):
@@ -130,7 +130,7 @@ class BasePassManager(ABC):
130
130
  return new_passmanager
131
131
  except PassManagerError as ex:
132
132
  raise TypeError(
133
- "unsupported operand type + for %s and %s" % (self.__class__, other.__class__)
133
+ f"unsupported operand type + for {self.__class__} and {other.__class__}"
134
134
  ) from ex
135
135
 
136
136
  @abstractmethod
@@ -225,7 +225,7 @@ class BasePassManager(ABC):
225
225
  in_programs = [in_programs]
226
226
  is_list = False
227
227
 
228
- # If we're not going to run in parallel, we want to avoid spending time `dill` serialising
228
+ # If we're not going to run in parallel, we want to avoid spending time `dill` serializing
229
229
  # ourselves, since that can be quite expensive.
230
230
  if len(in_programs) == 1 or not should_run_in_parallel(num_processes):
231
231
  out = [
@@ -242,7 +242,7 @@ class BasePassManager(ABC):
242
242
  # Pass manager may contain callable and we need to serialize through dill rather than pickle.
243
243
  # See https://github.com/Qiskit/qiskit-terra/pull/3290
244
244
  # Note that serialized object is deserialized as a different object.
245
- # Thus, we can resue the same manager without state collision, without building it per thread.
245
+ # Thus, we can reuse the same manager without state collision, without building it per thread.
246
246
  return parallel_map(
247
247
  _run_workflow_in_new_process,
248
248
  values=in_programs,
@@ -420,7 +420,6 @@ Results V2
420
420
  SamplerPubResult
421
421
  BasePrimitiveJob
422
422
  PrimitiveJob
423
- Shaped
424
423
 
425
424
  Estimator V1
426
425
  ------------
@@ -466,16 +465,13 @@ from .containers import (
466
465
  DataBin,
467
466
  PrimitiveResult,
468
467
  PubResult,
469
- SamplerPubResult,
470
468
  EstimatorPubLike,
471
469
  SamplerPubLike,
470
+ SamplerPubResult,
472
471
  BindingsArrayLike,
473
472
  ObservableLike,
474
473
  ObservablesArrayLike,
475
- Shaped,
476
474
  )
477
-
478
-
479
475
  from .estimator import Estimator
480
476
  from .primitive_job import BasePrimitiveJob, PrimitiveJob
481
477
  from .sampler import Sampler
@@ -9,9 +9,8 @@
9
9
  # Any modifications or derivative works of this code must retain this
10
10
  # copyright notice, and modified files need to carry a notice indicating
11
11
  # that they have been altered from the originals.
12
- """
13
- Expectation value class
14
- """
12
+
13
+ """Estimator V1 implementation for an arbitrary Backend object."""
15
14
 
16
15
  from __future__ import annotations
17
16
 
@@ -35,6 +34,7 @@ from qiskit.transpiler.passes import (
35
34
  Optimize1qGatesDecomposition,
36
35
  SetLayout,
37
36
  )
37
+ from qiskit.utils.deprecation import deprecate_func
38
38
 
39
39
  from .base import BaseEstimator, EstimatorResult
40
40
  from .primitive_job import PrimitiveJob
@@ -65,6 +65,8 @@ def _run_circuits(
65
65
  max_circuits = getattr(backend.configuration(), "max_experiments", None)
66
66
  elif isinstance(backend, BackendV2):
67
67
  max_circuits = backend.max_circuits
68
+ else:
69
+ raise RuntimeError("Backend version not supported")
68
70
  if max_circuits:
69
71
  jobs = [
70
72
  backend.run(circuits[pos : pos + max_circuits], **run_options)
@@ -90,18 +92,26 @@ class BackendEstimator(BaseEstimator[PrimitiveJob[EstimatorResult]]):
90
92
  """Evaluates expectation value using Pauli rotation gates.
91
93
 
92
94
  The :class:`~.BackendEstimator` class is a generic implementation of the
93
- :class:`~.BaseEstimator` interface that is used to wrap a :class:`~.BackendV2`
94
- (or :class:`~.BackendV1`) object in the :class:`~.BaseEstimator` API. It
95
+ :class:`~.BaseEstimator` (V1) interface that is used to wrap a :class:`~.BackendV2`
96
+ (or :class:`~.BackendV1`) object in the :class:`~.BaseEstimator` V1 API. It
95
97
  facilitates using backends that do not provide a native
96
- :class:`~.BaseEstimator` implementation in places that work with
97
- :class:`~.BaseEstimator`. However,
98
- if you're using a provider that has a native implementation of
99
- :class:`~.BaseEstimator`, it is a better choice to leverage that native
100
- implementation as it will likely include additional optimizations and be
101
- a more efficient implementation. The generic nature of this class
102
- precludes doing any provider- or backend-specific optimizations.
98
+ :class:`~.BaseEstimator` V1 implementation in places that work with
99
+ :class:`~.BaseEstimator` V1.
100
+ However, if you're using a provider that has a native implementation of
101
+ :class:`~.BaseEstimatorV1` ( :class:`~.BaseEstimator`) or
102
+ :class:`~.BaseEstimatorV2`, it is a better
103
+ choice to leverage that native implementation as it will likely include
104
+ additional optimizations and be a more efficient implementation.
105
+ The generic nature of this class precludes doing any provider- or
106
+ backend-specific optimizations.
103
107
  """
104
108
 
109
+ @deprecate_func(
110
+ since="1.2",
111
+ additional_msg="All implementations of the `BaseEstimatorV1` interface "
112
+ "have been deprecated in favor of their V2 counterparts. "
113
+ "The V2 alternative for the `BackendEstimator` class is `BackendEstimatorV2`.",
114
+ )
105
115
  def __init__(
106
116
  self,
107
117
  backend: BackendV1 | BackendV2,
@@ -110,10 +120,10 @@ class BackendEstimator(BaseEstimator[PrimitiveJob[EstimatorResult]]):
110
120
  bound_pass_manager: PassManager | None = None,
111
121
  skip_transpilation: bool = False,
112
122
  ):
113
- """Initialize a new BackendEstimator instance
123
+ """Initialize a new BackendEstimator (V1) instance
114
124
 
115
125
  Args:
116
- backend: Required: the backend to run the primitive on
126
+ backend: (required) the backend to run the primitive on
117
127
  options: Default options.
118
128
  abelian_grouping: Whether the observable should be grouped into
119
129
  commuting
@@ -198,7 +208,7 @@ class BackendEstimator(BaseEstimator[PrimitiveJob[EstimatorResult]]):
198
208
  transpiled_circuit = common_circuit.copy()
199
209
  final_index_layout = list(range(common_circuit.num_qubits))
200
210
  else:
201
- transpiled_circuit = transpile(
211
+ transpiled_circuit = transpile( # pylint:disable=unexpected-keyword-arg
202
212
  common_circuit, self.backend, **self.transpile_options.__dict__
203
213
  )
204
214
  if transpiled_circuit.layout is not None:
@@ -72,7 +72,7 @@ class _PreprocessedData:
72
72
 
73
73
 
74
74
  class BackendEstimatorV2(BaseEstimatorV2):
75
- """Evaluates expectation values for provided quantum circuit and observable combinations
75
+ r"""Evaluates expectation values for provided quantum circuit and observable combinations.
76
76
 
77
77
  The :class:`~.BackendEstimatorV2` class is a generic implementation of the
78
78
  :class:`~.BaseEstimatorV2` interface that is used to wrap a :class:`~.BackendV2`
@@ -87,7 +87,19 @@ class BackendEstimatorV2(BaseEstimatorV2):
87
87
  precludes doing any provider- or backend-specific optimizations.
88
88
 
89
89
  This class does not perform any measurement or gate mitigation, and, presently, is only
90
- compatible with Pauli-based observables.
90
+ compatible with Pauli-based observables. More formally, given an observable of the type
91
+ :math:`O=\sum_{i=1}^Na_iP_i`, where :math:`a_i` is a complex number and :math:`P_i` is a
92
+ Pauli operator, the estimator calculates the expectation :math:`\mathbb{E}(P_i)` of each
93
+ :math:`P_i` and finally calculates the expectation value of :math:`O` as
94
+ :math:`\mathbb{E}(O)=\sum_{i=1}^Na_i\mathbb{E}(P_i)`. The reported ``std`` is calculated
95
+ as
96
+
97
+ .. math::
98
+
99
+ \frac{\sum_{i=1}^{n}|a_i|\sqrt{\textrm{Var}\big(P_i\big)}}{\sqrt{N}}\:,
100
+
101
+ where :math:`\textrm{Var}(P_i)` is the variance of :math:`P_i`, :math:`N=O(\epsilon^{-2})` is
102
+ the number of shots, and :math:`\epsilon` is the target precision [1].
91
103
 
92
104
  Each tuple of ``(circuit, observables, <optional> parameter values, <optional> precision)``,
93
105
  called an estimator primitive unified bloc (PUB), produces its own array-based result. The
@@ -104,6 +116,12 @@ class BackendEstimatorV2(BaseEstimatorV2):
104
116
 
105
117
  * ``seed_simulator``: The seed to use in the simulator. If None, a random seed will be used.
106
118
  Default: None.
119
+
120
+ **Reference:**
121
+
122
+ [1] O. Crawford, B. van Straaten, D. Wang, T. Parks, E. Campbell, St. Brierley,
123
+ Efficient quantum measurement of Pauli operators in the presence of finite sampling error.
124
+ `Quantum 5, 385 <https://doi.org/10.22331/q-2021-01-20-385>`_
107
125
  """
108
126
 
109
127
  def __init__(
@@ -172,7 +190,7 @@ class BackendEstimatorV2(BaseEstimatorV2):
172
190
  # reconstruct the result of pubs
173
191
  for i, pub_result in zip(lst, pub_results):
174
192
  results[i] = pub_result
175
- return PrimitiveResult(results)
193
+ return PrimitiveResult(results, metadata={"version": 2})
176
194
 
177
195
  def _run_pubs(self, pubs: list[EstimatorPub], shots: int) -> list[PubResult]:
178
196
  """Compute results for pubs that all require the same value of ``shots``."""
@@ -220,7 +238,6 @@ class BackendEstimatorV2(BaseEstimatorV2):
220
238
  param_indices = np.fromiter(np.ndindex(param_shape), dtype=object).reshape(param_shape)
221
239
  bc_param_ind, bc_obs = np.broadcast_arrays(param_indices, observables)
222
240
 
223
- # calculate expectation values for each pair of parameter value set and pauli
224
241
  param_obs_map = defaultdict(set)
225
242
  for index in np.ndindex(*bc_param_ind.shape):
226
243
  param_index = bc_param_ind[index]
@@ -254,10 +271,17 @@ class BackendEstimatorV2(BaseEstimatorV2):
254
271
  for pauli, coeff in bc_obs[index].items():
255
272
  expval, variance = expval_map[param_index, pauli]
256
273
  evs[index] += expval * coeff
257
- variances[index] += variance * coeff**2
258
- stds = np.sqrt(variances / shots)
274
+ variances[index] += np.abs(coeff) * variance**0.5
275
+ stds = variances / np.sqrt(shots)
259
276
  data_bin = DataBin(evs=evs, stds=stds, shape=evs.shape)
260
- return PubResult(data_bin, metadata={"target_precision": pub.precision})
277
+ return PubResult(
278
+ data_bin,
279
+ metadata={
280
+ "target_precision": pub.precision,
281
+ "shots": shots,
282
+ "circuit_metadata": pub.circuit.metadata,
283
+ },
284
+ )
261
285
 
262
286
  def _bind_and_add_measurements(
263
287
  self,
@@ -10,7 +10,7 @@
10
10
  # copyright notice, and modified files need to carry a notice indicating
11
11
  # that they have been altered from the originals.
12
12
 
13
- """Sampler implementation for an arbitrary Backend object."""
13
+ """Sampler V1 implementation for an arbitrary Backend object."""
14
14
 
15
15
  from __future__ import annotations
16
16
 
@@ -23,6 +23,7 @@ from qiskit.providers.backend import BackendV1, BackendV2
23
23
  from qiskit.providers.options import Options
24
24
  from qiskit.result import QuasiDistribution, Result
25
25
  from qiskit.transpiler.passmanager import PassManager
26
+ from qiskit.utils.deprecation import deprecate_func
26
27
 
27
28
  from .backend_estimator import _prepare_counts, _run_circuits
28
29
  from .base import BaseSampler, SamplerResult
@@ -31,21 +32,29 @@ from .utils import _circuit_key
31
32
 
32
33
 
33
34
  class BackendSampler(BaseSampler[PrimitiveJob[SamplerResult]]):
34
- """A :class:`~.BaseSampler` implementation that provides an interface for
35
- leveraging the sampler interface from any backend.
35
+ """A :class:`~.BaseSampler` (V1) implementation that provides a wrapper for
36
+ leveraging the Sampler V1 interface from any backend.
36
37
 
37
38
  This class provides a sampler interface from any backend and doesn't do
38
39
  any measurement mitigation, it just computes the probability distribution
39
40
  from the counts. It facilitates using backends that do not provide a
40
- native :class:`~.BaseSampler` implementation in places that work with
41
- :class:`~.BaseSampler`.
41
+ native :class:`~.BaseSampler` V1 implementation in places that work with
42
+ :class:`~.BaseSampler` V1.
42
43
  However, if you're using a provider that has a native implementation of
43
- :class:`~.BaseSampler`, it is a better choice to leverage that native
44
- implementation as it will likely include additional optimizations and be
45
- a more efficient implementation. The generic nature of this class
46
- precludes doing any provider- or backend-specific optimizations.
44
+ :class:`~.BaseSamplerV1` ( :class:`~.BaseSampler`) or
45
+ :class:`~.BaseESamplerV2`, it is a better
46
+ choice to leverage that native implementation as it will likely include
47
+ additional optimizations and be a more efficient implementation.
48
+ The generic nature of this class precludes doing any provider- or
49
+ backend-specific optimizations.
47
50
  """
48
51
 
52
+ @deprecate_func(
53
+ since="1.2",
54
+ additional_msg="All implementations of the `BaseSamplerV1` interface "
55
+ "have been deprecated in favor of their V2 counterparts. "
56
+ "The V2 alternative for the `BackendSampler` class is `BackendSamplerV2`.",
57
+ )
49
58
  def __init__(
50
59
  self,
51
60
  backend: BackendV1 | BackendV2,
@@ -53,10 +62,10 @@ class BackendSampler(BaseSampler[PrimitiveJob[SamplerResult]]):
53
62
  bound_pass_manager: PassManager | None = None,
54
63
  skip_transpilation: bool = False,
55
64
  ):
56
- """Initialize a new BackendSampler
65
+ """Initialize a new BackendSampler (V1) instance
57
66
 
58
67
  Args:
59
- backend: Required: the backend to run the sampler primitive on
68
+ backend: (required) the backend to run the sampler primitive on
60
69
  options: Default options.
61
70
  bound_pass_manager: An optional pass manager to run after
62
71
  parameter binding.
@@ -176,7 +185,7 @@ class BackendSampler(BaseSampler[PrimitiveJob[SamplerResult]]):
176
185
 
177
186
  start = len(self._transpiled_circuits)
178
187
  self._transpiled_circuits.extend(
179
- transpile(
188
+ transpile( # pylint:disable=unexpected-keyword-arg
180
189
  self.preprocessed_circuits[start:],
181
190
  self.backend,
182
191
  **self.transpile_options.__dict__,