qiskit 1.4.1__cp39-abi3-macosx_11_0_arm64.whl → 2.0.0rc1__cp39-abi3-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (456) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +2 -5
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/circuit/__init__.py +24 -5
  5. qiskit/circuit/{add_control.py → _add_control.py} +32 -12
  6. qiskit/circuit/_classical_resource_map.py +5 -3
  7. qiskit/circuit/barrier.py +3 -7
  8. qiskit/circuit/classical/expr/__init__.py +31 -3
  9. qiskit/circuit/classical/expr/constructors.py +248 -28
  10. qiskit/circuit/classical/expr/expr.py +104 -3
  11. qiskit/circuit/classical/expr/visitors.py +75 -0
  12. qiskit/circuit/classical/types/__init__.py +12 -8
  13. qiskit/circuit/classical/types/ordering.py +14 -7
  14. qiskit/circuit/classical/types/types.py +36 -0
  15. qiskit/circuit/commutation_checker.py +34 -7
  16. qiskit/circuit/controlflow/__init__.py +32 -1
  17. qiskit/circuit/controlflow/_builder_utils.py +9 -5
  18. qiskit/circuit/controlflow/box.py +163 -0
  19. qiskit/circuit/controlflow/break_loop.py +1 -1
  20. qiskit/circuit/controlflow/builder.py +139 -39
  21. qiskit/circuit/controlflow/continue_loop.py +1 -3
  22. qiskit/circuit/controlflow/control_flow.py +10 -0
  23. qiskit/circuit/controlflow/for_loop.py +2 -1
  24. qiskit/circuit/controlflow/if_else.py +3 -16
  25. qiskit/circuit/controlflow/switch_case.py +2 -8
  26. qiskit/circuit/controlflow/while_loop.py +2 -7
  27. qiskit/circuit/controlledgate.py +2 -4
  28. qiskit/circuit/delay.py +40 -11
  29. qiskit/circuit/duration.py +0 -15
  30. qiskit/circuit/gate.py +2 -4
  31. qiskit/circuit/instruction.py +2 -141
  32. qiskit/circuit/instructionset.py +7 -54
  33. qiskit/circuit/library/__init__.py +34 -5
  34. qiskit/circuit/library/arithmetic/__init__.py +16 -10
  35. qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  36. qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +2 -2
  37. qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +1 -1
  38. qiskit/circuit/library/arithmetic/exact_reciprocal.py +64 -21
  39. qiskit/circuit/library/arithmetic/integer_comparator.py +37 -80
  40. qiskit/circuit/library/arithmetic/linear_amplitude_function.py +169 -2
  41. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +59 -5
  42. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +154 -6
  43. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +114 -4
  44. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +191 -15
  45. qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +93 -39
  46. qiskit/circuit/library/arithmetic/quadratic_form.py +168 -2
  47. qiskit/circuit/library/arithmetic/weighted_adder.py +73 -1
  48. qiskit/circuit/library/bit_flip_oracle.py +130 -0
  49. qiskit/circuit/library/blueprintcircuit.py +52 -16
  50. qiskit/circuit/library/data_preparation/initializer.py +1 -1
  51. qiskit/circuit/library/data_preparation/pauli_feature_map.py +4 -4
  52. qiskit/circuit/library/data_preparation/state_preparation.py +1 -1
  53. qiskit/circuit/library/generalized_gates/gms.py +1 -1
  54. qiskit/circuit/library/generalized_gates/isometry.py +1 -1
  55. qiskit/circuit/library/generalized_gates/pauli.py +1 -2
  56. qiskit/circuit/library/generalized_gates/uc.py +97 -7
  57. qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +1 -1
  58. qiskit/circuit/library/generalized_gates/unitary.py +4 -2
  59. qiskit/circuit/library/hamiltonian_gate.py +1 -1
  60. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
  61. qiskit/circuit/library/n_local/n_local.py +1 -1
  62. qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -1
  63. qiskit/circuit/library/overlap.py +2 -2
  64. qiskit/circuit/library/pauli_evolution.py +39 -24
  65. qiskit/circuit/library/phase_oracle.py +130 -51
  66. qiskit/circuit/library/standard_gates/__init__.py +0 -1
  67. qiskit/circuit/library/standard_gates/dcx.py +3 -4
  68. qiskit/circuit/library/standard_gates/ecr.py +3 -4
  69. qiskit/circuit/library/standard_gates/global_phase.py +5 -6
  70. qiskit/circuit/library/standard_gates/h.py +4 -9
  71. qiskit/circuit/library/standard_gates/i.py +2 -2
  72. qiskit/circuit/library/standard_gates/iswap.py +3 -4
  73. qiskit/circuit/library/standard_gates/p.py +15 -34
  74. qiskit/circuit/library/standard_gates/r.py +2 -6
  75. qiskit/circuit/library/standard_gates/rx.py +5 -15
  76. qiskit/circuit/library/standard_gates/rxx.py +3 -6
  77. qiskit/circuit/library/standard_gates/ry.py +5 -17
  78. qiskit/circuit/library/standard_gates/ryy.py +3 -6
  79. qiskit/circuit/library/standard_gates/rz.py +5 -17
  80. qiskit/circuit/library/standard_gates/rzx.py +3 -6
  81. qiskit/circuit/library/standard_gates/rzz.py +3 -6
  82. qiskit/circuit/library/standard_gates/s.py +6 -15
  83. qiskit/circuit/library/standard_gates/swap.py +4 -11
  84. qiskit/circuit/library/standard_gates/sx.py +7 -12
  85. qiskit/circuit/library/standard_gates/t.py +6 -7
  86. qiskit/circuit/library/standard_gates/u.py +2 -10
  87. qiskit/circuit/library/standard_gates/u1.py +5 -16
  88. qiskit/circuit/library/standard_gates/u2.py +2 -6
  89. qiskit/circuit/library/standard_gates/u3.py +3 -11
  90. qiskit/circuit/library/standard_gates/x.py +13 -60
  91. qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -5
  92. qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -5
  93. qiskit/circuit/library/standard_gates/y.py +4 -9
  94. qiskit/circuit/library/standard_gates/z.py +5 -15
  95. qiskit/circuit/measure.py +11 -2
  96. qiskit/circuit/parameterexpression.py +4 -0
  97. qiskit/circuit/quantumcircuit.py +881 -555
  98. qiskit/circuit/random/utils.py +12 -6
  99. qiskit/circuit/reset.py +5 -2
  100. qiskit/circuit/singleton.py +5 -11
  101. qiskit/circuit/store.py +0 -8
  102. qiskit/compiler/__init__.py +1 -7
  103. qiskit/compiler/transpiler.py +38 -196
  104. qiskit/converters/circuit_to_dag.py +4 -2
  105. qiskit/converters/circuit_to_dagdependency.py +0 -2
  106. qiskit/converters/circuit_to_dagdependency_v2.py +0 -1
  107. qiskit/converters/circuit_to_gate.py +1 -1
  108. qiskit/converters/circuit_to_instruction.py +16 -29
  109. qiskit/converters/dag_to_circuit.py +5 -5
  110. qiskit/converters/dag_to_dagdependency.py +0 -1
  111. qiskit/converters/dag_to_dagdependency_v2.py +0 -1
  112. qiskit/converters/dagdependency_to_circuit.py +0 -6
  113. qiskit/converters/dagdependency_to_dag.py +0 -6
  114. qiskit/dagcircuit/collect_blocks.py +32 -20
  115. qiskit/dagcircuit/dagdependency.py +3 -37
  116. qiskit/dagcircuit/dagdependency_v2.py +2 -80
  117. qiskit/dagcircuit/dagnode.py +14 -2
  118. qiskit/passmanager/__init__.py +24 -6
  119. qiskit/passmanager/passmanager.py +26 -24
  120. qiskit/primitives/__init__.py +44 -35
  121. qiskit/primitives/backend_estimator_v2.py +102 -23
  122. qiskit/primitives/backend_sampler_v2.py +5 -20
  123. qiskit/primitives/base/__init__.py +4 -4
  124. qiskit/primitives/base/base_estimator.py +77 -82
  125. qiskit/primitives/base/base_primitive_job.py +2 -2
  126. qiskit/primitives/base/{base_primitive.py → base_primitive_v1.py} +1 -1
  127. qiskit/primitives/base/{base_result.py → base_result_v1.py} +1 -1
  128. qiskit/primitives/base/base_sampler.py +52 -60
  129. qiskit/primitives/base/{estimator_result.py → estimator_result_v1.py} +2 -2
  130. qiskit/primitives/base/{sampler_result.py → sampler_result_v1.py} +2 -2
  131. qiskit/primitives/base/{validation.py → validation_v1.py} +34 -15
  132. qiskit/primitives/containers/bindings_array.py +3 -1
  133. qiskit/primitives/containers/bit_array.py +23 -0
  134. qiskit/primitives/containers/data_bin.py +3 -1
  135. qiskit/primitives/containers/observables_array.py +19 -2
  136. qiskit/primitives/statevector_sampler.py +6 -8
  137. qiskit/primitives/utils.py +14 -189
  138. qiskit/providers/__init__.py +4 -130
  139. qiskit/providers/backend.py +11 -314
  140. qiskit/providers/basic_provider/__init__.py +3 -1
  141. qiskit/providers/basic_provider/basic_provider.py +29 -9
  142. qiskit/providers/basic_provider/basic_simulator.py +158 -298
  143. qiskit/providers/exceptions.py +0 -33
  144. qiskit/providers/fake_provider/__init__.py +0 -37
  145. qiskit/providers/fake_provider/generic_backend_v2.py +32 -693
  146. qiskit/qasm2/__init__.py +21 -6
  147. qiskit/qasm2/export.py +2 -10
  148. qiskit/qasm2/parse.py +11 -25
  149. qiskit/qasm3/__init__.py +5 -1
  150. qiskit/qasm3/ast.py +44 -0
  151. qiskit/qasm3/exporter.py +65 -27
  152. qiskit/qasm3/printer.py +35 -4
  153. qiskit/qpy/__init__.py +141 -19
  154. qiskit/qpy/binary_io/__init__.py +0 -1
  155. qiskit/qpy/binary_io/circuits.py +91 -116
  156. qiskit/qpy/binary_io/schedules.py +61 -388
  157. qiskit/qpy/binary_io/value.py +154 -28
  158. qiskit/qpy/common.py +10 -7
  159. qiskit/qpy/formats.py +41 -0
  160. qiskit/qpy/interface.py +29 -62
  161. qiskit/qpy/type_keys.py +58 -221
  162. qiskit/quantum_info/analysis/distance.py +3 -1
  163. qiskit/quantum_info/operators/dihedral/dihedral.py +3 -1
  164. qiskit/quantum_info/operators/operator.py +6 -2
  165. qiskit/quantum_info/operators/symplectic/clifford.py +3 -1
  166. qiskit/quantum_info/operators/symplectic/pauli.py +4 -2
  167. qiskit/quantum_info/operators/symplectic/pauli_list.py +17 -5
  168. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +40 -6
  169. qiskit/quantum_info/states/densitymatrix.py +16 -6
  170. qiskit/quantum_info/states/stabilizerstate.py +35 -4
  171. qiskit/quantum_info/states/statevector.py +16 -6
  172. qiskit/result/__init__.py +5 -17
  173. qiskit/result/models.py +18 -10
  174. qiskit/result/result.py +28 -126
  175. qiskit/result/sampled_expval.py +1 -2
  176. qiskit/result/utils.py +3 -4
  177. qiskit/synthesis/__init__.py +21 -1
  178. qiskit/synthesis/arithmetic/__init__.py +3 -1
  179. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  180. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +1 -1
  181. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +2 -2
  182. qiskit/{providers/fake_provider/backends_v1/fake_20q → synthesis/arithmetic/comparators}/__init__.py +4 -6
  183. qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
  184. qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
  185. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -1
  186. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +1 -1
  187. qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
  188. qiskit/{result/mitigation → synthesis/boolean}/__init__.py +2 -2
  189. qiskit/synthesis/boolean/boolean_expression.py +231 -0
  190. qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
  191. qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
  192. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +2 -0
  193. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  194. qiskit/synthesis/evolution/product_formula.py +44 -35
  195. qiskit/synthesis/evolution/qdrift.py +17 -24
  196. qiskit/synthesis/evolution/suzuki_trotter.py +20 -27
  197. qiskit/synthesis/linear/linear_depth_lnn.py +6 -221
  198. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +4 -205
  199. qiskit/synthesis/multi_controlled/__init__.py +1 -0
  200. qiskit/synthesis/multi_controlled/mcx_synthesis.py +5 -2
  201. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
  202. qiskit/synthesis/one_qubit/one_qubit_decompose.py +1 -1
  203. qiskit/synthesis/two_qubit/__init__.py +1 -0
  204. qiskit/synthesis/two_qubit/two_qubit_decompose.py +28 -145
  205. qiskit/transpiler/__init__.py +32 -232
  206. qiskit/transpiler/basepasses.py +20 -51
  207. qiskit/transpiler/layout.py +1 -1
  208. qiskit/transpiler/passes/__init__.py +2 -40
  209. qiskit/transpiler/passes/basis/basis_translator.py +4 -3
  210. qiskit/transpiler/passes/basis/decompose.py +1 -15
  211. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -5
  212. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +3 -2
  213. qiskit/transpiler/passes/layout/apply_layout.py +4 -0
  214. qiskit/transpiler/passes/layout/dense_layout.py +2 -39
  215. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +4 -4
  216. qiskit/transpiler/passes/layout/sabre_layout.py +7 -3
  217. qiskit/transpiler/passes/layout/vf2_layout.py +2 -20
  218. qiskit/transpiler/passes/layout/vf2_post_layout.py +60 -125
  219. qiskit/transpiler/passes/layout/vf2_utils.py +2 -26
  220. qiskit/transpiler/passes/optimization/__init__.py +1 -3
  221. qiskit/transpiler/passes/optimization/collect_and_collapse.py +2 -0
  222. qiskit/transpiler/passes/optimization/collect_cliffords.py +5 -0
  223. qiskit/transpiler/passes/optimization/collect_linear_functions.py +5 -0
  224. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +16 -1
  225. qiskit/transpiler/passes/optimization/commutation_analysis.py +3 -3
  226. qiskit/transpiler/passes/optimization/consolidate_blocks.py +41 -19
  227. qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
  228. qiskit/transpiler/passes/optimization/light_cone.py +135 -0
  229. qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +0 -1
  230. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +18 -22
  231. qiskit/transpiler/passes/optimization/optimize_annotated.py +3 -2
  232. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +6 -4
  233. qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +5 -2
  234. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +26 -3
  235. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -0
  236. qiskit/transpiler/passes/routing/__init__.py +0 -1
  237. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -1
  238. qiskit/transpiler/passes/routing/sabre_swap.py +14 -6
  239. qiskit/transpiler/passes/routing/star_prerouting.py +1 -1
  240. qiskit/transpiler/passes/scheduling/__init__.py +1 -7
  241. qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -4
  242. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -9
  243. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +17 -16
  244. qiskit/transpiler/passes/scheduling/padding/base_padding.py +30 -2
  245. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +20 -58
  246. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +11 -3
  247. qiskit/transpiler/passes/scheduling/scheduling/alap.py +5 -39
  248. qiskit/transpiler/passes/scheduling/scheduling/asap.py +4 -35
  249. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +10 -16
  250. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +127 -59
  251. qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
  252. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +176 -601
  253. qiskit/transpiler/passes/synthesis/hls_plugins.py +294 -1
  254. qiskit/transpiler/passes/synthesis/plugin.py +4 -0
  255. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +16 -10
  256. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -697
  257. qiskit/transpiler/passes/utils/__init__.py +0 -1
  258. qiskit/transpiler/passes/utils/check_gate_direction.py +13 -5
  259. qiskit/transpiler/passes/utils/control_flow.py +2 -6
  260. qiskit/transpiler/passes/utils/gate_direction.py +7 -0
  261. qiskit/transpiler/passes/utils/remove_final_measurements.py +40 -33
  262. qiskit/transpiler/passmanager.py +13 -0
  263. qiskit/transpiler/passmanager_config.py +5 -81
  264. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +225 -344
  265. qiskit/transpiler/preset_passmanagers/common.py +140 -167
  266. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +101 -322
  267. qiskit/transpiler/preset_passmanagers/level0.py +2 -11
  268. qiskit/transpiler/preset_passmanagers/level1.py +2 -14
  269. qiskit/transpiler/preset_passmanagers/level2.py +2 -12
  270. qiskit/transpiler/preset_passmanagers/level3.py +2 -11
  271. qiskit/transpiler/preset_passmanagers/plugin.py +5 -3
  272. qiskit/transpiler/target.py +67 -524
  273. qiskit/user_config.py +8 -4
  274. qiskit/utils/__init__.py +13 -12
  275. qiskit/utils/deprecation.py +4 -112
  276. qiskit/utils/optionals.py +11 -4
  277. qiskit/utils/parallel.py +214 -87
  278. qiskit/utils/units.py +4 -1
  279. qiskit/visualization/__init__.py +3 -7
  280. qiskit/visualization/array.py +4 -1
  281. qiskit/visualization/bloch.py +1 -1
  282. qiskit/visualization/circuit/_utils.py +19 -19
  283. qiskit/visualization/circuit/circuit_visualization.py +11 -4
  284. qiskit/visualization/circuit/matplotlib.py +13 -23
  285. qiskit/visualization/circuit/text.py +7 -3
  286. qiskit/visualization/dag_visualization.py +2 -1
  287. qiskit/visualization/gate_map.py +39 -154
  288. qiskit/visualization/pass_manager_visualization.py +6 -2
  289. qiskit/visualization/state_visualization.py +6 -0
  290. qiskit/visualization/timeline/core.py +18 -12
  291. qiskit/visualization/timeline/interface.py +19 -18
  292. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/METADATA +2 -2
  293. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/RECORD +297 -444
  294. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/WHEEL +2 -1
  295. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/entry_points.txt +8 -2
  296. qiskit/assembler/__init__.py +0 -42
  297. qiskit/assembler/assemble_circuits.py +0 -451
  298. qiskit/assembler/assemble_schedules.py +0 -367
  299. qiskit/assembler/disassemble.py +0 -310
  300. qiskit/assembler/run_config.py +0 -77
  301. qiskit/circuit/bit.py +0 -106
  302. qiskit/circuit/classicalfunction/__init__.py +0 -152
  303. qiskit/circuit/classicalfunction/boolean_expression.py +0 -138
  304. qiskit/circuit/classicalfunction/classical_element.py +0 -54
  305. qiskit/circuit/classicalfunction/classical_function_visitor.py +0 -155
  306. qiskit/circuit/classicalfunction/classicalfunction.py +0 -182
  307. qiskit/circuit/classicalfunction/exceptions.py +0 -41
  308. qiskit/circuit/classicalfunction/types.py +0 -18
  309. qiskit/circuit/classicalfunction/utils.py +0 -91
  310. qiskit/circuit/classicalregister.py +0 -57
  311. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +0 -405
  312. qiskit/circuit/quantumregister.py +0 -75
  313. qiskit/circuit/register.py +0 -246
  314. qiskit/compiler/assembler.py +0 -689
  315. qiskit/compiler/scheduler.py +0 -109
  316. qiskit/compiler/sequencer.py +0 -71
  317. qiskit/primitives/backend_estimator.py +0 -486
  318. qiskit/primitives/backend_sampler.py +0 -222
  319. qiskit/primitives/estimator.py +0 -172
  320. qiskit/primitives/sampler.py +0 -162
  321. qiskit/providers/backend_compat.py +0 -507
  322. qiskit/providers/fake_provider/backends_v1/__init__.py +0 -22
  323. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +0 -18
  324. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +0 -1
  325. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +0 -1
  326. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +0 -37
  327. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +0 -1
  328. qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +0 -1
  329. qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +0 -43
  330. qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +0 -1
  331. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +0 -18
  332. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +0 -1
  333. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +0 -1
  334. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +0 -50
  335. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +0 -1
  336. qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +0 -18
  337. qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +0 -1
  338. qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +0 -41
  339. qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +0 -1
  340. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +0 -18
  341. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +0 -1
  342. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +0 -1
  343. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +0 -44
  344. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +0 -1
  345. qiskit/providers/fake_provider/fake_1q.py +0 -91
  346. qiskit/providers/fake_provider/fake_backend.py +0 -165
  347. qiskit/providers/fake_provider/fake_openpulse_2q.py +0 -391
  348. qiskit/providers/fake_provider/fake_openpulse_3q.py +0 -340
  349. qiskit/providers/fake_provider/fake_pulse_backend.py +0 -49
  350. qiskit/providers/fake_provider/fake_qasm_backend.py +0 -77
  351. qiskit/providers/fake_provider/utils/backend_converter.py +0 -150
  352. qiskit/providers/fake_provider/utils/json_decoder.py +0 -109
  353. qiskit/providers/models/__init__.py +0 -89
  354. qiskit/providers/models/backendconfiguration.py +0 -1040
  355. qiskit/providers/models/backendproperties.py +0 -535
  356. qiskit/providers/models/backendstatus.py +0 -104
  357. qiskit/providers/models/jobstatus.py +0 -77
  358. qiskit/providers/models/pulsedefaults.py +0 -305
  359. qiskit/providers/provider.py +0 -95
  360. qiskit/pulse/__init__.py +0 -158
  361. qiskit/pulse/builder.py +0 -2262
  362. qiskit/pulse/calibration_entries.py +0 -381
  363. qiskit/pulse/channels.py +0 -227
  364. qiskit/pulse/configuration.py +0 -245
  365. qiskit/pulse/exceptions.py +0 -45
  366. qiskit/pulse/filters.py +0 -309
  367. qiskit/pulse/instruction_schedule_map.py +0 -424
  368. qiskit/pulse/instructions/__init__.py +0 -67
  369. qiskit/pulse/instructions/acquire.py +0 -150
  370. qiskit/pulse/instructions/delay.py +0 -71
  371. qiskit/pulse/instructions/directives.py +0 -154
  372. qiskit/pulse/instructions/frequency.py +0 -135
  373. qiskit/pulse/instructions/instruction.py +0 -270
  374. qiskit/pulse/instructions/phase.py +0 -152
  375. qiskit/pulse/instructions/play.py +0 -99
  376. qiskit/pulse/instructions/reference.py +0 -100
  377. qiskit/pulse/instructions/snapshot.py +0 -82
  378. qiskit/pulse/library/__init__.py +0 -97
  379. qiskit/pulse/library/continuous.py +0 -430
  380. qiskit/pulse/library/pulse.py +0 -148
  381. qiskit/pulse/library/samplers/__init__.py +0 -15
  382. qiskit/pulse/library/samplers/decorators.py +0 -295
  383. qiskit/pulse/library/samplers/strategies.py +0 -71
  384. qiskit/pulse/library/symbolic_pulses.py +0 -1989
  385. qiskit/pulse/library/waveform.py +0 -136
  386. qiskit/pulse/macros.py +0 -262
  387. qiskit/pulse/parameter_manager.py +0 -445
  388. qiskit/pulse/parser.py +0 -314
  389. qiskit/pulse/reference_manager.py +0 -58
  390. qiskit/pulse/schedule.py +0 -1854
  391. qiskit/pulse/transforms/__init__.py +0 -106
  392. qiskit/pulse/transforms/alignments.py +0 -406
  393. qiskit/pulse/transforms/base_transforms.py +0 -71
  394. qiskit/pulse/transforms/canonicalization.py +0 -498
  395. qiskit/pulse/transforms/dag.py +0 -122
  396. qiskit/pulse/utils.py +0 -149
  397. qiskit/qobj/__init__.py +0 -75
  398. qiskit/qobj/common.py +0 -81
  399. qiskit/qobj/converters/__init__.py +0 -18
  400. qiskit/qobj/converters/lo_config.py +0 -177
  401. qiskit/qobj/converters/pulse_instruction.py +0 -897
  402. qiskit/qobj/pulse_qobj.py +0 -709
  403. qiskit/qobj/qasm_qobj.py +0 -708
  404. qiskit/qobj/utils.py +0 -46
  405. qiskit/result/mitigation/base_readout_mitigator.py +0 -79
  406. qiskit/result/mitigation/correlated_readout_mitigator.py +0 -277
  407. qiskit/result/mitigation/local_readout_mitigator.py +0 -328
  408. qiskit/result/mitigation/utils.py +0 -217
  409. qiskit/scheduler/__init__.py +0 -40
  410. qiskit/scheduler/config.py +0 -37
  411. qiskit/scheduler/lowering.py +0 -187
  412. qiskit/scheduler/methods/__init__.py +0 -15
  413. qiskit/scheduler/methods/basic.py +0 -140
  414. qiskit/scheduler/schedule_circuit.py +0 -69
  415. qiskit/scheduler/sequence.py +0 -104
  416. qiskit/transpiler/passes/calibration/__init__.py +0 -17
  417. qiskit/transpiler/passes/calibration/base_builder.py +0 -79
  418. qiskit/transpiler/passes/calibration/builders.py +0 -20
  419. qiskit/transpiler/passes/calibration/exceptions.py +0 -22
  420. qiskit/transpiler/passes/calibration/pulse_gate.py +0 -100
  421. qiskit/transpiler/passes/calibration/rx_builder.py +0 -164
  422. qiskit/transpiler/passes/calibration/rzx_builder.py +0 -411
  423. qiskit/transpiler/passes/calibration/rzx_templates.py +0 -58
  424. qiskit/transpiler/passes/optimization/cx_cancellation.py +0 -65
  425. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +0 -162
  426. qiskit/transpiler/passes/optimization/normalize_rx_angle.py +0 -157
  427. qiskit/transpiler/passes/routing/stochastic_swap.py +0 -532
  428. qiskit/transpiler/passes/scheduling/alap.py +0 -153
  429. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +0 -255
  430. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -107
  431. qiskit/transpiler/passes/scheduling/asap.py +0 -175
  432. qiskit/transpiler/passes/scheduling/base_scheduler.py +0 -310
  433. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +0 -313
  434. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -93
  435. qiskit/utils/deprecate_pulse.py +0 -119
  436. qiskit/utils/multiprocessing.py +0 -56
  437. qiskit/visualization/pulse_v2/__init__.py +0 -21
  438. qiskit/visualization/pulse_v2/core.py +0 -901
  439. qiskit/visualization/pulse_v2/device_info.py +0 -173
  440. qiskit/visualization/pulse_v2/drawings.py +0 -253
  441. qiskit/visualization/pulse_v2/events.py +0 -254
  442. qiskit/visualization/pulse_v2/generators/__init__.py +0 -40
  443. qiskit/visualization/pulse_v2/generators/barrier.py +0 -76
  444. qiskit/visualization/pulse_v2/generators/chart.py +0 -208
  445. qiskit/visualization/pulse_v2/generators/frame.py +0 -436
  446. qiskit/visualization/pulse_v2/generators/snapshot.py +0 -133
  447. qiskit/visualization/pulse_v2/generators/waveform.py +0 -645
  448. qiskit/visualization/pulse_v2/interface.py +0 -459
  449. qiskit/visualization/pulse_v2/layouts.py +0 -387
  450. qiskit/visualization/pulse_v2/plotters/__init__.py +0 -17
  451. qiskit/visualization/pulse_v2/plotters/base_plotter.py +0 -53
  452. qiskit/visualization/pulse_v2/plotters/matplotlib.py +0 -201
  453. qiskit/visualization/pulse_v2/stylesheet.py +0 -312
  454. qiskit/visualization/pulse_v2/types.py +0 -242
  455. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/LICENSE.txt +0 -0
  456. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/top_level.txt +0 -0
