qiskit 1.4.2__cp39-abi3-macosx_11_0_arm64.whl → 2.0.0__cp39-abi3-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (459) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +3 -9
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/circuit/__init__.py +35 -10
  5. qiskit/circuit/{add_control.py → _add_control.py} +32 -12
  6. qiskit/circuit/_classical_resource_map.py +5 -3
  7. qiskit/circuit/barrier.py +3 -7
  8. qiskit/circuit/classical/expr/__init__.py +31 -3
  9. qiskit/circuit/classical/expr/constructors.py +236 -28
  10. qiskit/circuit/classical/expr/expr.py +104 -3
  11. qiskit/circuit/classical/expr/visitors.py +75 -0
  12. qiskit/circuit/classical/types/__init__.py +12 -8
  13. qiskit/circuit/classical/types/ordering.py +14 -7
  14. qiskit/circuit/classical/types/types.py +36 -0
  15. qiskit/circuit/commutation_checker.py +34 -7
  16. qiskit/circuit/controlflow/__init__.py +32 -1
  17. qiskit/circuit/controlflow/_builder_utils.py +9 -5
  18. qiskit/circuit/controlflow/box.py +163 -0
  19. qiskit/circuit/controlflow/break_loop.py +1 -1
  20. qiskit/circuit/controlflow/builder.py +139 -39
  21. qiskit/circuit/controlflow/continue_loop.py +1 -3
  22. qiskit/circuit/controlflow/control_flow.py +10 -0
  23. qiskit/circuit/controlflow/for_loop.py +2 -1
  24. qiskit/circuit/controlflow/if_else.py +3 -16
  25. qiskit/circuit/controlflow/switch_case.py +2 -8
  26. qiskit/circuit/controlflow/while_loop.py +2 -7
  27. qiskit/circuit/controlledgate.py +2 -4
  28. qiskit/circuit/delay.py +40 -11
  29. qiskit/circuit/duration.py +0 -15
  30. qiskit/circuit/gate.py +2 -4
  31. qiskit/circuit/instruction.py +2 -141
  32. qiskit/circuit/instructionset.py +7 -54
  33. qiskit/circuit/library/__init__.py +469 -154
  34. qiskit/circuit/library/arithmetic/__init__.py +16 -10
  35. qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  36. qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +2 -2
  37. qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +1 -1
  38. qiskit/circuit/library/arithmetic/exact_reciprocal.py +64 -21
  39. qiskit/circuit/library/arithmetic/integer_comparator.py +37 -80
  40. qiskit/circuit/library/arithmetic/linear_amplitude_function.py +169 -2
  41. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +59 -5
  42. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +154 -6
  43. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +114 -4
  44. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +191 -15
  45. qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +93 -39
  46. qiskit/circuit/library/arithmetic/quadratic_form.py +168 -2
  47. qiskit/circuit/library/arithmetic/weighted_adder.py +73 -1
  48. qiskit/circuit/library/bit_flip_oracle.py +130 -0
  49. qiskit/circuit/library/blueprintcircuit.py +52 -16
  50. qiskit/circuit/library/data_preparation/initializer.py +1 -1
  51. qiskit/circuit/library/data_preparation/pauli_feature_map.py +4 -4
  52. qiskit/circuit/library/data_preparation/state_preparation.py +1 -1
  53. qiskit/circuit/library/generalized_gates/gms.py +1 -1
  54. qiskit/circuit/library/generalized_gates/isometry.py +1 -1
  55. qiskit/circuit/library/generalized_gates/pauli.py +1 -2
  56. qiskit/circuit/library/generalized_gates/uc.py +97 -7
  57. qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +1 -1
  58. qiskit/circuit/library/generalized_gates/unitary.py +4 -2
  59. qiskit/circuit/library/graph_state.py +1 -0
  60. qiskit/circuit/library/hamiltonian_gate.py +1 -1
  61. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
  62. qiskit/circuit/library/n_local/n_local.py +1 -1
  63. qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -1
  64. qiskit/circuit/library/overlap.py +2 -2
  65. qiskit/circuit/library/pauli_evolution.py +39 -24
  66. qiskit/circuit/library/phase_oracle.py +130 -51
  67. qiskit/circuit/library/standard_gates/__init__.py +0 -1
  68. qiskit/circuit/library/standard_gates/dcx.py +3 -4
  69. qiskit/circuit/library/standard_gates/ecr.py +3 -4
  70. qiskit/circuit/library/standard_gates/global_phase.py +5 -6
  71. qiskit/circuit/library/standard_gates/h.py +4 -9
  72. qiskit/circuit/library/standard_gates/i.py +2 -2
  73. qiskit/circuit/library/standard_gates/iswap.py +3 -4
  74. qiskit/circuit/library/standard_gates/p.py +15 -34
  75. qiskit/circuit/library/standard_gates/r.py +7 -10
  76. qiskit/circuit/library/standard_gates/rx.py +5 -15
  77. qiskit/circuit/library/standard_gates/rxx.py +3 -6
  78. qiskit/circuit/library/standard_gates/ry.py +5 -17
  79. qiskit/circuit/library/standard_gates/ryy.py +3 -6
  80. qiskit/circuit/library/standard_gates/rz.py +5 -17
  81. qiskit/circuit/library/standard_gates/rzx.py +3 -6
  82. qiskit/circuit/library/standard_gates/rzz.py +3 -6
  83. qiskit/circuit/library/standard_gates/s.py +6 -15
  84. qiskit/circuit/library/standard_gates/swap.py +4 -11
  85. qiskit/circuit/library/standard_gates/sx.py +7 -12
  86. qiskit/circuit/library/standard_gates/t.py +6 -7
  87. qiskit/circuit/library/standard_gates/u.py +2 -10
  88. qiskit/circuit/library/standard_gates/u1.py +5 -16
  89. qiskit/circuit/library/standard_gates/u2.py +2 -6
  90. qiskit/circuit/library/standard_gates/u3.py +3 -11
  91. qiskit/circuit/library/standard_gates/x.py +14 -62
  92. qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -5
  93. qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -5
  94. qiskit/circuit/library/standard_gates/y.py +4 -9
  95. qiskit/circuit/library/standard_gates/z.py +5 -15
  96. qiskit/circuit/measure.py +11 -2
  97. qiskit/circuit/parameterexpression.py +7 -1
  98. qiskit/circuit/quantumcircuit.py +890 -564
  99. qiskit/circuit/random/utils.py +12 -6
  100. qiskit/circuit/reset.py +5 -2
  101. qiskit/circuit/singleton.py +5 -11
  102. qiskit/circuit/store.py +0 -8
  103. qiskit/compiler/__init__.py +1 -7
  104. qiskit/compiler/transpiler.py +38 -196
  105. qiskit/converters/circuit_to_dag.py +6 -4
  106. qiskit/converters/circuit_to_dagdependency.py +0 -2
  107. qiskit/converters/circuit_to_dagdependency_v2.py +0 -1
  108. qiskit/converters/circuit_to_gate.py +1 -1
  109. qiskit/converters/circuit_to_instruction.py +16 -29
  110. qiskit/converters/dag_to_circuit.py +7 -8
  111. qiskit/converters/dag_to_dagdependency.py +0 -1
  112. qiskit/converters/dag_to_dagdependency_v2.py +0 -1
  113. qiskit/converters/dagdependency_to_circuit.py +0 -6
  114. qiskit/converters/dagdependency_to_dag.py +0 -6
  115. qiskit/dagcircuit/collect_blocks.py +32 -20
  116. qiskit/dagcircuit/dagdependency.py +3 -37
  117. qiskit/dagcircuit/dagdependency_v2.py +5 -82
  118. qiskit/dagcircuit/dagnode.py +14 -2
  119. qiskit/passmanager/__init__.py +24 -6
  120. qiskit/passmanager/passmanager.py +26 -24
  121. qiskit/primitives/__init__.py +44 -35
  122. qiskit/primitives/backend_estimator_v2.py +102 -23
  123. qiskit/primitives/backend_sampler_v2.py +5 -20
  124. qiskit/primitives/base/__init__.py +4 -4
  125. qiskit/primitives/base/base_estimator.py +77 -82
  126. qiskit/primitives/base/base_primitive_job.py +2 -2
  127. qiskit/primitives/base/{base_primitive.py → base_primitive_v1.py} +1 -1
  128. qiskit/primitives/base/{base_result.py → base_result_v1.py} +1 -1
  129. qiskit/primitives/base/base_sampler.py +52 -60
  130. qiskit/primitives/base/{estimator_result.py → estimator_result_v1.py} +2 -2
  131. qiskit/primitives/base/{sampler_result.py → sampler_result_v1.py} +2 -2
  132. qiskit/primitives/base/{validation.py → validation_v1.py} +34 -15
  133. qiskit/primitives/containers/bindings_array.py +3 -1
  134. qiskit/primitives/containers/bit_array.py +23 -0
  135. qiskit/primitives/containers/data_bin.py +3 -1
  136. qiskit/primitives/containers/observables_array.py +19 -2
  137. qiskit/primitives/statevector_sampler.py +6 -8
  138. qiskit/primitives/utils.py +14 -189
  139. qiskit/providers/__init__.py +4 -130
  140. qiskit/providers/backend.py +11 -314
  141. qiskit/providers/basic_provider/__init__.py +3 -1
  142. qiskit/providers/basic_provider/basic_provider.py +29 -9
  143. qiskit/providers/basic_provider/basic_simulator.py +158 -298
  144. qiskit/providers/exceptions.py +0 -33
  145. qiskit/providers/fake_provider/__init__.py +0 -37
  146. qiskit/providers/fake_provider/generic_backend_v2.py +32 -693
  147. qiskit/qasm2/__init__.py +21 -6
  148. qiskit/qasm2/export.py +2 -10
  149. qiskit/qasm2/parse.py +11 -25
  150. qiskit/qasm3/__init__.py +5 -1
  151. qiskit/qasm3/ast.py +44 -0
  152. qiskit/qasm3/exporter.py +65 -27
  153. qiskit/qasm3/printer.py +35 -4
  154. qiskit/qpy/__init__.py +162 -19
  155. qiskit/qpy/binary_io/__init__.py +0 -1
  156. qiskit/qpy/binary_io/circuits.py +98 -130
  157. qiskit/qpy/binary_io/schedules.py +69 -439
  158. qiskit/qpy/binary_io/value.py +154 -31
  159. qiskit/qpy/common.py +10 -7
  160. qiskit/qpy/formats.py +41 -0
  161. qiskit/qpy/interface.py +34 -81
  162. qiskit/qpy/type_keys.py +58 -221
  163. qiskit/quantum_info/analysis/distance.py +3 -1
  164. qiskit/quantum_info/operators/dihedral/dihedral.py +3 -1
  165. qiskit/quantum_info/operators/operator.py +6 -2
  166. qiskit/quantum_info/operators/symplectic/clifford.py +3 -1
  167. qiskit/quantum_info/operators/symplectic/pauli.py +4 -2
  168. qiskit/quantum_info/operators/symplectic/pauli_list.py +17 -5
  169. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +40 -6
  170. qiskit/quantum_info/states/densitymatrix.py +16 -6
  171. qiskit/quantum_info/states/stabilizerstate.py +35 -4
  172. qiskit/quantum_info/states/statevector.py +16 -6
  173. qiskit/result/__init__.py +5 -17
  174. qiskit/result/models.py +18 -11
  175. qiskit/result/result.py +38 -134
  176. qiskit/result/sampled_expval.py +1 -2
  177. qiskit/result/utils.py +3 -4
  178. qiskit/synthesis/__init__.py +21 -1
  179. qiskit/synthesis/arithmetic/__init__.py +3 -1
  180. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  181. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +1 -1
  182. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +2 -2
  183. qiskit/{providers/fake_provider/backends_v1/fake_20q → synthesis/arithmetic/comparators}/__init__.py +4 -6
  184. qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
  185. qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
  186. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -1
  187. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +1 -1
  188. qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
  189. qiskit/{result/mitigation → synthesis/boolean}/__init__.py +2 -2
  190. qiskit/synthesis/boolean/boolean_expression.py +231 -0
  191. qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
  192. qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
  193. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  194. qiskit/synthesis/evolution/product_formula.py +44 -35
  195. qiskit/synthesis/evolution/qdrift.py +17 -24
  196. qiskit/synthesis/evolution/suzuki_trotter.py +20 -27
  197. qiskit/synthesis/linear/linear_depth_lnn.py +6 -221
  198. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +4 -205
  199. qiskit/synthesis/multi_controlled/__init__.py +1 -0
  200. qiskit/synthesis/multi_controlled/mcx_synthesis.py +5 -2
  201. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
  202. qiskit/synthesis/one_qubit/one_qubit_decompose.py +1 -1
  203. qiskit/synthesis/two_qubit/__init__.py +1 -0
  204. qiskit/synthesis/two_qubit/two_qubit_decompose.py +28 -145
  205. qiskit/transpiler/__init__.py +32 -232
  206. qiskit/transpiler/basepasses.py +20 -51
  207. qiskit/transpiler/layout.py +1 -1
  208. qiskit/transpiler/passes/__init__.py +4 -40
  209. qiskit/transpiler/passes/basis/basis_translator.py +5 -4
  210. qiskit/transpiler/passes/basis/decompose.py +1 -15
  211. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -5
  212. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +3 -2
  213. qiskit/transpiler/passes/layout/apply_layout.py +4 -0
  214. qiskit/transpiler/passes/layout/dense_layout.py +2 -39
  215. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +3 -4
  216. qiskit/transpiler/passes/layout/sabre_layout.py +7 -3
  217. qiskit/transpiler/passes/layout/vf2_layout.py +2 -20
  218. qiskit/transpiler/passes/layout/vf2_post_layout.py +60 -125
  219. qiskit/transpiler/passes/layout/vf2_utils.py +2 -26
  220. qiskit/transpiler/passes/optimization/__init__.py +2 -3
  221. qiskit/transpiler/passes/optimization/collect_and_collapse.py +2 -0
  222. qiskit/transpiler/passes/optimization/collect_cliffords.py +5 -0
  223. qiskit/transpiler/passes/optimization/collect_linear_functions.py +5 -0
  224. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +16 -1
  225. qiskit/transpiler/passes/optimization/commutation_analysis.py +3 -3
  226. qiskit/transpiler/passes/optimization/consolidate_blocks.py +41 -19
  227. qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
  228. qiskit/transpiler/passes/optimization/light_cone.py +135 -0
  229. qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +0 -1
  230. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +18 -22
  231. qiskit/transpiler/passes/optimization/optimize_annotated.py +3 -2
  232. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +6 -4
  233. qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +5 -2
  234. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +26 -3
  235. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -0
  236. qiskit/transpiler/passes/routing/__init__.py +0 -1
  237. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -1
  238. qiskit/transpiler/passes/routing/sabre_swap.py +14 -6
  239. qiskit/transpiler/passes/routing/star_prerouting.py +1 -1
  240. qiskit/transpiler/passes/scheduling/__init__.py +1 -7
  241. qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -4
  242. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -9
  243. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +17 -16
  244. qiskit/transpiler/passes/scheduling/padding/base_padding.py +32 -4
  245. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +25 -63
  246. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +12 -4
  247. qiskit/transpiler/passes/scheduling/scheduling/alap.py +5 -39
  248. qiskit/transpiler/passes/scheduling/scheduling/asap.py +4 -35
  249. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +10 -16
  250. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +134 -62
  251. qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
  252. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +176 -601
  253. qiskit/transpiler/passes/synthesis/hls_plugins.py +294 -1
  254. qiskit/transpiler/passes/synthesis/plugin.py +4 -0
  255. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +16 -10
  256. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -697
  257. qiskit/transpiler/passes/utils/__init__.py +0 -1
  258. qiskit/transpiler/passes/utils/check_gate_direction.py +13 -5
  259. qiskit/transpiler/passes/utils/control_flow.py +2 -6
  260. qiskit/transpiler/passes/utils/gate_direction.py +7 -0
  261. qiskit/transpiler/passes/utils/remove_final_measurements.py +40 -33
  262. qiskit/transpiler/passmanager.py +13 -0
  263. qiskit/transpiler/passmanager_config.py +5 -81
  264. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +225 -344
  265. qiskit/transpiler/preset_passmanagers/common.py +140 -167
  266. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +107 -322
  267. qiskit/transpiler/preset_passmanagers/level0.py +2 -11
  268. qiskit/transpiler/preset_passmanagers/level1.py +2 -14
  269. qiskit/transpiler/preset_passmanagers/level2.py +2 -12
  270. qiskit/transpiler/preset_passmanagers/level3.py +2 -11
  271. qiskit/transpiler/preset_passmanagers/plugin.py +5 -3
  272. qiskit/transpiler/target.py +78 -524
  273. qiskit/user_config.py +8 -4
  274. qiskit/utils/__init__.py +13 -12
  275. qiskit/utils/deprecation.py +4 -112
  276. qiskit/utils/optionals.py +11 -4
  277. qiskit/utils/parallel.py +214 -87
  278. qiskit/utils/units.py +4 -1
  279. qiskit/visualization/__init__.py +3 -7
  280. qiskit/visualization/array.py +4 -1
  281. qiskit/visualization/bloch.py +1 -1
  282. qiskit/visualization/circuit/_utils.py +19 -19
  283. qiskit/visualization/circuit/circuit_visualization.py +11 -4
  284. qiskit/visualization/circuit/matplotlib.py +13 -23
  285. qiskit/visualization/circuit/text.py +7 -3
  286. qiskit/visualization/counts_visualization.py +4 -0
  287. qiskit/visualization/dag_visualization.py +2 -1
  288. qiskit/visualization/gate_map.py +39 -154
  289. qiskit/visualization/library.py +4 -1
  290. qiskit/visualization/pass_manager_visualization.py +6 -2
  291. qiskit/visualization/state_visualization.py +19 -2
  292. qiskit/visualization/timeline/core.py +19 -13
  293. qiskit/visualization/timeline/interface.py +19 -18
  294. qiskit/visualization/timeline/plotters/matplotlib.py +4 -1
  295. {qiskit-1.4.2.dist-info → qiskit-2.0.0.dist-info}/METADATA +4 -3
  296. {qiskit-1.4.2.dist-info → qiskit-2.0.0.dist-info}/RECORD +300 -447
  297. {qiskit-1.4.2.dist-info → qiskit-2.0.0.dist-info}/WHEEL +2 -1
  298. {qiskit-1.4.2.dist-info → qiskit-2.0.0.dist-info}/entry_points.txt +8 -2
  299. qiskit/assembler/__init__.py +0 -42
  300. qiskit/assembler/assemble_circuits.py +0 -451
  301. qiskit/assembler/assemble_schedules.py +0 -367
  302. qiskit/assembler/disassemble.py +0 -310
  303. qiskit/assembler/run_config.py +0 -77
  304. qiskit/circuit/bit.py +0 -106
  305. qiskit/circuit/classicalfunction/__init__.py +0 -152
  306. qiskit/circuit/classicalfunction/boolean_expression.py +0 -138
  307. qiskit/circuit/classicalfunction/classical_element.py +0 -54
  308. qiskit/circuit/classicalfunction/classical_function_visitor.py +0 -155
  309. qiskit/circuit/classicalfunction/classicalfunction.py +0 -182
  310. qiskit/circuit/classicalfunction/exceptions.py +0 -41
  311. qiskit/circuit/classicalfunction/types.py +0 -18
  312. qiskit/circuit/classicalfunction/utils.py +0 -91
  313. qiskit/circuit/classicalregister.py +0 -57
  314. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +0 -405
  315. qiskit/circuit/quantumregister.py +0 -75
  316. qiskit/circuit/register.py +0 -246
  317. qiskit/compiler/assembler.py +0 -689
  318. qiskit/compiler/scheduler.py +0 -109
  319. qiskit/compiler/sequencer.py +0 -71
  320. qiskit/primitives/backend_estimator.py +0 -486
  321. qiskit/primitives/backend_sampler.py +0 -222
  322. qiskit/primitives/estimator.py +0 -172
  323. qiskit/primitives/sampler.py +0 -162
  324. qiskit/providers/backend_compat.py +0 -507
  325. qiskit/providers/fake_provider/backends_v1/__init__.py +0 -22
  326. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +0 -18
  327. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +0 -1
  328. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +0 -1
  329. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +0 -37
  330. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +0 -1
  331. qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +0 -1
  332. qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +0 -43
  333. qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +0 -1
  334. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +0 -18
  335. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +0 -1
  336. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +0 -1
  337. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +0 -50
  338. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +0 -1
  339. qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +0 -18
  340. qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +0 -1
  341. qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +0 -41
  342. qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +0 -1
  343. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +0 -18
  344. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +0 -1
  345. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +0 -1
  346. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +0 -44
  347. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +0 -1
  348. qiskit/providers/fake_provider/fake_1q.py +0 -91
  349. qiskit/providers/fake_provider/fake_backend.py +0 -165
  350. qiskit/providers/fake_provider/fake_openpulse_2q.py +0 -391
  351. qiskit/providers/fake_provider/fake_openpulse_3q.py +0 -340
  352. qiskit/providers/fake_provider/fake_pulse_backend.py +0 -49
  353. qiskit/providers/fake_provider/fake_qasm_backend.py +0 -77
  354. qiskit/providers/fake_provider/utils/backend_converter.py +0 -150
  355. qiskit/providers/fake_provider/utils/json_decoder.py +0 -109
  356. qiskit/providers/models/__init__.py +0 -89
  357. qiskit/providers/models/backendconfiguration.py +0 -1040
  358. qiskit/providers/models/backendproperties.py +0 -535
  359. qiskit/providers/models/backendstatus.py +0 -104
  360. qiskit/providers/models/jobstatus.py +0 -77
  361. qiskit/providers/models/pulsedefaults.py +0 -305
  362. qiskit/providers/provider.py +0 -95
  363. qiskit/pulse/__init__.py +0 -158
  364. qiskit/pulse/builder.py +0 -2262
  365. qiskit/pulse/calibration_entries.py +0 -381
  366. qiskit/pulse/channels.py +0 -227
  367. qiskit/pulse/configuration.py +0 -245
  368. qiskit/pulse/exceptions.py +0 -45
  369. qiskit/pulse/filters.py +0 -309
  370. qiskit/pulse/instruction_schedule_map.py +0 -424
  371. qiskit/pulse/instructions/__init__.py +0 -67
  372. qiskit/pulse/instructions/acquire.py +0 -150
  373. qiskit/pulse/instructions/delay.py +0 -71
  374. qiskit/pulse/instructions/directives.py +0 -154
  375. qiskit/pulse/instructions/frequency.py +0 -135
  376. qiskit/pulse/instructions/instruction.py +0 -270
  377. qiskit/pulse/instructions/phase.py +0 -152
  378. qiskit/pulse/instructions/play.py +0 -99
  379. qiskit/pulse/instructions/reference.py +0 -100
  380. qiskit/pulse/instructions/snapshot.py +0 -82
  381. qiskit/pulse/library/__init__.py +0 -97
  382. qiskit/pulse/library/continuous.py +0 -430
  383. qiskit/pulse/library/pulse.py +0 -148
  384. qiskit/pulse/library/samplers/__init__.py +0 -15
  385. qiskit/pulse/library/samplers/decorators.py +0 -295
  386. qiskit/pulse/library/samplers/strategies.py +0 -71
  387. qiskit/pulse/library/symbolic_pulses.py +0 -1989
  388. qiskit/pulse/library/waveform.py +0 -136
  389. qiskit/pulse/macros.py +0 -262
  390. qiskit/pulse/parameter_manager.py +0 -445
  391. qiskit/pulse/parser.py +0 -314
  392. qiskit/pulse/reference_manager.py +0 -58
  393. qiskit/pulse/schedule.py +0 -1854
  394. qiskit/pulse/transforms/__init__.py +0 -106
  395. qiskit/pulse/transforms/alignments.py +0 -406
  396. qiskit/pulse/transforms/base_transforms.py +0 -71
  397. qiskit/pulse/transforms/canonicalization.py +0 -498
  398. qiskit/pulse/transforms/dag.py +0 -122
  399. qiskit/pulse/utils.py +0 -149
  400. qiskit/qobj/__init__.py +0 -75
  401. qiskit/qobj/common.py +0 -81
  402. qiskit/qobj/converters/__init__.py +0 -18
  403. qiskit/qobj/converters/lo_config.py +0 -177
  404. qiskit/qobj/converters/pulse_instruction.py +0 -897
  405. qiskit/qobj/pulse_qobj.py +0 -709
  406. qiskit/qobj/qasm_qobj.py +0 -708
  407. qiskit/qobj/utils.py +0 -46
  408. qiskit/result/mitigation/base_readout_mitigator.py +0 -79
  409. qiskit/result/mitigation/correlated_readout_mitigator.py +0 -277
  410. qiskit/result/mitigation/local_readout_mitigator.py +0 -328
  411. qiskit/result/mitigation/utils.py +0 -217
  412. qiskit/scheduler/__init__.py +0 -40
  413. qiskit/scheduler/config.py +0 -37
  414. qiskit/scheduler/lowering.py +0 -187
  415. qiskit/scheduler/methods/__init__.py +0 -15
  416. qiskit/scheduler/methods/basic.py +0 -140
  417. qiskit/scheduler/schedule_circuit.py +0 -69
  418. qiskit/scheduler/sequence.py +0 -104
  419. qiskit/transpiler/passes/calibration/__init__.py +0 -17
  420. qiskit/transpiler/passes/calibration/base_builder.py +0 -79
  421. qiskit/transpiler/passes/calibration/builders.py +0 -20
  422. qiskit/transpiler/passes/calibration/exceptions.py +0 -22
  423. qiskit/transpiler/passes/calibration/pulse_gate.py +0 -100
  424. qiskit/transpiler/passes/calibration/rx_builder.py +0 -164
  425. qiskit/transpiler/passes/calibration/rzx_builder.py +0 -411
  426. qiskit/transpiler/passes/calibration/rzx_templates.py +0 -58
  427. qiskit/transpiler/passes/optimization/cx_cancellation.py +0 -65
  428. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +0 -162
  429. qiskit/transpiler/passes/optimization/normalize_rx_angle.py +0 -157
  430. qiskit/transpiler/passes/routing/stochastic_swap.py +0 -532
  431. qiskit/transpiler/passes/scheduling/alap.py +0 -153
  432. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +0 -255
  433. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -107
  434. qiskit/transpiler/passes/scheduling/asap.py +0 -175
  435. qiskit/transpiler/passes/scheduling/base_scheduler.py +0 -310
  436. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +0 -313
  437. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -93
  438. qiskit/utils/deprecate_pulse.py +0 -119
  439. qiskit/utils/multiprocessing.py +0 -56
  440. qiskit/visualization/pulse_v2/__init__.py +0 -21
  441. qiskit/visualization/pulse_v2/core.py +0 -901
  442. qiskit/visualization/pulse_v2/device_info.py +0 -173
  443. qiskit/visualization/pulse_v2/drawings.py +0 -253
  444. qiskit/visualization/pulse_v2/events.py +0 -254
  445. qiskit/visualization/pulse_v2/generators/__init__.py +0 -40
  446. qiskit/visualization/pulse_v2/generators/barrier.py +0 -76
  447. qiskit/visualization/pulse_v2/generators/chart.py +0 -208
  448. qiskit/visualization/pulse_v2/generators/frame.py +0 -436
  449. qiskit/visualization/pulse_v2/generators/snapshot.py +0 -133
  450. qiskit/visualization/pulse_v2/generators/waveform.py +0 -645
  451. qiskit/visualization/pulse_v2/interface.py +0 -459
  452. qiskit/visualization/pulse_v2/layouts.py +0 -387
  453. qiskit/visualization/pulse_v2/plotters/__init__.py +0 -17
  454. qiskit/visualization/pulse_v2/plotters/base_plotter.py +0 -53
  455. qiskit/visualization/pulse_v2/plotters/matplotlib.py +0 -201
  456. qiskit/visualization/pulse_v2/stylesheet.py +0 -312
  457. qiskit/visualization/pulse_v2/types.py +0 -242
  458. {qiskit-1.4.2.dist-info → qiskit-2.0.0.dist-info/licenses}/LICENSE.txt +0 -0
  459. {qiskit-1.4.2.dist-info → qiskit-2.0.0.dist-info}/top_level.txt +0 -0
