qiskit 1.0.2__cp38-abi3-win32.whl → 1.1.0__cp38-abi3-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +27 -16
  3. qiskit/_accelerate.pyd +0 -0
  4. qiskit/_numpy_compat.py +73 -0
  5. qiskit/assembler/__init__.py +5 -10
  6. qiskit/assembler/disassemble.py +5 -6
  7. qiskit/circuit/__init__.py +1061 -232
  8. qiskit/circuit/_classical_resource_map.py +10 -6
  9. qiskit/circuit/_utils.py +18 -8
  10. qiskit/circuit/annotated_operation.py +21 -0
  11. qiskit/circuit/barrier.py +10 -13
  12. qiskit/circuit/bit.py +0 -1
  13. qiskit/circuit/classical/__init__.py +2 -2
  14. qiskit/circuit/classical/expr/__init__.py +39 -5
  15. qiskit/circuit/classical/expr/constructors.py +84 -1
  16. qiskit/circuit/classical/expr/expr.py +83 -13
  17. qiskit/circuit/classical/expr/visitors.py +83 -0
  18. qiskit/circuit/classical/types/__init__.py +5 -4
  19. qiskit/circuit/classicalfunction/__init__.py +1 -0
  20. qiskit/circuit/commutation_checker.py +86 -51
  21. qiskit/circuit/controlflow/_builder_utils.py +9 -1
  22. qiskit/circuit/controlflow/break_loop.py +8 -22
  23. qiskit/circuit/controlflow/builder.py +116 -1
  24. qiskit/circuit/controlflow/continue_loop.py +8 -22
  25. qiskit/circuit/controlflow/control_flow.py +47 -8
  26. qiskit/circuit/controlflow/for_loop.py +8 -23
  27. qiskit/circuit/controlflow/if_else.py +13 -27
  28. qiskit/circuit/controlflow/switch_case.py +14 -21
  29. qiskit/circuit/controlflow/while_loop.py +9 -23
  30. qiskit/circuit/controlledgate.py +2 -2
  31. qiskit/circuit/delay.py +7 -5
  32. qiskit/circuit/gate.py +20 -7
  33. qiskit/circuit/instruction.py +31 -30
  34. qiskit/circuit/instructionset.py +9 -22
  35. qiskit/circuit/library/__init__.py +3 -13
  36. qiskit/circuit/library/arithmetic/integer_comparator.py +2 -2
  37. qiskit/circuit/library/arithmetic/quadratic_form.py +3 -2
  38. qiskit/circuit/library/blueprintcircuit.py +29 -7
  39. qiskit/circuit/library/data_preparation/state_preparation.py +6 -5
  40. qiskit/circuit/library/generalized_gates/diagonal.py +5 -4
  41. qiskit/circuit/library/generalized_gates/isometry.py +51 -254
  42. qiskit/circuit/library/generalized_gates/pauli.py +2 -2
  43. qiskit/circuit/library/generalized_gates/permutation.py +4 -1
  44. qiskit/circuit/library/generalized_gates/rv.py +15 -11
  45. qiskit/circuit/library/generalized_gates/uc.py +2 -98
  46. qiskit/circuit/library/generalized_gates/unitary.py +9 -4
  47. qiskit/circuit/library/hamiltonian_gate.py +11 -5
  48. qiskit/circuit/library/n_local/efficient_su2.py +5 -5
  49. qiskit/circuit/library/n_local/n_local.py +100 -49
  50. qiskit/circuit/library/n_local/two_local.py +3 -59
  51. qiskit/circuit/library/overlap.py +3 -3
  52. qiskit/circuit/library/phase_oracle.py +1 -1
  53. qiskit/circuit/library/quantum_volume.py +39 -38
  54. qiskit/circuit/library/standard_gates/equivalence_library.py +50 -0
  55. qiskit/circuit/library/standard_gates/global_phase.py +4 -2
  56. qiskit/circuit/library/standard_gates/i.py +1 -2
  57. qiskit/circuit/library/standard_gates/iswap.py +1 -2
  58. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +11 -5
  59. qiskit/circuit/library/standard_gates/p.py +31 -15
  60. qiskit/circuit/library/standard_gates/r.py +4 -3
  61. qiskit/circuit/library/standard_gates/rx.py +7 -4
  62. qiskit/circuit/library/standard_gates/rxx.py +4 -3
  63. qiskit/circuit/library/standard_gates/ry.py +7 -4
  64. qiskit/circuit/library/standard_gates/ryy.py +4 -3
  65. qiskit/circuit/library/standard_gates/rz.py +7 -4
  66. qiskit/circuit/library/standard_gates/rzx.py +4 -3
  67. qiskit/circuit/library/standard_gates/rzz.py +4 -3
  68. qiskit/circuit/library/standard_gates/s.py +4 -8
  69. qiskit/circuit/library/standard_gates/t.py +2 -4
  70. qiskit/circuit/library/standard_gates/u.py +16 -11
  71. qiskit/circuit/library/standard_gates/u1.py +6 -2
  72. qiskit/circuit/library/standard_gates/u2.py +4 -2
  73. qiskit/circuit/library/standard_gates/u3.py +9 -5
  74. qiskit/circuit/library/standard_gates/x.py +22 -11
  75. qiskit/circuit/library/standard_gates/xx_minus_yy.py +4 -3
  76. qiskit/circuit/library/standard_gates/xx_plus_yy.py +7 -5
  77. qiskit/circuit/library/standard_gates/z.py +1 -2
  78. qiskit/circuit/measure.py +4 -1
  79. qiskit/circuit/operation.py +13 -8
  80. qiskit/circuit/parameter.py +11 -6
  81. qiskit/circuit/quantumcircuit.py +1910 -260
  82. qiskit/circuit/quantumcircuitdata.py +2 -2
  83. qiskit/circuit/reset.py +5 -2
  84. qiskit/circuit/store.py +95 -0
  85. qiskit/compiler/assembler.py +22 -22
  86. qiskit/compiler/transpiler.py +63 -112
  87. qiskit/converters/__init__.py +17 -2
  88. qiskit/converters/circuit_to_dag.py +7 -0
  89. qiskit/converters/circuit_to_dagdependency_v2.py +47 -0
  90. qiskit/converters/circuit_to_gate.py +2 -0
  91. qiskit/converters/circuit_to_instruction.py +22 -0
  92. qiskit/converters/dag_to_circuit.py +4 -0
  93. qiskit/converters/dag_to_dagdependency_v2.py +44 -0
  94. qiskit/dagcircuit/collect_blocks.py +15 -10
  95. qiskit/dagcircuit/dagcircuit.py +434 -124
  96. qiskit/dagcircuit/dagdependency.py +19 -12
  97. qiskit/dagcircuit/dagdependency_v2.py +641 -0
  98. qiskit/dagcircuit/dagdepnode.py +19 -16
  99. qiskit/dagcircuit/dagnode.py +14 -4
  100. qiskit/passmanager/passmanager.py +11 -11
  101. qiskit/primitives/__init__.py +22 -12
  102. qiskit/primitives/backend_estimator.py +3 -5
  103. qiskit/primitives/backend_estimator_v2.py +410 -0
  104. qiskit/primitives/backend_sampler_v2.py +287 -0
  105. qiskit/primitives/base/base_estimator.py +4 -9
  106. qiskit/primitives/base/base_sampler.py +2 -2
  107. qiskit/primitives/containers/__init__.py +6 -4
  108. qiskit/primitives/containers/bit_array.py +293 -2
  109. qiskit/primitives/containers/data_bin.py +123 -50
  110. qiskit/primitives/containers/estimator_pub.py +10 -3
  111. qiskit/primitives/containers/observables_array.py +2 -2
  112. qiskit/primitives/containers/pub_result.py +1 -1
  113. qiskit/primitives/containers/sampler_pub.py +19 -3
  114. qiskit/primitives/containers/sampler_pub_result.py +74 -0
  115. qiskit/primitives/containers/shape.py +4 -4
  116. qiskit/primitives/statevector_estimator.py +4 -4
  117. qiskit/primitives/statevector_sampler.py +7 -12
  118. qiskit/providers/__init__.py +65 -34
  119. qiskit/providers/backend.py +2 -2
  120. qiskit/providers/backend_compat.py +8 -10
  121. qiskit/providers/basic_provider/__init__.py +2 -23
  122. qiskit/providers/basic_provider/basic_provider_tools.py +67 -31
  123. qiskit/providers/basic_provider/basic_simulator.py +81 -21
  124. qiskit/providers/fake_provider/__init__.py +1 -1
  125. qiskit/providers/fake_provider/fake_1q.py +1 -1
  126. qiskit/providers/fake_provider/fake_backend.py +3 -408
  127. qiskit/providers/fake_provider/generic_backend_v2.py +26 -14
  128. qiskit/providers/models/__init__.py +2 -2
  129. qiskit/providers/provider.py +16 -0
  130. qiskit/pulse/builder.py +4 -1
  131. qiskit/pulse/parameter_manager.py +60 -4
  132. qiskit/pulse/schedule.py +29 -13
  133. qiskit/pulse/utils.py +61 -20
  134. qiskit/qasm2/__init__.py +1 -5
  135. qiskit/qasm2/parse.py +1 -4
  136. qiskit/qasm3/__init__.py +42 -5
  137. qiskit/qasm3/ast.py +19 -0
  138. qiskit/qasm3/exporter.py +178 -106
  139. qiskit/qasm3/printer.py +27 -5
  140. qiskit/qobj/converters/pulse_instruction.py +6 -6
  141. qiskit/qpy/__init__.py +299 -67
  142. qiskit/qpy/binary_io/circuits.py +216 -47
  143. qiskit/qpy/binary_io/schedules.py +42 -36
  144. qiskit/qpy/binary_io/value.py +201 -22
  145. qiskit/qpy/common.py +1 -1
  146. qiskit/qpy/exceptions.py +20 -0
  147. qiskit/qpy/formats.py +29 -0
  148. qiskit/qpy/type_keys.py +21 -0
  149. qiskit/quantum_info/analysis/distance.py +3 -3
  150. qiskit/quantum_info/analysis/make_observable.py +2 -1
  151. qiskit/quantum_info/analysis/z2_symmetries.py +2 -1
  152. qiskit/quantum_info/operators/channel/chi.py +9 -8
  153. qiskit/quantum_info/operators/channel/choi.py +10 -9
  154. qiskit/quantum_info/operators/channel/kraus.py +2 -1
  155. qiskit/quantum_info/operators/channel/ptm.py +10 -9
  156. qiskit/quantum_info/operators/channel/quantum_channel.py +2 -1
  157. qiskit/quantum_info/operators/channel/stinespring.py +2 -1
  158. qiskit/quantum_info/operators/channel/superop.py +12 -11
  159. qiskit/quantum_info/operators/channel/transformations.py +12 -11
  160. qiskit/quantum_info/operators/dihedral/dihedral.py +5 -4
  161. qiskit/quantum_info/operators/operator.py +43 -30
  162. qiskit/quantum_info/operators/scalar_op.py +10 -9
  163. qiskit/quantum_info/operators/symplectic/base_pauli.py +70 -59
  164. qiskit/quantum_info/operators/symplectic/clifford.py +36 -9
  165. qiskit/quantum_info/operators/symplectic/pauli.py +53 -6
  166. qiskit/quantum_info/operators/symplectic/pauli_list.py +36 -14
  167. qiskit/quantum_info/operators/symplectic/random.py +3 -2
  168. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +61 -36
  169. qiskit/quantum_info/states/densitymatrix.py +13 -13
  170. qiskit/quantum_info/states/stabilizerstate.py +3 -3
  171. qiskit/quantum_info/states/statevector.py +14 -13
  172. qiskit/quantum_info/states/utils.py +5 -3
  173. qiskit/result/__init__.py +6 -0
  174. qiskit/result/mitigation/correlated_readout_mitigator.py +3 -2
  175. qiskit/result/mitigation/local_readout_mitigator.py +2 -1
  176. qiskit/result/mitigation/utils.py +3 -2
  177. qiskit/scheduler/__init__.py +10 -1
  178. qiskit/scheduler/methods/__init__.py +1 -8
  179. qiskit/synthesis/__init__.py +3 -6
  180. qiskit/synthesis/discrete_basis/commutator_decompose.py +2 -2
  181. qiskit/synthesis/evolution/lie_trotter.py +7 -14
  182. qiskit/synthesis/evolution/qdrift.py +3 -4
  183. qiskit/synthesis/linear/cnot_synth.py +1 -3
  184. qiskit/synthesis/linear/linear_circuits_utils.py +1 -1
  185. qiskit/synthesis/linear_phase/cz_depth_lnn.py +4 -18
  186. qiskit/synthesis/permutation/__init__.py +1 -0
  187. qiskit/synthesis/permutation/permutation_reverse_lnn.py +90 -0
  188. qiskit/synthesis/qft/qft_decompose_lnn.py +2 -6
  189. qiskit/synthesis/two_qubit/two_qubit_decompose.py +165 -954
  190. qiskit/synthesis/two_qubit/xx_decompose/circuits.py +13 -12
  191. qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +7 -1
  192. qiskit/synthesis/unitary/aqc/__init__.py +1 -1
  193. qiskit/synthesis/unitary/aqc/cnot_structures.py +2 -1
  194. qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +2 -1
  195. qiskit/synthesis/unitary/qsd.py +3 -2
  196. qiskit/transpiler/__init__.py +7 -3
  197. qiskit/transpiler/layout.py +140 -61
  198. qiskit/transpiler/passes/__init__.py +10 -2
  199. qiskit/transpiler/passes/basis/basis_translator.py +9 -4
  200. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
  201. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
  202. qiskit/transpiler/passes/calibration/rzx_builder.py +2 -1
  203. qiskit/transpiler/passes/layout/apply_layout.py +8 -3
  204. qiskit/transpiler/passes/layout/sabre_layout.py +15 -3
  205. qiskit/transpiler/passes/layout/set_layout.py +1 -1
  206. qiskit/transpiler/passes/optimization/__init__.py +2 -0
  207. qiskit/transpiler/passes/optimization/commutation_analysis.py +2 -2
  208. qiskit/transpiler/passes/optimization/commutative_cancellation.py +1 -1
  209. qiskit/transpiler/passes/optimization/consolidate_blocks.py +1 -1
  210. qiskit/transpiler/passes/optimization/cx_cancellation.py +10 -0
  211. qiskit/transpiler/passes/optimization/elide_permutations.py +114 -0
  212. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +9 -3
  213. qiskit/transpiler/passes/optimization/optimize_annotated.py +248 -12
  214. qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
  215. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +1 -3
  216. qiskit/transpiler/passes/routing/__init__.py +1 -0
  217. qiskit/transpiler/passes/routing/basic_swap.py +13 -2
  218. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +8 -1
  219. qiskit/transpiler/passes/routing/lookahead_swap.py +7 -1
  220. qiskit/transpiler/passes/routing/sabre_swap.py +10 -6
  221. qiskit/transpiler/passes/routing/star_prerouting.py +417 -0
  222. qiskit/transpiler/passes/routing/stochastic_swap.py +24 -8
  223. qiskit/transpiler/passes/scheduling/__init__.py +1 -1
  224. qiskit/transpiler/passes/scheduling/alap.py +1 -2
  225. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +1 -2
  226. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +9 -6
  227. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +8 -0
  228. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +13 -4
  229. qiskit/transpiler/passes/scheduling/asap.py +1 -2
  230. qiskit/transpiler/passes/scheduling/base_scheduler.py +21 -2
  231. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +26 -4
  232. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +24 -2
  233. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +28 -4
  234. qiskit/transpiler/passes/synthesis/aqc_plugin.py +2 -2
  235. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +120 -13
  236. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +162 -55
  237. qiskit/transpiler/passes/utils/gates_basis.py +3 -3
  238. qiskit/transpiler/passmanager.py +44 -1
  239. qiskit/transpiler/preset_passmanagers/__init__.py +3 -3
  240. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +34 -16
  241. qiskit/transpiler/preset_passmanagers/common.py +4 -6
  242. qiskit/transpiler/preset_passmanagers/plugin.py +9 -1
  243. qiskit/utils/__init__.py +3 -2
  244. qiskit/utils/optionals.py +6 -2
  245. qiskit/utils/parallel.py +24 -15
  246. qiskit/visualization/array.py +1 -1
  247. qiskit/visualization/bloch.py +2 -3
  248. qiskit/visualization/circuit/matplotlib.py +44 -14
  249. qiskit/visualization/circuit/text.py +38 -18
  250. qiskit/visualization/counts_visualization.py +3 -6
  251. qiskit/visualization/dag_visualization.py +6 -7
  252. qiskit/visualization/gate_map.py +9 -1
  253. qiskit/visualization/pulse_v2/interface.py +8 -3
  254. qiskit/visualization/state_visualization.py +3 -2
  255. qiskit/visualization/timeline/interface.py +18 -8
  256. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/METADATA +12 -8
  257. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/RECORD +261 -251
  258. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/WHEEL +1 -1
  259. qiskit/_qasm2.pyd +0 -0
  260. qiskit/_qasm3.pyd +0 -0
  261. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/LICENSE.txt +0 -0
  262. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/entry_points.txt +0 -0
  263. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/top_level.txt +0 -0