@@ -14,11 +14,13 @@
14
14
  """Integer Comparator."""
15
15
 
16
16
  from __future__ import annotations
17
- import math
18
17
 
19
- from qiskit.circuit import QuantumCircuit, QuantumRegister, AncillaRegister
18
+ from qiskit.circuit import QuantumRegister, AncillaRegister, Gate
20
19
  from qiskit.circuit.exceptions import CircuitError
21
- from ..boolean_logic import OR
20
+ from qiskit.synthesis.arithmetic.comparators import (
21
+ synth_integer_comparator_2s,
22
+ synth_integer_comparator_greedy,
23
+ )
22
24
  from ..blueprintcircuit import BlueprintCircuit
23
25
 
24
26
 
@@ -134,19 +136,6 @@ class IntegerComparator(BlueprintCircuit):
134
136
  qr_ancilla = AncillaRegister(num_ancillas)
135
137
  self.add_register(qr_ancilla)
136
138
 
137
- def _get_twos_complement(self) -> list[int]:
138
- """Returns the 2's complement of ``self.value`` as array.
139
-
140
- Returns:
141
- The 2's complement of ``self.value``.
142
- """
143
- twos_complement = pow(2, self.num_state_qubits) - math.ceil(self.value)
144
- twos_complement = f"{twos_complement:b}".rjust(self.num_state_qubits, "0")
145
- twos_complement = [
146
- 1 if twos_complement[i] == "1" else 0 for i in reversed(range(len(twos_complement)))
147
- ]
148
- return twos_complement
149
-
150
139
  def _check_configuration(self, raise_on_failure: bool = True) -> bool:
151
140
  """Check if the current configuration is valid."""
152
141
  valid = True
@@ -176,68 +165,36 @@ class IntegerComparator(BlueprintCircuit):
176
165
 
177
166
  super()._build()
178
167
 
179
- qr_state = self.qubits[: self.num_state_qubits]
180
- q_compare = self.qubits[self.num_state_qubits]
181
- qr_ancilla = self.qubits[self.num_state_qubits + 1 :]
182
-
183
- circuit = QuantumCircuit(*self.qregs, name=self.name)
184
-
185
- if self.value <= 0: # condition always satisfied for non-positive values
186
- if self._geq: # otherwise the condition is never satisfied
187
- circuit.x(q_compare)
188
- # condition never satisfied for values larger than or equal to 2^n
189
- elif self.value < pow(2, self.num_state_qubits):
190
-
191
- if self.num_state_qubits > 1:
192
- twos = self._get_twos_complement()
193
- for i in range(self.num_state_qubits):
194
- if i == 0:
195
- if twos[i] == 1:
196
- circuit.cx(qr_state[i], qr_ancilla[i])
197
- elif i < self.num_state_qubits - 1:
198
- if twos[i] == 1:
199
- circuit.compose(
200
- OR(2), [qr_state[i], qr_ancilla[i - 1], qr_ancilla[i]], inplace=True
201
- )
202
- else:
203
- circuit.ccx(qr_state[i], qr_ancilla[i - 1], qr_ancilla[i])
204
- else:
205
- if twos[i] == 1:
206
- # OR needs the result argument as qubit not register, thus
207
- # access the index [0]
208
- circuit.compose(
209
- OR(2), [qr_state[i], qr_ancilla[i - 1], q_compare], inplace=True
210
- )
211
- else:
212
- circuit.ccx(qr_state[i], qr_ancilla[i - 1], q_compare)
213
-
214
- # flip result bit if geq flag is false
215
- if not self._geq:
216
- circuit.x(q_compare)
217
-
218
- # uncompute ancillas state
219
- for i in reversed(range(self.num_state_qubits - 1)):
220
- if i == 0:
221
- if twos[i] == 1:
222
- circuit.cx(qr_state[i], qr_ancilla[i])
223
- else:
224
- if twos[i] == 1:
225
- circuit.compose(
226
- OR(2), [qr_state[i], qr_ancilla[i - 1], qr_ancilla[i]], inplace=True
227
- )
228
- else:
229
- circuit.ccx(qr_state[i], qr_ancilla[i - 1], qr_ancilla[i])
230
- else:
231
-
232
- # num_state_qubits == 1 and value == 1:
233
- circuit.cx(qr_state[0], q_compare)
234
-
235
- # flip result bit if geq flag is false
236
- if not self._geq:
237
- circuit.x(q_compare)
238
-
239
- else:
240
- if not self._geq: # otherwise the condition is never satisfied
241
- circuit.x(q_compare)
242
-
168
+ circuit = synth_integer_comparator_2s(self.num_state_qubits, self.value, self.geq)
243
169
  self.append(circuit.to_gate(), self.qubits)