@@ -17,7 +17,7 @@ from __future__ import annotations
17
17
 
18
18
  from itertools import product
19
19
 
20
- from qiskit.circuit import QuantumRegister, QuantumCircuit
20
+ from qiskit.circuit import QuantumRegister, QuantumCircuit, Gate
21
21
  from qiskit.circuit.exceptions import CircuitError
22
22
 
23
23
  from .functional_pauli_rotations import FunctionalPauliRotations
@@ -253,52 +253,68 @@ class PolynomialPauliRotations(FunctionalPauliRotations):
253
253
 
254
254
  return valid
255
255
 
256
- def _get_rotation_coefficients(self) -> dict[tuple[int, ...], float]:
257
- """Compute the coefficient of each monomial.
256
+ def _build(self):
257
+ """If not already built, build the circuit."""
258
+ if self._is_built:
259
+ return
258
260
 
259
- Returns:
260
- A dictionary with pairs ``{control_state: rotation angle}`` where ``control_state``
261
- is a tuple of ``0`` or ``1`` bits.
262
- """
263
- # determine the control states
264
- all_combinations = list(product([0, 1], repeat=self.num_state_qubits))
265
- valid_combinations = []
266
- for combination in all_combinations:
267
- if 0 < sum(combination) <= self.degree:
268
- valid_combinations += [combination]
261
+ super()._build()
269
262
 