@@ -18,28 +18,67 @@ import typing
18
18
  from abc import ABC, abstractmethod
19
19
 
20
20
  from qiskit.circuit.instruction import Instruction
21
+ from qiskit.circuit.exceptions import CircuitError
21
22
 
22
23
  if typing.TYPE_CHECKING:
23
24
  from qiskit.circuit import QuantumCircuit
25
+ from qiskit.circuit.classical import expr
24
26
 
25
27
 
26
28
  class ControlFlowOp(Instruction, ABC):
27
- """Abstract class to encapsulate all control flow operations."""
29
+ """Abstract class to encapsulate all control flow operations.
30
+
31
+ All subclasses of :class:`ControlFlowOp` have an internal attribute,
32
+ :attr:`~ControlFlowOp.blocks`, which exposes the inner subcircuits used in the different blocks
33
+ of the control flow.
34
+ """
35
+
36
+ def __init__(self, *args, **kwargs):
37
+ super().__init__(*args, **kwargs)
38
+ for block in self.blocks:
39
+ if block.num_input_vars:
40
+ raise CircuitError("control-flow blocks cannot contain input variables")
28
41
 
29
42
  @property
30
43
  @abstractmethod
31
44
  def blocks(self) -> tuple[QuantumCircuit, ...]:
32
- """Tuple of QuantumCircuits which may be executed as part of the
33
- execution of this ControlFlowOp. May be parameterized by a loop
34
- parameter to be resolved at run time.
35
- """
45
+ """Tuple of :class:`.QuantumCircuit`\\ s which may be executed as part of the
46
+ execution of this :class:`ControlFlowOp`."""
36
47
 
