qiskit 1.1.1__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 (347) 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/__init__.py +8 -0
  18. qiskit/circuit/classicalfunction/boolean_expression.py +1 -1
  19. qiskit/circuit/classicalfunction/classical_function_visitor.py +5 -5
  20. qiskit/circuit/classicalfunction/utils.py +1 -1
  21. qiskit/circuit/classicalregister.py +1 -1
  22. qiskit/circuit/commutation_checker.py +83 -35
  23. qiskit/circuit/controlflow/_builder_utils.py +1 -1
  24. qiskit/circuit/controlflow/builder.py +10 -6
  25. qiskit/circuit/controlflow/if_else.py +2 -2
  26. qiskit/circuit/controlflow/switch_case.py +1 -1
  27. qiskit/circuit/delay.py +1 -1
  28. qiskit/circuit/duration.py +2 -2
  29. qiskit/circuit/equivalence.py +5 -7
  30. qiskit/circuit/gate.py +11 -8
  31. qiskit/circuit/instruction.py +31 -13
  32. qiskit/circuit/instructionset.py +2 -5
  33. qiskit/circuit/library/__init__.py +2 -1
  34. qiskit/circuit/library/arithmetic/linear_amplitude_function.py +1 -1
  35. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +1 -1
  36. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +1 -1
  37. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +1 -1
  38. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +3 -3
  39. qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +1 -1
  40. qiskit/circuit/library/basis_change/__init__.py +1 -1
  41. qiskit/circuit/library/basis_change/qft.py +40 -6
  42. qiskit/circuit/library/blueprintcircuit.py +3 -5
  43. qiskit/circuit/library/data_preparation/__init__.py +9 -2
  44. qiskit/circuit/library/data_preparation/initializer.py +8 -0
  45. qiskit/circuit/library/data_preparation/state_preparation.py +98 -178
  46. qiskit/circuit/library/generalized_gates/isometry.py +8 -8
  47. qiskit/circuit/library/generalized_gates/linear_function.py +3 -2
  48. qiskit/circuit/library/generalized_gates/mcg_up_to_diagonal.py +4 -4
  49. qiskit/circuit/library/generalized_gates/permutation.py +8 -9
  50. qiskit/circuit/library/generalized_gates/uc.py +3 -3
  51. qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +2 -2
  52. qiskit/circuit/library/generalized_gates/unitary.py +13 -11
  53. qiskit/circuit/library/graph_state.py +1 -1
  54. qiskit/circuit/library/hamiltonian_gate.py +1 -2
  55. qiskit/circuit/library/hidden_linear_function.py +1 -1
  56. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +3 -2
  57. qiskit/circuit/library/n_local/n_local.py +4 -5
  58. qiskit/circuit/library/n_local/pauli_two_design.py +1 -1
  59. qiskit/circuit/library/n_local/qaoa_ansatz.py +6 -8
  60. qiskit/circuit/library/n_local/two_local.py +1 -1
  61. qiskit/circuit/library/overlap.py +11 -5
  62. qiskit/circuit/library/pauli_evolution.py +7 -3
  63. qiskit/circuit/library/standard_gates/dcx.py +3 -0
  64. qiskit/circuit/library/standard_gates/ecr.py +3 -0
  65. qiskit/circuit/library/standard_gates/global_phase.py +3 -0
  66. qiskit/circuit/library/standard_gates/h.py +13 -5
  67. qiskit/circuit/library/standard_gates/i.py +3 -0
  68. qiskit/circuit/library/standard_gates/iswap.py +3 -0
  69. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +19 -10
  70. qiskit/circuit/library/standard_gates/p.py +14 -9
  71. qiskit/circuit/library/standard_gates/r.py +3 -0
  72. qiskit/circuit/library/standard_gates/rx.py +21 -6
  73. qiskit/circuit/library/standard_gates/rxx.py +40 -1
  74. qiskit/circuit/library/standard_gates/ry.py +21 -6
  75. qiskit/circuit/library/standard_gates/ryy.py +40 -1
  76. qiskit/circuit/library/standard_gates/rz.py +22 -6
  77. qiskit/circuit/library/standard_gates/rzx.py +40 -1
  78. qiskit/circuit/library/standard_gates/rzz.py +41 -2
  79. qiskit/circuit/library/standard_gates/s.py +77 -0
  80. qiskit/circuit/library/standard_gates/swap.py +12 -5
  81. qiskit/circuit/library/standard_gates/sx.py +14 -5
  82. qiskit/circuit/library/standard_gates/t.py +5 -0
  83. qiskit/circuit/library/standard_gates/u.py +22 -7
  84. qiskit/circuit/library/standard_gates/u1.py +8 -3
  85. qiskit/circuit/library/standard_gates/u2.py +3 -0
  86. qiskit/circuit/library/standard_gates/u3.py +22 -7
  87. qiskit/circuit/library/standard_gates/x.py +158 -92
  88. qiskit/circuit/library/standard_gates/xx_minus_yy.py +40 -1
  89. qiskit/circuit/library/standard_gates/xx_plus_yy.py +52 -11
  90. qiskit/circuit/library/standard_gates/y.py +6 -1
  91. qiskit/circuit/library/standard_gates/z.py +8 -1
  92. qiskit/circuit/operation.py +1 -1
  93. qiskit/circuit/parameter.py +9 -10
  94. qiskit/circuit/parameterexpression.py +16 -13
  95. qiskit/circuit/parametertable.py +1 -190
  96. qiskit/circuit/parametervector.py +1 -1
  97. qiskit/circuit/quantumcircuit.py +395 -385
  98. qiskit/circuit/quantumcircuitdata.py +3 -5
  99. qiskit/circuit/quantumregister.py +1 -1
  100. qiskit/circuit/random/__init__.py +1 -1
  101. qiskit/circuit/random/utils.py +175 -26
  102. qiskit/circuit/register.py +5 -7
  103. qiskit/circuit/singleton.py +3 -3
  104. qiskit/circuit/tools/pi_check.py +4 -4
  105. qiskit/compiler/assembler.py +95 -24
  106. qiskit/compiler/scheduler.py +2 -2
  107. qiskit/compiler/transpiler.py +42 -128
  108. qiskit/converters/circuit_to_dag.py +4 -6
  109. qiskit/converters/circuit_to_gate.py +4 -8
  110. qiskit/converters/circuit_to_instruction.py +5 -17
  111. qiskit/converters/dag_to_circuit.py +2 -6
  112. qiskit/dagcircuit/collect_blocks.py +2 -2
  113. qiskit/dagcircuit/dagcircuit.py +197 -187
  114. qiskit/dagcircuit/dagdependency.py +4 -4
  115. qiskit/dagcircuit/dagdependency_v2.py +4 -4
  116. qiskit/dagcircuit/dagdepnode.py +1 -1
  117. qiskit/dagcircuit/dagnode.py +66 -157
  118. qiskit/passmanager/flow_controllers.py +1 -1
  119. qiskit/passmanager/passmanager.py +3 -3
  120. qiskit/primitives/__init__.py +1 -5
  121. qiskit/primitives/backend_estimator.py +25 -15
  122. qiskit/primitives/backend_estimator_v2.py +31 -7
  123. qiskit/primitives/backend_sampler.py +21 -12
  124. qiskit/primitives/backend_sampler_v2.py +12 -3
  125. qiskit/primitives/base/base_estimator.py +31 -4
  126. qiskit/primitives/base/base_primitive.py +2 -2
  127. qiskit/primitives/base/base_result.py +2 -2
  128. qiskit/primitives/base/base_sampler.py +26 -2
  129. qiskit/primitives/base/estimator_result.py +2 -2
  130. qiskit/primitives/base/sampler_result.py +2 -2
  131. qiskit/primitives/containers/__init__.py +0 -1
  132. qiskit/primitives/containers/bindings_array.py +2 -2
  133. qiskit/primitives/containers/bit_array.py +113 -12
  134. qiskit/primitives/containers/shape.py +3 -3
  135. qiskit/primitives/estimator.py +9 -2
  136. qiskit/primitives/primitive_job.py +1 -1
  137. qiskit/primitives/sampler.py +10 -3
  138. qiskit/primitives/statevector_estimator.py +5 -3
  139. qiskit/primitives/statevector_sampler.py +11 -5
  140. qiskit/primitives/utils.py +16 -0
  141. qiskit/providers/backend.py +15 -6
  142. qiskit/providers/backend_compat.py +7 -4
  143. qiskit/providers/basic_provider/basic_provider_tools.py +1 -1
  144. qiskit/providers/basic_provider/basic_simulator.py +33 -25
  145. qiskit/providers/fake_provider/fake_backend.py +10 -3
  146. qiskit/providers/fake_provider/fake_openpulse_2q.py +157 -149
  147. qiskit/providers/fake_provider/fake_openpulse_3q.py +228 -220
  148. qiskit/providers/fake_provider/fake_pulse_backend.py +2 -1
  149. qiskit/providers/fake_provider/fake_qasm_backend.py +7 -2
  150. qiskit/providers/fake_provider/generic_backend_v2.py +519 -68
  151. qiskit/providers/models/__init__.py +48 -11
  152. qiskit/providers/models/backendconfiguration.py +50 -4
  153. qiskit/providers/models/backendproperties.py +13 -2
  154. qiskit/providers/models/pulsedefaults.py +10 -11
  155. qiskit/providers/options.py +13 -13
  156. qiskit/providers/providerutils.py +3 -1
  157. qiskit/pulse/configuration.py +8 -12
  158. qiskit/pulse/instruction_schedule_map.py +3 -5
  159. qiskit/pulse/instructions/acquire.py +7 -8
  160. qiskit/pulse/instructions/instruction.py +2 -3
  161. qiskit/pulse/library/samplers/decorators.py +5 -9
  162. qiskit/pulse/library/symbolic_pulses.py +4 -7
  163. qiskit/pulse/library/waveform.py +2 -5
  164. qiskit/pulse/macros.py +11 -6
  165. qiskit/pulse/parser.py +8 -10
  166. qiskit/pulse/schedule.py +12 -20
  167. qiskit/pulse/transforms/alignments.py +1 -3
  168. qiskit/pulse/utils.py +1 -2
  169. qiskit/qasm/libs/stdgates.inc +35 -28
  170. qiskit/qasm2/__init__.py +7 -7
  171. qiskit/qasm2/export.py +5 -9
  172. qiskit/qasm2/parse.py +1 -1
  173. qiskit/qasm3/ast.py +9 -25
  174. qiskit/qasm3/exporter.py +582 -479
  175. qiskit/qasm3/printer.py +7 -16
  176. qiskit/qobj/common.py +10 -0
  177. qiskit/qobj/converters/lo_config.py +9 -0
  178. qiskit/qobj/converters/pulse_instruction.py +13 -6
  179. qiskit/qobj/pulse_qobj.py +69 -15
  180. qiskit/qobj/qasm_qobj.py +72 -20
  181. qiskit/qobj/utils.py +9 -0
  182. qiskit/qpy/__init__.py +1 -1
  183. qiskit/qpy/binary_io/circuits.py +8 -5
  184. qiskit/qpy/binary_io/schedules.py +1 -1
  185. qiskit/qpy/binary_io/value.py +3 -3
  186. qiskit/qpy/interface.py +3 -2
  187. qiskit/qpy/type_keys.py +2 -2
  188. qiskit/quantum_info/operators/channel/quantum_channel.py +3 -6
  189. qiskit/quantum_info/operators/channel/superop.py +2 -2
  190. qiskit/quantum_info/operators/channel/transformations.py +1 -1
  191. qiskit/quantum_info/operators/dihedral/dihedral.py +3 -4
  192. qiskit/quantum_info/operators/dihedral/dihedral_circuits.py +1 -3
  193. qiskit/quantum_info/operators/dihedral/random.py +6 -3
  194. qiskit/quantum_info/operators/measures.py +2 -2
  195. qiskit/quantum_info/operators/op_shape.py +12 -20
  196. qiskit/quantum_info/operators/operator.py +14 -21
  197. qiskit/quantum_info/operators/predicates.py +1 -0
  198. qiskit/quantum_info/operators/symplectic/base_pauli.py +7 -11
  199. qiskit/quantum_info/operators/symplectic/clifford.py +1 -1
  200. qiskit/quantum_info/operators/symplectic/pauli.py +14 -12
  201. qiskit/quantum_info/operators/symplectic/pauli_list.py +9 -10
  202. qiskit/quantum_info/operators/symplectic/random.py +1 -1
  203. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +15 -17
  204. qiskit/quantum_info/quaternion.py +1 -1
  205. qiskit/quantum_info/states/densitymatrix.py +5 -8
  206. qiskit/quantum_info/states/stabilizerstate.py +128 -37
  207. qiskit/quantum_info/states/statevector.py +4 -8
  208. qiskit/result/counts.py +2 -2
  209. qiskit/result/mitigation/correlated_readout_mitigator.py +2 -2
  210. qiskit/result/mitigation/local_readout_mitigator.py +2 -2
  211. qiskit/result/mitigation/utils.py +1 -3
  212. qiskit/result/models.py +17 -16
  213. qiskit/result/result.py +15 -20
  214. qiskit/scheduler/lowering.py +2 -2
  215. qiskit/synthesis/__init__.py +2 -1
  216. qiskit/synthesis/clifford/__init__.py +1 -1
  217. qiskit/synthesis/clifford/clifford_decompose_ag.py +2 -2
  218. qiskit/synthesis/clifford/clifford_decompose_bm.py +10 -240
  219. qiskit/synthesis/clifford/clifford_decompose_greedy.py +9 -303
  220. qiskit/synthesis/clifford/clifford_decompose_layers.py +25 -23
  221. qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_full.py +1 -1
  222. qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_general.py +1 -1
  223. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +2 -2
  224. qiskit/synthesis/discrete_basis/solovay_kitaev.py +24 -14
  225. qiskit/synthesis/evolution/evolution_synthesis.py +4 -2
  226. qiskit/synthesis/evolution/lie_trotter.py +46 -19
  227. qiskit/synthesis/evolution/product_formula.py +111 -55
  228. qiskit/synthesis/evolution/qdrift.py +40 -10
  229. qiskit/synthesis/evolution/suzuki_trotter.py +43 -33
  230. qiskit/synthesis/linear/__init__.py +1 -0
  231. qiskit/synthesis/linear/cnot_synth.py +22 -96
  232. qiskit/synthesis/linear/linear_depth_lnn.py +8 -8
  233. qiskit/synthesis/linear/linear_matrix_utils.py +13 -161
  234. qiskit/synthesis/linear_phase/cnot_phase_synth.py +1 -1
  235. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +3 -3
  236. qiskit/synthesis/linear_phase/cz_depth_lnn.py +1 -1
  237. qiskit/synthesis/one_qubit/one_qubit_decompose.py +29 -29
  238. qiskit/synthesis/permutation/permutation_full.py +5 -29
  239. qiskit/synthesis/permutation/permutation_lnn.py +2 -24
  240. qiskit/synthesis/permutation/permutation_utils.py +2 -59
  241. qiskit/synthesis/qft/__init__.py +1 -0
  242. qiskit/synthesis/qft/qft_decompose_full.py +79 -0
  243. qiskit/synthesis/qft/qft_decompose_lnn.py +17 -9
  244. qiskit/synthesis/stabilizer/stabilizer_circuit.py +6 -6
  245. qiskit/synthesis/stabilizer/stabilizer_decompose.py +2 -2
  246. qiskit/synthesis/two_qubit/local_invariance.py +8 -38
  247. qiskit/synthesis/two_qubit/two_qubit_decompose.py +48 -129
  248. qiskit/synthesis/unitary/aqc/cnot_structures.py +1 -1
  249. qiskit/synthesis/unitary/qsd.py +5 -3
  250. qiskit/transpiler/__init__.py +6 -5
  251. qiskit/transpiler/basepasses.py +1 -1
  252. qiskit/transpiler/coupling.py +3 -3
  253. qiskit/transpiler/instruction_durations.py +1 -2
  254. qiskit/transpiler/layout.py +6 -6
  255. qiskit/transpiler/passes/__init__.py +2 -0
  256. qiskit/transpiler/passes/basis/basis_translator.py +84 -64
  257. qiskit/transpiler/passes/basis/translate_parameterized.py +3 -5
  258. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
  259. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +10 -10
  260. qiskit/transpiler/passes/calibration/rx_builder.py +3 -3
  261. qiskit/transpiler/passes/calibration/rzx_builder.py +3 -3
  262. qiskit/transpiler/passes/layout/apply_layout.py +13 -3
  263. qiskit/transpiler/passes/layout/sabre_layout.py +10 -8
  264. qiskit/transpiler/passes/layout/sabre_pre_layout.py +4 -1
  265. qiskit/transpiler/passes/layout/set_layout.py +2 -2
  266. qiskit/transpiler/passes/layout/vf2_layout.py +1 -1
  267. qiskit/transpiler/passes/layout/vf2_utils.py +3 -3
  268. qiskit/transpiler/passes/optimization/__init__.py +1 -0
  269. qiskit/transpiler/passes/optimization/collect_cliffords.py +6 -15
  270. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +2 -2
  271. qiskit/transpiler/passes/optimization/commutation_analysis.py +7 -10
  272. qiskit/transpiler/passes/optimization/commutative_cancellation.py +35 -19
  273. qiskit/transpiler/passes/optimization/consolidate_blocks.py +17 -8
  274. qiskit/transpiler/passes/optimization/inverse_cancellation.py +6 -6
  275. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +64 -41
  276. qiskit/transpiler/passes/optimization/optimize_1q_gates.py +1 -1
  277. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +83 -0
  278. qiskit/transpiler/passes/optimization/template_matching/backward_match.py +1 -1
  279. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +2 -2
  280. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -1
  281. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -2
  282. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/pauli_2q_evolution_commutation.py +5 -1
  283. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +1 -1
  284. qiskit/transpiler/passes/routing/layout_transformation.py +2 -1
  285. qiskit/transpiler/passes/routing/sabre_swap.py +35 -26
  286. qiskit/transpiler/passes/routing/star_prerouting.py +80 -105
  287. qiskit/transpiler/passes/routing/stochastic_swap.py +1 -3
  288. qiskit/transpiler/passes/scheduling/alap.py +1 -2
  289. qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -2
  290. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
  291. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +2 -2
  292. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +1 -1
  293. qiskit/transpiler/passes/scheduling/asap.py +1 -2
  294. qiskit/transpiler/passes/scheduling/base_scheduler.py +5 -5
  295. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +3 -3
  296. qiskit/transpiler/passes/scheduling/padding/base_padding.py +1 -1
  297. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +20 -14
  298. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +7 -6
  299. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +4 -3
  300. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +211 -36
  301. qiskit/transpiler/passes/synthesis/plugin.py +2 -2
  302. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +83 -40
  303. qiskit/transpiler/passes/utils/__init__.py +0 -1
  304. qiskit/transpiler/passes/utils/check_gate_direction.py +4 -4
  305. qiskit/transpiler/passes/utils/check_map.py +3 -6
  306. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +3 -4
  307. qiskit/transpiler/passes/utils/error.py +2 -2
  308. qiskit/transpiler/passes/utils/fixed_point.py +3 -3
  309. qiskit/transpiler/passes/utils/gate_direction.py +1 -1
  310. qiskit/transpiler/passes/utils/gates_basis.py +1 -2
  311. qiskit/transpiler/passmanager.py +7 -6
  312. qiskit/transpiler/preset_passmanagers/__init__.py +4 -228
  313. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +73 -18
  314. qiskit/transpiler/preset_passmanagers/common.py +3 -6
  315. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +518 -0
  316. qiskit/transpiler/preset_passmanagers/level0.py +1 -1
  317. qiskit/transpiler/target.py +27 -8
  318. qiskit/user_config.py +29 -6
  319. qiskit/utils/classtools.py +3 -3
  320. qiskit/utils/deprecation.py +3 -2
  321. qiskit/utils/lazy_tester.py +2 -2
  322. qiskit/utils/optionals.py +8 -8
  323. qiskit/visualization/bloch.py +62 -24
  324. qiskit/visualization/circuit/_utils.py +34 -10
  325. qiskit/visualization/circuit/circuit_visualization.py +23 -16
  326. qiskit/visualization/circuit/latex.py +29 -27
  327. qiskit/visualization/circuit/matplotlib.py +4 -2
  328. qiskit/visualization/circuit/qcstyle.py +2 -2
  329. qiskit/visualization/circuit/text.py +9 -15
  330. qiskit/visualization/dag_visualization.py +12 -5
  331. qiskit/visualization/pass_manager_visualization.py +9 -9
  332. qiskit/visualization/pulse_v2/core.py +1 -1
  333. qiskit/visualization/pulse_v2/events.py +1 -1
  334. qiskit/visualization/pulse_v2/generators/frame.py +3 -4
  335. qiskit/visualization/pulse_v2/generators/waveform.py +5 -9
  336. qiskit/visualization/pulse_v2/layouts.py +1 -5
  337. qiskit/visualization/pulse_v2/plotters/matplotlib.py +1 -2
  338. qiskit/visualization/state_visualization.py +5 -6
  339. qiskit/visualization/timeline/plotters/matplotlib.py +1 -2
  340. qiskit/visualization/transition_visualization.py +7 -2
  341. {qiskit-1.1.1.dist-info → qiskit-1.2.0.dist-info}/METADATA +28 -28
  342. {qiskit-1.1.1.dist-info → qiskit-1.2.0.dist-info}/RECORD +346 -344
  343. {qiskit-1.1.1.dist-info → qiskit-1.2.0.dist-info}/WHEEL +1 -1
  344. {qiskit-1.1.1.dist-info → qiskit-1.2.0.dist-info}/entry_points.txt +3 -0
  345. qiskit/transpiler/passes/utils/block_to_matrix.py +0 -47
  346. {qiskit-1.1.1.dist-info → qiskit-1.2.0.dist-info}/LICENSE.txt +0 -0
  347. {qiskit-1.1.1.dist-info → qiskit-1.2.0.dist-info}/top_level.txt +0 -0