270
- rotation_coeffs = {control_state: 0.0 for control_state in valid_combinations}
263
+ gate = PolynomialPauliRotationsGate(self.num_state_qubits, self.coeffs, self.basis)
264
+ self.append(gate, self.qubits)
271
265
 
272
- # compute the coefficients for the control states
273
- for i, coeff in enumerate(self.coeffs[1:]):
274
- i += 1 # since we skip the first element we need to increase i by one
275
266
 
276
- # iterate over the multinomial coefficients
277
- for comb, num_combs in _multinomial_coefficients(self.num_state_qubits, i).items():
278
- control_state: tuple[int, ...] = ()
279
- power = 1
280
- for j, qubit in enumerate(comb):
281
- if qubit > 0: # means we control on qubit i
282
- control_state += (1,)
283
- power *= 2 ** (j * qubit)
284
- else:
285
- control_state += (0,)
267
+ class PolynomialPauliRotationsGate(Gate):
268
+ r"""A gate implementing polynomial Pauli rotations.
286
269
 
287
- # Add angle
288
- rotation_coeffs[control_state] += coeff * num_combs * power
270
+ For a polynomial :math:`p(x)`, a basis state :math:`|i\rangle` and a target qubit
271
+ :math:`|0\rangle` this operator acts as:
289
272
 
290
- return rotation_coeffs
273
+ .. math::
291
274
 
292
- def _build(self):
293
- """If not already built, build the circuit."""
294
- if self._is_built:
295
- return
275
+ |i\rangle |0\rangle \mapsto \cos\left(\frac{p(i)}{2}\right) |i\rangle |0\rangle
276
+ + \sin\left(\frac{p(i)}{2}\right) |i\rangle |1\rangle
296
277
 
297
- super()._build()
278
+ Let n be the number of qubits representing the state, d the degree of p(x) and q_i the qubits,
279
+ where q_0 is the least significant qubit. Then for
298
280
 
299
- circuit = QuantumCircuit(*self.qregs, name=self.name)
300
- qr_state = circuit.qubits[: self.num_state_qubits]
301
- qr_target = circuit.qubits[self.num_state_qubits]
281
+ .. math::
282
+
283
+ x = \sum_{i=0}^{n-1} 2^i q_i,
284
+
285
+ we can write
286
+
287
+ .. math::
288
+
289
+ p(x) = \sum_{j=0}^{j=d} c_j x^j
290
+
291
+ where :math:`c` are the input coefficients, ``coeffs``.
292
+ """
293
+
294
+ def __init__(
295
+ self,
296
+ num_state_qubits: int,
297
+ coeffs: list[float] | None = None,
298
+ basis: str = "Y",
299
+ label: str | None = None,
300
+ ) -> None:
301
+ """Prepare an approximation to a state with amplitudes specified by a polynomial.
302
+
303
+ Args:
304
+ num_state_qubits: The number of qubits representing the state.
305
+ coeffs: The coefficients of the polynomial. ``coeffs[i]`` is the coefficient of the
306
+ i-th power of x. Defaults to linear: [0, 1].
307
+ basis: The type of Pauli rotation ('X', 'Y', 'Z').
308
+ label: A label for the gate.
309
+ """
310
+ self.coeffs = coeffs or [0, 1]
311
+ self.basis = basis.lower()
312
+ super().__init__("PolyPauli", num_state_qubits + 1, [], label=label)
313
+
314
+ def _define(self):
315
+ circuit = QuantumCircuit(self.num_qubits)
316
+ qr_state = circuit.qubits[: self.num_qubits - 1]
317
+ qr_target = circuit.qubits[-1]
302
318
 