37
48
  @abstractmethod
38
49
  def replace_blocks(self, blocks: typing.Iterable[QuantumCircuit]) -> ControlFlowOp:
39
- """Replace blocks and return new instruction.
50
+ """Return a new version of this control-flow operations with the :attr:`blocks` mapped to
51
+ the given new ones.
52
+
53
+ Typically this is used in a workflow such as::
54
+
55
+ existing_op = ...
56
+
57
+ def map_block(block: QuantumCircuit) -> QuantumCircuit:
58
+ new_block = block.copy_empty_like()
59
+ # ... do something to `new_block` ...
60
+ return new_block
61
+
62
+ new_op = existing_op.replace_blocks(
63
+ map_block(block) for block in existing_op.blocks
64
+ )
65
+
66
+ It is the caller's responsibility to ensure that the mapped blocks are defined over a
67
+ unified set of circuit resources, much like constructing a :class:`ControlFlowOp` using its
68
+ default constructor.
69
+
40
70
  Args:
41
- blocks: Tuple of QuantumCircuits to replace in instruction.
71
+ blocks: the new subcircuit blocks to use.
42
72
 
43
73
  Returns:
44
- New ControlFlowOp with replaced blocks.
74
+ New :class:`ControlFlowOp` with replaced blocks.
45
75
  """
76
+
77
+ def iter_captured_vars(self) -> typing.Iterable[expr.Var]:
78
+ """Get an iterator over the unique captured variables in all blocks of this construct."""
79
+ seen = set()
80
+ for block in self.blocks:
81
+ for var in block.iter_captured_vars():
82
+ if var not in seen:
83
+ seen.add(var)
84
+ yield var
@@ -29,28 +29,6 @@ class ForLoopOp(ControlFlowOp):
29
29
  """A circuit operation which repeatedly executes a subcircuit
