qiskit 1.3.0b1__cp39-abi3-win32.whl → 1.3.0rc2__cp39-abi3-win32.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 (360) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +20 -1
  3. qiskit/_accelerate.pyd +0 -0
  4. qiskit/assembler/assemble_schedules.py +2 -0
  5. qiskit/circuit/__init__.py +44 -1
  6. qiskit/circuit/_standard_gates_commutations.py +585 -0
  7. qiskit/circuit/barrier.py +2 -0
  8. qiskit/circuit/controlflow/builder.py +3 -3
  9. qiskit/circuit/controlflow/if_else.py +13 -5
  10. qiskit/circuit/controlflow/while_loop.py +10 -2
  11. qiskit/circuit/delay.py +20 -3
  12. qiskit/circuit/equivalence.py +13 -214
  13. qiskit/circuit/gate.py +3 -1
  14. qiskit/circuit/instruction.py +32 -11
  15. qiskit/circuit/instructionset.py +2 -0
  16. qiskit/circuit/library/__init__.py +110 -14
  17. qiskit/circuit/library/arithmetic/__init__.py +9 -2
  18. qiskit/circuit/library/arithmetic/adders/__init__.py +1 -0
  19. qiskit/circuit/library/arithmetic/adders/adder.py +154 -2
  20. qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +20 -56
  21. qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +14 -1
  22. qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +21 -91
  23. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +1 -1
  24. qiskit/circuit/library/arithmetic/multipliers/__init__.py +1 -0
  25. qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +8 -1
  26. qiskit/circuit/library/arithmetic/multipliers/multiplier.py +94 -3
  27. qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +8 -1
  28. qiskit/circuit/library/arithmetic/weighted_adder.py +1 -1
  29. qiskit/circuit/library/basis_change/qft.py +20 -38
  30. qiskit/circuit/library/blueprintcircuit.py +64 -0
  31. qiskit/circuit/library/boolean_logic/__init__.py +4 -4
  32. qiskit/circuit/library/boolean_logic/inner_product.py +81 -4
  33. qiskit/circuit/library/boolean_logic/quantum_and.py +107 -4
  34. qiskit/circuit/library/boolean_logic/quantum_or.py +107 -3
  35. qiskit/circuit/library/boolean_logic/quantum_xor.py +97 -3
  36. qiskit/circuit/library/data_preparation/__init__.py +6 -3
  37. qiskit/circuit/library/data_preparation/{z_feature_map.py → _z_feature_map.py} +45 -34
  38. qiskit/circuit/library/data_preparation/_zz_feature_map.py +150 -0
  39. qiskit/circuit/library/data_preparation/pauli_feature_map.py +342 -29
  40. qiskit/circuit/library/fourier_checking.py +72 -11
  41. qiskit/circuit/library/generalized_gates/__init__.py +1 -1
  42. qiskit/circuit/library/generalized_gates/diagonal.py +45 -51
  43. qiskit/circuit/library/generalized_gates/gms.py +67 -14
  44. qiskit/circuit/library/generalized_gates/gr.py +4 -4
  45. qiskit/circuit/library/generalized_gates/isometry.py +2 -2
  46. qiskit/circuit/library/generalized_gates/linear_function.py +12 -6
  47. qiskit/circuit/library/generalized_gates/mcmt.py +167 -107
  48. qiskit/circuit/library/generalized_gates/permutation.py +8 -6
  49. qiskit/circuit/library/generalized_gates/rv.py +8 -9
  50. qiskit/circuit/library/graph_state.py +93 -10
  51. qiskit/circuit/library/grover_operator.py +270 -2
  52. qiskit/circuit/library/hidden_linear_function.py +83 -20
  53. qiskit/circuit/library/iqp.py +99 -20
  54. qiskit/circuit/library/n_local/__init__.py +19 -7
  55. qiskit/circuit/library/n_local/efficient_su2.py +118 -5
  56. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +259 -0
  57. qiskit/circuit/library/n_local/excitation_preserving.py +130 -6
  58. qiskit/circuit/library/n_local/n_local.py +406 -5
  59. qiskit/circuit/library/n_local/pauli_two_design.py +106 -4
  60. qiskit/circuit/library/n_local/qaoa_ansatz.py +80 -1
  61. qiskit/circuit/library/n_local/real_amplitudes.py +127 -7
  62. qiskit/circuit/library/n_local/two_local.py +14 -7
  63. qiskit/circuit/library/overlap.py +91 -26
  64. qiskit/circuit/library/pauli_evolution.py +17 -15
  65. qiskit/circuit/library/phase_estimation.py +80 -4
  66. qiskit/circuit/library/quantum_volume.py +72 -20
  67. qiskit/circuit/library/standard_gates/__init__.py +20 -1
  68. qiskit/circuit/library/standard_gates/dcx.py +2 -1
  69. qiskit/circuit/library/standard_gates/ecr.py +2 -2
  70. qiskit/circuit/library/standard_gates/h.py +4 -3
  71. qiskit/circuit/library/standard_gates/i.py +2 -1
  72. qiskit/circuit/library/standard_gates/iswap.py +2 -2
  73. qiskit/circuit/library/standard_gates/p.py +20 -12
  74. qiskit/circuit/library/standard_gates/r.py +1 -1
  75. qiskit/circuit/library/standard_gates/rx.py +4 -3
  76. qiskit/circuit/library/standard_gates/rxx.py +2 -2
  77. qiskit/circuit/library/standard_gates/ry.py +4 -3
  78. qiskit/circuit/library/standard_gates/ryy.py +2 -2
  79. qiskit/circuit/library/standard_gates/rz.py +13 -12
  80. qiskit/circuit/library/standard_gates/rzx.py +6 -6
  81. qiskit/circuit/library/standard_gates/rzz.py +1 -1
  82. qiskit/circuit/library/standard_gates/s.py +4 -4
  83. qiskit/circuit/library/standard_gates/swap.py +3 -3
  84. qiskit/circuit/library/standard_gates/sx.py +4 -3
  85. qiskit/circuit/library/standard_gates/t.py +2 -2
  86. qiskit/circuit/library/standard_gates/u.py +11 -3
  87. qiskit/circuit/library/standard_gates/u1.py +65 -15
  88. qiskit/circuit/library/standard_gates/u2.py +4 -1
  89. qiskit/circuit/library/standard_gates/u3.py +31 -3
  90. qiskit/circuit/library/standard_gates/x.py +7 -5
  91. qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -2
  92. qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -2
  93. qiskit/circuit/library/standard_gates/y.py +4 -3
  94. qiskit/circuit/library/standard_gates/z.py +3 -3
  95. qiskit/circuit/library/templates/clifford/clifford_2_1.py +9 -8
  96. qiskit/circuit/library/templates/clifford/clifford_2_2.py +10 -9
  97. qiskit/circuit/library/templates/clifford/clifford_2_3.py +9 -7
  98. qiskit/circuit/library/templates/clifford/clifford_2_4.py +9 -8
  99. qiskit/circuit/library/templates/clifford/clifford_3_1.py +9 -8
  100. qiskit/circuit/library/templates/clifford/clifford_4_1.py +10 -9
  101. qiskit/circuit/library/templates/clifford/clifford_4_2.py +10 -9
  102. qiskit/circuit/library/templates/clifford/clifford_4_3.py +10 -9
  103. qiskit/circuit/library/templates/clifford/clifford_4_4.py +10 -9
  104. qiskit/circuit/library/templates/clifford/clifford_5_1.py +10 -9
  105. qiskit/circuit/library/templates/clifford/clifford_6_1.py +10 -9
  106. qiskit/circuit/library/templates/clifford/clifford_6_2.py +10 -9
  107. qiskit/circuit/library/templates/clifford/clifford_6_3.py +10 -9
  108. qiskit/circuit/library/templates/clifford/clifford_6_4.py +9 -8
  109. qiskit/circuit/library/templates/clifford/clifford_6_5.py +10 -9
  110. qiskit/circuit/library/templates/clifford/clifford_8_1.py +10 -9
  111. qiskit/circuit/library/templates/clifford/clifford_8_2.py +10 -9
  112. qiskit/circuit/library/templates/clifford/clifford_8_3.py +10 -9
  113. qiskit/circuit/library/templates/nct/template_nct_2a_1.py +9 -7
  114. qiskit/circuit/library/templates/nct/template_nct_2a_2.py +10 -8
  115. qiskit/circuit/library/templates/nct/template_nct_2a_3.py +12 -10
  116. qiskit/circuit/library/templates/nct/template_nct_4a_1.py +16 -14
  117. qiskit/circuit/library/templates/nct/template_nct_4a_2.py +14 -12
  118. qiskit/circuit/library/templates/nct/template_nct_4a_3.py +12 -10
  119. qiskit/circuit/library/templates/nct/template_nct_4b_1.py +14 -12
  120. qiskit/circuit/library/templates/nct/template_nct_4b_2.py +12 -10
  121. qiskit/circuit/library/templates/nct/template_nct_5a_1.py +12 -10
  122. qiskit/circuit/library/templates/nct/template_nct_5a_2.py +12 -10
  123. qiskit/circuit/library/templates/nct/template_nct_5a_3.py +12 -10
  124. qiskit/circuit/library/templates/nct/template_nct_5a_4.py +11 -9
  125. qiskit/circuit/library/templates/nct/template_nct_6a_1.py +11 -9
  126. qiskit/circuit/library/templates/nct/template_nct_6a_2.py +12 -10
  127. qiskit/circuit/library/templates/nct/template_nct_6a_3.py +12 -10
  128. qiskit/circuit/library/templates/nct/template_nct_6a_4.py +12 -10
  129. qiskit/circuit/library/templates/nct/template_nct_6b_1.py +12 -10
  130. qiskit/circuit/library/templates/nct/template_nct_6b_2.py +12 -10
  131. qiskit/circuit/library/templates/nct/template_nct_6c_1.py +12 -10
  132. qiskit/circuit/library/templates/nct/template_nct_7a_1.py +13 -11
  133. qiskit/circuit/library/templates/nct/template_nct_7b_1.py +13 -11
  134. qiskit/circuit/library/templates/nct/template_nct_7c_1.py +13 -11
  135. qiskit/circuit/library/templates/nct/template_nct_7d_1.py +13 -11
  136. qiskit/circuit/library/templates/nct/template_nct_7e_1.py +13 -11
  137. qiskit/circuit/library/templates/nct/template_nct_9a_1.py +13 -11
  138. qiskit/circuit/library/templates/nct/template_nct_9c_1.py +11 -9
  139. qiskit/circuit/library/templates/nct/template_nct_9c_10.py +12 -10
  140. qiskit/circuit/library/templates/nct/template_nct_9c_11.py +12 -10
  141. qiskit/circuit/library/templates/nct/template_nct_9c_12.py +12 -10
  142. qiskit/circuit/library/templates/nct/template_nct_9c_2.py +12 -10
  143. qiskit/circuit/library/templates/nct/template_nct_9c_3.py +12 -10
  144. qiskit/circuit/library/templates/nct/template_nct_9c_4.py +12 -10
  145. qiskit/circuit/library/templates/nct/template_nct_9c_5.py +12 -10
  146. qiskit/circuit/library/templates/nct/template_nct_9c_6.py +12 -10
  147. qiskit/circuit/library/templates/nct/template_nct_9c_7.py +12 -10
  148. qiskit/circuit/library/templates/nct/template_nct_9c_8.py +12 -10
  149. qiskit/circuit/library/templates/nct/template_nct_9c_9.py +12 -10
  150. qiskit/circuit/library/templates/nct/template_nct_9d_1.py +11 -9
  151. qiskit/circuit/library/templates/nct/template_nct_9d_10.py +12 -10
  152. qiskit/circuit/library/templates/nct/template_nct_9d_2.py +12 -10
  153. qiskit/circuit/library/templates/nct/template_nct_9d_3.py +12 -10
  154. qiskit/circuit/library/templates/nct/template_nct_9d_4.py +12 -10
  155. qiskit/circuit/library/templates/nct/template_nct_9d_5.py +12 -10
  156. qiskit/circuit/library/templates/nct/template_nct_9d_6.py +12 -10
  157. qiskit/circuit/library/templates/nct/template_nct_9d_7.py +12 -10
  158. qiskit/circuit/library/templates/nct/template_nct_9d_8.py +12 -10
  159. qiskit/circuit/library/templates/nct/template_nct_9d_9.py +12 -10
  160. qiskit/circuit/library/templates/rzx/rzx_cy.py +11 -10
  161. qiskit/circuit/library/templates/rzx/rzx_xz.py +16 -15
  162. qiskit/circuit/library/templates/rzx/rzx_yz.py +12 -10
  163. qiskit/circuit/library/templates/rzx/rzx_zz1.py +22 -20
  164. qiskit/circuit/library/templates/rzx/rzx_zz2.py +16 -15
  165. qiskit/circuit/library/templates/rzx/rzx_zz3.py +17 -15
  166. qiskit/circuit/parameter.py +4 -0
  167. qiskit/circuit/parameterexpression.py +167 -34
  168. qiskit/circuit/quantumcircuit.py +162 -126
  169. qiskit/circuit/singleton.py +2 -0
  170. qiskit/circuit/store.py +2 -0
  171. qiskit/circuit/twirling.py +145 -0
  172. qiskit/compiler/assembler.py +17 -4
  173. qiskit/compiler/scheduler.py +2 -0
  174. qiskit/compiler/sequencer.py +2 -0
  175. qiskit/compiler/transpiler.py +81 -26
  176. qiskit/converters/circuit_to_dag.py +2 -2
  177. qiskit/converters/circuit_to_dagdependency.py +1 -1
  178. qiskit/converters/circuit_to_dagdependency_v2.py +1 -1
  179. qiskit/converters/circuit_to_instruction.py +1 -1
  180. qiskit/converters/dag_to_circuit.py +7 -5
  181. qiskit/converters/dag_to_dagdependency.py +1 -1
  182. qiskit/converters/dag_to_dagdependency_v2.py +1 -1
  183. qiskit/converters/dagdependency_to_circuit.py +5 -1
  184. qiskit/converters/dagdependency_to_dag.py +6 -1
  185. qiskit/dagcircuit/collect_blocks.py +3 -3
  186. qiskit/dagcircuit/dagdependency.py +18 -5
  187. qiskit/dagcircuit/dagdependency_v2.py +1 -1
  188. qiskit/dagcircuit/dagnode.py +2 -2
  189. qiskit/passmanager/__init__.py +2 -2
  190. qiskit/primitives/backend_estimator.py +5 -2
  191. qiskit/primitives/backend_sampler_v2.py +61 -18
  192. qiskit/primitives/base/base_estimator.py +2 -2
  193. qiskit/primitives/containers/data_bin.py +9 -1
  194. qiskit/primitives/statevector_sampler.py +1 -1
  195. qiskit/primitives/utils.py +1 -1
  196. qiskit/providers/__init__.py +3 -3
  197. qiskit/providers/backend.py +12 -1
  198. qiskit/providers/backend_compat.py +23 -3
  199. qiskit/providers/basic_provider/basic_simulator.py +12 -2
  200. qiskit/providers/fake_provider/fake_pulse_backend.py +6 -1
  201. qiskit/providers/fake_provider/generic_backend_v2.py +46 -30
  202. qiskit/providers/models/pulsedefaults.py +2 -0
  203. qiskit/pulse/builder.py +59 -18
  204. qiskit/pulse/calibration_entries.py +4 -1
  205. qiskit/pulse/channels.py +2 -0
  206. qiskit/pulse/exceptions.py +2 -0
  207. qiskit/pulse/instruction_schedule_map.py +21 -6
  208. qiskit/pulse/instructions/acquire.py +2 -0
  209. qiskit/pulse/instructions/delay.py +2 -0
  210. qiskit/pulse/instructions/directives.py +8 -0
  211. qiskit/pulse/instructions/frequency.py +3 -0
  212. qiskit/pulse/instructions/instruction.py +2 -0
  213. qiskit/pulse/instructions/phase.py +3 -0
  214. qiskit/pulse/instructions/play.py +2 -0
  215. qiskit/pulse/instructions/reference.py +2 -0
  216. qiskit/pulse/instructions/snapshot.py +2 -0
  217. qiskit/pulse/library/pulse.py +2 -0
  218. qiskit/pulse/library/symbolic_pulses.py +28 -0
  219. qiskit/pulse/library/waveform.py +2 -0
  220. qiskit/pulse/macros.py +1 -1
  221. qiskit/pulse/schedule.py +12 -13
  222. qiskit/pulse/transforms/alignments.py +5 -3
  223. qiskit/pulse/transforms/dag.py +7 -0
  224. qiskit/qasm2/export.py +5 -3
  225. qiskit/qasm2/parse.py +46 -2
  226. qiskit/qasm3/__init__.py +1 -0
  227. qiskit/qasm3/ast.py +123 -15
  228. qiskit/qasm3/exporter.py +103 -77
  229. qiskit/qobj/converters/pulse_instruction.py +6 -4
  230. qiskit/qpy/__init__.py +181 -0
  231. qiskit/qpy/binary_io/circuits.py +20 -5
  232. qiskit/qpy/binary_io/schedules.py +3 -4
  233. qiskit/qpy/binary_io/value.py +310 -13
  234. qiskit/qpy/common.py +46 -2
  235. qiskit/qpy/formats.py +7 -0
  236. qiskit/qpy/interface.py +40 -4
  237. qiskit/quantum_info/__init__.py +4 -0
  238. qiskit/quantum_info/operators/channel/transformations.py +28 -21
  239. qiskit/quantum_info/operators/dihedral/dihedral.py +1 -1
  240. qiskit/quantum_info/operators/operator.py +54 -8
  241. qiskit/quantum_info/operators/symplectic/base_pauli.py +11 -19
  242. qiskit/quantum_info/operators/symplectic/clifford.py +1 -1
  243. qiskit/quantum_info/operators/symplectic/clifford_circuits.py +1 -1
  244. qiskit/quantum_info/operators/symplectic/pauli.py +2 -0
  245. qiskit/quantum_info/operators/symplectic/pauli_list.py +4 -4
  246. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +23 -2
  247. qiskit/quantum_info/states/densitymatrix.py +5 -5
  248. qiskit/quantum_info/states/stabilizerstate.py +1 -1
  249. qiskit/quantum_info/states/statevector.py +6 -6
  250. qiskit/result/mitigation/base_readout_mitigator.py +1 -1
  251. qiskit/result/mitigation/correlated_readout_mitigator.py +9 -1
  252. qiskit/result/mitigation/local_readout_mitigator.py +9 -1
  253. qiskit/result/mitigation/utils.py +57 -0
  254. qiskit/scheduler/config.py +2 -0
  255. qiskit/scheduler/methods/basic.py +3 -0
  256. qiskit/scheduler/schedule_circuit.py +2 -0
  257. qiskit/scheduler/sequence.py +2 -0
  258. qiskit/synthesis/__init__.py +25 -0
  259. qiskit/synthesis/arithmetic/__init__.py +16 -0
  260. qiskit/synthesis/arithmetic/adders/__init__.py +17 -0
  261. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +154 -0
  262. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +103 -0
  263. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +161 -0
  264. qiskit/synthesis/arithmetic/multipliers/__init__.py +16 -0
  265. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +102 -0
  266. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +99 -0
  267. qiskit/synthesis/clifford/clifford_decompose_bm.py +1 -2
  268. qiskit/synthesis/clifford/clifford_decompose_greedy.py +3 -2
  269. qiskit/synthesis/clifford/clifford_decompose_layers.py +2 -1
  270. qiskit/synthesis/evolution/__init__.py +1 -0
  271. qiskit/synthesis/evolution/lie_trotter.py +16 -42
  272. qiskit/synthesis/evolution/pauli_network.py +80 -0
  273. qiskit/synthesis/evolution/product_formula.py +165 -238
  274. qiskit/synthesis/evolution/qdrift.py +36 -29
  275. qiskit/synthesis/evolution/suzuki_trotter.py +87 -27
  276. qiskit/synthesis/multi_controlled/__init__.py +1 -0
  277. qiskit/synthesis/multi_controlled/mcmt_vchain.py +52 -0
  278. qiskit/synthesis/qft/qft_decompose_full.py +19 -1
  279. qiskit/synthesis/qft/qft_decompose_lnn.py +2 -1
  280. qiskit/synthesis/stabilizer/stabilizer_decompose.py +2 -1
  281. qiskit/synthesis/two_qubit/two_qubit_decompose.py +4 -63
  282. qiskit/synthesis/unitary/qsd.py +5 -5
  283. qiskit/transpiler/__init__.py +21 -14
  284. qiskit/transpiler/basepasses.py +1 -1
  285. qiskit/transpiler/passes/__init__.py +2 -0
  286. qiskit/transpiler/passes/basis/basis_translator.py +9 -565
  287. qiskit/transpiler/passes/basis/decompose.py +45 -12
  288. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
  289. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
  290. qiskit/transpiler/passes/calibration/pulse_gate.py +4 -2
  291. qiskit/transpiler/passes/calibration/rx_builder.py +11 -7
  292. qiskit/transpiler/passes/calibration/rzx_builder.py +46 -30
  293. qiskit/transpiler/passes/layout/disjoint_utils.py +15 -13
  294. qiskit/transpiler/passes/layout/sabre_layout.py +7 -2
  295. qiskit/transpiler/passes/layout/sabre_pre_layout.py +5 -0
  296. qiskit/transpiler/passes/optimization/__init__.py +1 -0
  297. qiskit/transpiler/passes/optimization/collect_cliffords.py +19 -3
  298. qiskit/transpiler/passes/optimization/collect_linear_functions.py +1 -1
  299. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +2 -2
  300. qiskit/transpiler/passes/optimization/commutative_inverse_cancellation.py +1 -1
  301. qiskit/transpiler/passes/optimization/consolidate_blocks.py +48 -131
  302. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +4 -2
  303. qiskit/transpiler/passes/optimization/elide_permutations.py +9 -32
  304. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +5 -11
  305. qiskit/transpiler/passes/optimization/optimize_1q_gates.py +1 -1
  306. qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py +1 -1
  307. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +69 -0
  308. qiskit/transpiler/passes/optimization/template_matching/backward_match.py +5 -5
  309. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +4 -4
  310. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +2 -2
  311. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +1 -1
  312. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +1 -1
  313. qiskit/transpiler/passes/routing/sabre_swap.py +7 -3
  314. qiskit/transpiler/passes/routing/star_prerouting.py +2 -2
  315. qiskit/transpiler/passes/scheduling/alap.py +1 -1
  316. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +2 -2
  317. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
  318. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +2 -0
  319. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +2 -2
  320. qiskit/transpiler/passes/scheduling/asap.py +1 -1
  321. qiskit/transpiler/passes/scheduling/base_scheduler.py +14 -12
  322. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +9 -4
  323. qiskit/transpiler/passes/scheduling/padding/base_padding.py +1 -1
  324. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +16 -5
  325. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +4 -1
  326. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +6 -2
  327. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +9 -4
  328. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +262 -99
  329. qiskit/transpiler/passes/synthesis/hls_plugins.py +637 -7
  330. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +3 -3
  331. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +55 -34
  332. qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +2 -56
  333. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +5 -0
  334. qiskit/transpiler/passes/utils/gate_direction.py +12 -275
  335. qiskit/transpiler/passes/utils/gates_basis.py +7 -30
  336. qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +2 -1
  337. qiskit/transpiler/passmanager_config.py +22 -4
  338. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +40 -14
  339. qiskit/transpiler/preset_passmanagers/common.py +5 -3
  340. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +125 -42
  341. qiskit/transpiler/preset_passmanagers/plugin.py +1 -1
  342. qiskit/transpiler/target.py +74 -16
  343. qiskit/utils/deprecate_pulse.py +119 -0
  344. qiskit/visualization/circuit/_utils.py +2 -2
  345. qiskit/visualization/circuit/circuit_visualization.py +3 -2
  346. qiskit/visualization/circuit/matplotlib.py +1 -1
  347. qiskit/visualization/dag_visualization.py +1 -1
  348. qiskit/visualization/pass_manager_visualization.py +3 -14
  349. qiskit/visualization/pulse_v2/interface.py +3 -1
  350. qiskit/visualization/timeline/core.py +25 -2
  351. qiskit/visualization/timeline/interface.py +12 -0
  352. {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/METADATA +9 -8
  353. {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/RECORD +357 -346
  354. {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/WHEEL +1 -1
  355. {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/entry_points.txt +19 -0
  356. qiskit/circuit/library/data_preparation/zz_feature_map.py +0 -118
  357. qiskit/synthesis/two_qubit/weyl.py +0 -97
  358. qiskit/transpiler/passes/synthesis/qubit_tracker.py +0 -132
  359. {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/LICENSE.txt +0 -0
  360. {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/top_level.txt +0 -0
@@ -17,21 +17,28 @@ from __future__ import annotations
17
17
  import collections
18
18
  import itertools
19
19
  import typing
20
- from collections.abc import Callable, Mapping, Sequence
20
+ from collections.abc import Callable, Mapping, Sequence, Iterable
21
21
 
22
22
  import numpy
23
- from qiskit.circuit.quantumcircuit import QuantumCircuit
23
+ from qiskit.circuit.gate import Gate
24
+ from qiskit.circuit.quantumcircuit import QuantumCircuit, ParameterValueType
25
+ from qiskit.circuit.parametervector import ParameterVector, ParameterVectorElement
24
26
  from qiskit.circuit.quantumregister import QuantumRegister
25
27
  from qiskit.circuit import (
26
28
  Instruction,
27
29
  Parameter,
28
- ParameterVector,
29
30
  ParameterExpression,
30
31
  CircuitInstruction,
31
32
  )
32
33
  from qiskit.exceptions import QiskitError
33
34
  from qiskit.circuit.library.standard_gates import get_standard_gate_name_mapping
34
- from qiskit._accelerate.circuit_library import get_entangler_map as fast_entangler_map
35
+ from qiskit.utils.deprecation import deprecate_func
36
+
37
+ from qiskit._accelerate.circuit_library import (
38
+ Block,
39
+ py_n_local,
40
+ get_entangler_map as fast_entangler_map,
41
+ )
35
42
 
36
43
  from ..blueprintcircuit import BlueprintCircuit
37
44
 
@@ -39,6 +46,219 @@ from ..blueprintcircuit import BlueprintCircuit
39
46
  if typing.TYPE_CHECKING:
40
47
  import qiskit # pylint: disable=cyclic-import
41
48
 
49
+ # entanglement for an individual block, e.g. if the block is CXGate() and we have
50
+ # 3 qubits, this could be [(0, 1), (1, 2), (2, 0)]
51
+ BlockEntanglement = typing.Union[str, Iterable[Iterable[int]]]
52
+
53
+
54
+ def n_local(
55
+ num_qubits: int,
56
+ rotation_blocks: str | Gate | Iterable[str | Gate],
57
+ entanglement_blocks: str | Gate | Iterable[str | Gate],
58
+ entanglement: (
59
+ BlockEntanglement
60
+ | Iterable[BlockEntanglement]
61
+ | Callable[[int], BlockEntanglement | Iterable[BlockEntanglement]]
62
+ ) = "full",
63
+ reps: int = 3,
64
+ insert_barriers: bool = False,
65
+ parameter_prefix: str = "θ",
66
+ overwrite_block_parameters: bool = True,
67
+ skip_final_rotation_layer: bool = False,
68
+ skip_unentangled_qubits: bool = False,
69
+ name: str | None = "nlocal",
70
+ ) -> QuantumCircuit:
71
+ r"""Construct an n-local variational circuit.
72
+
73
+ The structure of the n-local circuit are alternating rotation and entanglement layers.
74
+ In both layers, parameterized circuit-blocks act on the circuit in a defined way.
75
+ In the rotation layer, the blocks are applied stacked on top of each other, while in the
76
+ entanglement layer according to the ``entanglement`` strategy.
77
+ The circuit blocks can have arbitrary sizes (smaller equal to the number of qubits in the
78
+ circuit). Each layer is repeated ``reps`` times, and by default a final rotation layer is
79
+ appended.
80
+
81
+ For instance, a rotation block on 2 qubits and an entanglement block on 4 qubits using
82
+ ``"linear"`` entanglement yields the following circuit.
83
+
84
+ .. parsed-literal::
85
+
86
+ ┌──────┐ ░ ┌──────┐ ░ ┌──────┐
87
+ ┤0 ├─░─┤0 ├──────────────── ... ─░─┤0 ├
88
+ │ Rot │ ░ │ │┌──────┐ ░ │ Rot │
89
+ ┤1 ├─░─┤1 ├┤0 ├──────── ... ─░─┤1 ├
90
+ ├──────┤ ░ │ Ent ││ │┌──────┐ ░ ├──────┤
91
+ ┤0 ├─░─┤2 ├┤1 ├┤0 ├ ... ─░─┤0 ├
92
+ │ Rot │ ░ │ ││ Ent ││ │ ░ │ Rot │
93
+ ┤1 ├─░─┤3 ├┤2 ├┤1 ├ ... ─░─┤1 ├
94
+ ├──────┤ ░ └──────┘│ ││ Ent │ ░ ├──────┤
95
+ ┤0 ├─░─────────┤3 ├┤2 ├ ... ─░─┤0 ├
96
+ │ Rot │ ░ └──────┘│ │ ░ │ Rot │
97
+ ┤1 ├─░─────────────────┤3 ├ ... ─░─┤1 ├
98
+ └──────┘ ░ └──────┘ ░ └──────┘
99
+
100
+ | |
101
+ +---------------------------------+
102
+ repeated reps times
103
+
104
+ Entanglement:
105
+
106
+ The entanglement describes the connections of the gates in the entanglement layer.
107
+ For a two-qubit gate for example, the entanglement contains pairs of qubits on which the
108
+ gate should acts, e.g. ``[[ctrl0, target0], [ctrl1, target1], ...]``.
109
+ A set of default entanglement strategies is provided and can be selected by name:
110
+
111
+ * ``"full"`` entanglement is each qubit is entangled with all the others.
112
+ * ``"linear"`` entanglement is qubit :math:`i` entangled with qubit :math:`i + 1`,
113
+ for all :math:`i \in \{0, 1, ... , n - 2\}`, where :math:`n` is the total number of qubits.
114
+ * ``"reverse_linear"`` entanglement is qubit :math:`i` entangled with qubit :math:`i + 1`,
115
+ for all :math:`i \in \{n-2, n-3, ... , 1, 0\}`, where :math:`n` is the total number of qubits.
116
+ Note that if ``entanglement_blocks=="cx"`` then this option provides the same unitary as
117
+ ``"full"`` with fewer entangling gates.
118
+ * ``"pairwise"`` entanglement is one layer where qubit :math:`i` is entangled with qubit
119
+ :math:`i + 1`, for all even values of :math:`i`, and then a second layer where qubit :math:`i`
120
+ is entangled with qubit :math:`i + 1`, for all odd values of :math:`i`.
121
+ * ``"circular"`` entanglement is linear entanglement but with an additional entanglement of the
122
+ first and last qubit before the linear part.
123
+ * ``"sca"`` (shifted-circular-alternating) entanglement is a generalized and modified version
124
+ of the proposed circuit 14 in `Sim et al. <https://arxiv.org/abs/1905.10876>`__.
125
+ It consists of circular entanglement where the "long" entanglement connecting the first with
126
+ the last qubit is shifted by one each block. Furthermore the role of control and target
127
+ qubits are swapped every block (therefore alternating).
128
+
129
+ If an entanglement layer contains multiple blocks, then the entanglement should be
130
+ given as list of entanglements for each block. For example::
131
+
132
+ entanglement_blocks = ["rxx", "ryy"]
133
+ entanglement = ["full", "linear"] # full for rxx and linear for ryy
134
+
135
+ or::
136
+
137
+ structure_rxx = [[0, 1], [2, 3]]
138
+ structure_ryy = [[0, 2]]
139
+ entanglement = [structure_rxx, structure_ryy]
140
+
141
+ Finally, the entanglement can vary in each repetition of the circuit. For this, we
142
+ support passing a callable that takes as input the layer index and returns the entanglement
143
+ for the layer in the above format. See the examples below for a concrete example.
144
+
145
+ Examples:
146
+
147
+ The rotation and entanglement gates can be specified via single strings, if they
148
+ are made up of a single block per layer:
149
+
150
+ .. plot::
151
+ :include-source:
152
+ :context:
153
+
154
+ from qiskit.circuit.library import n_local
155
+
156
+ circuit = n_local(3, "ry", "cx", "linear", reps=2, insert_barriers=True)
157
+ circuit.draw("mpl")
158
+
159
+ Multiple gates per layer can be set by passing a list. Here, for example, we use
160
+ Pauli-Y and Pauli-Z rotations in the rotation layer:
161
+
162
+ .. plot::
163
+ :include-source:
164
+ :context:
165
+
166
+ circuit = n_local(3, ["ry", "rz"], "cz", "full", reps=1, insert_barriers=True)
167
+ circuit.draw("mpl")
168
+
169
+ To omit rotation or entanglement layers, the block can be set to an empty list:
170
+
171
+ .. plot::
172
+ :include-source:
173
+ :context:
174
+
175
+ circuit = n_local(4, [], "cry", reps=2)
176
+ circuit.draw("mpl")
177
+
178
+ The entanglement can be set explicitly via the ``entanglement`` argument:
179
+
180
+ .. plot::
181
+ :include-source:
182
+ :context:
183
+
184
+ entangler_map = [[0, 1], [2, 0]]
185
+ circuit = n_local(3, "x", "crx", entangler_map, reps=2)
186
+ circuit.draw("mpl")
187
+
188
+ We can set different entanglements per layer, by specifing a callable that takes
189
+ as input the current layer index, and returns the entanglement structure. For example,
190
+ the following uses different entanglements for odd and even layers:
191
+
192
+ .. plot:
193
+ :include-source:
194
+ :context:
195
+
196
+ def entanglement(layer_index):
197
+ if layer_index % 2 == 0:
198
+ return [[0, 1], [0, 2]]
199
+ return [[1, 2]]
200
+
201
+ circuit = n_local(3, "x", "cx", entanglement, reps=3, insert_barriers=True)
202
+ circuit.draw("mpl")
203
+
204
+
205
+ Args:
206
+ num_qubits: The number of qubits of the circuit.
207
+ rotation_blocks: The blocks used in the rotation layers. If multiple are passed,
208
+ these will be applied one after another (like new sub-layers).
209
+ entanglement_blocks: The blocks used in the entanglement layers. If multiple are passed,
210
+ these will be applied one after another.
211
+ entanglement: The indices specifying on which qubits the input blocks act. This is
212
+ specified by string describing an entanglement strategy (see the additional info)
213
+ or a list of qubit connections.
214
+ If a list of entanglement blocks is passed, different entanglement for each block can
215
+ be specified by passing a list of entanglements. To specify varying entanglement for
216
+ each repetition, pass a callable that takes as input the layer and returns the
217
+ entanglement for that layer.
218
+ Defaults to ``"full"``, meaning an all-to-all entanglement structure.
219
+ reps: Specifies how often the rotation blocks and entanglement blocks are repeated.
220
+ insert_barriers: If ``True``, barriers are inserted in between each layer. If ``False``,
221
+ no barriers are inserted.
222
+ parameter_prefix: The prefix used if default parameters are generated.
223
+ overwrite_block_parameters: If the parameters in the added blocks should be overwritten.
224
+ If ``False``, the parameters in the blocks are not changed.
225
+ skip_final_rotation_layer: Whether a final rotation layer is added to the circuit.
226
+ skip_unentangled_qubits: If ``True``, the rotation gates act only on qubits that
227
+ are entangled. If ``False``, the rotation gates act on all qubits.
228
+ name: The name of the circuit.
229
+
230
+ Returns:
231
+ An n-local circuit.
232
+ """
233
+ if reps < 0:
234
+ # this is an important check, since we cast this to an unsigned integer Rust-side
235
+ raise ValueError(f"reps must be non-negative, but is {reps}")
236
+
237
+ supported_gates = get_standard_gate_name_mapping()
238
+ rotation_blocks = _normalize_blocks(
239
+ rotation_blocks, supported_gates, overwrite_block_parameters
240
+ )
241
+ entanglement_blocks = _normalize_blocks(
242
+ entanglement_blocks, supported_gates, overwrite_block_parameters
243
+ )
244
+
245
+ entanglement = _normalize_entanglement(entanglement, len(entanglement_blocks))
246
+
247
+ data = py_n_local(
248
+ num_qubits=num_qubits,
249
+ rotation_blocks=rotation_blocks,
250
+ entanglement_blocks=entanglement_blocks,
251
+ entanglement=entanglement,
252
+ reps=reps,
253
+ insert_barriers=insert_barriers,
254
+ parameter_prefix=parameter_prefix,
255
+ skip_final_rotation_layer=skip_final_rotation_layer,
256
+ skip_unentangled_qubits=skip_unentangled_qubits,
257
+ )
258
+ circuit = QuantumCircuit._from_circuit_data(data, add_regs=True, name=name)
259
+
260
+ return circuit
261
+
42
262
 
43
263
  class NLocal(BlueprintCircuit):
44
264
  """The n-local circuit class.
@@ -54,7 +274,7 @@ class NLocal(BlueprintCircuit):
54
274
  For instance, a rotation block on 2 qubits and an entanglement block on 4 qubits using
55
275
  ``'linear'`` entanglement yields the following circuit.
56
276
 
57
- .. parsed-literal::
277
+ .. code-block:: text
58
278
 
59
279
  ┌──────┐ ░ ┌──────┐ ░ ┌──────┐
60
280
  ┤0 ├─░─┤0 ├──────────────── ... ─░─┤0 ├
@@ -76,8 +296,18 @@ class NLocal(BlueprintCircuit):
76
296
 
77
297
  If specified, barriers can be inserted in between every block.
78
298
  If an initial state object is provided, it is added in front of the NLocal.
299
+
300
+ .. seealso::
301
+
302
+ The :func:`.n_local` function constructs a functionally equivalent circuit, but faster.
303
+
79
304
  """
80
305
 
306
+ @deprecate_func(
307
+ since="1.3",
308
+ additional_msg="Use the function qiskit.circuit.library.n_local instead.",
309
+ pending=True,
310
+ )
81
311
  def __init__(
82
312
  self,
83
313
  num_qubits: int | None = None,
@@ -1069,3 +1299,174 @@ def _stdlib_gate_from_simple_block(block: QuantumCircuit) -> _StdlibGateResult |
1069
1299
  ):
1070
1300
  return None
1071
1301
  return _StdlibGateResult(instruction.operation.base_class, len(instruction.operation.params))
1302
+
1303
+
1304
+ def _normalize_entanglement(
1305
+ entanglement: (
1306
+ BlockEntanglement
1307
+ | Iterable[BlockEntanglement]
1308
+ | Callable[[int], BlockEntanglement | Iterable[BlockEntanglement]]
1309
+ ),
1310
+ num_entanglement_blocks: int,
1311
+ ) -> list[str | list[tuple[int]]] | Callable[[int], list[str | list[tuple[int]]]]:
1312
+ """If the entanglement is Iterable[Iterable], normalize to list[tuple]."""
1313
+ if isinstance(entanglement, str):
1314
+ return [entanglement] * num_entanglement_blocks
1315
+
1316
+ if callable(entanglement):
1317
+ return lambda offset: _normalize_entanglement(entanglement(offset), num_entanglement_blocks)
1318
+
1319
+ # here, entanglement is an Iterable
1320
+ if len(entanglement) == 0:
1321
+ # handle edge cases when entanglement is set to an empty list
1322
+ return [[]]
1323
+
1324
+ # if the entanglement is Iterable[Iterable[int]], normalize to Iterable[Iterable[Iterable[int]]]
1325
+ try:
1326
+ # if users e.g. gave Iterable[int] this in invalid and will raise a TypeError
1327
+ if isinstance(entanglement[0][0], (int, numpy.integer)):
1328
+ entanglement = [entanglement]
1329
+ except TypeError as exc:
1330
+ raise TypeError(f"Invalid entanglement type: {entanglement}.") from exc
1331
+
1332
+ # ensure the number of block entanglements matches the number of blocks
1333
+ if len(entanglement) != num_entanglement_blocks:
1334
+ raise QiskitError(
1335
+ f"Number of block-entanglements ({len(entanglement)}) must match number of "
1336
+ f"entanglement blocks ({num_entanglement_blocks})!"
1337
+ )
1338
+
1339
+ # normalize the data: str remains, and Iterable[Iterable[int]] becomes list[tuple[int]]
1340
+ normalized = []
1341
+ for block in entanglement:
1342
+ if isinstance(block, str):
1343
+ normalized.append(block)
1344
+ else:
1345
+ normalized.append([tuple(connections) for connections in block])
1346
+
1347
+ return normalized
1348
+
1349
+
1350
+ def _normalize_blocks(
1351
+ blocks: str | Gate | Iterable[str | Gate],
1352
+ supported_gates: dict[str, Gate],
1353
+ overwrite_block_parameters: bool,
1354
+ ) -> list[Block]:
1355
+ # normalize the input into an iterable -- we add an extra check for a circuit as
1356
+ # courtesy to the users, since the NLocal class used to accept circuits
1357
+ if isinstance(blocks, (str, Gate, QuantumCircuit)):
1358
+ blocks = [blocks]
1359
+
1360
+ normalized = []
1361
+ for block in blocks:
1362
+ # since the NLocal circuit accepted circuits as inputs, we raise a warning here
1363
+ # to simplify the transition (even though, strictly speaking, quantum circuits are
1364
+ # not a supported input type)
1365
+ if isinstance(block, QuantumCircuit):
1366
+ raise ValueError(
1367
+ "The blocks should be of type Gate or str, but you passed a QuantumCircuit. "
1368
+ "You can call .to_gate() on the circuit to turn it into a Gate object."
1369
+ )
1370
+
1371
+ is_standard = False
1372
+ if isinstance(block, str):
1373
+ if block not in supported_gates:
1374
+ raise ValueError(f"Unsupported gate: {block}")
1375
+ block = supported_gates[block]
1376
+ is_standard = True
1377
+ elif isinstance(block, Gate) and getattr(block, "_standard_gate", None) is not None:
1378
+ if len(block.params) == 0:
1379
+ is_standard = True
1380
+ # the fast path will always overwrite block parameters
1381
+ elif overwrite_block_parameters:
1382
+ # if all parameters are plain Parameter objects, this is a plain
1383
+ # standard gate we do not need to propagate parameterizations for
1384
+ is_standard = all(isinstance(p, Parameter) for p in block.params)
1385
+
1386
+ if is_standard:
1387
+ block = Block.from_standard_gate(block._standard_gate)
1388
+ else:
1389
+ if overwrite_block_parameters:
1390
+ num_parameters, builder = _get_gate_builder(block)
1391
+ else:
1392
+ num_parameters, builder = _trivial_builder(block)
1393
+
1394
+ block = Block.from_callable(block.num_qubits, num_parameters, builder)
1395
+
1396
+ normalized.append(block)
1397
+
1398
+ return normalized
1399
+
1400
+
1401
+ def _trivial_builder(
1402
+ gate: Gate,
1403
+ ) -> tuple[int, Callable[list[Parameter], tuple[Gate, list[ParameterValueType]]]]:
1404
+
1405
+ def builder(_):
1406
+ copied = gate.copy()
1407
+ return copied, copied.params
1408
+
1409
+ return 0, builder
1410
+
1411
+
1412
+ def _get_gate_builder(
1413
+ gate: Gate,
1414
+ ) -> tuple[int, Callable[list[Parameter], tuple[Gate, list[ParameterValueType]]]]:
1415
+ """Construct a callable that handles parameter-rebinding.
1416
+
1417
+ For a given gate, this return the number of free parameters and a callable that can be
1418
+ used to obtain a re-parameterized version of the gate. For example::
1419
+
1420
+ x, y = Parameter("x"), Parameter("y")
1421
+ gate = CUGate(x, 2 * y, 0.5, 0.)
1422
+
1423
+ num_parameters, builder = _build_gate(gate)
1424
+ print(num_parameters) # prints 2
1425
+
1426
+ a, b = Parameter("a"), Parameter("b")
1427
+ new_gate, new_params = builder([a, b])
1428
+ print(new_gate) # CUGate(a, 2 * b, 0.5, 0)
1429
+ print(new_params) # [a, 2 * b, 0.5, 0]
1430
+
1431
+ """
1432
+ free_parameters = set()
1433
+ for p in gate.params:
1434
+ if isinstance(p, ParameterExpression):
1435
+ free_parameters |= set(p.parameters)
1436
+
1437
+ num_parameters = len(free_parameters)
1438
+
1439
+ sorted_parameters = _sort_parameters(free_parameters)
1440
+
1441
+ def builder(new_parameters):
1442
+ out = gate.copy()
1443
+
1444
+ # re-bind the ``Gate.params`` attribute
1445
+ param_dict = dict(zip(sorted_parameters, new_parameters))
1446
+ bound_params = gate.params.copy()
1447
+ for i, expr in enumerate(gate.params):
1448
+ if isinstance(expr, ParameterExpression):
1449
+ for parameter in expr.parameters:
1450
+ expr = expr.assign(parameter, param_dict[parameter])
1451
+ bound_params[i] = expr
1452
+
1453
+ out.params = bound_params
1454
+
1455
+ # if the definition exists, rebind it
1456
+ if out._definition is not None:
1457
+ out._definition.assign_parameters(param_dict, inplace=True)
1458
+
1459
+ return out, bound_params
1460
+
1461
+ return num_parameters, builder
1462
+
1463
+
1464
+ def _sort_parameters(parameters):
1465
+ """Sort a list of Parameter objects."""
1466
+
1467
+ def key(parameter):
1468
+ if isinstance(parameter, ParameterVectorElement):
1469
+ return (parameter.vector.name, parameter.index)
1470
+ return (parameter.name,)
1471
+
1472
+ return sorted(parameters, key=key)
@@ -16,9 +16,104 @@ from __future__ import annotations
16
16
  import numpy as np
17
17
 
18
18
  from qiskit.circuit import QuantumCircuit
19
+ from qiskit.circuit.library.standard_gates import RXGate, RYGate, RZGate, CZGate
20
+ from qiskit.utils.deprecation import deprecate_func
21
+ from qiskit._accelerate.circuit_library import Block, py_n_local
22
+ from .two_local import TwoLocal
19
23
 
20
24
 
21
- from .two_local import TwoLocal
25
+ def pauli_two_design(
26
+ num_qubits: int,
27
+ reps: int = 3,
28
+ seed: int | None = None,
29
+ insert_barriers: bool = False,
30
+ parameter_prefix: str = "θ",
31
+ name: str = "PauliTwoDesign",
32
+ ) -> QuantumCircuit:
33
+ r"""Construct a Pauli 2-design ansatz.
34
+
35
+ This class implements a particular form of a 2-design circuit [1], which is frequently studied
36
+ in quantum machine learning literature, such as, e.g., the investigation of Barren plateaus in
37
+ variational algorithms [2].
38
+
39
+ The circuit consists of alternating rotation and entanglement layers with
40
+ an initial layer of :math:`\sqrt{H} = RY(\pi/4)` gates.
41
+ The rotation layers contain single qubit Pauli rotations, where the axis is chosen uniformly
42
+ at random to be X, Y or Z. The entanglement layers is compromised of pairwise CZ gates
43
+ with a total depth of 2.
44
+
45
+ For instance, the circuit could look like this:
46
+
47
+ .. parsed-literal::
48
+
49
+ ┌─────────┐┌──────────┐ ░ ┌──────────┐ ░ ┌──────────┐
50
+ q_0: ┤ RY(π/4) ├┤ RZ(θ[0]) ├─■─────░─┤ RY(θ[4]) ├─■─────░──┤ RZ(θ[8]) ├
51
+ ├─────────┤├──────────┤ │ ░ ├──────────┤ │ ░ ├──────────┤
52
+ q_1: ┤ RY(π/4) ├┤ RZ(θ[1]) ├─■──■──░─┤ RY(θ[5]) ├─■──■──░──┤ RX(θ[9]) ├
53
+ ├─────────┤├──────────┤ │ ░ ├──────────┤ │ ░ ┌┴──────────┤
54
+ q_2: ┤ RY(π/4) ├┤ RX(θ[2]) ├─■──■──░─┤ RY(θ[6]) ├─■──■──░─┤ RX(θ[10]) ├
55
+ ├─────────┤├──────────┤ │ ░ ├──────────┤ │ ░ ├───────────┤
56
+ q_3: ┤ RY(π/4) ├┤ RZ(θ[3]) ├─■─────░─┤ RX(θ[7]) ├─■─────░─┤ RY(θ[11]) ├
57
+ └─────────┘└──────────┘ ░ └──────────┘ ░ └───────────┘
58
+
59
+ Examples:
60
+
61
+ .. plot::
62
+ :include-source:
63
+
64
+ from qiskit.circuit.library import pauli_two_design
65
+ circuit = pauli_two_design(4, reps=2, seed=5, insert_barriers=True)
66
+ circuit.draw("mpl")
67
+
68
+ Args:
69
+ num_qubits: The number of qubits of the Pauli Two-Design circuit.
70
+ reps: Specifies how often a block consisting of a rotation layer and entanglement
71
+ layer is repeated.
72
+ seed: The seed for randomly choosing the axes of the Pauli rotations.
73
+ parameter_prefix: The prefix used for the rotation parameters.
74
+ insert_barriers: If ``True``, barriers are inserted in between each layer. If ``False``,
75
+ no barriers are inserted. Defaults to ``False``.
76
+ name: The circuit name.
77
+
78
+ Returns:
79
+ A Pauli 2-design circuit.
80
+
81
+ References:
82
+
83
+ [1]: Nakata et al., Unitary 2-designs from random X- and Z-diagonal unitaries.
84
+ `arXiv:1502.07514 <https://arxiv.org/pdf/1502.07514.pdf>`_
85
+
86
+ [2]: McClean et al., Barren plateaus in quantum neural network training landscapes.
87
+ `arXiv:1803.11173 <https://arxiv.org/pdf/1803.11173.pdf>`_
88
+ """
89
+ rng = np.random.default_rng(seed)
90
+ random_block = Block.from_callable(1, 1, lambda params: _random_pauli_builder(params, rng))
91
+ cz_block = Block.from_standard_gate(CZGate._standard_gate)
92
+
93
+ data = py_n_local(
94
+ num_qubits=num_qubits,
95
+ reps=reps,
96
+ rotation_blocks=[random_block],
97
+ entanglement_blocks=[cz_block],
98
+ entanglement=["pairwise"],
99
+ insert_barriers=insert_barriers,
100
+ skip_final_rotation_layer=False,
101
+ skip_unentangled_qubits=False,
102
+ parameter_prefix=parameter_prefix,
103
+ )
104
+ two_design = QuantumCircuit._from_circuit_data(data)
105
+
106
+ circuit = QuantumCircuit(num_qubits, name=name)
107
+ circuit.ry(np.pi / 4, circuit.qubits)
108
+ circuit.compose(two_design, inplace=True, copy=False)
109
+
110
+ return circuit
111
+
112
+
113
+ def _random_pauli_builder(params, rng):
114
+ gate_cls = rng.choice([RXGate, RYGate, RZGate])
115
+ gate = gate_cls(params[0])
116
+ return gate, gate.params
22
117
 
23
118
 
24
119
  class PauliTwoDesign(TwoLocal):
@@ -37,7 +132,7 @@ class PauliTwoDesign(TwoLocal):
37
132
  For instance, the circuit could look like this (but note that choosing a different seed
38
133
  yields different Pauli rotations).
39
134
 
40
- .. parsed-literal::
135
+ .. code-block:: text
41
136
 
42
137
  ┌─────────┐┌──────────┐ ░ ┌──────────┐ ░ ┌──────────┐
43
138
  q_0: ┤ RY(π/4) ├┤ RZ(θ[0]) ├─■─────░─┤ RY(θ[4]) ├─■─────░──┤ RZ(θ[8]) ├
@@ -58,6 +153,10 @@ class PauliTwoDesign(TwoLocal):
58
153
  circuit = PauliTwoDesign(4, reps=2, seed=5, insert_barriers=True)
59
154
  circuit.draw('mpl')
60
155
 
156
+ .. seealso::
157
+
158
+ The :func:`.pauli_two_design` function constructs the functionally same circuit, but faster.
159
+
61
160
  References:
62
161
 
63
162
  [1]: Nakata et al., Unitary 2-designs from random X- and Z-diagonal unitaries.
@@ -67,6 +166,11 @@ class PauliTwoDesign(TwoLocal):
67
166
  `arXiv:1803.11173 <https://arxiv.org/pdf/1803.11173.pdf>`_
68
167
  """
69
168
 
169
+ @deprecate_func(
170
+ since="1.3",
171
+ additional_msg="Use the function qiskit.circuit.library.pauli_two_design instead.",
172
+ pending=True,
173
+ )
70
174
  def __init__(
71
175
  self,
72
176
  num_qubits: int | None = None,
@@ -85,8 +189,6 @@ class PauliTwoDesign(TwoLocal):
85
189
  no barriers are inserted. Defaults to ``False``.
86
190
 
87
191
  """
88
- from qiskit.circuit.library import RYGate # pylint: disable=cyclic-import
89
-
90
192
  # store a random number generator
91
193
  self._seed = seed
92
194
  self._rng = np.random.default_rng(seed)
@@ -21,8 +21,87 @@ from qiskit.circuit.parametervector import ParameterVector
21
21
  from qiskit.circuit.quantumcircuit import QuantumCircuit
22
22
  from qiskit.circuit.quantumregister import QuantumRegister
23
23
  from qiskit.quantum_info import SparsePauliOp
24
+ from qiskit.quantum_info.operators.base_operator import BaseOperator
25
+
26
+ from .evolved_operator_ansatz import (
27
+ EvolvedOperatorAnsatz,
28
+ _is_pauli_identity,
29
+ evolved_operator_ansatz,
30
+ )
31
+
32
+
33
+ def qaoa_ansatz(
34
+ cost_operator: BaseOperator,
35
+ reps: int = 1,
36
+ initial_state: QuantumCircuit | None = None,
37
+ mixer_operator: BaseOperator | None = None,
38
+ insert_barriers: bool = False,
39
+ name: str = "QAOA",
40
+ flatten: bool = True,
41
+ ) -> QuantumCircuit:
42
+ r"""A generalized QAOA quantum circuit with a support of custom initial states and mixers.
43
+
44
+ Examples:
45
+
46
+ To define the QAOA ansatz we require a cost Hamiltonian, encoding the classical
47
+ optimization problem:
48
+
49
+ .. plot::
50
+ :include-source:
51
+
52
+ from qiskit.quantum_info import SparsePauliOp
53
+ from qiskit.circuit.library import qaoa_ansatz
54
+
55
+ cost_operator = SparsePauliOp(["ZZII", "IIZZ", "ZIIZ"])
56
+ ansatz = qaoa_ansatz(cost_operator, reps=3, insert_barriers=True)
57
+ ansatz.draw("mpl")
58
+
59
+ Args:
60
+ cost_operator: The operator representing the cost of the optimization problem, denoted as
61
+ :math:`U(C, \gamma)` in [1].
62
+ reps: The integer determining the depth of the circuit, called :math:`p` in [1].
63
+ initial_state: An optional initial state to use, which defaults to a layer of
64
+ Hadamard gates preparing the :math:`|+\rangle^{\otimes n}` state.
65
+ If a custom mixer is chosen, this circuit should be set to prepare its ground state,
66
+ to appropriately fulfill the annealing conditions.
67
+ mixer_operator: An optional custom mixer, which defaults to global Pauli-:math:`X`
68
+ rotations. This is denoted as :math:`U(B, \beta)` in [1]. If this is set,
69
+ the ``initial_state`` might also require modification.
70
+ insert_barriers: Whether to insert barriers in-between the cost and mixer operators.
71
+ name: The name of the circuit.
72
+ flatten: If ``True``, a flat circuit is returned instead of nesting it inside multiple
73
+ layers of gate objects. Setting this to ``False`` is significantly less performant,
74
+ especially for parameter binding, but can be desirable for a cleaner visualization.
24
75
 
25
- from .evolved_operator_ansatz import EvolvedOperatorAnsatz, _is_pauli_identity
76
+ References:
77
+
78
+ [1]: Farhi et al., A Quantum Approximate Optimization Algorithm.
79
+ `arXiv:1411.4028 <https://arxiv.org/pdf/1411.4028>`_
80
+ """
81
+ num_qubits = cost_operator.num_qubits
82
+
83
+ if initial_state is None:
84
+ initial_state = QuantumCircuit(num_qubits)
85
+ initial_state.h(range(num_qubits))
86
+
87
+ if mixer_operator is None:
88
+ mixer_operator = SparsePauliOp.from_sparse_list(
89
+ [("X", [i], 1) for i in range(num_qubits)], num_qubits
90
+ )
91
+
92
+ parameter_prefix = ["γ", "β"]
93
+
94
+ return initial_state.compose(
95
+ evolved_operator_ansatz(
96
+ [cost_operator, mixer_operator],
97
+ reps=reps,
98
+ insert_barriers=insert_barriers,
99
+ parameter_prefix=parameter_prefix,
100
+ name=name,
101
+ flatten=flatten,
102
+ ),
103
+ copy=False,
104
+ )
26
105
 
27
106
 
28
107
  class QAOAAnsatz(EvolvedOperatorAnsatz):