303
319
  rotation_coeffs = self._get_rotation_coefficients()
304
320
 
@@ -332,4 +348,42 @@ class PolynomialPauliRotations(FunctionalPauliRotations):
332
348
  else:
333
349
  circuit.crz(rotation_coeffs[c], qr_control[0], qr_target)
334
350
 
335
- self.append(circuit.to_gate(), self.qubits)
351
+ self.definition = circuit
352
+
353
+ def _get_rotation_coefficients(self) -> dict[tuple[int, ...], float]:
354
+ """Compute the coefficient of each monomial.
355
+
356
+ Returns:
357
+ A dictionary with pairs ``{control_state: rotation angle}`` where ``control_state``
358
+ is a tuple of ``0`` or ``1`` bits.
359
+ """
360
+ # determine the control states
361
+ num_state_qubits = self.num_qubits - 1
362
+ degree = len(self.coeffs) - 1
363
+ all_combinations = list(product([0, 1], repeat=num_state_qubits))
364
+ valid_combinations = []
365
+ for combination in all_combinations:
366
+ if 0 < sum(combination) <= degree:
367
+ valid_combinations += [combination]
368
+
369
+ rotation_coeffs = {control_state: 0.0 for control_state in valid_combinations}
370
+
371
+ # compute the coefficients for the control states
372
+ for i, coeff in enumerate(self.coeffs[1:]):
373
+ i += 1 # since we skip the first element we need to increase i by one
374
+
375
+ # iterate over the multinomial coefficients
376
+ for comb, num_combs in _multinomial_coefficients(num_state_qubits, i).items():
377
+ control_state: tuple[int, ...] = ()
378
+ power = 1
379
+ for j, qubit in enumerate(comb):
380
+ if qubit > 0: # means we control on qubit i
381
+ control_state += (1,)
382
+ power *= 2 ** (j * qubit)
383
+ else:
384
+ control_state += (0,)
385
+
386
+ # Add angle
387
+ rotation_coeffs[control_state] += coeff * num_combs * power
388
+
389
+ return rotation_coeffs
@@ -12,13 +12,18 @@
12
12
 