30
30
  (``body``) parameterized by a parameter ``loop_parameter`` through
31
31
  the set of integer values provided in ``indexset``.
32
-
33
- Parameters:
34
- indexset: A collection of integers to loop over.
35
- loop_parameter: The placeholder parameterizing ``body`` to which
36
- the values from ``indexset`` will be assigned.
37
- body: The loop body to be repeatedly executed.
38
- label: An optional label for identifying the instruction.
39
-
40
- **Circuit symbol:**
41
-
42
- .. parsed-literal::
43
-
44
- ┌───────────┐
45
- q_0: ┤0 ├
46
- │ │
47
- q_1: ┤1 ├
48
- │ for_loop │
49
- q_2: ┤2 ├
50
- │ │
51
- c_0: ╡0 ╞
52
- └───────────┘
53
-
54
32
  """
55
33
 
56
34
  def __init__(
@@ -60,9 +38,16 @@ class ForLoopOp(ControlFlowOp):
60
38
  body: QuantumCircuit,
61
39
  label: Optional[str] = None,
62
40
  ):
41
+ """
42
+ Args:
43
+ indexset: A collection of integers to loop over.
44
+ loop_parameter: The placeholder parameterizing ``body`` to which
45
+ the values from ``indexset`` will be assigned.
46
+ body: The loop body to be repeatedly executed.
47
+ label: An optional label for identifying the instruction.
48
+ """
63
49
  num_qubits = body.num_qubits
64
50
  num_clbits = body.num_clbits
65
-
66
51
  super().__init__(
67
52
  "for_loop", num_qubits, num_clbits, [indexset, loop_parameter, body], label=label
68
53
  )
@@ -44,38 +44,11 @@ class IfElseOp(ControlFlowOp):
44
44
  provided condition (``condition``) evaluates to true, and
45
45
  optionally evaluates another program (``false_body``) otherwise.
46
46
 
47
- Parameters:
48
- condition: A condition to be evaluated at circuit runtime which,
49
- if true, will trigger the evaluation of ``true_body``. Can be
50
- specified as either a tuple of a ``ClassicalRegister`` to be
51
- tested for equality with a given ``int``, or as a tuple of a
52
- ``Clbit`` to be compared to either a ``bool`` or an ``int``.
53
- true_body: A program to be executed if ``condition`` evaluates
54
- to true.
55
- false_body: A optional program to be executed if ``condition``
56
- evaluates to false.
57
- label: An optional label for identifying the instruction.
58
-
59
47
  If provided, ``false_body`` must be of the same ``num_qubits`` and
60
48
  ``num_clbits`` as ``true_body``.
61
49
 
62
50
  The classical bits used in ``condition`` must be a subset of those attached
63
51
  to the circuit on which this ``IfElseOp`` will be appended.
64
-
65
- **Circuit symbol:**
66
-
67
- .. parsed-literal::
68
-
69
- ┌───────────┐
70
- q_0: ┤0 ├
71
- │ │
72
- q_1: ┤1 ├
73
- │ if_else │
74
- q_2: ┤2 ├
75
- │ │
76
- c_0: ╡0 ╞
77
- └───────────┘
78
-
79
52
  """