170
+
171
+
172
+ class IntegerComparatorGate(Gate):
173
+ r"""Perform a :math:`\geq` (or :math:`<`) on a qubit register against a classical integer.
174
+
175
+ This operator compares basis states :math:`|i\rangle_n` against a classically given integer
176
+ :math:`L` of fixed value and flips a target qubit if :math:`i \geq L`
177
+ (or :math:`<` depending on the parameter ``geq``):
178
+
179
+ .. math::
180
+
181
+ |i\rangle_n |0\rangle \mapsto |i\rangle_n |i \geq L\rangle
182
+
183
+ """
184
+
185
+ def __init__(
186
+ self, num_state_qubits: int, value: int, geq: bool = True, label: str | None = None
187
+ ):
188
+ r"""
189
+ Args:
190
+ num_state_qubits: The number of qubits in the registers.
191
+ value: The value :math:`L` to compre to.
192
+ geq: If ``True`` compute :math:`i \geq L`, otherwise compute :math:`i < L`.
193
+ label: An optional label for the gate.
194
+ """
195
+ super().__init__("IntComp", num_state_qubits + 1, [], label=label)
196
+ self.value = value
197
+ self.geq = geq
198
+
199
+ def _define(self):
200
+ self.definition = synth_integer_comparator_greedy(self.num_qubits - 1, self.value, self.geq)
@@ -14,9 +14,12 @@
14
14
 