@@ -28,15 +28,15 @@ from qiskit.circuit import QuantumCircuit
28
28
  from qiskit.synthesis.linear.linear_matrix_utils import (
29
29
  calc_inverse_matrix,
30
30
  check_invertible_binary_matrix,
31
- _col_op,
32
- _row_op,
31
+ col_op,
32
+ row_op,
33
33
  )
34
34
 
35
35
 
36
36
  def _row_op_update_instructions(cx_instructions, mat, a, b):
37
37
  # Add a cx gate to the instructions and update the matrix mat
38
38
  cx_instructions.append((a, b))
39
- _row_op(mat, a, b)
39
+ row_op(mat, a, b)
40
40
 
41
41
 
42
42
  def _get_lower_triangular(n, mat, mat_inv):
@@ -62,7 +62,7 @@ def _get_lower_triangular(n, mat, mat_inv):
62
62
  first_j = j
63
63
  else:
64
64
  # cx_instructions_cols (L instructions) are not needed
65
- _col_op(mat, j, first_j)
65
+ col_op(mat, j, first_j)
66
66
  # Use row operations directed upwards to zero out all "1"s above the remaining "1" in row i
67
67
  for k in reversed(range(0, i)):
68
68
  if mat[k, first_j]:
@@ -70,8 +70,8 @@ def _get_lower_triangular(n, mat, mat_inv):
70
70
 