80
53
 
81
54
  def __init__(
@@ -85,6 +58,19 @@ class IfElseOp(ControlFlowOp):
85
58
  false_body: QuantumCircuit | None = None,
86
59
  label: str | None = None,
87
60
  ):
61
+ """
62
+ Args:
63
+ condition: A condition to be evaluated in real time during circuit execution which,
64
+ if true, will trigger the evaluation of ``true_body``. Can be
65
+ specified as either a tuple of a ``ClassicalRegister`` to be
66
+ tested for equality with a given ``int``, or as a tuple of a
67
+ ``Clbit`` to be compared to either a ``bool`` or an ``int``.
68
+ true_body: A program to be executed if ``condition`` evaluates
69
+ to true.
70
+ false_body: A optional program to be executed if ``condition``
71
+ evaluates to false.
72
+ label: An optional label for identifying the instruction.
73
+ """
88
74
  # pylint: disable=cyclic-import
89
75
  from qiskit.circuit import QuantumCircuit
90
76
 
@@ -32,39 +32,25 @@ if TYPE_CHECKING:
32
32
 
33
33
 
34
34
  class _DefaultCaseType:
35
- """The type of the default-case singleton. This is used instead of just having
36
- ``CASE_DEFAULT = object()`` so we can set the pretty-printing properties, which are class-level
37
- only."""
35
+ # Note: Sphinx uses the docstring of this singleton class object as the documentation of the
36
+ # `CASE_DEFAULT` object.
37
+
38
+ """A special object that represents the "default" case of a switch statement. If you use this
39
+ as a case target, it must be the last case, and will match anything that wasn't already matched.
40
+ When using the builder interface of :meth:`.QuantumCircuit.switch`, this can also be accessed as
41
+ the ``DEFAULT`` attribute of the bound case-builder object."""
38
42
 
39
43
  def __repr__(self):
40
44
  return "<default case>"
41
45
 
42
46
 
43
47
  CASE_DEFAULT = _DefaultCaseType()
44
- """A special object that represents the "default" case of a switch statement. If you use this
45
- as a case target, it must be the last case, and will match anything that wasn't already matched.
46
- When using the builder interface of :meth:`.QuantumCircuit.switch`, this can also be accessed as the
47
- ``DEFAULT`` attribute of the bound case-builder object."""
48
48
 
49
49
 
50
50
  class SwitchCaseOp(ControlFlowOp):
51
51
  """A circuit operation that executes one particular circuit block based on matching a given
52
52
  ``target`` against an ordered list of ``values``. The special value :data:`.CASE_DEFAULT` can
53
53
  be used to represent a default condition.
54
-
55
- This is the low-level interface for creating a switch-case statement; in general, the circuit
56
- method :meth:`.QuantumCircuit.switch` should be used as a context manager to access the
57
- builder interface. At the low level, you must ensure that all the circuit blocks contain equal
58
- numbers of qubits and clbits, and that the order the virtual bits of the containing circuit
59
- should be bound is the same for all blocks. This will likely mean that each circuit block is
60
- wider than its natural width, as each block must span the union of all the spaces covered by
61
- *any* of the blocks.
62
-
63
- Args:
64
- target: the runtime value to switch on.
65
- cases: an ordered iterable of the corresponding value of the ``target`` and the circuit
66
- block that should be executed if this is matched. There is no fall-through between
67
- blocks, and the order matters.
68
54
  """
69
55
 
70
56
  def __init__(
@@ -74,6 +60,13 @@ class SwitchCaseOp(ControlFlowOp):
74
60
  *,
75
61
  label: Optional[str] = None,
76
62
  ):
63
+ """
64
+ Args:
65
+ target: the real-time value to switch on.
66
+ cases: an ordered iterable of the corresponding value of the ``target`` and the circuit
67
+ block that should be executed if this is matched. There is no fall-through between
68
+ blocks, and the order matters.
69
+ """
77
70
  # pylint: disable=cyclic-import
78
71
  from qiskit.circuit import QuantumCircuit
79
72
 