15
15
  from __future__ import annotations
16
16
  import numpy as np
17
- from qiskit.circuit import QuantumCircuit
17
+ from qiskit.circuit import QuantumCircuit, Gate
18
18
 
19
- from .piecewise_linear_pauli_rotations import PiecewiseLinearPauliRotations
19
+ from .piecewise_linear_pauli_rotations import (
20
+ PiecewiseLinearPauliRotations,
21
+ PiecewiseLinearPauliRotationsGate,
22
+ )
20
23
 
21
24
 
22
25
  class LinearAmplitudeFunction(QuantumCircuit):
@@ -173,6 +176,170 @@ class LinearAmplitudeFunction(QuantumCircuit):
173
176
  return value
174
177
 
175
178
 
179
+ class LinearAmplitudeFunctionGate(Gate):
180
+ r"""A circuit implementing a (piecewise) linear function on qubit amplitudes.
181
+
182
+ An amplitude function :math:`F` of a function :math:`f` is a mapping
183
+
184
+ .. math::
185
+
186
+ F|x\rangle|0\rangle = \sqrt{1 - \hat{f}(x)} |x\rangle|0\rangle + \sqrt{\hat{f}(x)}
187
+ |x\rangle|1\rangle.
188
+
189
+ for a function :math:`\hat{f}: \{ 0, ..., 2^n - 1 \} \rightarrow [0, 1]`, where
190
+ :math:`|x\rangle` is a :math:`n` qubit state.
191
+
192
+ This circuit implements :math:`F` for piecewise linear functions :math:`\hat{f}`.
193
+ In this case, the mapping :math:`F` can be approximately implemented using a Taylor expansion
194
+ and linearly controlled Pauli-Y rotations, see [1, 2] for more detail. This approximation
195
+ uses a ``rescaling_factor`` to determine the accuracy of the Taylor expansion.
196
+
197
+ In general, the function of interest :math:`f` is defined from some interval :math:`[a,b]`,
198
+ the ``domain`` to :math:`[c,d]`, the ``image``, instead of :math:`\{ 1, ..., N \}` to
199
+ :math:`[0, 1]`. Using an affine transformation we can rescale :math:`f` to :math:`\hat{f}`:
200
+
201
+ .. math::
202
+
203
+ \hat{f}(x) = \frac{f(\phi(x)) - c}{d - c}
204
+
205
+ with
206
+
207
+ .. math::
208
+
209
+ \phi(x) = a + \frac{b - a}{2^n - 1} x.
210
+
211
+ If :math:`f` is a piecewise linear function on :math:`m` intervals
212
+ :math:`[p_{i-1}, p_i], i \in \{1, ..., m\}` with slopes :math:`\alpha_i` and
213
+ offsets :math:`\beta_i` it can be written as
214
+
215
+ .. math::
216
+
217
+ f(x) = \sum_{i=1}^m 1_{[p_{i-1}, p_i]}(x) (\alpha_i x + \beta_i)
218
+
219
+ where :math:`1_{[a, b]}` is an indication function that is 1 if the argument is in the interval
220
+ :math:`[a, b]` and otherwise 0. The breakpoints :math:`p_i` can be specified by the
221
+ ``breakpoints`` argument.
222
+
223
+ References:
224
+
225
+ [1]: Woerner, S., & Egger, D. J. (2018).
226
+ Quantum Risk Analysis.
227
+ `arXiv:1806.06893 <http://arxiv.org/abs/1806.06893>`_
228
+
229
+ [2]: Gacon, J., Zoufal, C., & Woerner, S. (2020).
230
+ Quantum-Enhanced Simulation-Based Optimization.
231
+ `arXiv:2005.10780 <http://arxiv.org/abs/2005.10780>`_
232
+ """
233
+
234
+ def __init__(
235
+ self,
236
+ num_state_qubits: int,
237
+ slope: float | list[float],
238
+ offset: float | list[float],
239
+ domain: tuple[float, float],
240
+ image: tuple[float, float],
241
+ rescaling_factor: float = 1,
242
+ breakpoints: list[float] | None = None,
243
+ label: str = "F",
244
+ ) -> None:
245
+ r"""
246
+ Args:
247
+ num_state_qubits: The number of qubits used to encode the variable :math:`x`.
248
+ slope: The slope of the linear function. Can be a list of slopes if it is a piecewise
249
+ linear function.
250
+ offset: The offset of the linear function. Can be a list of offsets if it is a piecewise
251
+ linear function.
252
+ domain: The domain of the function as tuple :math:`(x_\min{}, x_\max{})`.
253
+ image: The image of the function as tuple :math:`(f_\min{}, f_\max{})`.
254
+ rescaling_factor: The rescaling factor to adjust the accuracy in the Taylor
255
+ approximation.
256
+ breakpoints: The breakpoints if the function is piecewise linear. If None, the function
257
+ is not piecewise.
258
+ label: A label for the gate.
259
+ """
260
+ if not hasattr(slope, "__len__"):
261
+ slope = [slope]
262
+ if not hasattr(offset, "__len__"):
263
+ offset = [offset]
264
+
265
+ # ensure that the breakpoints include the first point of the domain
266
+ if breakpoints is None:
267
+ breakpoints = [domain[0]]
268
+ else:
269
+ if not np.isclose(breakpoints[0], domain[0]):
270
+ breakpoints = [domain[0]] + breakpoints
271
+
272
+ _check_sizes_match(slope, offset, breakpoints)
273
+ _check_sorted_and_in_range(breakpoints, domain)
274
+
275
+ self.slope = slope
276
+ self.offset = offset
277
+ self.domain = domain
278
+ self.image = image
279
+ self.rescaling_factor = rescaling_factor
280
+ self.breakpoints = breakpoints
281
+
282
+ num_compare = int(len(breakpoints) > 1)
283
+ super().__init__("LinFunction", num_state_qubits + num_compare + 1, [], label=label)
284
+
285
+ def _define(self):
286
+ num_compare = int(len(self.breakpoints) > 1)
287
+ num_state_qubits = self.num_qubits - num_compare - 1
288
+
289
+ # do rescaling
290
+ a, b = self.domain
291
+ c, d = self.image
292
+
293
+ mapped_breakpoints = []
294
+ mapped_slope = []
295
+ mapped_offset = []
296
+ for i, point in enumerate(self.breakpoints):
297
+ mapped_breakpoint = (point - a) / (b - a) * (2**num_state_qubits - 1)
298
+ mapped_breakpoints += [mapped_breakpoint]
299
+
300
+ # factor (upper - lower) / (2^n - 1) is for the scaling of x to [l,u]
301
+ # note that the +l for mapping to [l,u] is already included in
302
+ # the offsets given as parameters
303
+ mapped_slope += [self.slope[i] * (b - a) / (2**num_state_qubits - 1)]
304
+ mapped_offset += [self.offset[i]]
305
+
306
+ # approximate linear behavior by scaling and contracting around pi/4
307
+ slope_angles = np.zeros(len(self.breakpoints))
308
+ offset_angles = np.pi / 4 * (1 - self.rescaling_factor) * np.ones_like(slope_angles)
309
+ for i, (slope_i, offset_i) in enumerate(zip(mapped_slope, mapped_offset)):
310
+ slope_angles[i] = np.pi * self.rescaling_factor * slope_i / 2 / (d - c)
311
+ offset_angles[i] += np.pi * self.rescaling_factor * (offset_i - c) / 2 / (d - c)
312
+
313
+ # use PWLPauliRotations to implement the function
314
+ pwl_pauli_rotation = PiecewiseLinearPauliRotationsGate(
315
+ num_state_qubits, mapped_breakpoints, 2 * slope_angles, 2 * offset_angles
316
+ )
317
+
318
+ self.definition = QuantumCircuit(pwl_pauli_rotation.num_qubits)
319
+ self.definition.append(pwl_pauli_rotation, self.definition.qubits)
320
+
321
+ def post_processing(self, scaled_value: float) -> float:
322
+ r"""Map the function value of the approximated :math:`\hat{f}` to :math:`f`.
323
+
324
+ Args:
325
+ scaled_value: A function value from the Taylor expansion of :math:`\hat{f}(x)`.
326
+
327
+ Returns:
328
+ The ``scaled_value`` mapped back to the domain of :math:`f`, by first inverting
329
+ the transformation used for the Taylor approximation and then mapping back from
330
+ :math:`[0, 1]` to the original domain.
331
+ """
332
+ # revert the mapping applied in the Taylor approximation
333
+ value = scaled_value - 1 / 2 + np.pi / 4 * self.rescaling_factor
334
+ value *= 2 / np.pi / self.rescaling_factor
335
+
336
+ # map the value from [0, 1] back to the original domain
337
+ value *= self.image[1] - self.image[0]
338
+ value += self.image[0]
339
+
340
+ return value
341
+
342
+
176
343
  def _check_sorted_and_in_range(breakpoints, domain):