71
71
  # Apply only U instructions to get the permuted L
72
72
  for inst in cx_instructions_rows:
73
- _row_op(mat_t, inst[0], inst[1])
74
- _col_op(mat_inv_t, inst[0], inst[1])
73
+ row_op(mat_t, inst[0], inst[1])
74
+ col_op(mat_inv_t, inst[0], inst[1])
75
75
  return mat_t, mat_inv_t
76
76
 
77
77
 
@@ -210,7 +210,7 @@ def _north_west_to_identity(n, mat):
210
210
  def _optimize_cx_circ_depth_5n_line(mat):
211
211
  # Optimize CX circuit in depth bounded by 5n for LNN connectivity.
212
212
  # The algorithm [1] has two steps:
213
- # a) transform the originl matrix to a north-west matrix (m2nw),
213
+ # a) transform the original matrix to a north-west matrix (m2nw),
214
214
  # b) transform the north-west matrix to identity (nw2id).
215
215
  #
216
216
  # A square n-by-n matrix A is called north-west if A[i][j]=0 for all i+j>=n
@@ -222,7 +222,7 @@ def _optimize_cx_circ_depth_5n_line(mat):
222
222
 
223
223
  # According to [1] the synthesis is done on the inverse matrix
224
224
  # so the matrix mat is inverted at this step