@@ -30,31 +30,8 @@ class WhileLoopOp(ControlFlowOp):
30
30
  """A circuit operation which repeatedly executes a subcircuit (``body``) until
31
31
  a condition (``condition``) evaluates as False.
32
32
 
33
- Parameters:
34
- condition: A condition to be checked prior to executing ``body``. Can be
35
- specified as either a tuple of a ``ClassicalRegister`` to be tested
36
- for equality with a given ``int``, or as a tuple of a ``Clbit`` to
37
- be compared to either a ``bool`` or an ``int``.
38
- body: The loop body to be repeatedly executed.
39
- label: An optional label for identifying the instruction.
40
-
41
33
  The classical bits used in ``condition`` must be a subset of those attached
42
34
  to ``body``.
43
-
44
- **Circuit symbol:**
45
-
46
- .. parsed-literal::
47
-
48
- ┌─────────────┐
49
- q_0: ┤0 ├
50
- │ │
51
- q_1: ┤1 ├
52
- │ while_loop │
53
- q_2: ┤2 ├
54
- │ │
55
- c_0: ╡0 ╞
56
- └─────────────┘
57
-
58
35
  """
59
36
 
60
37
  def __init__(
@@ -63,6 +40,15 @@ class WhileLoopOp(ControlFlowOp):
63
40
  body: QuantumCircuit,
64
41
  label: str | None = None,
65
42
  ):
43
+ """
44
+ Args:
45
+ condition: A condition to be checked prior to executing ``body``. Can be
46
+ specified as either a tuple of a ``ClassicalRegister`` to be tested
47
+ for equality with a given ``int``, or as a tuple of a ``Clbit`` to
48
+ be compared to either a ``bool`` or an ``int``.
49
+ body: The loop body to be repeatedly executed.
50
+ label: An optional label for identifying the instruction.
51
+ """
66
52
  num_qubits = body.num_qubits
67
53
  num_clbits = body.num_clbits
68
54
 
@@ -111,9 +111,9 @@ class ControlledGate(Gate):
111
111
  @property
112
112
  def definition(self) -> QuantumCircuit:
113
113
  """Return definition in terms of other basic gates. If the gate has
114
- open controls, as determined from `self.ctrl_state`, the returned
114
+ open controls, as determined from :attr:`ctrl_state`, the returned
115
115
  definition is conjugated with X without changing the internal
116
- `_definition`.
116
+ ``_definition``.
117
117
  """
118
118
  if self._open_ctrl:
119
119
  closed_gate = self.to_mutable()
qiskit/circuit/delay.py CHANGED
@@ -17,14 +17,20 @@ import numpy as np
17
17
  from qiskit.circuit.exceptions import CircuitError
18
18
  from qiskit.circuit.instruction import Instruction
19
19
  from qiskit.circuit.gate import Gate
20
+ from qiskit.circuit import _utils
20
21
  from qiskit.circuit.parameterexpression import ParameterExpression
21
22
 
22
23
 
24
+ @_utils.with_gate_array(np.eye(2, dtype=complex))
23
25
  class Delay(Instruction):
24
26
  """Do nothing and just delay/wait/idle for a specified duration."""
25
27
 
26
28
  def __init__(self, duration, unit="dt"):
27
- """Create new delay instruction."""
29
+ """
30
+ Args:
31
+ duration: the length of time of the duration. Given in units of ``unit``.
32
+ unit: the unit of the duration. Must be ``"dt"`` or an SI-prefixed seconds unit.
33
+ """
28
34
  if unit not in {"s", "ms", "us", "ns", "ps", "dt"}:
29
35
  raise CircuitError("Unknown unit %s is specified." % unit)
30
36
 
@@ -49,10 +55,6 @@ class Delay(Instruction):
49
55
  """Set the duration of this delay."""
50
56
  self.params = [duration]
51
57
 
52
- def __array__(self, dtype=None):
53
- """Return the identity matrix."""
54
- return np.array([[1, 0], [0, 1]], dtype=dtype)
55
-
56
58
  def to_matrix(self) -> np.ndarray:
57
59
  """Return a Numpy.array for the unitary matrix. This has been
58
60
  added to enable simulation without making delay a full Gate type.
qiskit/circuit/gate.py CHANGED
@@ -18,7 +18,7 @@ import numpy as np
18
18
 
19
19
  from qiskit.circuit.parameterexpression import ParameterExpression
20
20
  from qiskit.circuit.exceptions import CircuitError
21
- from .annotated_operation import AnnotatedOperation, ControlModifier
21
+ from .annotated_operation import AnnotatedOperation, ControlModifier, PowerModifier
22
22
  from .instruction import Instruction
23
23
 
24
24
 
@@ -62,23 +62,36 @@ class Gate(Instruction):
62
62
  return self.__array__(dtype=complex)
63
63
  raise CircuitError(f"to_matrix not defined for this {type(self)}")
64
64
 
65
- def power(self, exponent: float):
66
- """Creates a unitary gate as `gate^exponent`.
65
+ def power(self, exponent: float, annotated: bool = False):
66
+ """Raise this gate to the power of ``exponent``.
67
+
68
+ Implemented either as a unitary gate (ref. :class:`~.library.UnitaryGate`)
69
+ or as an annotated operation (ref. :class:`.AnnotatedOperation`). In the case of several standard
70
+ gates, such as :class:`.RXGate`, when the power of a gate can be expressed in terms of another
71
+ standard gate that is returned directly.
67
72
 
68
73
  Args:
69
- exponent (float): Gate^exponent
74
+ exponent (float): the power to raise the gate to
75
+ annotated (bool): indicates whether the power gate can be implemented
76
+ as an annotated operation. In the case of several standard
77
+ gates, such as :class:`.RXGate`, this argument is ignored when
78
+ the power of a gate can be expressed in terms of another
79
+ standard gate.
70
80
 
71
81
  Returns:
72
- .library.UnitaryGate: To which `to_matrix` is self.to_matrix^exponent.
82
+ An operation implementing ``gate^exponent``
73
83
 
74
84
  Raises:
75
- CircuitError: If Gate is not unitary
85
+ CircuitError: If gate is not unitary
76
86
  """