177
344
  if breakpoints is None:
178
345
  return
@@ -13,9 +13,10 @@
13
13
 
14
14
  """Linearly-controlled X, Y or Z rotation."""
15
15
 
16
+ from __future__ import annotations
16
17
  from typing import Optional
17
18
 
18
- from qiskit.circuit import QuantumRegister, QuantumCircuit
19
+ from qiskit.circuit import QuantumRegister, QuantumCircuit, Gate
19
20
  from qiskit.circuit.exceptions import CircuitError
20
21
 
21
22
  from .functional_pauli_rotations import FunctionalPauliRotations
@@ -164,12 +165,65 @@ class LinearPauliRotations(FunctionalPauliRotations):
164
165
  return
165
166
 
166
167
  super()._build()
168
+ gate = LinearPauliRotationsGate(self.num_state_qubits, self.slope, self.offset, self.basis)
169
+ self.append(gate, self.qubits)
167
170
 
168
- circuit = QuantumCircuit(*self.qregs, name=self.name)
171
+
172
+ class LinearPauliRotationsGate(Gate):
173
+ r"""Linearly-controlled X, Y or Z rotation.
174
+
175
+ For a register of state qubits :math:`|x\rangle`, a target qubit :math:`|0\rangle` and the
176
+ basis ``'Y'`` this circuit acts as:
177
+
178
+ .. parsed-literal::
179
+
180
+ q_0: ─────────────────────────■───────── ... ──────────────────────
181
+
182
+ .
183
+
184
+ q_(n-1): ─────────────────────────┼───────── ... ───────────■──────────
185
+ ┌────────────┐ ┌───────┴───────┐ ┌─────────┴─────────┐
186
+ q_n: ─┤ RY(offset) ├──┤ RY(2^0 slope) ├ ... ┤ RY(2^(n-1) slope) ├
187
+ └────────────┘ └───────────────┘ └───────────────────┘
188
+
189
+ This can for example be used to approximate linear functions, with :math:`a =` ``slope``:math:`/2`
190
+ and :math:`b =` ``offset``:math:`/2` and the basis ``'Y'``:
191
+
192
+ .. math::
193
+
194
+ |x\rangle |0\rangle \mapsto \cos(ax + b)|x\rangle|0\rangle + \sin(ax + b)|x\rangle |1\rangle
195
+
196
+ Since for small arguments :math:`\sin(x) \approx x` this operator can be used to approximate
197
+ linear functions.
198
+ """
199
+
200
+ def __init__(
201
+ self,
202
+ num_state_qubits: int,
203
+ slope: float = 1,
204
+ offset: float = 0,
205
+ basis: str = "Y",
206
+ label: str | None = None,
207
+ ) -> None:
208
+ r"""
209
+ Args:
210
+ num_state_qubits: The number of qubits representing the state :math:`|x\rangle`.
211
+ slope: The slope of the controlled rotation.
212
+ offset: The offset of the controlled rotation.
213
+ basis: The type of Pauli rotation ('X', 'Y', 'Z').
214
+ label: The label of the gate.
215
+ """
216
+ super().__init__("LinPauliRot", num_state_qubits + 1, [], label=label)
217
+ self.slope = slope
218
+ self.offset = offset
219
+ self.basis = basis.lower()
220
+
221
+ def _define(self):
222
+ circuit = QuantumCircuit(self.num_qubits, name=self.name)
169
223
 