225
- mat_inv = mat.copy()
225
+ mat_inv = mat.astype(bool, copy=True)
226
226
  mat_cpy = calc_inverse_matrix(mat_inv)
227
227
 
228
228
  n = len(mat_cpy)
@@ -12,164 +12,16 @@
12
12
 
13
13
  """Utility functions for handling binary matrices."""
14
14
 
15
- from typing import Optional, Union
16
- import numpy as np
17
- from qiskit.exceptions import QiskitError
18
-
19
-
20
- def check_invertible_binary_matrix(mat: np.ndarray):
21
- """Check that a binary matrix is invertible.
22
-
23
- Args:
24
- mat: a binary matrix.
25
-
26
- Returns:
27
- bool: True if mat in invertible and False otherwise.
28
- """
29
- if len(mat.shape) != 2 or mat.shape[0] != mat.shape[1]:
30
- return False
31
-
32
- rank = _compute_rank(mat)
33
- return rank == mat.shape[0]
34
-
35
-
36
- def random_invertible_binary_matrix(
37
- num_qubits: int, seed: Optional[Union[np.random.Generator, int]] = None
38
- ):
39
- """Generates a random invertible n x n binary matrix.
40
-
41
- Args:
42
- num_qubits: the matrix size.
43
- seed: a random seed.
44
-
45
- Returns:
46
- np.ndarray: A random invertible binary matrix of size num_qubits.
47
- """
48
- if isinstance(seed, np.random.Generator):
49
- rng = seed
50
- else:
51
- rng = np.random.default_rng(seed)
52
-
53
- rank = 0
54
- while rank != num_qubits:
55
- mat = rng.integers(2, size=(num_qubits, num_qubits))
56
- rank = _compute_rank(mat)
57
- return mat
58
-
59
-
60
- def _gauss_elimination(mat, ncols=None, full_elim=False):
61
- """Gauss elimination of a matrix mat with m rows and n columns.
62
- If full_elim = True, it allows full elimination of mat[:, 0 : ncols]
63
- Returns the matrix mat."""
64
-
65
- mat, _ = _gauss_elimination_with_perm(mat, ncols, full_elim)
66
- return mat
67
-
68
-
69
- def _gauss_elimination_with_perm(mat, ncols=None, full_elim=False):
70
- """Gauss elimination of a matrix mat with m rows and n columns.
71
- If full_elim = True, it allows full elimination of mat[:, 0 : ncols]
72
- Returns the matrix mat, and the permutation perm that was done on the rows during the process.
73
- perm[0 : rank] represents the indices of linearly independent rows in the original matrix."""
74
-
75
- # Treat the matrix A as containing integer values
76
- mat = np.array(mat, dtype=int, copy=True)
77
-
78
- m = mat.shape[0] # no. of rows
79
- n = mat.shape[1] # no. of columns
80
- if ncols is not None:
81
- n = min(n, ncols) # no. of active columns
82
-
83
- perm = np.array(range(m)) # permutation on the rows
84
-
85
- r = 0 # current rank
86
- k = 0 # current pivot column
87
- while (r < m) and (k < n):
88
- is_non_zero = False
89
- new_r = r
90
- for j in range(k, n):
91
- for i in range(r, m):
92
- if mat[i][j]:
93
- is_non_zero = True
94
- k = j
95
- new_r = i
96
- break
97
- if is_non_zero:
98
- break
99
- if not is_non_zero:
100
- return mat, perm # A is in the canonical form
101
-
102
- if new_r != r:
103
- mat[[r, new_r]] = mat[[new_r, r]]
104
- perm[r], perm[new_r] = perm[new_r], perm[r]
105
-
106
- if full_elim:
107
- for i in range(0, r):
108
- if mat[i][k]:
109
- mat[i] = mat[i] ^ mat[r]
110
-
111
- for i in range(r + 1, m):
112
- if mat[i][k]:
113
- mat[i] = mat[i] ^ mat[r]
114
- r += 1
115
-
116
- return mat, perm
117
-
118
-
119
- def calc_inverse_matrix(mat: np.ndarray, verify: bool = False):
120
- """Given a square numpy(dtype=int) matrix mat, tries to compute its inverse.
121
-
122
- Args:
123
- mat: a boolean square matrix.
124
- verify: if True asserts that the multiplication of mat and its inverse is the identity matrix.
125
-
126
- Returns:
127
- np.ndarray: the inverse matrix.
128
-
129
- Raises:
130
- QiskitError: if the matrix is not square.
131
- QiskitError: if the matrix is not invertible.
132
- """
133
-
134
- if mat.shape[0] != mat.shape[1]:
135
- raise QiskitError("Matrix to invert is a non-square matrix.")
136
-
137
- n = mat.shape[0]
138
- # concatenate the matrix and identity
139
- mat1 = np.concatenate((mat, np.eye(n, dtype=int)), axis=1)
140
- mat1 = _gauss_elimination(mat1, None, full_elim=True)
141
-
142
- r = _compute_rank_after_gauss_elim(mat1[:, 0:n])
143
-
144
- if r < n:
145
- raise QiskitError("The matrix is not invertible.")
146
-
147
- matinv = mat1[:, n : 2 * n]
148
-
149
- if verify:
150
- mat2 = np.dot(mat, matinv) % 2
151
- assert np.array_equal(mat2, np.eye(n))
152
-
153
- return matinv
154
-
155
-
156
- def _compute_rank_after_gauss_elim(mat):
157
- """Given a matrix A after Gaussian elimination, computes its rank
158
- (i.e. simply the number of nonzero rows)"""
159
- return np.sum(mat.any(axis=1))
160
-
161
-
162
- def _compute_rank(mat):
163
- """Given a matrix A computes its rank"""
164
- mat = _gauss_elimination(mat)
165
- return np.sum(mat.any(axis=1))
166
-
167
-
168
- def _row_op(mat, ctrl, trgt):
169
- # Perform ROW operation on a matrix mat
170
- mat[trgt] = mat[trgt] ^ mat[ctrl]
171
-
172
-
173
- def _col_op(mat, ctrl, trgt):
174
- # Perform COL operation on a matrix mat
175
- mat[:, ctrl] = mat[:, trgt] ^ mat[:, ctrl]
15
+ # pylint: disable=unused-import
16
+ from qiskit._accelerate.synthesis.linear import (
17
+ gauss_elimination,
18
+ gauss_elimination_with_perm,
19
+ compute_rank_after_gauss_elim,
20
+ compute_rank,
21
+ calc_inverse_matrix,
22
+ binary_matmul,
23
+ random_invertible_binary_matrix,
24
+ check_invertible_binary_matrix,
25
+ row_op,
26
+ col_op,
27
+ )
@@ -123,7 +123,7 @@ def synth_cnot_phase_aam(
123
123
 
124
124
  # Implementation of the pseudo-code (Algorithm 1) in the aforementioned paper
125
125
  sta.append([cnots, range_list, epsilon])
126
- while sta != []:
126
+ while sta:
127
127
  [cnots, ilist, qubit] = sta.pop()
128
128
  if cnots == []:
129
129
  continue
@@ -39,7 +39,7 @@ from qiskit.synthesis.linear.linear_depth_lnn import _optimize_cx_circ_depth_5n_
39
39
  def _initialize_phase_schedule(mat_z):
40
40
  """
41
41
  Given a CZ layer (represented as an n*n CZ matrix Mz)
42
- Return a scheudle of phase gates implementing Mz in a SWAP-only netwrok
42
+ Return a schedule of phase gates implementing Mz in a SWAP-only netwrok
43
43
  (c.f. Alg 1, [2])
44
44
  """
45
45
  n = len(mat_z)
@@ -173,7 +173,7 @@ def _apply_phase_to_nw_circuit(n, phase_schedule, seq, swap_plus):
173
173
  of exactly n layers of boxes, each being either a SWAP or a SWAP+. That is,
174
174
  each northwest diagonalization circuit can be uniquely represented by which
175
175
  of its n(n-1)/2 boxes are SWAP+ and which are SWAP.
176
- Return a QuantumCircuit that computes the phase scheudle S inside CX
176
+ Return a QuantumCircuit that computes the phase schedule S inside CX
177
177
  """
178
178
  cir = QuantumCircuit(n)
179
179
 
@@ -217,7 +217,7 @@ def _apply_phase_to_nw_circuit(n, phase_schedule, seq, swap_plus):
217
217
 
218
218
  def synth_cx_cz_depth_line_my(mat_x: np.ndarray, mat_z: np.ndarray) -> QuantumCircuit:
219
219
  """
220
- Joint synthesis of a -CZ-CX- circuit for linear nearest neighbour (LNN) connectivity,
220
+ Joint synthesis of a -CZ-CX- circuit for linear nearest neighbor (LNN) connectivity,
221
221
  with 2-qubit depth at most 5n, based on Maslov and Yang.
222
222
  This method computes the CZ circuit inside the CX circuit via phase gate insertions.
223
223
 
@@ -119,7 +119,7 @@ def _create_patterns(n):
119
119
 
120
120
 
121
121
  def synth_cz_depth_line_mr(mat: np.ndarray) -> QuantumCircuit:
122
- r"""Synthesis of a CZ circuit for linear nearest neighbour (LNN) connectivity,
122
+ r"""Synthesis of a CZ circuit for linear nearest neighbor (LNN) connectivity,
123
123
  based on Maslov and Roetteler.
124
124
 
125
125
  Note that this method *reverts* the order of qubits in the circuit,
@@ -14,6 +14,7 @@
14
14
  Decompose a single-qubit unitary via Euler angles.
15
15
  """
16
16
  from __future__ import annotations
17
+ from typing import TYPE_CHECKING
17
18
  import numpy as np
18
19
 
19
20
  from qiskit._accelerate import euler_one_qubit_decomposer
@@ -37,6 +38,9 @@ from qiskit.quantum_info.operators.predicates import is_unitary_matrix
37
38
  from qiskit.circuit.gate import Gate
38
39
  from qiskit.quantum_info.operators.operator import Operator
39
40
 
41
+ if TYPE_CHECKING:
42
+ from qiskit.dagcircuit import DAGCircuit
43
+
40
44
  DEFAULT_ATOL = 1e-12
41
45
 
42
46
  ONE_QUBIT_EULER_BASIS_GATES = {
@@ -150,43 +154,33 @@ class OneQubitEulerDecomposer:
150
154
  self.basis = basis # sets: self._basis, self._params, self._circuit
151
155
  self.use_dag = use_dag
152
156
 
153
- def build_circuit(self, gates, global_phase):
157
+ def build_circuit(self, gates, global_phase) -> QuantumCircuit | DAGCircuit:
154
158
  """Return the circuit or dag object from a list of gates."""
155
159
  qr = [Qubit()]
156
160
  lookup_gate = False
157
161
  if len(gates) > 0 and isinstance(gates[0], tuple):
158
162
  lookup_gate = True
159
163
 
160
- if self.use_dag:
161
- from qiskit.dagcircuit import dagcircuit
162
-
163
- dag = dagcircuit.DAGCircuit()
164
- dag.global_phase = global_phase
165
- dag.add_qubits(qr)
166
- for gate_entry in gates:
167
- if lookup_gate:
168
- gate = NAME_MAP[gate_entry[0]](*gate_entry[1])
169
- else:
170
- gate = gate_entry
171
-
172
- dag.apply_operation_back(gate, (qr[0],), check=False)
173
- return dag
174
- else:
175
- circuit = QuantumCircuit(qr, global_phase=global_phase)
176
- for gate_entry in gates:
177
- if lookup_gate:
178
- gate = NAME_MAP[gate_entry[0]](*gate_entry[1])
179
- else:
180
- gate = gate_entry
181
- circuit._append(gate, [qr[0]], [])
182
- return circuit
164
+ from qiskit.dagcircuit import dagcircuit
165
+
166
+ dag = dagcircuit.DAGCircuit()
167
+ dag.global_phase = global_phase
168
+ dag.add_qubits(qr)
169
+ for gate_entry in gates:
170
+ if lookup_gate:
171
+ gate = NAME_MAP[gate_entry[0].name](*gate_entry[1])
172
+ else:
173
+ gate = gate_entry.name
174
+
175
+ dag.apply_operation_back(gate, (qr[0],), check=False)
176
+ return dag
183
177
 
184
178
  def __call__(
185
179
  self,
186
180
  unitary: Operator | Gate | np.ndarray,
187
181
  simplify: bool = True,
188
182
  atol: float = DEFAULT_ATOL,
189
- ) -> QuantumCircuit:
183
+ ) -> QuantumCircuit | DAGCircuit:
190
184
  """Decompose single qubit gate into a circuit.
191
185
 
192
186
  Args:
@@ -221,11 +215,17 @@ class OneQubitEulerDecomposer:
221
215
  return self._decompose(unitary, simplify=simplify, atol=atol)
222
216
 
223
217
  def _decompose(self, unitary, simplify=True, atol=DEFAULT_ATOL):
224
- circuit_sequence = euler_one_qubit_decomposer.unitary_to_gate_sequence(
225
- unitary, [self.basis], 0, None, simplify, atol
218
+ if self.use_dag:
219
+ circuit_sequence = euler_one_qubit_decomposer.unitary_to_gate_sequence(
220
+ unitary, [self.basis], 0, None, simplify, atol
221
+ )
222
+ circuit = self.build_circuit(circuit_sequence, circuit_sequence.global_phase)
223
+ return circuit
224
+ return QuantumCircuit._from_circuit_data(
225
+ euler_one_qubit_decomposer.unitary_to_circuit(
226
+ unitary, [self.basis], 0, None, simplify, atol
227
+ )
226
228
  )
227
- circuit = self.build_circuit(circuit_sequence, circuit_sequence.global_phase)
228
- return circuit
229
229
 
230
230
  @property
231
231
  def basis(self):
@@ -16,11 +16,9 @@ from __future__ import annotations
16
16
 
17
17
  import numpy as np
18
18
  from qiskit.circuit.quantumcircuit import QuantumCircuit
19
- from .permutation_utils import (
20
- _get_ordered_swap,
21
- _inverse_pattern,
22
- _pattern_to_cycles,
23
- _decompose_cycles,
19
+ from qiskit._accelerate.synthesis.permutation import (
20
+ _synth_permutation_basic,
21
+ _synth_permutation_acg,
24
22
  )
25
23
 
26
24
 
@@ -44,17 +42,7 @@ def synth_permutation_basic(pattern: list[int] | np.ndarray[int]) -> QuantumCirc
44
42
  Returns:
45
43
  The synthesized quantum circuit.
46
44
  """
47
- # This is the very original Qiskit algorithm for synthesizing permutations.
48
-
49
- num_qubits = len(pattern)
50
- qc = QuantumCircuit(num_qubits)
51
-
52
- swaps = _get_ordered_swap(pattern)
53
-
54
- for swap in swaps:
55
- qc.swap(swap[0], swap[1])
56
-
57
- return qc
45
+ return QuantumCircuit._from_circuit_data(_synth_permutation_basic(pattern))
58
46
 
59
47
 
60
48
  def synth_permutation_acg(pattern: list[int] | np.ndarray[int]) -> QuantumCircuit:
@@ -87,16 +75,4 @@ def synth_permutation_acg(pattern: list[int] | np.ndarray[int]) -> QuantumCircui
87
75
  *Routing Permutations on Graphs Via Matchings.*,
88
76
  `(Full paper) <https://www.cs.tau.ac.il/~nogaa/PDFS/r.pdf>`_
89
77
  """
90
-
91
- num_qubits = len(pattern)
92
- qc = QuantumCircuit(num_qubits)
93
-
94
- # invert pattern (Qiskit notation is opposite)
95
- cur_pattern = _inverse_pattern(pattern)
96
- cycles = _pattern_to_cycles(cur_pattern)
97
- swaps = _decompose_cycles(cycles)
98
-
99
- for swap in swaps:
100
- qc.swap(swap[0], swap[1])
101
-
102
- return qc
78
+ return QuantumCircuit._from_circuit_data(_synth_permutation_acg(pattern))
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
  import numpy as np
17
17
  from qiskit.circuit.quantumcircuit import QuantumCircuit
18
- from .permutation_utils import _inverse_pattern
18
+ from qiskit._accelerate.synthesis.permutation import _synth_permutation_depth_lnn_kms
19
19
 
20
20
 
21
21
  def synth_permutation_depth_lnn_kms(pattern: list[int] | np.ndarray[int]) -> QuantumCircuit:
@@ -49,26 +49,4 @@ def synth_permutation_depth_lnn_kms(pattern: list[int] | np.ndarray[int]) -> Qua
49
49
  # In the permutation synthesis code below the notation is opposite:
50
50
  # [2, 4, 3, 0, 1] means that 0 maps to 2, 1 to 3, 2 to 3, 3 to 0, and 4 to 1.
51
51
  # This is why we invert the pattern.
52
- cur_pattern = _inverse_pattern(pattern)
53
-
54
- num_qubits = len(cur_pattern)
55
- qc = QuantumCircuit(num_qubits)
56
-
57
- # add conditional odd-even swap layers
58
- for i in range(num_qubits):
59
- _create_swap_layer(qc, cur_pattern, i % 2)
60
-
61
- return qc
62
-
63
-
64
- def _create_swap_layer(qc, pattern, starting_point):
65
- """Implements a single swap layer, consisting of conditional swaps between each
66
- neighboring couple. The starting_point is the first qubit to use (either 0 or 1
67
- for even or odd layers respectively). Mutates both the quantum circuit ``qc``
68
- and the permutation pattern ``pattern``.
69
- """
70
- num_qubits = len(pattern)
71
- for j in range(starting_point, num_qubits - 1, 2):
72
- if pattern[j] > pattern[j + 1]:
73
- qc.swap(j, j + 1)
74
- pattern[j], pattern[j + 1] = pattern[j + 1], pattern[j]
52
+ return QuantumCircuit._from_circuit_data(_synth_permutation_depth_lnn_kms(pattern))
@@ -12,62 +12,5 @@
12
12
 
13
13
  """Utility functions for handling permutations."""
14
14
 
15
-
16
- def _get_ordered_swap(permutation_in):
17
- """Sorts the input permutation by iterating through the permutation list
18
- and putting each element to its correct position via a SWAP (if it's not
19
- at the correct position already). If ``n`` is the length of the input
20
- permutation, this requires at most ``n`` SWAPs.
21
-
22
- More precisely, if the input permutation is a cycle of length ``m``,
23
- then this creates a quantum circuit with ``m-1`` SWAPs (and of depth ``m-1``);
24
- if the input permutation consists of several disjoint cycles, then each cycle
25
- is essentially treated independently.
26
- """
27
- permutation = list(permutation_in[:])
28
- swap_list = []
29
- index_map = _inverse_pattern(permutation_in)
30
- for i, val in enumerate(permutation):
31
- if val != i:
32
- j = index_map[i]
33
- swap_list.append((i, j))
34
- permutation[i], permutation[j] = permutation[j], permutation[i]
35
- index_map[val] = j
36
- index_map[i] = i
37
- swap_list.reverse()
38
- return swap_list
39
-
40
-
41
- def _inverse_pattern(pattern):
42
- """Finds inverse of a permutation pattern."""
43
- b_map = {pos: idx for idx, pos in enumerate(pattern)}
44
- return [b_map[pos] for pos in range(len(pattern))]
45
-
46
-
47
- def _pattern_to_cycles(pattern):
48
- """Given a permutation pattern, creates its disjoint cycle decomposition."""
49
- nq = len(pattern)
50
- explored = [False] * nq
51
- cycles = []
52
- for i in pattern:
53
- cycle = []
54
- while not explored[i]:
55
- cycle.append(i)
56
- explored[i] = True
57
- i = pattern[i]
58
- if len(cycle) >= 2:
59
- cycles.append(cycle)
60
- return cycles
61
-
62
-
63
- def _decompose_cycles(cycles):
64
- """Given a disjoint cycle decomposition, decomposes every cycle into a SWAP
65
- circuit of depth 2."""
66
- swap_list = []
67
- for cycle in cycles:
68
- m = len(cycle)
69
- for i in range((m - 1) // 2):
70
- swap_list.append((cycle[i - 1], cycle[m - 3 - i]))
71
- for i in range(m // 2):
72
- swap_list.append((cycle[i - 1], cycle[m - 2 - i]))
73
- return swap_list
15
+ # pylint: disable=unused-import
16
+ from qiskit._accelerate.synthesis.permutation import _inverse_pattern, _validate_permutation
@@ -13,3 +13,4 @@
13
13
  """Module containing stabilizer QFT circuit synthesis."""
14
14
 
15
15
  from .qft_decompose_lnn import synth_qft_line
16
+ from .qft_decompose_full import synth_qft_full
@@ -0,0 +1,79 @@
1
+ # This code is part of Qiskit.
2
+ #
3
+ # (C) Copyright IBM 2024.
4
+ #
5
+ # This code is licensed under the Apache License, Version 2.0. You may
6
+ # obtain a copy of this license in the LICENSE.txt file in the root directory
7
+ # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8
+ #
9
+ # Any modifications or derivative works of this code must retain this
10
+ # copyright notice, and modified files need to carry a notice indicating
11
+ # that they have been altered from the originals.
12
+ """
13
+ Circuit synthesis for a QFT circuit.
14
+ """
15
+
16
+ from __future__ import annotations
17
+ import numpy as np
18
+ from qiskit.circuit.quantumcircuit import QuantumCircuit
19
+
20
+
21
+ def synth_qft_full(
22
+ num_qubits: int,
23
+ do_swaps: bool = True,
24
+ approximation_degree: int = 0,
25
+ insert_barriers: bool = False,
26
+ inverse: bool = False,
27
+ name: str | None = None,
28
+ ) -> QuantumCircuit:
29
+ """Construct a circuit for the Quantum Fourier Transform using all-to-all connectivity.
30
+
31
+ .. note::
32
+
33
+ With the default value of ``do_swaps = True``, this synthesis algorithm creates a
34
+ circuit that faithfully implements the QFT operation. This circuit contains a sequence
35
+ of swap gates at the end, corresponding to reversing the order of its output qubits.
36
+ In some applications this reversal permutation can be avoided. Setting ``do_swaps = False``
37
+ creates a circuit without this reversal permutation, at the expense that this circuit
38
+ implements the "QFT-with-reversal" instead of QFT. Alternatively, the
39
+ :class:`~.ElidePermutations` transpiler pass is able to remove these swap gates.
40
+
41
+ Args:
42
+ num_qubits: The number of qubits on which the Quantum Fourier Transform acts.
43
+ do_swaps: Whether to synthesize the "QFT" or the "QFT-with-reversal" operation.
44
+ approximation_degree: The degree of approximation (0 for no approximation).
45
+ It is possible to implement the QFT approximately by ignoring
46
+ controlled-phase rotations with the angle beneath a threshold. This is discussed
47
+ in more detail in https://arxiv.org/abs/quant-ph/9601018 or
48
+ https://arxiv.org/abs/quant-ph/0403071.
49
+ insert_barriers: If ``True``, barriers are inserted for improved visualization.
50
+ inverse: If ``True``, the inverse Quantum Fourier Transform is constructed.
51
+ name: The name of the circuit.
52
+
53
+ Returns:
54
+ A circuit implementing the QFT operation.
55
+
56
+ """
57
+
58
+ circuit = QuantumCircuit(num_qubits, name=name)
59
+
60
+ for j in reversed(range(num_qubits)):
61
+ circuit.h(j)
62
+ num_entanglements = max(0, j - max(0, approximation_degree - (num_qubits - j - 1)))
63
+ for k in reversed(range(j - num_entanglements, j)):
64
+ # Use negative exponents so that the angle safely underflows to zero, rather than
65
+ # using a temporary variable that overflows to infinity in the worst case.
66
+ lam = np.pi * (2.0 ** (k - j))
67
+ circuit.cp(lam, j, k)
68
+
69
+ if insert_barriers:
70
+ circuit.barrier()
71
+
72
+ if do_swaps:
73
+ for i in range(num_qubits // 2):
74
+ circuit.swap(i, num_qubits - i - 1)
75
+
76
+ if inverse:
77
+ circuit = circuit.inverse()
78
+
79
+ return circuit
@@ -21,21 +21,29 @@ from qiskit.synthesis.permutation.permutation_reverse_lnn import _append_reverse
21
21
  def synth_qft_line(
22
22
  num_qubits: int, do_swaps: bool = True, approximation_degree: int = 0
23
23
  ) -> QuantumCircuit:
24
- """Synthesis of a QFT circuit for a linear nearest neighbor connectivity.
25
- Based on Fig 2.b in Fowler et al. [1].
24
+ """Construct a circuit for the Quantum Fourier Transform using linear
25
+ neighbor connectivity.
26
26
 
27
- Note that this method *reverts* the order of qubits in the circuit,
28
- compared to the original :class:`.QFT` code.
29
- Hence, the default value of the ``do_swaps`` parameter is ``True``
30
- since it produces a circuit with fewer CX gates.
27
+ The construction is based on Fig 2.b in Fowler et al. [1].
28
+
29
+ .. note::
30
+
31
+ With the default value of ``do_swaps = True``, this synthesis algorithm creates a
32
+ circuit that faithfully implements the QFT operation. When ``do_swaps = False``,
33
+ this synthesis algorithm creates a circuit that corresponds to "QFT-with-reversal":
34
+ applying the QFT and reversing the order of its output qubits.
31
35
 
32
36
  Args:
33
- num_qubits: The number of qubits on which the QFT acts.
37
+ num_qubits: The number of qubits on which the Quantum Fourier Transform acts.
34
38
  approximation_degree: The degree of approximation (0 for no approximation).
35
- do_swaps: Whether to include the final swaps in the QFT.
39
+ It is possible to implement the QFT approximately by ignoring
40
+ controlled-phase rotations with the angle beneath a threshold. This is discussed
41
+ in more detail in https://arxiv.org/abs/quant-ph/9601018 or
42
+ https://arxiv.org/abs/quant-ph/0403071.
43
+ do_swaps: Whether to synthesize the "QFT" or the "QFT-with-reversal" operation.
36
44
 
37
45
  Returns:
38
- A circuit implementation of the QFT circuit.
46
+ A circuit implementing the QFT operation.
39
47
 
40
48
  References:
41
49
  1. A. G. Fowler, S. J. Devitt, and L. C. L. Hollenberg,