13
13
  """A circuit implementing a quadratic form on binary variables."""
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  from typing import Union, Optional, List
16
18
  import math
19
+ from collections.abc import Sequence
17
20
 
18
21
  import numpy as np
19
22
 
20
- from qiskit.circuit import QuantumCircuit, QuantumRegister, ParameterExpression
21
- from ..basis_change import QFT
23
+ from qiskit.circuit import QuantumCircuit, QuantumRegister, ParameterExpression, Gate, CircuitError
24
+ from ..basis_change import QFT, QFTGate
25
+
26
+ _ValueType = Union[int, float, np.integer, np.floating, ParameterExpression]
22
27
 
23
28
 
24
29
  class QuadraticForm(QuantumCircuit):
@@ -171,6 +176,101 @@ class QuadraticForm(QuantumCircuit):
171
176
  ) -> int:
172
177
  """Get the number of required result qubits.
173
178
 
179
+ Args:
180
+ quadratic: A matrix containing the quadratic coefficients.
181
+ linear: An array containing the linear coefficients.
182
+ offset: A constant offset.
183
+
184
+ Returns:
185
+ The number of qubits needed to represent the value of the quadratic form
186
+ in twos complement.
187
+ """
188
+ return QuadraticFormGate.required_result_qubits(quadratic, linear, offset)
189
+
190
+
191
+ class QuadraticFormGate(Gate):
192
+ r"""Implements a quadratic form on binary variables encoded in qubit registers.
193
+
194
+ A quadratic form on binary variables is a quadratic function :math:`Q` acting on a binary
195
+ variable of :math:`n` bits, :math:`x = x_0 ... x_{n-1}`. For an integer matrix :math:`A`,
196
+ an integer vector :math:`b` and an integer :math:`c` the function can be written as
197
+
198
+ .. math::
199
+
200
+ Q(x) = x^T A x + x^T b + c
201
+
202
+ If :math:`A`, :math:`b` or :math:`c` contain scalar values, this circuit computes only
203
+ an approximation of the quadratic form.
204
+
205
+ Provided with :math:`m` qubits to encode the value, this circuit computes :math:`Q(x) \mod 2^m`
206
+ in [two's complement](https://stackoverflow.com/questions/1049722/what-is-2s-complement)
207
+ representation.
208
+
209
+ .. math::
210
+
211
+ |x\rangle_n |0\rangle_m \mapsto |x\rangle_n |(Q(x) + 2^m) \mod 2^m \rangle_m
212
+
213
+ Since we use two's complement e.g. the value of :math:`Q(x) = 3` requires 2 bits to represent
214
+ the value and 1 bit for the sign: `3 = '011'` where the first `0` indicates a positive value.
215
+ On the other hand, :math:`Q(x) = -3` would be `-3 = '101'`, where the first `1` indicates
216
+ a negative value and `01` is the two's complement of `3`.
217
+
218
+ If the value of :math:`Q(x)` is too large to be represented with `m` qubits, the resulting
219
+ bitstring is :math:`(Q(x) + 2^m) \mod 2^m)`.
220
+
221
+ The implementation of this circuit is discussed in [1], Fig. 6.
222
+
223
+ References:
224
+ [1]: Gilliam et al., Grover Adaptive Search for Constrained Polynomial Binary Optimization.
225
+ `arXiv:1912.04088 <https://arxiv.org/pdf/1912.04088.pdf>`_
226
+
227
+ """
228
+
229
+ def __init__(
230
+ self,
231
+ num_result_qubits: int | None = None,
232
+ quadratic: Sequence[Sequence[float]] | None = None,
233
+ linear: Sequence[Sequence[float]] | None = None,
234
+ offset: float | None = None,
235
+ label: str = "Q(x)",
236
+ ):
237
+ # check inputs match
238
+ if quadratic is not None and linear is not None:
239
+ if len(quadratic) != len(linear):
240
+ raise ValueError("Mismatching sizes of quadratic and linear.")
241
+
242
+ # temporarily set quadratic and linear to [] instead of None so we can iterate over them
243
+ if quadratic is None:
244
+ quadratic = []
245
+
246
+ if linear is None:
247
+ linear = []
248
+
249
+ if offset is None:
250
+ offset = 0
251
+
252
+ self.num_input_qubits = np.max([1, len(linear), len(quadratic)])
253
+
254
+ # deduce number of result bits if not added
255
+ if num_result_qubits is None:
256
+ num_result_qubits = self.required_result_qubits(quadratic, linear, offset)
257
+
258
+ self.num_result_qubits = num_result_qubits
259
+ self.quadratic = quadratic
260
+ self.linear = linear
261
+ self.offset = offset
262
+
263
+ num_qubits = int(self.num_input_qubits + self.num_result_qubits)
264
+ super().__init__("QuadraticForm", num_qubits, [], label=label)
265
+
266
+ @staticmethod
267
+ def required_result_qubits(
268
+ quadratic: Sequence[Sequence[float]],
269
+ linear: Sequence[float],
270
+ offset: float,
271
+ ) -> int:
272
+ """Get the number of required result qubits.
273
+
174
274
  Args:
175
275
  quadratic: A matrix containing the quadratic coefficients.
176
276
  linear: An array containing the linear coefficients.
@@ -196,3 +296,69 @@ class QuadraticForm(QuantumCircuit):
196
296
  num_result_qubits = 1 + max(num_qubits_for_min, num_qubits_for_max)
197
297
 
198
298
  return num_result_qubits
299
+
300
+ def validate_parameter(self, parameter):
301
+ if isinstance(parameter, _ValueType):
302
+ return parameter
303
+
304
+ if isinstance(parameter, (np.ndarray, Sequence)):
305
+ if all(isinstance(el, _ValueType) for el in parameter):
306
+ return parameter
307
+ for params in parameter:
308
+ if not all(isinstance(el, _ValueType) for el in params):
309
+ raise CircuitError(
310
+ f"Invalid parameter type {type(parameter)} for QuadraticFormGate"
311
+ )
312
+
313
+ return parameter
314
+
315
+ return super().validate_parameter(parameter)
316
+
317
+ def _define(self):
318
+ quadratic, linear, offset = self.quadratic, self.linear, self.offset
319
+
320
+ qr_input = QuantumRegister(self.num_input_qubits)
321
+ qr_result = QuantumRegister(self.num_result_qubits)
322
+ circuit = QuantumCircuit(qr_input, qr_result)
323
+
324
+ # set quadratic and linear again to None if they were None
325
+ if len(quadratic) == 0:
326
+ quadratic = None
327
+
328
+ if len(linear) == 0:
329
+ linear = None
330
+
331
+ scaling = np.pi * 2 ** (1 - self.num_result_qubits)
332
+
333
+ # initial QFT
334
+ qft = QFTGate(self.num_result_qubits)
335
+ circuit.append(qft, qr_result)
336
+
337
+ # constant coefficient
338
+ if offset != 0:
339
+ for i, q_i in enumerate(qr_result):
340
+ circuit.p(scaling * 2**i * offset, q_i)
341
+
342
+ # the linear part consists of the vector and the diagonal of the
343
+ # matrix, since x_i * x_i = x_i, as x_i is a binary variable
344
+ for j in range(self.num_input_qubits):
345
+ value = linear[j] if linear is not None else 0
346
+ value += quadratic[j][j] if quadratic is not None else 0
347
+ if value != 0:
348
+ for i, q_i in enumerate(qr_result):
349
+ circuit.cp(scaling * 2**i * value, qr_input[j], q_i)
350
+
351
+ # the quadratic part adds A_ij and A_ji as x_i x_j == x_j x_i
352
+ if quadratic is not None:
353
+ for j in range(self.num_input_qubits):
354
+ for k in range(j + 1, self.num_input_qubits):
355
+ value = quadratic[j][k] + quadratic[k][j]
356
+ if value != 0:
357
+ for i, q_i in enumerate(qr_result):
358
+ circuit.mcp(scaling * 2**i * value, [qr_input[j], qr_input[k]], q_i)
359
+
360
+ # add the inverse QFT
361
+ iqft = qft.inverse()
362
+ circuit.append(iqft, qr_result)
363
+
364
+ self.definition = circuit
@@ -12,10 +12,12 @@
12
12
 
13
13
  """Compute the weighted sum of qubit states."""
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  from typing import List, Optional
16
18
  import numpy as np
17
19
 
18
- from qiskit.circuit import QuantumRegister, AncillaRegister, QuantumCircuit
20
+ from qiskit.circuit import QuantumRegister, AncillaRegister, QuantumCircuit, Gate
19
21
 
20
22
  from ..blueprintcircuit import BlueprintCircuit
21
23
 
@@ -335,3 +337,73 @@ class WeightedAdder(BlueprintCircuit):
335
337
  circuit.x(qr_sum[j])
336
338
 
337
339
  self.append(circuit.to_gate(), self.qubits)
340
+
341
+
342
+ class WeightedSumGate(Gate):
343
+ r"""A gate to compute the weighted sum of qubit registers.
344
+
345
+ Given :math:`n` qubit basis states :math:`q_0, \ldots, q_{n-1} \in \{0, 1\}` and non-negative
346
+ integer weights :math:`\lambda_0, \ldots, \lambda_{n-1}`, this implements the operation
347
+
348
+ .. math::
349
+
350
+ |q_0 \ldots q_{n-1}\rangle |0\rangle_s
351
+ \mapsto |q_0 \ldots q_{n-1}\rangle |\sum_{j=0}^{n-1} \lambda_j q_j\rangle_s
352
+
353
+ where :math:`s` is the number of sum qubits required.
354
+ This can be computed as
355
+
356
+ .. math::
357
+
358
+ s = 1 + \left\lfloor \log_2\left( \sum_{j=0}^{n-1} \lambda_j \right) \right\rfloor
359
+
360
+ or :math:`s = 1` if the sum of the weights is 0 (then the expression in the logarithm is
361
+ invalid).
362
+
363
+ For qubits in a circuit diagram, the first weight applies to the upper-most qubit.
364
+ For an example where the state of 4 qubits is added into a sum register, the circuit can
365
+ be schematically drawn as
366
+
367
+ .. code-block:: text
368
+
369
+ ┌──────────────┐
370
+ state_0: ┤0 ├ | state_0 * weights[0]
371
+ │ │ |
372
+ state_1: ┤1 ├ | + state_1 * weights[1]
373
+ │ │ |
374
+ state_2: ┤2 ├ | + state_2 * weights[2]
375
+ │ │ |
376
+ state_3: ┤3 WeightedSum ├ | + state_3 * weights[3]
377
+ │ │
378
+ sum_0: ┤4 ├ |
379
+ │ │ |
380
+ sum_1: ┤5 ├ | = sum_0 * 2^0 + sum_1 * 2^1 + sum_2 * 2^2
381
+ │ │ |
382
+ sum_2: ┤6 ├ |
383
+ └──────────────┘
384
+ """
385
+
386
+ def __init__(
387
+ self,
388
+ num_state_qubits: int,
389
+ weights: list[int] | None = None,
390
+ label: str | None = None,
391
+ ) -> None:
392
+ """
393
+ Args:
394
+ num_state_qubits: The number of state qubits.
395
+ weights: List of weights, one for each state qubit. If none are provided they
396
+ default to 1 for every qubit.
397
+ label: The name of the circuit.
398
+ """
399
+ if weights is None:
400
+ weights = [1] * num_state_qubits
401
+
402
+ self.num_state_qubits = num_state_qubits
403
+
404
+ if sum(weights) > 0:
405
+ self.num_sum_qubits = int(np.floor(np.log2(sum(weights))) + 1)
406
+ else:
407
+ self.num_sum_qubits = 1
408
+
409
+ super().__init__("WeightedSum", self.num_state_qubits + self.num_sum_qubits, weights, label)
@@ -0,0 +1,130 @@
1
+ # This code is part of Qiskit.
2
+ #
3
+ # (C) Copyright IBM 2025.
4
+ #
5
+ # This code is licensed under the Apache License, Version 2.0. You may
6
+ # obtain a copy of this license in the LICENSE.txt file in the root directory
7
+ # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8
+ #
9
+ # Any modifications or derivative works of this code must retain this
10
+ # copyright notice, and modified files need to carry a notice indicating
11
+ # that they have been altered from the originals.
12
+
13
+ """Bit-flip Oracle object."""
14
+
15
+ from __future__ import annotations
16
+
17
+ from qiskit.circuit import Gate
18
+
19
+ from qiskit.synthesis.boolean.boolean_expression import BooleanExpression
20
+
21
+
22
+ class BitFlipOracleGate(Gate):
23
+ r"""Implements a bit-flip oracle
24
+
25
+ The Bit-flip Oracle Gate object constructs circuits for any arbitrary
26
+ input logical expressions. A logical expression is composed of logical operators
27
+ `&` (logical `AND`), `|` (logical `OR`),
28
+ `~` (logical `NOT`), and `^` (logical `XOR`).
29
+ as well as symbols for literals (variables).
30
+ For example, `'a & b'`, and `(v0 | ~v1) & (~v2 & v3)`
31
+ are both valid string representation of boolean logical expressions.
32
+
33
+ A bit-flip oracle for a boolean function `f(x)` performs the following
34
+ quantum operation:
35
+
36
+ .. math::
37
+
38
+ |x\rangle|y\rangle \mapsto |x\rangle|f(x)\oplus y\rangle
39
+
40
+ For convenience, this oracle, in addition to parsing arbitrary logical expressions,
41
+ also supports input strings in the `DIMACS CNF format
42
+ <https://web.archive.org/web/20190325181937/https://www.satcompetition.org/2009/format-benchmarks2009.html>`__,
43
+ which is the standard format for specifying SATisfiability (SAT) problem instances in
44
+ `Conjunctive Normal Form (CNF) <https://en.wikipedia.org/wiki/Conjunctive_normal_form>`__,
45
+ which is a conjunction of one or more clauses, where a clause is a disjunction of one
46
+ or more literals.
47
+ See :meth:`qiskit.circuit.library.bit_flip_oracle.BitFlipOracleGate.from_dimacs_file`.
48
+
49
+ From 16 variables on, possible performance issues should be expected when using the
50
+ default synthesizer.
51
+ """
52
+
53
+ def __init__(
54
+ self,
55
+ expression: str,
56
+ var_order: list[str] | None = None,
57
+ label: str | None = None,
58
+ ) -> None:
59
+ """
60
+ Args:
61
+ expression: A Python-like boolean expression.
62
+ var_order: A list with the order in which variables will be created.
63
+ (default: by appearance)
64
+ label: A label for the gate to display in visualizations. Per default, the label is
65
+ set to display the textual represntation of the boolean expression (truncated if needed)
66
+ """
67
+ self.boolean_expression = BooleanExpression(expression, var_order=var_order)
68
+
69
+ if label is None:
70
+ short_expr_for_name = (expression[:15] + "...") if len(expression) > 15 else expression
71
+ label = short_expr_for_name
72
+
73
+ super().__init__(
74
+ name="Bit-flip Oracle",
75
+ num_qubits=self.boolean_expression.num_bits + 1,
76
+ params=[],
77
+ label=label,
78
+ )
79
+
80
+ def _define(self):
81
+ """Defined by the synthesized bit-flip oracle"""
82
+ self.definition = self.boolean_expression.synth(circuit_type="bit")
83
+
84
+ @classmethod
85
+ def from_dimacs_file(cls, filename: str) -> BitFlipOracleGate:
86
+ r"""Create a BitFlipOracleGate from the string in the DIMACS format.
87
+
88
+ It is possible to build a BitFlipOracleGate from a file in `DIMACS CNF format
89
+ <https://web.archive.org/web/20190325181937/https://www.satcompetition.org/2009/format-benchmarks2009.html>`__,
90
+ which is the standard format for specifying SATisfiability (SAT) problem instances in
91
+ `Conjunctive Normal Form (CNF) <https://en.wikipedia.org/wiki/Conjunctive_normal_form>`__,
92
+ which is a conjunction of one or more clauses, where a clause is a disjunction of one
93
+ or more literals.
94
+
95
+ The following is an example of a CNF expressed in the DIMACS format:
96
+
97
+ .. code:: text
98
+
99
+ c DIMACS CNF file with 3 satisfying assignments: 1 -2 3, -1 -2 -3, 1 2 -3.
100
+ p cnf 3 5
101
+ -1 -2 -3 0
102
+ 1 -2 3 0
103
+ 1 2 -3 0
104
+ 1 -2 -3 0
105
+ -1 2 3 0
106
+
107
+ The first line, following the `c` character, is a comment. The second line specifies that
108
+ the CNF is over three boolean variables --- let us call them :math:`x_1, x_2, x_3`, and
109
+ contains five clauses. The five clauses, listed afterwards, are implicitly joined by the
110
+ logical `AND` operator, :math:`\land`, while the variables in each clause, represented by
111
+ their indices, are implicitly disjoined by the logical `OR` operator, :math:`\lor`. The
112
+ :math:`-` symbol preceding a boolean variable index corresponds to the logical `NOT`
113
+ operator, :math:`\lnot`. Character `0` (zero) marks the end of each clause. Essentially,
114
+ the code above corresponds to the following CNF:
115
+
116
+ :math:`(\lnot x_1 \lor \lnot x_2 \lor \lnot x_3)
117
+ \land (x_1 \lor \lnot x_2 \lor x_3)
118
+ \land (x_1 \lor x_2 \lor \lnot x_3)
119
+ \land (x_1 \lor \lnot x_2 \lor \lnot x_3)
120
+ \land (\lnot x_1 \lor x_2 \lor x_3)`.
121
+
122
+
123
+ Args:
124
+ filename: A file in DIMACS format.
125
+
126
+ Returns:
127
+ BitFlipOracleGate: A quantum gate with a bit-flip oracle.
128
+ """
129
+ expr = BooleanExpression.from_dimacs_file(filename)
130
+ return cls(expr)
@@ -14,10 +14,12 @@
14
14
 
15
15
  from __future__ import annotations
16
16
  from abc import ABC, abstractmethod
17
+ import copy as _copy
17
18
 
18
19
  from qiskit._accelerate.circuit import CircuitData
19
- from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
20
+ from qiskit.circuit import QuantumRegister, ClassicalRegister
20
21
  from qiskit.circuit.parametertable import ParameterView
22
+ from qiskit.circuit.quantumcircuit import QuantumCircuit, _copy_metadata
21
23
 
22
24
 
23
25
  class BlueprintCircuit(QuantumCircuit, ABC):
@@ -37,7 +39,6 @@ class BlueprintCircuit(QuantumCircuit, ABC):
37
39
  super().__init__(*regs, name=name)
38
40
  self._qregs: list[QuantumRegister] = []
39
41
  self._cregs: list[ClassicalRegister] = []
40
- self._qubit_indices = {}
41
42
  self._is_built = False
42
43
  self._is_initialized = True
43
44
 
@@ -67,14 +68,24 @@ class BlueprintCircuit(QuantumCircuit, ABC):
67
68
 
68
69
  def _invalidate(self) -> None:
69
70
  """Invalidate the current circuit build."""
71
+ # Take out the registers before invalidating
72
+ qregs = self._data.qregs
73
+ cregs = self._data.cregs
70
74
  self._data = CircuitData(self._data.qubits, self._data.clbits)
75
+ # Re-add the registers
76
+ for qreg in qregs:
77
+ self._data.add_qreg(qreg)
78
+ for creg in cregs:
79
+ self._data.add_creg(creg)
71
80
  self.global_phase = 0
72
81
  self._is_built = False
73
82
 
74
83
  @property
75
84
  def qregs(self):
76
85
  """A list of the quantum registers associated with the circuit."""
77
- return self._qregs
86
+ if not self._is_initialized:
87
+ return self._qregs
88
+ return super().qregs
78
89
 
79
90
  @qregs.setter
80
91
  def qregs(self, qregs):
@@ -85,7 +96,6 @@ class BlueprintCircuit(QuantumCircuit, ABC):
85
96
  return
86
97
  self._qregs = []
87
98
  self._ancillas = []
88
- self._qubit_indices = {}
89
99
  self._data = CircuitData(clbits=self._data.clbits)
90
100
  self.global_phase = 0
91
101
  self._is_built = False
@@ -262,19 +272,45 @@ class BlueprintCircuit(QuantumCircuit, ABC):
262
272
  self._build()
263
273
  return super().num_connected_components(unitary_only=unitary_only)
264
274
 
265
- def copy_empty_like(self, name=None, *, vars_mode="alike"):
266
- if not self._is_built:
267
- self._build()
268
- cpy = super().copy_empty_like(name=name, vars_mode=vars_mode)
269
- # The base `copy_empty_like` will typically trigger code that `BlueprintCircuit` treats as
270
- # an "invalidation", so we have to manually restore properties deleted by that that
271
- # `copy_empty_like` is supposed to propagate.
272
- cpy.global_phase = self.global_phase
275
+ def copy_empty_like(
276
+ self, name: str | None = None, *, vars_mode: str = "alike"
277
+ ) -> QuantumCircuit:
278
+ """Return an empty :class:`.QuantumCircuit` of same size and metadata.
279
+
280
+ See also :meth:`.QuantumCircuit.copy_empty_like` for more details on copied metadata.
281
+
282
+ Args:
283
+ name: Name for the copied circuit. If None, then the name stays the same.
284
+ vars_mode: The mode to handle realtime variables in.
285
+
286
+ Returns:
287
+ An empty circuit of same dimensions. Note that the result is no longer a
288
+ :class:`.BlueprintCircuit`.
289
+ """
290
+
291
+ cpy = QuantumCircuit(*self.qregs, *self.cregs, name=name, global_phase=self.global_phase)
292
+ _copy_metadata(self, cpy, vars_mode)
273
293
  return cpy
274
294
 
275
- def copy(self, name=None):
295
+ def copy(self, name: str | None = None) -> BlueprintCircuit:
296
+ """Copy the blueprint circuit.
297
+
298
+ Args:
299
+ name: Name to be given to the copied circuit. If None, then the name stays the same.
300
+
301
+ Returns:
302
+ A deepcopy of the current blueprint circuit, with the specified name.
303
+ """
276
304
  if not self._is_built:
277
305
  self._build()
278
- circuit_copy = super().copy(name=name)
279
- circuit_copy._is_built = self._is_built
280
- return circuit_copy
306
+
307
+ cpy = _copy.copy(self)
308
+ _copy_metadata(self, cpy, "alike")
309
+
310
+ cpy._is_built = self._is_built
311
+ cpy._data = self._data.copy()
312
+
313
+ if name is not None:
314
+ cpy.name = name
315
+
316
+ return cpy