170
224
  # build the circuit
171
- qr_state = self.qubits[: self.num_state_qubits]
172
- qr_target = self.qubits[self.num_state_qubits]
225
+ qr_state = circuit.qubits[: self.num_qubits - 1]
226
+ qr_target = circuit.qubits[-1]
173
227
 
174
228
  if self.basis == "x":
175
229
  circuit.rx(self.offset, qr_target)
@@ -186,4 +240,4 @@ class LinearPauliRotations(FunctionalPauliRotations):
186
240
  else: # 'Z'
187
241
  circuit.crz(self.slope * pow(2, i), q_i, qr_target)
188
242
 
189
- self.append(circuit.to_gate(), self.qubits)
243
+ self.definition = circuit
@@ -17,11 +17,14 @@ from typing import Callable
17
17
  import numpy as np
18
18
  from numpy.polynomial.chebyshev import Chebyshev
19
19
 
20
- from qiskit.circuit import QuantumRegister, AncillaRegister
20
+ from qiskit.circuit import QuantumCircuit, QuantumRegister, AncillaRegister, Gate
21
21
  from qiskit.circuit.library.blueprintcircuit import BlueprintCircuit
22
22
  from qiskit.circuit.exceptions import CircuitError
23
23
 
24
- from .piecewise_polynomial_pauli_rotations import PiecewisePolynomialPauliRotations
24
+ from .piecewise_polynomial_pauli_rotations import (
25
+ PiecewisePolynomialPauliRotations,
26
+ PiecewisePolynomialPauliRotationsGate,
27
+ )
25
28
 
26
29
 
27
30
  class PiecewiseChebyshev(BlueprintCircuit):
@@ -346,9 +349,154 @@ class PiecewiseChebyshev(BlueprintCircuit):
346
349
  self.num_state_qubits, self.breakpoints, self.polynomials, name=self.name
347
350
  )
348
351
 