77
87
  # pylint: disable=cyclic-import
78
88
  from qiskit.quantum_info.operators import Operator
79
89
  from qiskit.circuit.library.generalized_gates.unitary import UnitaryGate
80
90
 
81
- return UnitaryGate(Operator(self).power(exponent), label=f"{self.name}^{exponent}")
91
+ if not annotated:
92
+ return UnitaryGate(Operator(self).power(exponent), label=f"{self.name}^{exponent}")
93
+ else:
94
+ return AnnotatedOperation(self, PowerModifier(exponent))
82
95
 
83
96
  def __pow__(self, exponent: float) -> "Gate":
84
97
  return self.power(exponent)
@@ -41,7 +41,6 @@ from typing import List, Type
41
41
  import numpy
42
42
 
43
43
  from qiskit.circuit.exceptions import CircuitError
44
- from qiskit.circuit.quantumregister import QuantumRegister
45
44
  from qiskit.circuit.classicalregister import ClassicalRegister, Clbit
46
45
  from qiskit.qobj.qasm_qobj import QasmQobjInstruction
47
46
  from qiskit.circuit.parameter import ParameterExpression
@@ -241,8 +240,8 @@ class Instruction(Operation):
241
240
  """
242
241
  if (
243
242
  self.name != other.name
244
- or other.num_qubits != other.num_qubits
245
- or other.num_clbits != other.num_clbits
243
+ or self.num_qubits != other.num_qubits
244
+ or self.num_clbits != other.num_clbits
246
245
  or len(self.params) != len(other.params)
247
246
  ):
248
247
  return False
@@ -269,12 +268,17 @@ class Instruction(Operation):
269
268
  return True
270
269
 
271
270
  def _define(self):
272
- """Populates self.definition with a decomposition of this gate."""
271
+ """Populate the cached :attr:`_definition` field of this :class:`Instruction`.
272
+
273
+ Subclasses should implement this method to provide lazy construction of their public
274
+ :attr:`definition` attribute. A subclass can use its :attr:`params` at the time of the
275
+ call. The method should populate :attr:`_definition` with a :class:`.QuantumCircuit` and
276
+ not return a value."""
273
277
  pass
274
278
 
275
279
  @property
276
280
  def params(self):
277
- """return instruction params."""
281
+ """The parameters of this :class:`Instruction`. Ideally these will be gate angles."""
278
282
  return self._params
279
283
 
280
284
  @params.setter
@@ -291,7 +295,8 @@ class Instruction(Operation):
291
295
  return parameter
292
296
 
293
297
  def is_parameterized(self):
294
- """Return True .IFF. instruction is parameterized else False"""
298
+ """Return whether the :class:`Instruction` contains :ref:`compile-time parameters
299
+ <circuit-compile-time-parameters>`."""
295
300
  return any(
296
301
  isinstance(param, ParameterExpression) and param.parameters for param in self.params
297
302
  )
@@ -520,18 +525,6 @@ class Instruction(Operation):
520
525
  cpy._definition = copy.deepcopy(self._definition, memo)
521
526
  return cpy
522
527
 
523
- def _qasmif(self, string):
524
- """Print an if statement if needed."""
525
- from qiskit.qasm2 import QASM2ExportError # pylint: disable=cyclic-import
526
-
527
- if self.condition is None:
528
- return string
529
- if not isinstance(self.condition[0], ClassicalRegister):
530
- raise QASM2ExportError(
531
- "OpenQASM 2 can only condition on registers, but got '{self.condition[0]}'"
532
- )
533
- return "if(%s==%d) " % (self.condition[0].name, self.condition[1]) + string
534
-
535
528
  def broadcast_arguments(self, qargs, cargs):
536
529
  """
537
530
  Validation of the arguments.
@@ -572,7 +565,13 @@ class Instruction(Operation):
572
565
  )
573
566
 
574
567
  def repeat(self, n):
575
- """Creates an instruction with `gate` repeated `n` amount of times.
568
+ """Creates an instruction with ``self`` repeated :math`n` times.
569
+
570
+ If this operation has a conditional, the output instruction will have the same conditional
571
+ and the inner repeated operations will be unconditional; instructions within a compound
572
+ definition cannot be conditioned on registers within Qiskit's data model. This means that
573
+ it is not valid to apply a repeated instruction to a clbit that it both writes to and reads
574
+ from in its condition.
576
575
 
577
576
  Args:
578
577
  n (int): Number of times to repeat the instruction
@@ -589,22 +588,24 @@ class Instruction(Operation):
589
588
  n = int(n)
590
589
 
591
590
  instruction = self._return_repeat(n)
592
- qargs = [] if self.num_qubits == 0 else QuantumRegister(self.num_qubits, "q")
593
- cargs = [] if self.num_clbits == 0 else ClassicalRegister(self.num_clbits, "c")
594
-
595
591
  if instruction.definition is None:
596
592
  # pylint: disable=cyclic-import
597
593
  from qiskit.circuit import QuantumCircuit, CircuitInstruction
598
594
 
599
- qc = QuantumCircuit()
600
- if qargs:
601
- qc.add_register(qargs)
602
- if cargs:
603
- qc.add_register(cargs)
604
- circuit_instruction = CircuitInstruction(self, qargs, cargs)
595
+ qc = QuantumCircuit(self.num_qubits, self.num_clbits)
596
+ qargs = tuple(qc.qubits)
597
+ cargs = tuple(qc.clbits)
598
+ base = self.copy()
599
+ if self.condition:
600
+ # Condition is handled on the outer instruction.
601
+ base = base.to_mutable()
602
+ base.condition = None
605
603
  for _ in [None] * n:
606
- qc._append(circuit_instruction)
607
- instruction.definition = qc
604
+ qc._append(CircuitInstruction(base, qargs, cargs))
605
+
606
+ instruction.definition = qc
607
+ if self.condition:
608
+ instruction = instruction.c_if(*self.condition)
608
609
  return instruction
609
610
 
610
611
  @property
@@ -87,7 +87,11 @@ class InstructionSet:
87
87
  self._instructions.append((data, pos))
88
88
 
89
89
  def inverse(self, annotated: bool = False):
90
- """Invert all instructions."""
90
+ """Invert all instructions.
91
+
92
+ .. note::
93
+ It is preferable to take the inverse *before* appending the gate(s) to the circuit.
94
+ """
91
95
  for i, instruction in enumerate(self._instructions):
92
96
  if isinstance(instruction, CircuitInstruction):
93
97
  self._instructions[i] = instruction.replace(
@@ -105,6 +109,10 @@ class InstructionSet:
105
109
  """Set a classical equality condition on all the instructions in this set between the
106
110
  :obj:`.ClassicalRegister` or :obj:`.Clbit` ``classical`` and value ``val``.
107
111
 
112
+ .. note::
113
+ You should prefer to use the :meth:`.QuantumCircuit.if_test` builder interface, rather
114
+ than using this method.
115
+
108
116
  .. note::
109
117
 
110
118
  This is a setter method, not an additive one. Calling this multiple times will silently
@@ -124,27 +132,6 @@ class InstructionSet:
124
132
  Raises:
125
133
  CircuitError: if the passed classical resource is invalid, or otherwise not resolvable
126
134
  to a concrete resource that these instructions are permitted to access.
127
-
128
- Example:
129
- .. plot::
130
- :include-source:
131
-
132
- from qiskit import ClassicalRegister, QuantumRegister, QuantumCircuit
133
-
134
- qr = QuantumRegister(2)
135
- cr = ClassicalRegister(2)
136
- qc = QuantumCircuit(qr, cr)
137
- qc.h(range(2))
138
- qc.measure(range(2), range(2))
139
-
140
- # apply x gate if the classical register has the value 2 (10 in binary)
141
- qc.x(0).c_if(cr, 2)
142
-
143
- # apply y gate if bit 0 is set to 1
144
- qc.y(1).c_if(0, 1)
145
-
146
- qc.draw('mpl')
147
-
148
135
  """
149
136
  if self._requester is None and not isinstance(classical, (Clbit, ClassicalRegister)):
150
137
  raise CircuitError(
@@ -129,29 +129,19 @@ For example:
129
129
  Standard Directives
130
130
  ===================
131
131
 
132
- ..
133
- This summary table deliberately does not generate toctree entries; these directives are "owned"
134
- by ``qiskit.circuit``.
135
-
136
132
  Directives are operations to the quantum stack that are meant to be interpreted by the backend or
137
133
  the transpiler. In general, the transpiler or backend might optionally ignore them if there is no
138
134
  implementation for them.
139
135
 
140
- .. autosummary::
141
- :toctree: ../stubs/
142
-
143
- Barrier
136
+ * :class:`qiskit.circuit.Barrier`
144
137
 
145
138
  Standard Operations
146
139
  ===================
147
140
 
148
141
  Operations are non-reversible changes in the quantum state of the circuit.
149
142
 
150
- .. autosummary::
151
- :toctree: ../stubs/
152
-
153
- Measure
154
- Reset
143
+ * :class:`qiskit.circuit.Measure`
144
+ * :class:`qiskit.circuit.Reset`
155
145
 
156
146
  Generalized Gates
157
147
  =================
@@ -14,7 +14,7 @@
14
14
  """Integer Comparator."""
15
15
 
16
16
  from __future__ import annotations
17
- import numpy as np
17
+ import math
18
18
 
19
19
  from qiskit.circuit import QuantumCircuit, QuantumRegister, AncillaRegister
20
20
  from qiskit.circuit.exceptions import CircuitError
@@ -140,7 +140,7 @@ class IntegerComparator(BlueprintCircuit):
140
140
  Returns:
141
141
  The 2's complement of ``self.value``.
142
142
  """
143
- twos_complement = pow(2, self.num_state_qubits) - int(np.ceil(self.value))
143
+ twos_complement = pow(2, self.num_state_qubits) - math.ceil(self.value)
144
144
  twos_complement = f"{twos_complement:b}".rjust(self.num_state_qubits, "0")
145
145
  twos_complement = [
146
146
  1 if twos_complement[i] == "1" else 0 for i in reversed(range(len(twos_complement)))
@@ -13,6 +13,7 @@
13
13
  """A circuit implementing a quadratic form on binary variables."""
14
14
 
15
15
  from typing import Union, Optional, List
16
+ import math
16
17
 
17
18
  import numpy as np
18
19
 
@@ -190,8 +191,8 @@ class QuadraticForm(QuantumCircuit):
190
191
 
191
192
  # the minimum number of qubits is the number of qubits needed to represent
192
193
  # the minimum/maximum value plus one sign qubit
193
- num_qubits_for_min = int(np.ceil(np.log2(max(-bounds[0], 1))))
194
- num_qubits_for_max = int(np.ceil(np.log2(bounds[1] + 1)))
194
+ num_qubits_for_min = math.ceil(math.log2(max(-bounds[0], 1)))
195
+ num_qubits_for_max = math.ceil(math.log2(bounds[1] + 1))
195
196
  num_result_qubits = 1 + max(num_qubits_for_min, num_qubits_for_max)
196
197
 
197
198
  return num_result_qubits