349
- # qr_state = self.qubits[: self.num_state_qubits]
350
- # qr_target = [self.qubits[self.num_state_qubits]]
351
- # qr_ancillas = self.qubits[self.num_state_qubits + 1 :]
352
-
353
352
  # Apply polynomial approximation
354
353
  self.append(poly_r.to_gate(), self.qubits)
354
+
355
+
356
+ class PiecewiseChebyshevGate(Gate):
357
+ r"""Piecewise Chebyshev approximation to an input function.
358
+
359
+ For a given function :math:`f(x)` and degree :math:`d`, this class implements a piecewise
360
+ polynomial Chebyshev approximation on :math:`n` qubits to :math:`f(x)` on the given intervals.
361
+ All the polynomials in the approximation are of degree :math:`d`.
362
+
363
+ The values of the parameters are calculated according to [1] and see [2] for a more
364
+ detailed explanation of the circuit construction and how it acts on the qubits.
365
+
366
+ Examples:
367
+
368
+ .. plot::
369
+ :alt: Example of generating a circuit with the piecewise Chebyshev gate.
370
+ :include-source:
371
+
372
+ import numpy as np
373
+ from qiskit import QuantumCircuit
374
+ from qiskit.circuit.library.arithmetic import PiecewiseChebyshevGate
375
+
376
+ f_x, num_state_qubits, degree, breakpoints = lambda x: np.arcsin(1 / x), 2, 2, [2, 4]
377
+ pw_approximation = PiecewiseChebyshevGate(f_x, num_state_qubits, degree, breakpoints)
378
+
379
+ qc = QuantumCircuit(pw_approximation.num_qubits)
380
+ qc.h(list(range(num_state_qubits)))
381
+ qc.append(pw_approximation, qc.qubits)
382
+ qc.draw(output="mpl")
383
+
384
+ References:
385
+
386
+ [1]: Haener, T., Roetteler, M., & Svore, K. M. (2018).
387
+ Optimizing Quantum Circuits for Arithmetic.
388
+ `arXiv:1805.12445 <http://arxiv.org/abs/1805.12445>`_
389
+ [2]: Carrera Vazquez, A., Hiptmair, H., & Woerner, S. (2022).
390
+ Enhancing the Quantum Linear Systems Algorithm Using Richardson Extrapolation.
391
+ `ACM Transactions on Quantum Computing 3, 1, Article 2 <https://doi.org/10.1145/3490631>`_
392
+ """
393
+
394
+ def __init__(
395
+ self,
396
+ f_x: float | Callable[[int], float],
397
+ num_state_qubits: int,
398
+ degree: int | None = None,
399
+ breakpoints: list[int] | None = None,
400
+ label: str | None = None,
401
+ ) -> None:
402
+ r"""
403
+ Args:
404
+ f_x: the function to be approximated. Constant functions should be specified
405
+ as f_x = constant.
406
+ num_state_qubits: number of qubits representing the state.
407
+ degree: the degree of the polynomials.
408
+ Defaults to ``1``.
409
+ breakpoints: the breakpoints to define the piecewise-linear function.
410
+ Defaults to the full interval.
411
+ label: A label for the gate.
412
+ """
413
+ # Store parameters
414
+ self.f_x = f_x
415
+ self.degree = degree if degree is not None else 1
416
+ self.num_state_qubits = num_state_qubits
417
+
418
+ # validate the breakpoints
419
+ if breakpoints is None:
420
+ breakpoints = [0]
421
+
422
+ # If the last breakpoint is < num_states, add the identity polynomial
423
+ num_states = 2**num_state_qubits
424
+ if breakpoints[-1] < num_states:
425
+ breakpoints = breakpoints + [num_states]
426
+
427
+ # If the first breakpoint is > 0, add the identity polynomial
428
+ if breakpoints[0] > 0:
429
+ breakpoints = [0] + breakpoints
430
+
431
+ self.breakpoints = breakpoints
432
+
433
+ num_compare = int(len(breakpoints) > 2)
434
+ super().__init__("PiecewiseChebyshev", num_state_qubits + num_compare + 1, [], label)
435
+
436
+ # after initialization, build the polynomials
437
+ self.polynomials = self._build_polynomials()
438
+
439
+ def _build_polynomials(self):
440
+ """The polynomials for the piecewise approximation.
441
+
442
+ Returns:
443
+ The polynomials for the piecewise approximation.
444
+
445
+ Raises:
446
+ TypeError: If the input function is not in the correct format.
447
+ """
448
+
449
+ # note this must be the private attribute since we handle missing breakpoints at
450
+ # 0 and 2 ^ num_qubits here (e.g. if the function we approximate is not defined at 0
451
+ # and the user takes that into account we just add an identity)
452
+ breakpoints = self.breakpoints
453
+
454
+ # Need to take into account the case in which no breakpoints were provided in first place
455
+ num_state_qubits = self.num_qubits - 1
456
+ if breakpoints == [0]:
457
+ breakpoints = [0, 2**num_state_qubits]
458
+
459
+ num_intervals = len(breakpoints)
460
+
461
+ # Calculate the polynomials
462
+ polynomials = []
463
+ for i in range(0, num_intervals - 1):
464
+ # Calculate the polynomial approximating the function on the current interval
465
+ try:
466
+ # If the function is constant don't call Chebyshev (not necessary and gives errors)
467
+ if isinstance(self.f_x, (float, int)):
468
+ # Append directly to list of polynomials
469
+ polynomials.append([self.f_x])
470
+ else:
471
+ poly = Chebyshev.interpolate(
472
+ self.f_x, self.degree, domain=[breakpoints[i], breakpoints[i + 1]]
473
+ )
474
+ # Convert polynomial to the standard basis and rescale it for the rotation gates
475
+ poly = 2 * poly.convert(kind=np.polynomial.Polynomial).coef
476
+ # Convert to list and append
477
+ polynomials.append(poly.tolist())
478
+ except ValueError as err:
479
+ raise TypeError(
480
+ " <lambda>() missing 1 required positional argument: '"
481
+ + self.f_x.__code__.co_varnames[0]
482
+ + "'."
483
+ + " Constant functions should be specified as 'f_x = constant'."
484
+ ) from err
485
+
486
+ # If the last breakpoint is < 2 ** num_qubits, add the identity polynomial
487
+ if breakpoints[-1] < 2**num_state_qubits:
488
+ polynomials = polynomials + [[2 * np.arcsin(1)]]
489
+
490
+ # If the first breakpoint is > 0, add the identity polynomial
491
+ if breakpoints[0] > 0:
492
+ polynomials = [[2 * np.arcsin(1)]] + polynomials
493
+
494
+ return polynomials
495
+
496
+ def _define(self):
497
+ poly_r = PiecewisePolynomialPauliRotationsGate(
498
+ self.num_state_qubits, self.breakpoints, self.polynomials
499
+ )
500
+
501
+ self.definition = QuantumCircuit(poly_r.num_qubits)
502
+ self.definition.append(poly_r, self.definition.qubits)