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
@@ -15,7 +15,8 @@
15
15
  """Quantum circuit object."""
16
16
 
17
17
  from __future__ import annotations
18
- import copy
18
+ import copy as _copy
19
+ import itertools
19
20
  import multiprocessing as mp
20
21
  import typing
21
22
  from collections import OrderedDict, defaultdict, namedtuple
@@ -35,7 +36,7 @@ from typing import (
35
36
  overload,
36
37
  )
37
38
  import numpy as np
38
- from qiskit._accelerate.quantum_circuit import CircuitData
39
+ from qiskit._accelerate.circuit import CircuitData
39
40
  from qiskit.exceptions import QiskitError
40
41
  from qiskit.utils.multiprocessing import is_main_process
41
42
  from qiskit.circuit.instruction import Instruction
@@ -44,6 +45,7 @@ from qiskit.circuit.parameter import Parameter
44
45
  from qiskit.circuit.exceptions import CircuitError
45
46
  from . import _classical_resource_map
46
47
  from ._utils import sort_parameters
48
+ from .controlflow import ControlFlowOp
47
49
  from .controlflow.builder import CircuitScopeInterface, ControlFlowBuilderBlock
48
50
  from .controlflow.break_loop import BreakLoopOp, BreakLoopPlaceholder
49
51
  from .controlflow.continue_loop import ContinueLoopOp, ContinueLoopPlaceholder
@@ -51,7 +53,7 @@ from .controlflow.for_loop import ForLoopOp, ForLoopContext
51
53
  from .controlflow.if_else import IfElseOp, IfContext
52
54
  from .controlflow.switch_case import SwitchCaseOp, SwitchContext
53
55
  from .controlflow.while_loop import WhileLoopOp, WhileLoopContext
54
- from .classical import expr
56
+ from .classical import expr, types
55
57
  from .parameterexpression import ParameterExpression, ParameterValueType
56
58
  from .quantumregister import QuantumRegister, Qubit, AncillaRegister, AncillaQubit
57
59
  from .classicalregister import ClassicalRegister, Clbit
@@ -63,6 +65,7 @@ from .register import Register
63
65
  from .bit import Bit
64
66
  from .quantumcircuitdata import QuantumCircuitData, CircuitInstruction
65
67
  from .delay import Delay
68
+ from .store import Store
66
69
 
67
70
  if typing.TYPE_CHECKING:
68
71
  import qiskit # pylint: disable=cyclic-import
@@ -103,95 +106,878 @@ ClbitSpecifier = Union[
103
106
  BitType = TypeVar("BitType", Qubit, Clbit)
104
107
 
105
108
 
109
+ # NOTE:
110
+ #
111
+ # If you're adding methods or attributes to `QuantumCircuit`, be sure to update the class docstring
112
+ # to document them in a suitable place. The class is huge, so we do its documentation manually so
113
+ # it has at least some amount of organisational structure.
114
+
115
+
106
116
  class QuantumCircuit:
107
- """Create a new circuit.
117
+ """Core Qiskit representation of a quantum circuit.
118
+
119
+ .. note::
120
+ For more details setting the :class:`QuantumCircuit` in context of all of the data
121
+ structures that go with it, how it fits into the rest of the :mod:`qiskit` package, and the
122
+ different regimes of quantum-circuit descriptions in Qiskit, see the module-level
123
+ documentation of :mod:`qiskit.circuit`.
124
+
125
+ Circuit attributes
126
+ ==================
127
+
128
+ :class:`QuantumCircuit` has a small number of public attributes, which are mostly older
129
+ functionality. Most of its functionality is accessed through methods.
130
+
131
+ A small handful of the attributes are intentionally mutable, the rest are data attributes that
132
+ should be considered immutable.
133
+
134
+ ========================= ======================================================================
135
+ Mutable attribute Summary
136
+ ========================= ======================================================================
137
+ :attr:`global_phase` The global phase of the circuit, measured in radians.
138
+ :attr:`metadata` Arbitrary user mapping, which Qiskit will preserve through the
139
+ transpiler, but otherwise completely ignore.
140
+ :attr:`name` An optional string name for the circuit.
141
+ ========================= ======================================================================
142
+
143
+ ========================= ======================================================================
144
+ Immutable data attribute Summary
145
+ ========================= ======================================================================
146
+ :attr:`ancillas` List of :class:`AncillaQubit`\\ s tracked by the circuit.
147
+ :attr:`calibrations` Custom user-supplied pulse calibrations for individual instructions.
148
+ :attr:`cregs` List of :class:`ClassicalRegister`\\ s tracked by the circuit.
149
+
150
+ :attr:`clbits` List of :class:`Clbit`\\ s tracked by the circuit.
151
+ :attr:`data` List of individual :class:`CircuitInstruction`\\ s that make up the
152
+ circuit.
153
+ :attr:`duration` Total duration of the circuit, added by scheduling transpiler passes.
154
+
155
+ :attr:`layout` Hardware layout and routing information added by the transpiler.
156
+ :attr:`num_ancillas` The number of ancilla qubits in the circuit.
157
+ :attr:`num_clbits` The number of clbits in the circuit.
158
+ :attr:`num_captured_vars` Number of captured real-time classical variables.
159
+
160
+ :attr:`num_declared_vars` Number of locally declared real-time classical variables in the outer
161
+ circuit scope.
162
+ :attr:`num_input_vars` Number of input real-time classical variables.
163
+ :attr:`num_parameters` Number of compile-time :class:`Parameter`\\ s in the circuit.
164
+ :attr:`num_qubits` Number of qubits in the circuit.
165
+
166
+ :attr:`num_vars` Total number of real-time classical variables in the outer circuit
167
+ scope.
168
+ :attr:`op_start_times` Start times of scheduled operations, added by scheduling transpiler
169
+ passes.
170
+ :attr:`parameters` Ordered set-like view of the compile-time :class:`Parameter`\\ s
171
+ tracked by the circuit.
172
+ :attr:`qregs` List of :class:`QuantumRegister`\\ s tracked by the circuit.
173
+
174
+ :attr:`qubits` List of :class:`Qubit`\\ s tracked by the circuit.
175
+ :attr:`unit` The unit of the :attr:`duration` field.
176
+ ========================= ======================================================================
177
+
178
+ The core attribute is :attr:`data`. This is a sequence-like object that exposes the
179
+ :class:`CircuitInstruction`\\ s contained in an ordered form. You generally should not mutate
180
+ this object directly; :class:`QuantumCircuit` is only designed for append-only operations (which
181
+ should use :meth:`append`). Most operations that mutate circuits in place should be written as
182
+ transpiler passes (:mod:`qiskit.transpiler`).
183
+
184
+ .. autoattribute:: data
185
+
186
+ Alongside the :attr:`data`, the :attr:`global_phase` of a circuit can have some impact on its
187
+ output, if the circuit is used to describe a :class:`.Gate` that may be controlled. This is
188
+ measured in radians and is directly settable.
189
+
190
+ .. autoattribute:: global_phase
191
+
192
+ The :attr:`name` of a circuit becomes the name of the :class:`~.circuit.Instruction` or
193
+ :class:`.Gate` resulting from :meth:`to_instruction` and :meth:`to_gate` calls, which can be
194
+ handy for visualizations.
195
+
196
+ .. autoattribute:: name
197
+
198
+ You can attach arbitrary :attr:`metadata` to a circuit. No part of core Qiskit will inspect
199
+ this or change its behavior based on metadata, but it will be faithfully passed through the
200
+ transpiler, so you can tag your circuits yourself. When serializing a circuit with QPY (see
201
+ :mod:`qiskit.qpy`), the metadata will be JSON-serialized and you may need to pass a custom
202
+ serializer to handle non-JSON-compatible objects within it (see :func:`.qpy.dump` for more
203
+ detail). This field is ignored during export to OpenQASM 2 or 3.
204
+
205
+ .. autoattribute:: metadata
206
+
207
+ :class:`QuantumCircuit` exposes data attributes tracking its internal quantum and classical bits
208
+ and registers. These appear as Python :class:`list`\\ s, but you should treat them as
209
+ immutable; changing them will *at best* have no effect, and more likely will simply corrupt
210
+ the internal data of the :class:`QuantumCircuit`.
211
+
212
+ .. autoattribute:: qregs
213
+ .. autoattribute:: cregs
214
+ .. autoattribute:: qubits
215
+ .. autoattribute:: ancillas
216
+ .. autoattribute:: clbits
217
+
218
+ The :ref:`compile-time parameters <circuit-compile-time-parameters>` present in instructions on
219
+ the circuit are available in :attr:`parameters`. This has a canonical order (mostly lexical,
220
+ except in the case of :class:`.ParameterVector`), which matches the order that parameters will
221
+ be assigned when using the list forms of :meth:`assign_parameters`, but also supports
222
+ :class:`set`-like constant-time membership testing.
223
+
224
+ .. autoattribute:: parameters
225
+
226
+ The storage of any :ref:`manual pulse-level calibrations <circuit-calibrations>` for individual
227
+ instructions on the circuit is in :attr:`calibrations`. This presents as a :class:`dict`, but
228
+ should not be mutated directly; use the methods discussed in :ref:`circuit-calibrations`.
229
+
230
+ .. autoattribute:: calibrations
231
+
232
+ If you have transpiled your circuit, so you have a physical circuit, you can inspect the
233
+ :attr:`layout` attribute for information stored by the transpiler about how the virtual qubits
234
+ of the source circuit map to the hardware qubits of your physical circuit, both at the start and
235
+ end of the circuit.
236
+
237
+ .. autoattribute:: layout
238
+
239
+ If your circuit was also *scheduled* as part of a transpilation, it will expose the individual
240
+ timings of each instruction, along with the total :attr:`duration` of the circuit.
241
+
242
+ .. autoattribute:: duration
243
+ .. autoattribute:: unit
244
+ .. autoattribute:: op_start_times
245
+
246
+ Finally, :class:`QuantumCircuit` exposes several simple properties as dynamic read-only numeric
247
+ attributes.
248
+
249
+ .. autoattribute:: num_ancillas
250
+ .. autoattribute:: num_clbits
251
+ .. autoattribute:: num_captured_vars
252
+ .. autoattribute:: num_declared_vars
253
+ .. autoattribute:: num_input_vars
254
+ .. autoattribute:: num_parameters
255
+ .. autoattribute:: num_qubits
256
+ .. autoattribute:: num_vars
257
+
258
+ Creating new circuits
259
+ =====================
260
+
261
+ ========================= =====================================================================
262
+ Method Summary
263
+ ========================= =====================================================================
264
+ :meth:`__init__` Default constructor of no-instruction circuits.
265
+ :meth:`copy` Make a complete copy of an existing circuit.
266
+ :meth:`copy_empty_like` Copy data objects from one circuit into a new one without any
267
+ instructions.
268
+ :meth:`from_instructions` Infer data objects needed from a list of instructions.
269
+ :meth:`from_qasm_file` Legacy interface to :func:`.qasm2.load`.
270
+ :meth:`from_qasm_str` Legacy interface to :func:`.qasm2.loads`.
271
+ ========================= =====================================================================
272
+
273
+ The default constructor (``QuantumCircuit(...)``) produces a circuit with no initial
274
+ instructions. The arguments to the default constructor can be used to seed the circuit with
275
+ quantum and classical data storage, and to provide a name, global phase and arbitrary metadata.
276
+ All of these fields can be expanded later.
277
+
278
+ .. automethod:: __init__
279
+
280
+ If you have an existing circuit, you can produce a copy of it using :meth:`copy`, including all
281
+ its instructions. This is useful if you want to keep partial circuits while extending another,
282
+ or to have a version you can mutate in-place while leaving the prior one intact.
108
283
 
109
- A circuit is a list of instructions bound to some registers.
284
+ .. automethod:: copy
110
285
 
111
- Args:
112
- regs (list(:class:`~.Register`) or list(``int``) or list(list(:class:`~.Bit`))): The
113
- registers to be included in the circuit.
286
+ Similarly, if you want a circuit that contains all the same data objects (bits, registers,
287
+ variables, etc) but with none of the instructions, you can use :meth:`copy_empty_like`. This is
288
+ quite common when you want to build up a new layer of a circuit to then use apply onto the back
289
+ with :meth:`compose`, or to do a full rewrite of a circuit's instructions.
290
+
291
+ .. automethod:: copy_empty_like
292
+
293
+ In some cases, it is most convenient to generate a list of :class:`.CircuitInstruction`\\ s
294
+ separately to an entire circuit context, and then to build a circuit from this. The
295
+ :meth:`from_instructions` constructor will automatically capture all :class:`.Qubit` and
296
+ :class:`.Clbit` instances used in the instructions, and create a new :class:`QuantumCircuit`
297
+ object that has the correct resources and all the instructions.
298
+
299
+ .. automethod:: from_instructions
300
+
301
+ :class:`QuantumCircuit` also still has two constructor methods that are legacy wrappers around
302
+ the importers in :mod:`qiskit.qasm2`. These automatically apply :ref:`the legacy compatibility
303
+ settings <qasm2-legacy-compatibility>` of :func:`~.qasm2.load` and :func:`~.qasm2.loads`.
304
+
305
+ .. automethod:: from_qasm_file
306
+ .. automethod:: from_qasm_str
307
+
308
+ Data objects on circuits
309
+ ========================
114
310
 
115
- * If a list of :class:`~.Register` objects, represents the :class:`.QuantumRegister`
116
- and/or :class:`.ClassicalRegister` objects to include in the circuit.
311
+ .. _circuit-adding-data-objects:
312
+
313
+ Adding data objects
314
+ -------------------
117
315
 
118
- For example:
316
+ ============================= =================================================================
317
+ Method Adds this kind of data
318
+ ============================= =================================================================
319
+ :meth:`add_bits` :class:`.Qubit`\\ s and :class:`.Clbit`\\ s.
320
+ :meth:`add_register` :class:`.QuantumRegister` and :class:`.ClassicalRegister`.
321
+ :meth:`add_var` :class:`~.expr.Var` nodes with local scope and initializers.
322
+ :meth:`add_input` :class:`~.expr.Var` nodes that are treated as circuit inputs.
323
+ :meth:`add_capture` :class:`~.expr.Var` nodes captured from containing scopes.
324
+ :meth:`add_uninitialized_var` :class:`~.expr.Var` nodes with local scope and undefined state.
325
+ ============================= =================================================================
119
326
 
120
- * ``QuantumCircuit(QuantumRegister(4))``
121
- * ``QuantumCircuit(QuantumRegister(4), ClassicalRegister(3))``
122
- * ``QuantumCircuit(QuantumRegister(4, 'qr0'), QuantumRegister(2, 'qr1'))``
327
+ Typically you add most of the data objects (:class:`.Qubit`, :class:`.Clbit`,
328
+ :class:`.ClassicalRegister`, etc) to the circuit as part of using the :meth:`__init__` default
329
+ constructor, or :meth:`copy_empty_like`. However, it is also possible to add these afterwards.
330
+ Typed classical data, such as standalone :class:`~.expr.Var` nodes (see
331
+ :ref:`circuit-repr-real-time-classical`), can be both constructed and added with separate
332
+ methods.
123
333
 
124
- * If a list of ``int``, the amount of qubits and/or classical bits to include in
125
- the circuit. It can either be a single int for just the number of quantum bits,
126
- or 2 ints for the number of quantum bits and classical bits, respectively.
334
+ New registerless :class:`.Qubit` and :class:`.Clbit` objects are added using :meth:`add_bits`.
335
+ These objects must not already be present in the circuit. You can check if a bit exists in the
336
+ circuit already using :meth:`find_bit`.
337
+
338
+ .. automethod:: add_bits
339
+
340
+ Registers are added to the circuit with :meth:`add_register`. In this method, it is not an
341
+ error if some of the bits are already present in the circuit. In this case, the register will
342
+ be an "alias" over the bits. This is not generally well-supported by hardware backends; it is
343
+ probably best to stay away from relying on it. The registers a given bit is in are part of the
344
+ return of :meth:`find_bit`.
127
345
 
128
- For example:
346
+ .. automethod:: add_register
129
347
 
130
- * ``QuantumCircuit(4) # A QuantumCircuit with 4 qubits``
131
- * ``QuantumCircuit(4, 3) # A QuantumCircuit with 4 qubits and 3 classical bits``
348
+ :ref:`Real-time, typed classical data <circuit-repr-real-time-classical>` is represented on the
349
+ circuit by :class:`~.expr.Var` nodes with a well-defined :class:`~.types.Type`. It is possible
350
+ to instantiate these separately to a circuit (see :meth:`.Var.new`), but it is often more
351
+ convenient to use circuit methods that will automatically manage the types and expression
352
+ initialization for you. The two most common methods are :meth:`add_var` (locally scoped
353
+ variables) and :meth:`add_input` (inputs to the circuit).
132
354
 
133
- * If a list of python lists containing :class:`.Bit` objects, a collection of
134
- :class:`.Bit` s to be added to the circuit.
355
+ .. automethod:: add_var
356
+ .. automethod:: add_input
135
357
 
358
+ In addition, there are two lower-level methods that can be useful for programmatic generation of
359
+ circuits. When working interactively, you will most likely not need these; most uses of
360
+ :meth:`add_uninitialized_var` are part of :meth:`copy_empty_like`, and most uses of
361
+ :meth:`add_capture` would be better off using :ref:`the control-flow builder interface
362
+ <circuit-control-flow-methods>`.
136
363
 
137
- name (str): the name of the quantum circuit. If not set, an
138
- automatically generated string will be assigned.
139
- global_phase (float or ParameterExpression): The global phase of the circuit in radians.
140
- metadata (dict): Arbitrary key value metadata to associate with the
141
- circuit. This gets stored as free-form data in a dict in the
142
- :attr:`~qiskit.circuit.QuantumCircuit.metadata` attribute. It will
143
- not be directly used in the circuit.
364
+ .. automethod:: add_uninitialized_var
365
+ .. automethod:: add_capture
144
366
 
145
- Raises:
146
- CircuitError: if the circuit name, if given, is not valid.
367
+ Working with bits and registers
368
+ -------------------------------
369
+
370
+ A :class:`.Bit` instance is, on its own, just a unique handle for circuits to use in their own
371
+ contexts. If you have got a :class:`.Bit` instance and a cirucit, just can find the contexts
372
+ that the bit exists in using :meth:`find_bit`, such as its integer index in the circuit and any
373
+ registers it is contained in.
374
+
375
+ .. automethod:: find_bit
376
+
377
+ Similarly, you can query a circuit to see if a register has already been added to it by using
378
+ :meth:`has_register`.
379
+
380
+ .. automethod:: has_register
381
+
382
+ Working with compile-time parameters
383
+ ------------------------------------
384
+
385
+ .. seealso::
386
+ :ref:`circuit-compile-time-parameters`
387
+ A more complete discussion of what compile-time parametrization is, and how it fits into
388
+ Qiskit's data model.
389
+
390
+ Unlike bits, registers, and real-time typed classical data, compile-time symbolic parameters are
391
+ not manually added to a circuit. Their presence is inferred by being contained in operations
392
+ added to circuits and the global phase. An ordered list of all parameters currently in a
393
+ circuit is at :attr:`QuantumCircuit.parameters`.
394
+
395
+ The most common operation on :class:`.Parameter` instances is to replace them in symbolic
396
+ operations with some numeric value, or another symbolic expression. This is done with
397
+ :meth:`assign_parameters`.
398
+
399
+ .. automethod:: assign_parameters
400
+
401
+ The circuit tracks parameters by :class:`.Parameter` instances themselves, and forbids having
402
+ multiple parameters of the same name to avoid some problems when interoperating with OpenQASM or
403
+ other external formats. You can use :meth:`has_parameter` and :meth:`get_parameter` to query
404
+ the circuit for a parameter with the given string name.
405
+
406
+ .. automethod:: has_parameter
407
+ .. automethod:: get_parameter
408
+
409
+ .. _circuit-real-time-methods:
410
+
411
+ Working with real-time typed classical data
412
+ -------------------------------------------
413
+
414
+ .. seealso::
415
+ :mod:`qiskit.circuit.classical`
416
+ Module-level documentation for how the variable-, expression- and type-systems work, the
417
+ objects used to represent them, and the classical operations available.
418
+
419
+ :ref:`circuit-repr-real-time-classical`
420
+ A discussion of how real-time data fits into the entire :mod:`qiskit.circuit` data model
421
+ as a whole.
422
+
423
+ :ref:`circuit-adding-data-objects`
424
+ The methods for adding new :class:`~.expr.Var` variables to a circuit after
425
+ initialization.
426
+
427
+ You can retrive a :class:`~.expr.Var` instance attached to a circuit by using its variable name
428
+ using :meth:`get_var`, or check if a circuit contains a given variable with :meth:`has_var`.
429
+
430
+ .. automethod:: get_var
431
+ .. automethod:: has_var
432
+
433
+ There are also several iterator methods that you can use to get the full set of variables
434
+ tracked by a circuit. At least one of :meth:`iter_input_vars` and :meth:`iter_captured_vars`
435
+ will be empty, as inputs and captures are mutually exclusive. All of the iterators have
436
+ corresponding dynamic properties on :class:`QuantumCircuit` that contain their length:
437
+ :attr:`num_vars`, :attr:`num_input_vars`, :attr:`num_captured_vars` and
438
+ :attr:`num_declared_vars`.
439
+
440
+ .. automethod:: iter_vars
441
+ .. automethod:: iter_input_vars
442
+ .. automethod:: iter_captured_vars
443
+ .. automethod:: iter_declared_vars
444
+
445
+
446
+ .. _circuit-adding-operations:
447
+
448
+ Adding operations to circuits
449
+ =============================
450
+
451
+ You can add anything that implements the :class:`.Operation` interface to a circuit as a single
452
+ instruction, though most things you will want to add will be :class:`~.circuit.Instruction` or
453
+ :class:`~.circuit.Gate` instances.
454
+
455
+ .. seealso::
456
+ :ref:`circuit-operations-instructions`
457
+ The :mod:`qiskit.circuit`-level documentation on the different interfaces that Qiskit
458
+ uses to define circuit-level instructions.
459
+
460
+ .. _circuit-append-compose:
461
+
462
+ Methods to add general operations
463
+ ---------------------------------
464
+
465
+ These are the base methods that handle adding any object, including user-defined ones, onto
466
+ circuits.
467
+
468
+ =============== ===============================================================================
469
+ Method When to use it
470
+ =============== ===============================================================================
471
+ :meth:`append` Add an instruction as a single object onto a circuit.
472
+ :meth:`_append` Same as :meth:`append`, but a low-level interface that elides almost all error
473
+ checking.
474
+ :meth:`compose` Inline the instructions from one circuit onto another.
475
+ :meth:`tensor` Like :meth:`compose`, but strictly for joining circuits that act on disjoint
476
+ qubits.
477
+ =============== ===============================================================================
478
+
479
+ :class:`QuantumCircuit` has two main ways that you will add more operations onto a circuit.
480
+ Which to use depends on whether you want to add your object as a single "instruction"
481
+ (:meth:`append`), or whether you want to join the instructions from two circuits together
482
+ (:meth:`compose`).
483
+
484
+ A single instruction or operation appears as a single entry in the :attr:`data` of the circuit,
485
+ and as a single box when drawn in the circuit visualizers (see :meth:`draw`). A single
486
+ instruction is the "unit" that a hardware backend might be defined in terms of (see
487
+ :class:`.Target`). An :class:`~.circuit.Instruction` can come with a
488
+ :attr:`~.circuit.Instruction.definition`, which is one rule the transpiler (see
489
+ :mod:`qiskit.transpiler`) will be able to fall back on to decompose it for hardware, if needed.
490
+ An :class:`.Operation` that is not also an :class:`~.circuit.Instruction` can
491
+ only be decomposed if it has some associated high-level synthesis method registered for it (see
492
+ :mod:`qiskit.transpiler.passes.synthesis.plugin`).
493
+
494
+ A :class:`QuantumCircuit` alone is not a single :class:`~.circuit.Instruction`; it is rather
495
+ more complicated, since it can, in general, represent a complete program with typed classical
496
+ memory inputs and outputs, and control flow. Qiskit's (and most hardware's) data model does not
497
+ yet have the concept of re-usable callable subroutines with virtual quantum operands. You can
498
+ convert simple circuits that act only on qubits with unitary operations into a :class:`.Gate`
499
+ using :meth:`to_gate`, and simple circuits acting only on qubits and clbits into a
500
+ :class:`~.circuit.Instruction` with :meth:`to_instruction`.
501
+
502
+ When you have an :class:`.Operation`, :class:`~.circuit.Instruction`, or :class:`.Gate`, add it
503
+ to the circuit, specifying the qubit and clbit arguments with :meth:`append`.
504
+
505
+ .. automethod:: append
506
+
507
+ :meth:`append` does quite substantial error checking to ensure that you cannot accidentally
508
+ break the data model of :class:`QuantumCircuit`. If you are programmatically generating a
509
+ circuit from known-good data, you can elide much of this error checking by using the fast-path
510
+ appender :meth:`_append`, but at the risk that the caller is responsible for ensuring they are
511
+ passing only valid data.
512
+
513
+ .. automethod:: _append
514
+
515
+ In other cases, you may want to join two circuits together, applying the instructions from one
516
+ circuit onto specified qubits and clbits on another circuit. This "inlining" operation is
517
+ called :meth:`compose` in Qiskit. :meth:`compose` is, in general, more powerful than
518
+ a :meth:`to_instruction`-plus-:meth:`append` combination for joining two circuits, because it
519
+ can also link typed classical data together, and allows for circuit control-flow operations to
520
+ be joined onto another circuit.
521
+
522
+ The downsides to :meth:`compose` are that it is a more complex operation that can involve more
523
+ rewriting of the operand, and that it necessarily must move data from one circuit object to
524
+ another. If you are building up a circuit for yourself and raw performance is a core goal,
525
+ consider passing around your base circuit and having different parts of your algorithm write
526
+ directly to the base circuit, rather than building a temporary layer circuit.
527
+
528
+ .. automethod:: compose
529
+
530
+ If you are trying to join two circuits that will apply to completely disjoint qubits and clbits,
531
+ :meth:`tensor` is a convenient wrapper around manually adding bit objects and calling
532
+ :meth:`compose`.
533
+
534
+ .. automethod:: tensor
535
+
536
+ As some rules of thumb:
537
+
538
+ * If you have a single :class:`.Operation`, :class:`~.circuit.Instruction` or :class:`.Gate`,
539
+ you should definitely use :meth:`append` or :meth:`_append`.
540
+ * If you have a :class:`QuantumCircuit` that represents a single atomic instruction for a larger
541
+ circuit that you want to re-use, you probably want to call :meth:`to_instruction` or
542
+ :meth:`to_gate`, and then apply the result of that to the circuit using :meth:`append`.
543
+ * If you have a :class:`QuantumCircuit` that represents a larger "layer" of another circuit, or
544
+ contains typed classical variables or control flow, you should use :meth:`compose` to merge it
545
+ onto another circuit.
546
+ * :meth:`tensor` is wanted far more rarely than either :meth:`append` or :meth:`compose`.
547
+ Internally, it is mostly a wrapper around :meth:`add_bits` and :meth:`compose`.
548
+
549
+ Some potential pitfalls to beware of:
550
+
551
+ * Even if you re-use a custom :class:`~.circuit.Instruction` during circuit construction, the
552
+ transpiler will generally have to "unroll" each invocation of it to its inner decomposition
553
+ before beginning work on it. This should not prevent you from using the
554
+ :meth:`to_instruction`-plus-:meth:`append` pattern, as the transpiler will improve in this
555
+ regard over time.
556
+ * :meth:`compose` will, by default, produce a new circuit for backwards compatibility. This is
557
+ more expensive, and not usually what you want, so you should set ``inplace=True``.
558
+ * Both :meth:`append` and :meth:`compose` (but not :meth:`_append`) have a ``copy`` keyword
559
+ argument that defaults to ``True``. In these cases, the incoming :class:`.Operation`
560
+ instances will be copied if Qiskit detects that the objects have mutability about them (such
561
+ as taking gate parameters). If you are sure that you will not re-use the objects again in
562
+ other places, you should set ``copy=False`` to prevent this copying, which can be a
563
+ substantial speed-up for large objects.
564
+
565
+ Methods to add standard instructions
566
+ ------------------------------------
567
+
568
+ The :class:`QuantumCircuit` class has helper methods to add many of the Qiskit standard-library
569
+ instructions and gates onto a circuit. These are generally equivalent to manually constructing
570
+ an instance of the relevent :mod:`qiskit.circuit.library` object, then passing that to
571
+ :meth:`append` with the remaining arguments placed into the ``qargs`` and ``cargs`` fields as
572
+ appropriate.
573
+
574
+ The following methods apply special non-unitary :class:`~.circuit.Instruction` operations to the
575
+ circuit:
576
+
577
+ =============================== ====================================================
578
+ :class:`QuantumCircuit` method :mod:`qiskit.circuit` :class:`~.circuit.Instruction`
579
+ =============================== ====================================================
580
+ :meth:`barrier` :class:`Barrier`
581
+ :meth:`delay` :class:`Delay`
582
+ :meth:`initialize` :class:`~library.Initialize`
583
+ :meth:`measure` :class:`Measure`
584
+ :meth:`reset` :class:`Reset`
585
+ :meth:`store` :class:`Store`
586
+ =============================== ====================================================
587
+
588
+ These methods apply uncontrolled unitary :class:`.Gate` instances to the circuit:
589
+
590
+ =============================== ============================================
591
+ :class:`QuantumCircuit` method :mod:`qiskit.circuit.library` :class:`.Gate`
592
+ =============================== ============================================
593
+ :meth:`dcx` :class:`~library.DCXGate`
594
+ :meth:`ecr` :class:`~library.ECRGate`
595
+ :meth:`h` :class:`~library.HGate`
596
+ :meth:`id` :class:`~library.IGate`
597
+ :meth:`iswap` :class:`~library.iSwapGate`
598
+ :meth:`ms` :class:`~library.MSGate`
599
+ :meth:`p` :class:`~library.PhaseGate`
600
+ :meth:`pauli` :class:`~library.PauliGate`
601
+ :meth:`prepare_state` :class:`~library.StatePreparation`
602
+ :meth:`r` :class:`~library.RGate`
603
+ :meth:`rcccx` :class:`~library.RC3XGate`
604
+ :meth:`rccx` :class:`~library.RCCXGate`
605
+ :meth:`rv` :class:`~library.RVGate`
606
+ :meth:`rx` :class:`~library.RXGate`
607
+ :meth:`rxx` :class:`~library.RXXGate`
608
+ :meth:`ry` :class:`~library.RYGate`
609
+ :meth:`ryy` :class:`~library.RYYGate`
610
+ :meth:`rz` :class:`~library.RZGate`
611
+ :meth:`rzx` :class:`~library.RZXGate`
612
+ :meth:`rzz` :class:`~library.RZZGate`
613
+ :meth:`s` :class:`~library.SGate`
614
+ :meth:`sdg` :class:`~library.SdgGate`
615
+ :meth:`swap` :class:`~library.SwapGate`
616
+ :meth:`sx` :class:`~library.SXGate`
617
+ :meth:`sxdg` :class:`~library.SXdgGate`
618
+ :meth:`t` :class:`~library.TGate`
619
+ :meth:`tdg` :class:`~library.TdgGate`
620
+ :meth:`u` :class:`~library.UGate`
621
+ :meth:`unitary` :class:`~library.UnitaryGate`
622
+ :meth:`x` :class:`~library.XGate`
623
+ :meth:`y` :class:`~library.YGate`
624
+ :meth:`z` :class:`~library.ZGate`
625
+ =============================== ============================================
626
+
627
+ The following methods apply :class:`Gate` instances that are also controlled gates, so are
628
+ direct subclasses of :class:`ControlledGate`:
629
+
630
+ =============================== ======================================================
631
+ :class:`QuantumCircuit` method :mod:`qiskit.circuit.library` :class:`.ControlledGate`
632
+ =============================== ======================================================
633
+ :meth:`ccx` :class:`~library.CCXGate`
634
+ :meth:`ccz` :class:`~library.CCZGate`
635
+ :meth:`ch` :class:`~library.CHGate`
636
+ :meth:`cp` :class:`~library.CPhaseGate`
637
+ :meth:`crx` :class:`~library.CRXGate`
638
+ :meth:`cry` :class:`~library.CRYGate`
639
+ :meth:`crz` :class:`~library.CRZGate`
640
+ :meth:`cs` :class:`~library.CSGate`
641
+ :meth:`csdg` :class:`~library.CSdgGate`
642
+ :meth:`cswap` :class:`~library.CSwapGate`
643
+ :meth:`csx` :class:`~library.CSXGate`
644
+ :meth:`cu` :class:`~library.CUGate`
645
+ :meth:`cx` :class:`~library.CXGate`
646
+ :meth:`cy` :class:`~library.CYGate`
647
+ :meth:`cz` :class:`~library.CZGate`
648
+ =============================== ======================================================
649
+
650
+ Finally, these methods apply particular generalized multiply controlled gates to the circuit,
651
+ often with eager syntheses. They are listed in terms of the *base* gate they are controlling,
652
+ since their exact output is often a synthesised version of a gate.
653
+
654
+ =============================== =================================================
655
+ :class:`QuantumCircuit` method Base :mod:`qiskit.circuit.library` :class:`.Gate`
656
+ =============================== =================================================
657
+ :meth:`mcp` :class:`~library.PhaseGate`
658
+ :meth:`mcrx` :class:`~library.RXGate`
659
+ :meth:`mcry` :class:`~library.RYGate`
660
+ :meth:`mcrz` :class:`~library.RZGate`
661
+ :meth:`mcx` :class:`~library.XGate`
662
+ =============================== =================================================
663
+
664
+ The rest of this section is the API listing of all the individual methods; the tables above are
665
+ summaries whose links will jump you to the correct place.
666
+
667
+ .. automethod:: barrier
668
+ .. automethod:: ccx
669
+ .. automethod:: ccz
670
+ .. automethod:: ch
671
+ .. automethod:: cp
672
+ .. automethod:: crx
673
+ .. automethod:: cry
674
+ .. automethod:: crz
675
+ .. automethod:: cs
676
+ .. automethod:: csdg
677
+ .. automethod:: cswap
678
+ .. automethod:: csx
679
+ .. automethod:: cu
680
+ .. automethod:: cx
681
+ .. automethod:: cy
682
+ .. automethod:: cz
683
+ .. automethod:: dcx
684
+ .. automethod:: delay
685
+ .. automethod:: ecr
686
+ .. automethod:: h
687
+ .. automethod:: id
688
+ .. automethod:: initialize
689
+ .. automethod:: iswap
690
+ .. automethod:: mcp
691
+ .. automethod:: mcrx
692
+ .. automethod:: mcry
693
+ .. automethod:: mcrz
694
+ .. automethod:: mcx
695
+ .. automethod:: measure
696
+ .. automethod:: ms
697
+ .. automethod:: p
698
+ .. automethod:: pauli
699
+ .. automethod:: prepare_state
700
+ .. automethod:: r
701
+ .. automethod:: rcccx
702
+ .. automethod:: rccx
703
+ .. automethod:: reset
704
+ .. automethod:: rv
705
+ .. automethod:: rx
706
+ .. automethod:: rxx
707
+ .. automethod:: ry
708
+ .. automethod:: ryy
709
+ .. automethod:: rz
710
+ .. automethod:: rzx
711
+ .. automethod:: rzz
712
+ .. automethod:: s
713
+ .. automethod:: sdg
714
+ .. automethod:: store
715
+ .. automethod:: swap
716
+ .. automethod:: sx
717
+ .. automethod:: sxdg
718
+ .. automethod:: t
719
+ .. automethod:: tdg
720
+ .. automethod:: u
721
+ .. automethod:: unitary
722
+ .. automethod:: x
723
+ .. automethod:: y
724
+ .. automethod:: z
725
+
726
+
727
+ .. _circuit-control-flow-methods:
728
+
729
+ Adding control flow to circuits
730
+ -------------------------------
731
+
732
+ .. seealso::
733
+ :ref:`circuit-control-flow-repr`
734
+
735
+ Discussion of how control-flow operations are represented in the whole :mod:`qiskit.circuit`
736
+ context.
737
+
738
+ ============================== ================================================================
739
+ :class:`QuantumCircuit` method Control-flow instruction
740
+ ============================== ================================================================
741
+ :meth:`if_test` :class:`.IfElseOp` with only a ``True`` body.
742
+ :meth:`if_else` :class:`.IfElseOp` with both ``True`` and ``False`` bodies.
743
+ :meth:`while_loop` :class:`.WhileLoopOp`.
744
+ :meth:`switch` :class:`.SwitchCaseOp`.
745
+ :meth:`for_loop` :class:`.ForLoopOp`.
746
+ :meth:`break_loop` :class:`.BreakLoopOp`.
747
+ :meth:`continue_loop` :class:`.ContinueLoopOp`.
748
+ ============================== ================================================================
749
+
750
+ :class:`QuantumCircuit` has corresponding methods for all of the control-flow operations that
751
+ are supported by Qiskit. These have two forms for calling them. The first is a very
752
+ straightfowards convenience wrapper that takes in the block bodies of the instructions as
753
+ :class:`QuantumCircuit` arguments, and simply constructs and appends the corresponding
754
+ :class:`.ControlFlowOp`.
755
+
756
+ The second form, which we strongly recommend you use for constructing control flow, is called
757
+ *the builder interface*. Here, the methods take only the real-time discriminant of the
758
+ operation, and return `context managers
759
+ <https://docs.python.org/3/library/stdtypes.html#typecontextmanager>`__ that you enter using
760
+ ``with``. You can then use regular :class:`QuantumCircuit` methods within those blocks to build
761
+ up the control-flow bodies, and Qiskit will automatically track which of the data resources are
762
+ needed for the inner blocks, building the complete :class:`.ControlFlowOp` as you leave the
763
+ ``with`` statement. It is far simpler and less error-prone to build control flow
764
+ programmatically this way.
765
+
766
+ ..
767
+ TODO: expand the examples of the builder interface.
768
+
769
+ .. automethod:: break_loop
770
+ .. automethod:: continue_loop
771
+ .. automethod:: for_loop
772
+ .. automethod:: if_else
773
+ .. automethod:: if_test
774
+ .. automethod:: switch
775
+ .. automethod:: while_loop
776
+
777
+
778
+ Converting circuits to single objects
779
+ -------------------------------------
780
+
781
+ As discussed in :ref:`circuit-append-compose`, you can convert a circuit to either an
782
+ :class:`~.circuit.Instruction` or a :class:`.Gate` using two helper methods.
783
+
784
+ .. automethod:: to_instruction
785
+ .. automethod:: to_gate
786
+
787
+
788
+ Helper mutation methods
789
+ -----------------------
790
+
791
+ There are two higher-level methods on :class:`QuantumCircuit` for appending measurements to the
792
+ end of a circuit. Note that by default, these also add an extra register.
793
+
794
+ .. automethod:: measure_active
795
+ .. automethod:: measure_all
796
+
797
+ There are two "subtractive" methods on :class:`QuantumCircuit` as well. This is not a use-case
798
+ that :class:`QuantumCircuit` is designed for; typically you should just look to use
799
+ :meth:`copy_empty_like` in place of :meth:`clear`, and run :meth:`remove_final_measurements` as
800
+ its transpiler-pass form :class:`.RemoveFinalMeasurements`.
801
+
802
+ .. automethod:: clear
803
+ .. automethod:: remove_final_measurements
804
+
805
+ .. _circuit-calibrations:
806
+
807
+ Manual calibration of instructions
808
+ ----------------------------------
809
+
810
+ :class:`QuantumCircuit` can store :attr:`calibrations` of instructions that define the pulses
811
+ used to run them on one particular hardware backend. You can
812
+
813
+ .. automethod:: add_calibration
814
+ .. automethod:: has_calibration_for
815
+
816
+
817
+ Circuit properties
818
+ ==================
819
+
820
+ Simple circuit metrics
821
+ ----------------------
822
+
823
+ When constructing quantum circuits, there are several properties that help quantify
824
+ the "size" of the circuits, and their ability to be run on a noisy quantum device.
825
+ Some of these, like number of qubits, are straightforward to understand, while others
826
+ like depth and number of tensor components require a bit more explanation. Here we will
827
+ explain all of these properties, and, in preparation for understanding how circuits change
828
+ when run on actual devices, highlight the conditions under which they change.
829
+
830
+ Consider the following circuit:
147
831
 
148
- Examples:
832
+ .. plot::
833
+ :include-source:
149
834
 
150
- Construct a simple Bell state circuit.
835
+ from qiskit import QuantumCircuit
836
+ qc = QuantumCircuit(12)
837
+ for idx in range(5):
838
+ qc.h(idx)
839
+ qc.cx(idx, idx+5)
151
840
 
152
- .. plot::
153
- :include-source:
841
+ qc.cx(1, 7)
842
+ qc.x(8)
843
+ qc.cx(1, 9)
844
+ qc.x(7)
845
+ qc.cx(1, 11)
846
+ qc.swap(6, 11)
847
+ qc.swap(6, 9)
848
+ qc.swap(6, 10)
849
+ qc.x(6)
850
+ qc.draw('mpl')
154
851
 
155
- from qiskit import QuantumCircuit
852
+ From the plot, it is easy to see that this circuit has 12 qubits, and a collection of
853
+ Hadamard, CNOT, X, and SWAP gates. But how to quantify this programmatically? Because we
854
+ can do single-qubit gates on all the qubits simultaneously, the number of qubits in this
855
+ circuit is equal to the :meth:`width` of the circuit::
156
856
 
157
- qc = QuantumCircuit(2, 2)
158
- qc.h(0)
159
- qc.cx(0, 1)
160
- qc.measure([0, 1], [0, 1])
161
- qc.draw('mpl')
857
+ assert qc.width() == 12
162
858
 
163
- Construct a 5-qubit GHZ circuit.
859
+ We can also just get the number of qubits directly using :attr:`num_qubits`::
164
860
 
165
- .. code-block::
861
+ assert qc.num_qubits == 12
166
862
 
167
- from qiskit import QuantumCircuit
863
+ .. important::
168
864
 
169
- qc = QuantumCircuit(5)
170
- qc.h(0)
171
- qc.cx(0, range(1, 5))
172
- qc.measure_all()
865
+ For a quantum circuit composed from just qubits, the circuit width is equal
866
+ to the number of qubits. This is the definition used in quantum computing. However,
867
+ for more complicated circuits with classical registers, and classically controlled gates,
868
+ this equivalence breaks down. As such, from now on we will not refer to the number of
869
+ qubits in a quantum circuit as the width.
173
870
 
174
- Construct a 4-qubit Bernstein-Vazirani circuit using registers.
871
+ It is also straightforward to get the number and type of the gates in a circuit using
872
+ :meth:`count_ops`::
175
873
 
176
- .. plot::
177
- :include-source:
874
+ qc.count_ops()
178
875
 
179
- from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
876
+ .. parsed-literal::
180
877
 
181
- qr = QuantumRegister(3, 'q')
182
- anc = QuantumRegister(1, 'ancilla')
183
- cr = ClassicalRegister(3, 'c')
184
- qc = QuantumCircuit(qr, anc, cr)
878
+ OrderedDict([('cx', 8), ('h', 5), ('x', 3), ('swap', 3)])
185
879
 
186
- qc.x(anc[0])
187
- qc.h(anc[0])
188
- qc.h(qr[0:3])
189
- qc.cx(qr[0:3], anc[0])
190
- qc.h(qr[0:3])
191
- qc.barrier(qr)
192
- qc.measure(qr, cr)
880
+ We can also get just the raw count of operations by computing the circuits
881
+ :meth:`size`::
193
882
 
194
- qc.draw('mpl')
883
+ assert qc.size() == 19
884
+
885
+ A particularly important circuit property is known as the circuit :meth:`depth`. The depth
886
+ of a quantum circuit is a measure of how many "layers" of quantum gates, executed in
887
+ parallel, it takes to complete the computation defined by the circuit. Because quantum
888
+ gates take time to implement, the depth of a circuit roughly corresponds to the amount of
889
+ time it takes the quantum computer to execute the circuit. Thus, the depth of a circuit
890
+ is one important quantity used to measure if a quantum circuit can be run on a device.
891
+
892
+ The depth of a quantum circuit has a mathematical definition as the longest path in a
893
+ directed acyclic graph (DAG). However, such a definition is a bit hard to grasp, even for
894
+ experts. Fortunately, the depth of a circuit can be easily understood by anyone familiar
895
+ with playing `Tetris <https://en.wikipedia.org/wiki/Tetris>`_. Lets see how to compute this
896
+ graphically:
897
+
898
+ .. image:: /source_images/depth.gif
899
+
900
+ We can verify our graphical result using :meth:`QuantumCircuit.depth`::
901
+
902
+ assert qc.depth() == 9
903
+
904
+ .. automethod:: count_ops
905
+ .. automethod:: depth
906
+ .. automethod:: get_instructions
907
+ .. automethod:: num_connected_components
908
+ .. automethod:: num_nonlocal_gates
909
+ .. automethod:: num_tensor_factors
910
+ .. automethod:: num_unitary_factors
911
+ .. automethod:: size
912
+ .. automethod:: width
913
+
914
+ Accessing scheduling information
915
+ --------------------------------
916
+
917
+ If a :class:`QuantumCircuit` has been scheduled as part of a transpilation pipeline, the timing
918
+ information for individual qubits can be accessed. The whole-circuit timing information is
919
+ available through the :attr:`duration`, :attr:`unit` and :attr:`op_start_times` attributes.
920
+
921
+ .. automethod:: qubit_duration
922
+ .. automethod:: qubit_start_time
923
+ .. automethod:: qubit_stop_time
924
+
925
+ Instruction-like methods
926
+ ========================
927
+
928
+ ..
929
+ These methods really shouldn't be on `QuantumCircuit` at all. They're generally more
930
+ appropriate as `Instruction` or `Gate` methods. `reverse_ops` shouldn't be a method _full
931
+ stop_---it was copying a `DAGCircuit` method from an implementation detail of the original
932
+ `SabreLayout` pass in Qiskit.
933
+
934
+ :class:`QuantumCircuit` also contains a small number of methods that are very
935
+ :class:`~.circuit.Instruction`-like in detail. You may well find better integration and more
936
+ API support if you first convert your circuit to an :class:`~.circuit.Instruction`
937
+ (:meth:`to_instruction`) or :class:`.Gate` (:meth:`to_gate`) as appropriate, then call the
938
+ corresponding method.
939
+
940
+ .. automethod:: control
941
+ .. automethod:: inverse
942
+ .. automethod:: power
943
+ .. automethod:: repeat
944
+ .. automethod:: reverse_ops
945
+
946
+ Visualization
947
+ =============
948
+
949
+ Qiskit includes some drawing tools to give you a quick feel for what your circuit looks like.
950
+ This tooling is primarily targeted at producing either a `Matplotlib
951
+ <https://matplotlib.org/>`__- or text-based drawing. There is also a lesser-featured LaTeX
952
+ backend for drawing, but this is only for simple circuits, and is not as actively maintained.
953
+
954
+ .. seealso::
955
+ :mod:`qiskit.visualization`
956
+ The primary documentation for all of Qiskit's visualization tooling.
957
+
958
+ .. automethod:: draw
959
+
960
+ In addition to the core :meth:`draw` driver, there are two visualization-related helper methods,
961
+ which are mostly useful for quickly unwrapping some inner instructions or reversing the
962
+ :ref:`qubit-labelling conventions <circuit-conventions>` in the drawing. For more general
963
+ mutation, including basis-gate rewriting, you should use the transpiler
964
+ (:mod:`qiskit.transpiler`).
965
+
966
+ .. automethod:: decompose
967
+ .. automethod:: reverse_bits
968
+
969
+ Internal utilities
970
+ ==================
971
+
972
+ These functions are not intended for public use, but were accidentally left documented in the
973
+ public API during the 1.0 release. They will be removed in Qiskit 2.0, but will be supported
974
+ until then.
975
+
976
+ .. automethod:: cast
977
+ .. automethod:: cbit_argument_conversion
978
+ .. automethod:: cls_instances
979
+ .. automethod:: cls_prefix
980
+ .. automethod:: qbit_argument_conversion
195
981
  """
196
982
 
197
983
  instances = 0
@@ -203,7 +989,73 @@ class QuantumCircuit:
203
989
  name: str | None = None,
204
990
  global_phase: ParameterValueType = 0,
205
991
  metadata: dict | None = None,
992
+ inputs: Iterable[expr.Var] = (),
993
+ captures: Iterable[expr.Var] = (),
994
+ declarations: Mapping[expr.Var, expr.Expr] | Iterable[Tuple[expr.Var, expr.Expr]] = (),
206
995
  ):
996
+ """
997
+ Default constructor of :class:`QuantumCircuit`.
998
+
999
+ ..
1000
+ `QuantumCirucit` documents its `__init__` method explicitly, unlike most classes where
1001
+ it's implicitly appended to the class-level documentation, just because the class is so
1002
+ huge and has a lot of introductory material to its class docstring.
1003
+
1004
+ Args:
1005
+ regs: The registers to be included in the circuit.
1006
+
1007
+ * If a list of :class:`~.Register` objects, represents the :class:`.QuantumRegister`
1008
+ and/or :class:`.ClassicalRegister` objects to include in the circuit.
1009
+
1010
+ For example:
1011
+
1012
+ * ``QuantumCircuit(QuantumRegister(4))``
1013
+ * ``QuantumCircuit(QuantumRegister(4), ClassicalRegister(3))``
1014
+ * ``QuantumCircuit(QuantumRegister(4, 'qr0'), QuantumRegister(2, 'qr1'))``
1015
+
1016
+ * If a list of ``int``, the amount of qubits and/or classical bits to include in
1017
+ the circuit. It can either be a single int for just the number of quantum bits,
1018
+ or 2 ints for the number of quantum bits and classical bits, respectively.
1019
+
1020
+ For example:
1021
+
1022
+ * ``QuantumCircuit(4) # A QuantumCircuit with 4 qubits``
1023
+ * ``QuantumCircuit(4, 3) # A QuantumCircuit with 4 qubits and 3 classical bits``
1024
+
1025
+ * If a list of python lists containing :class:`.Bit` objects, a collection of
1026
+ :class:`.Bit` s to be added to the circuit.
1027
+
1028
+ name: the name of the quantum circuit. If not set, an automatically generated string
1029
+ will be assigned.
1030
+ global_phase: The global phase of the circuit in radians.
1031
+ metadata: Arbitrary key value metadata to associate with the circuit. This gets
1032
+ stored as free-form data in a dict in the
1033
+ :attr:`~qiskit.circuit.QuantumCircuit.metadata` attribute. It will not be directly
1034
+ used in the circuit.
1035
+ inputs: any variables to declare as ``input`` runtime variables for this circuit. These
1036
+ should already be existing :class:`.expr.Var` nodes that you build from somewhere
1037
+ else; if you need to create the inputs as well, use
1038
+ :meth:`QuantumCircuit.add_input`. The variables given in this argument will be
1039
+ passed directly to :meth:`add_input`. A circuit cannot have both ``inputs`` and
1040
+ ``captures``.
1041
+ captures: any variables that that this circuit scope should capture from a containing
1042
+ scope. The variables given here will be passed directly to :meth:`add_capture`. A
1043
+ circuit cannot have both ``inputs`` and ``captures``.
1044
+ declarations: any variables that this circuit should declare and initialize immediately.
1045
+ You can order this input so that later declarations depend on earlier ones
1046
+ (including inputs or captures). If you need to depend on values that will be
1047
+ computed later at runtime, use :meth:`add_var` at an appropriate point in the
1048
+ circuit execution.
1049
+
1050
+ This argument is intended for convenient circuit initialization when you already
1051
+ have a set of created variables. The variables used here will be directly passed to
1052
+ :meth:`add_var`, which you can use directly if this is the first time you are
1053
+ creating the variable.
1054
+
1055
+ Raises:
1056
+ CircuitError: if the circuit name, if given, is not valid.
1057
+ CircuitError: if both ``inputs`` and ``captures`` are given.
1058
+ """
207
1059
  if any(not isinstance(reg, (list, QuantumRegister, ClassicalRegister)) for reg in regs):
208
1060
  # check if inputs are integers, but also allow e.g. 2.0
209
1061
 
@@ -220,6 +1072,8 @@ class QuantumCircuit:
220
1072
 
221
1073
  regs = tuple(int(reg) for reg in regs) # cast to int
222
1074
  self._base_name = None
1075
+ self.name: str
1076
+ """A human-readable name for the circuit."""
223
1077
  if name is None:
224
1078
  self._base_name = self.cls_prefix()
225
1079
  self._name_update()
@@ -249,7 +1103,11 @@ class QuantumCircuit:
249
1103
  ] = []
250
1104
 
251
1105
  self.qregs: list[QuantumRegister] = []
1106
+ """A list of the :class:`QuantumRegister`\\ s in this circuit. You should not mutate
1107
+ this."""
252
1108
  self.cregs: list[ClassicalRegister] = []
1109
+ """A list of the :class:`ClassicalRegister`\\ s in this circuit. You should not mutate
1110
+ this."""
253
1111
 
254
1112
  # Dict mapping Qubit or Clbit instances to tuple comprised of 0) the
255
1113
  # corresponding index in circuit.{qubits,clbits} and 1) a list of
@@ -276,9 +1134,30 @@ class QuantumCircuit:
276
1134
  self._global_phase: ParameterValueType = 0
277
1135
  self.global_phase = global_phase
278
1136
 
279
- self.duration = None
1137
+ # Add classical variables. Resolve inputs and captures first because they can't depend on
1138
+ # anything, but declarations might depend on them.
1139
+ self._vars_input: dict[str, expr.Var] = {}
1140
+ self._vars_capture: dict[str, expr.Var] = {}
1141
+ self._vars_local: dict[str, expr.Var] = {}
1142
+ for input_ in inputs:
1143
+ self.add_input(input_)
1144
+ for capture in captures:
1145
+ self.add_capture(capture)
1146
+ if isinstance(declarations, Mapping):
1147
+ declarations = declarations.items()
1148
+ for var, initial in declarations:
1149
+ self.add_var(var, initial)
1150
+
1151
+ self.duration: int | float | None = None
1152
+ """The total duration of the circuit, set by a scheduling transpiler pass. Its unit is
1153
+ specified by :attr:`unit`."""
280
1154
  self.unit = "dt"
1155
+ """The unit that :attr:`duration` is specified in."""
281
1156
  self.metadata = {} if metadata is None else metadata
1157
+ """Arbitrary user-defined metadata for the circuit.
1158
+
1159
+ Qiskit will not examine the content of this mapping, but it will pass it through the
1160
+ transpiler and reattach it to the output, so you can track your own metadata."""
282
1161
 
283
1162
  @staticmethod
284
1163
  def from_instructions(
@@ -295,7 +1174,7 @@ class QuantumCircuit:
295
1174
  global_phase: ParameterValueType = 0,
296
1175
  metadata: dict | None = None,
297
1176
  ) -> "QuantumCircuit":
298
- """Construct a circuit from an iterable of CircuitInstructions.
1177
+ """Construct a circuit from an iterable of :class:`.CircuitInstruction`\\ s.
299
1178
 
300
1179
  Args:
301
1180
  instructions: The instructions to add to the circuit.
@@ -352,7 +1231,7 @@ class QuantumCircuit:
352
1231
 
353
1232
  @property
354
1233
  def data(self) -> QuantumCircuitData:
355
- """Return the circuit data (instructions and context).
1234
+ """The circuit data (instructions and context).
356
1235
 
357
1236
  Returns:
358
1237
  QuantumCircuitData: a list-like object containing the :class:`.CircuitInstruction`\\ s
@@ -387,10 +1266,10 @@ class QuantumCircuit:
387
1266
  return
388
1267
  if isinstance(data_input[0], CircuitInstruction):
389
1268
  for instruction in data_input:
390
- self.append(instruction)
1269
+ self.append(instruction, copy=False)
391
1270
  else:
392
1271
  for instruction, qargs, cargs in data_input:
393
- self.append(instruction, qargs, cargs)
1272
+ self.append(instruction, qargs, cargs, copy=False)
394
1273
 
395
1274
  @property
396
1275
  def op_start_times(self) -> list[int]:
@@ -497,7 +1376,7 @@ class QuantumCircuit:
497
1376
  cls = self.__class__
498
1377
  result = cls.__new__(cls)
499
1378
  for k in self.__dict__.keys() - {"_data", "_builder_api"}:
500
- setattr(result, k, copy.deepcopy(self.__dict__[k], memo))
1379
+ setattr(result, k, _copy.deepcopy(self.__dict__[k], memo))
501
1380
 
502
1381
  result._builder_api = _OuterCircuitScopeInterface(result)
503
1382
 
@@ -505,10 +1384,10 @@ class QuantumCircuit:
505
1384
  # like we would when pickling.
506
1385
  result._data = self._data.copy()
507
1386
  result._data.replace_bits(
508
- qubits=copy.deepcopy(self._data.qubits, memo),
509
- clbits=copy.deepcopy(self._data.clbits, memo),
1387
+ qubits=_copy.deepcopy(self._data.qubits, memo),
1388
+ clbits=_copy.deepcopy(self._data.clbits, memo),
510
1389
  )
511
- result._data.map_ops(lambda op: copy.deepcopy(op, memo))
1390
+ result._data.map_ops(lambda op: _copy.deepcopy(op, memo))
512
1391
  return result
513
1392
 
514
1393
  @classmethod
@@ -583,9 +1462,7 @@ class QuantumCircuit:
583
1462
  q_1: ┤ RX(1.57) ├─────
584
1463
  └──────────┘
585
1464
  """
586
- reverse_circ = QuantumCircuit(
587
- self.qubits, self.clbits, *self.qregs, *self.cregs, name=self.name + "_reverse"
588
- )
1465
+ reverse_circ = self.copy_empty_like(self.name + "_reverse")
589
1466
 
590
1467
  for instruction in reversed(self.data):
591
1468
  reverse_circ._append(instruction.replace(operation=instruction.operation.reverse_ops()))
@@ -739,26 +1616,38 @@ class QuantumCircuit:
739
1616
 
740
1617
  return repeated_circ
741
1618
 
742
- def power(self, power: float, matrix_power: bool = False) -> "QuantumCircuit":
1619
+ def power(
1620
+ self, power: float, matrix_power: bool = False, annotated: bool = False
1621
+ ) -> "QuantumCircuit":
743
1622
  """Raise this circuit to the power of ``power``.
744
1623
 
745
- If ``power`` is a positive integer and ``matrix_power`` is ``False``, this implementation
746
- defaults to calling ``repeat``. Otherwise, if the circuit is unitary, the matrix is
747
- computed to calculate the matrix power.
1624
+ If ``power`` is a positive integer and both ``matrix_power`` and ``annotated``
1625
+ are ``False``, this implementation defaults to calling ``repeat``. Otherwise,
1626
+ the circuit is converted into a gate, and a new circuit, containing this gate
1627
+ raised to the given power, is returned. The gate raised to the given power is
1628
+ implemented either as a unitary gate if ``annotated`` is ``False`` or as an
1629
+ annotated operation if ``annotated`` is ``True``.
748
1630
 
749
1631
  Args:
750
1632
  power (float): The power to raise this circuit to.
751
- matrix_power (bool): If True, the circuit is converted to a matrix and then the
752
- matrix power is computed. If False, and ``power`` is a positive integer,
753
- the implementation defaults to ``repeat``.
1633
+ matrix_power (bool): indicates whether the inner power gate can be implemented
1634
+ as a unitary gate.
1635
+ annotated (bool): indicates whether the inner power gate can be implemented
1636
+ as an annotated operation.
754
1637
 
755
1638
  Raises:
756
- CircuitError: If the circuit needs to be converted to a gate but it is not unitary.
1639
+ CircuitError: If the circuit needs to be converted to a unitary gate, but is
1640
+ not unitary.
757
1641
 
758
1642
  Returns:
759
1643
  QuantumCircuit: A circuit implementing this circuit raised to the power of ``power``.
760
1644
  """
761
- if power >= 0 and isinstance(power, (int, np.integer)) and not matrix_power:
1645
+ if (
1646
+ power >= 0
1647
+ and isinstance(power, (int, np.integer))
1648
+ and not matrix_power
1649
+ and not annotated
1650
+ ):
762
1651
  return self.repeat(power)
763
1652
 
764
1653
  # attempt conversion to gate
@@ -774,12 +1663,12 @@ class QuantumCircuit:
774
1663
  except QiskitError as ex:
775
1664
  raise CircuitError(
776
1665
  "The circuit contains non-unitary operations and cannot be "
777
- "controlled. Note that no qiskit.circuit.Instruction objects may "
778
- "be in the circuit for this operation."
1666
+ "raised to a power. Note that no qiskit.circuit.Instruction "
1667
+ "objects may be in the circuit for this operation."
779
1668
  ) from ex
780
1669
 
781
1670
  power_circuit = QuantumCircuit(self.qubits, self.clbits, *self.qregs, *self.cregs)
782
- power_circuit.append(gate.power(power), list(range(gate.num_qubits)))
1671
+ power_circuit.append(gate.power(power, annotated=annotated), list(range(gate.num_qubits)))
783
1672
  return power_circuit
784
1673
 
785
1674
  def control(
@@ -831,10 +1720,36 @@ class QuantumCircuit:
831
1720
  front: bool = False,
832
1721
  inplace: bool = False,
833
1722
  wrap: bool = False,
1723
+ *,
1724
+ copy: bool = True,
1725
+ var_remap: Mapping[str | expr.Var, str | expr.Var] | None = None,
1726
+ inline_captures: bool = False,
834
1727
  ) -> Optional["QuantumCircuit"]:
835
- """Compose circuit with ``other`` circuit or instruction, optionally permuting wires.
1728
+ """Apply the instructions from one circuit onto specified qubits and/or clbits on another.
1729
+
1730
+ .. note::
1731
+
1732
+ By default, this creates a new circuit object, leaving ``self`` untouched. For most
1733
+ uses of this function, it is far more efficient to set ``inplace=True`` and modify the
1734
+ base circuit in-place.
836
1735
 
837
- ``other`` can be narrower or of equal width to ``self``.
1736
+ When dealing with realtime variables (:class:`.expr.Var` instances), there are two principal
1737
+ strategies for using :meth:`compose`:
1738
+
1739
+ 1. The ``other`` circuit is treated as entirely additive, including its variables. The
1740
+ variables in ``other`` must be entirely distinct from those in ``self`` (use
1741
+ ``var_remap`` to help with this), and all variables in ``other`` will be declared anew in
1742
+ the output with matching input/capture/local scoping to how they are in ``other``. This
1743
+ is generally what you want if you're joining two unrelated circuits.
1744
+
1745
+ 2. The ``other`` circuit was created as an exact extension to ``self`` to be inlined onto
1746
+ it, including acting on the existing variables in their states at the end of ``self``.
1747
+ In this case, ``other`` should be created with all these variables to be inlined declared
1748
+ as "captures", and then you can use ``inline_captures=True`` in this method to link them.
1749
+ This is generally what you want if you're building up a circuit by defining layers
1750
+ on-the-fly, or rebuilding a circuit using layers taken from itself. You might find the
1751
+ ``vars_mode="captures"`` argument to :meth:`copy_empty_like` useful to create each
1752
+ layer's base, in this case.
838
1753
 
839
1754
  Args:
840
1755
  other (qiskit.circuit.Instruction or QuantumCircuit):
@@ -845,8 +1760,35 @@ class QuantumCircuit:
845
1760
  front (bool): If True, front composition will be performed. This is not possible within
846
1761
  control-flow builder context managers.
847
1762
  inplace (bool): If True, modify the object. Otherwise return composed circuit.
1763
+ copy (bool): If ``True`` (the default), then the input is treated as shared, and any
1764
+ contained instructions will be copied, if they might need to be mutated in the
1765
+ future. You can set this to ``False`` if the input should be considered owned by
1766
+ the base circuit, in order to avoid unnecessary copies; in this case, it is not
1767
+ valid to use ``other`` afterwards, and some instructions may have been mutated in
1768
+ place.
1769
+ var_remap (Mapping): mapping to use to rewrite :class:`.expr.Var` nodes in ``other`` as
1770
+ they are inlined into ``self``. This can be used to avoid naming conflicts.
1771
+
1772
+ Both keys and values can be given as strings or direct :class:`.expr.Var` instances.
1773
+ If a key is a string, it matches any :class:`~.expr.Var` with the same name. If a
1774
+ value is a string, whenever a new key matches a it, a new :class:`~.expr.Var` is
1775
+ created with the correct type. If a value is a :class:`~.expr.Var`, its
1776
+ :class:`~.expr.Expr.type` must exactly match that of the variable it is replacing.
1777
+ inline_captures (bool): if ``True``, then all "captured" :class:`~.expr.Var` nodes in
1778
+ the ``other`` :class:`.QuantumCircuit` are assumed to refer to variables already
1779
+ declared in ``self`` (as any input/capture/local type), and the uses in ``other``
1780
+ will apply to the existing variables. If you want to build up a layer for an
1781
+ existing circuit to use with :meth:`compose`, you might find the
1782
+ ``vars_mode="captures"`` argument to :meth:`copy_empty_like` useful. Any remapping
1783
+ in ``vars_remap`` occurs before evaluating this variable inlining.
1784
+
1785
+ If this is ``False`` (the default), then all variables in ``other`` will be required
1786
+ to be distinct from those in ``self``, and new declarations will be made for them.
848
1787
  wrap (bool): If True, wraps the other circuit into a gate (or instruction, depending on
849
1788
  whether it contains only unitary instructions) before composing it onto self.
1789
+ Rather than using this option, it is almost always better to manually control this
1790
+ yourself by using :meth:`to_instruction` or :meth:`to_gate`, and then call
1791
+ :meth:`append`.
850
1792
 
851
1793
  Returns:
852
1794
  QuantumCircuit: the composed circuit (returns None if inplace==True).
@@ -903,6 +1845,31 @@ class QuantumCircuit:
903
1845
  # error that the user might want to correct in an interactive session.
904
1846
  dest = self if inplace else self.copy()
905
1847
 
1848
+ var_remap = {} if var_remap is None else var_remap
1849
+
1850
+ # This doesn't use `functools.cache` so we can access it during the variable remapping of
1851
+ # instructions. We cache all replacement lookups for a) speed and b) to ensure that
1852
+ # the same variable _always_ maps to the same replacement even if it's used in different
1853
+ # places in the recursion tree (such as being a captured variable).
1854
+ def replace_var(var: expr.Var, cache: Mapping[expr.Var, expr.Var]) -> expr.Var:
1855
+ # This is closing over an argument to `compose`.
1856
+ nonlocal var_remap
1857
+
1858
+ if out := cache.get(var):
1859
+ return out
1860
+ if (replacement := var_remap.get(var)) or (replacement := var_remap.get(var.name)):
1861
+ if isinstance(replacement, str):
1862
+ replacement = expr.Var.new(replacement, var.type)
1863
+ if replacement.type != var.type:
1864
+ raise CircuitError(
1865
+ f"mismatched types in replacement for '{var.name}':"
1866
+ f" '{var.type}' cannot become '{replacement.type}'"
1867
+ )
1868
+ else:
1869
+ replacement = var
1870
+ cache[var] = replacement
1871
+ return replacement
1872
+
906
1873
  # As a special case, allow composing some clbits onto no clbits - normally the destination
907
1874
  # has to be strictly larger. This allows composing final measurements onto unitary circuits.
908
1875
  if isinstance(other, QuantumCircuit):
@@ -931,11 +1898,11 @@ class QuantumCircuit:
931
1898
  # Need to keep a reference to the data for use after we've emptied it.
932
1899
  old_data = dest._data.copy()
933
1900
  dest.clear()
934
- dest.append(other, qubits, clbits)
1901
+ dest.append(other, qubits, clbits, copy=copy)
935
1902
  for instruction in old_data:
936
1903
  dest._append(instruction)
937
1904
  else:
938
- dest.append(other, qargs=qubits, cargs=clbits)
1905
+ dest.append(other, qargs=qubits, cargs=clbits, copy=copy)
939
1906
  return None if inplace else dest
940
1907
 
941
1908
  if other.num_qubits > dest.num_qubits or other.num_clbits > dest.num_clbits:
@@ -986,37 +1953,100 @@ class QuantumCircuit:
986
1953
  dest.unit = "dt"
987
1954
  dest.global_phase += other.global_phase
988
1955
 
989
- if not other.data:
990
- # Nothing left to do. Plus, accessing 'data' here is necessary
991
- # to trigger any lazy building since we now access '_data'
992
- # directly.
993
- return None if inplace else dest
1956
+ # This is required to trigger data builds if the `other` is an unbuilt `BlueprintCircuit`,
1957
+ # so we can the access the complete `CircuitData` object at `_data`.
1958
+ _ = other.data
994
1959
 
995
- variable_mapper = _classical_resource_map.VariableMapper(
996
- dest.cregs, edge_map, dest.add_register
997
- )
1960
+ def copy_with_remapping(
1961
+ source, dest, bit_map, var_map, inline_captures, new_qubits=None, new_clbits=None
1962
+ ):
1963
+ # Copy the instructions from `source` into `dest`, remapping variables in instructions
1964
+ # according to `var_map`. If `new_qubits` or `new_clbits` are given, the qubits and
1965
+ # clbits of the source instruction are remapped to those as well.
1966
+ for var in source.iter_input_vars():
1967
+ dest.add_input(replace_var(var, var_map))
1968
+ if inline_captures:
1969
+ for var in source.iter_captured_vars():
1970
+ replacement = replace_var(var, var_map)
1971
+ if not dest.has_var(replace_var(var, var_map)):
1972
+ if var is replacement:
1973
+ raise CircuitError(
1974
+ f"Variable '{var}' to be inlined is not in the base circuit."
1975
+ " If you wanted it to be automatically added, use"
1976
+ " `inline_captures=False`."
1977
+ )
1978
+ raise CircuitError(
1979
+ f"Replacement '{replacement}' for variable '{var}' is not in the"
1980
+ " base circuit. Is the replacement correct?"
1981
+ )
1982
+ else:
1983
+ for var in source.iter_captured_vars():
1984
+ dest.add_capture(replace_var(var, var_map))
1985
+ for var in source.iter_declared_vars():
1986
+ dest.add_uninitialized_var(replace_var(var, var_map))
1987
+
1988
+ def recurse_block(block):
1989
+ # Recurse the remapping into a control-flow block. Note that this doesn't remap the
1990
+ # clbits within; the story around nested classical-register-based control-flow
1991
+ # doesn't really work in the current data model, and we hope to replace it with
1992
+ # `Expr`-based control-flow everywhere.
1993
+ new_block = block.copy_empty_like()
1994
+ new_block._vars_input = {}
1995
+ new_block._vars_capture = {}
1996
+ new_block._vars_local = {}
1997
+ # For the recursion, we never want to inline captured variables because we're not
1998
+ # copying onto a base that has variables.
1999
+ copy_with_remapping(block, new_block, bit_map, var_map, inline_captures=False)
2000
+ return new_block
2001
+
2002
+ variable_mapper = _classical_resource_map.VariableMapper(
2003
+ dest.cregs, bit_map, var_map, add_register=dest.add_register
2004
+ )
998
2005
 
999
- def map_vars(op):
1000
- n_op = op.copy()
1001
- if (condition := getattr(n_op, "condition", None)) is not None:
1002
- n_op.condition = variable_mapper.map_condition(condition)
1003
- if isinstance(n_op, SwitchCaseOp):
1004
- n_op.target = variable_mapper.map_target(n_op.target)
1005
- return n_op
2006
+ def map_vars(op):
2007
+ n_op = op
2008
+ is_control_flow = isinstance(n_op, ControlFlowOp)
2009
+ if (
2010
+ not is_control_flow
2011
+ and (condition := getattr(n_op, "condition", None)) is not None
2012
+ ):
2013
+ n_op = n_op.copy() if n_op is op and copy else n_op
2014
+ n_op.condition = variable_mapper.map_condition(condition)
2015
+ elif is_control_flow:
2016
+ n_op = n_op.replace_blocks(recurse_block(block) for block in n_op.blocks)
2017
+ if isinstance(n_op, (IfElseOp, WhileLoopOp)):
2018
+ n_op.condition = variable_mapper.map_condition(n_op.condition)
2019
+ elif isinstance(n_op, SwitchCaseOp):
2020
+ n_op.target = variable_mapper.map_target(n_op.target)
2021
+ elif isinstance(n_op, Store):
2022
+ n_op = Store(
2023
+ variable_mapper.map_expr(n_op.lvalue), variable_mapper.map_expr(n_op.rvalue)
2024
+ )
2025
+ return n_op.copy() if n_op is op and copy else n_op
1006
2026
 
1007
- mapped_instrs: CircuitData = other._data.copy()
1008
- mapped_instrs.replace_bits(qubits=mapped_qubits, clbits=mapped_clbits)
1009
- mapped_instrs.map_ops(map_vars)
2027
+ instructions = source._data.copy()
2028
+ instructions.replace_bits(qubits=new_qubits, clbits=new_clbits)
2029
+ instructions.map_ops(map_vars)
2030
+ dest._current_scope().extend(instructions)
1010
2031
 
1011
2032
  append_existing = None
1012
2033
  if front:
1013
2034
  append_existing = dest._data.copy()
1014
2035
  dest.clear()
1015
-
1016
- circuit_scope = dest._current_scope()
1017
- circuit_scope.extend(mapped_instrs)
2036
+ copy_with_remapping(
2037
+ other,
2038
+ dest,
2039
+ bit_map=edge_map,
2040
+ # The actual `Var: Var` map gets built up from the more freeform user input as we
2041
+ # encounter the variables, since the user might be using string keys to refer to more
2042
+ # than one variable in separated scopes of control-flow operations.
2043
+ var_map={},
2044
+ inline_captures=inline_captures,
2045
+ new_qubits=mapped_qubits,
2046
+ new_clbits=mapped_clbits,
2047
+ )
1018
2048
  if append_existing:
1019
- circuit_scope.extend(append_existing)
2049
+ dest._current_scope().extend(append_existing)
1020
2050
 
1021
2051
  return None if inplace else dest
1022
2052
 
@@ -1112,25 +2142,90 @@ class QuantumCircuit:
1112
2142
 
1113
2143
  @property
1114
2144
  def qubits(self) -> list[Qubit]:
1115
- """
1116
- Returns a list of quantum bits in the order that the registers were added.
1117
- """
2145
+ """A list of :class:`Qubit`\\ s in the order that they were added. You should not mutate
2146
+ this."""
1118
2147
  return self._data.qubits
1119
2148
 
1120
2149
  @property
1121
2150
  def clbits(self) -> list[Clbit]:
1122
- """
1123
- Returns a list of classical bits in the order that the registers were added.
1124
- """
2151
+ """A list of :class:`Clbit`\\ s in the order that they were added. You should not mutate
2152
+ this."""
1125
2153
  return self._data.clbits
1126
2154
 
1127
2155
  @property
1128
2156
  def ancillas(self) -> list[AncillaQubit]:
1129
- """
1130
- Returns a list of ancilla bits in the order that the registers were added.
1131
- """
2157
+ """A list of :class:`AncillaQubit`\\ s in the order that they were added. You should not
2158
+ mutate this."""
1132
2159
  return self._ancillas
1133
2160
 
2161
+ @property
2162
+ def num_vars(self) -> int:
2163
+ """The number of real-time classical variables in the circuit.
2164
+
2165
+ This is the length of the :meth:`iter_vars` iterable."""
2166
+ return self.num_input_vars + self.num_captured_vars + self.num_declared_vars
2167
+
2168
+ @property
2169
+ def num_input_vars(self) -> int:
2170
+ """The number of real-time classical variables in the circuit marked as circuit inputs.
2171
+
2172
+ This is the length of the :meth:`iter_input_vars` iterable. If this is non-zero,
2173
+ :attr:`num_captured_vars` must be zero."""
2174
+ return len(self._vars_input)
2175
+
2176
+ @property
2177
+ def num_captured_vars(self) -> int:
2178
+ """The number of real-time classical variables in the circuit marked as captured from an
2179
+ enclosing scope.
2180
+
2181
+ This is the length of the :meth:`iter_captured_vars` iterable. If this is non-zero,
2182
+ :attr:`num_input_vars` must be zero."""
2183
+ return len(self._vars_capture)
2184
+
2185
+ @property
2186
+ def num_declared_vars(self) -> int:
2187
+ """The number of real-time classical variables in the circuit that are declared by this
2188
+ circuit scope, excluding inputs or captures.
2189
+
2190
+ This is the length of the :meth:`iter_declared_vars` iterable."""
2191
+ return len(self._vars_local)
2192
+
2193
+ def iter_vars(self) -> typing.Iterable[expr.Var]:
2194
+ """Get an iterable over all real-time classical variables in scope within this circuit.
2195
+
2196
+ This method will iterate over all variables in scope. For more fine-grained iterators, see
2197
+ :meth:`iter_declared_vars`, :meth:`iter_input_vars` and :meth:`iter_captured_vars`."""
2198
+ if self._control_flow_scopes:
2199
+ builder = self._control_flow_scopes[-1]
2200
+ return itertools.chain(builder.iter_captured_vars(), builder.iter_local_vars())
2201
+ return itertools.chain(
2202
+ self._vars_input.values(), self._vars_capture.values(), self._vars_local.values()
2203
+ )
2204
+
2205
+ def iter_declared_vars(self) -> typing.Iterable[expr.Var]:
2206
+ """Get an iterable over all real-time classical variables that are declared with automatic
2207
+ storage duration in this scope. This excludes input variables (see :meth:`iter_input_vars`)
2208
+ and captured variables (see :meth:`iter_captured_vars`)."""
2209
+ if self._control_flow_scopes:
2210
+ return self._control_flow_scopes[-1].iter_local_vars()
2211
+ return self._vars_local.values()
2212
+
2213
+ def iter_input_vars(self) -> typing.Iterable[expr.Var]:
2214
+ """Get an iterable over all real-time classical variables that are declared as inputs to
2215
+ this circuit scope. This excludes locally declared variables (see
2216
+ :meth:`iter_declared_vars`) and captured variables (see :meth:`iter_captured_vars`)."""
2217
+ if self._control_flow_scopes:
2218
+ return ()
2219
+ return self._vars_input.values()
2220
+
2221
+ def iter_captured_vars(self) -> typing.Iterable[expr.Var]:
2222
+ """Get an iterable over all real-time classical variables that are captured by this circuit
2223
+ scope from a containing scope. This excludes input variables (see :meth:`iter_input_vars`)
2224
+ and locally declared variables (see :meth:`iter_declared_vars`)."""
2225
+ if self._control_flow_scopes:
2226
+ return self._control_flow_scopes[-1].iter_captured_vars()
2227
+ return self._vars_capture.values()
2228
+
1134
2229
  def __and__(self, rhs: "QuantumCircuit") -> "QuantumCircuit":
1135
2230
  """Overload & to implement self.compose."""
1136
2231
  return self.compose(rhs)
@@ -1206,6 +2301,8 @@ class QuantumCircuit:
1206
2301
  instruction: Operation | CircuitInstruction,
1207
2302
  qargs: Sequence[QubitSpecifier] | None = None,
1208
2303
  cargs: Sequence[ClbitSpecifier] | None = None,
2304
+ *,
2305
+ copy: bool = True,
1209
2306
  ) -> InstructionSet:
1210
2307
  """Append one or more instructions to the end of the circuit, modifying the circuit in
1211
2308
  place.
@@ -1223,6 +2320,11 @@ class QuantumCircuit:
1223
2320
  :class:`.CircuitInstruction` with all its context.
1224
2321
  qargs: specifiers of the :class:`~.circuit.Qubit`\\ s to attach instruction to.
1225
2322
  cargs: specifiers of the :class:`.Clbit`\\ s to attach instruction to.
2323
+ copy: if ``True`` (the default), then the incoming ``instruction`` is copied before
2324
+ adding it to the circuit if it contains symbolic parameters, so it can be safely
2325
+ mutated without affecting other circuits the same instruction might be in. If you
2326
+ are sure this instruction will not be in other circuits, you can set this ``False``
2327
+ for a small speedup.
1226
2328
 
1227
2329
  Returns:
1228
2330
  qiskit.circuit.InstructionSet: a handle to the :class:`.CircuitInstruction`\\ s that
@@ -1261,11 +2363,25 @@ class QuantumCircuit:
1261
2363
  if params := getattr(operation, "params", ()):
1262
2364
  is_parameter = False
1263
2365
  for param in params:
1264
- is_parameter = is_parameter or isinstance(param, Parameter)
2366
+ is_parameter = is_parameter or isinstance(param, ParameterExpression)
1265
2367
  if isinstance(param, expr.Expr):
1266
2368
  param = _validate_expr(circuit_scope, param)
1267
- if is_parameter:
1268
- operation = copy.deepcopy(operation)
2369
+ if copy and is_parameter:
2370
+ operation = _copy.deepcopy(operation)
2371
+ if isinstance(operation, ControlFlowOp):
2372
+ # Verify that any variable bindings are valid. Control-flow ops are already enforced
2373
+ # by the class not to contain 'input' variables.
2374
+ if bad_captures := {
2375
+ var
2376
+ for var in itertools.chain.from_iterable(
2377
+ block.iter_captured_vars() for block in operation.blocks
2378
+ )
2379
+ if not self.has_var(var)
2380
+ }:
2381
+ raise CircuitError(
2382
+ f"Control-flow op attempts to capture '{bad_captures}'"
2383
+ " which are not in this circuit"
2384
+ )
1269
2385
 
1270
2386
  expanded_qargs = [self.qbit_argument_conversion(qarg) for qarg in qargs or []]
1271
2387
  expanded_cargs = [self.cbit_argument_conversion(carg) for carg in cargs or []]
@@ -1286,33 +2402,31 @@ class QuantumCircuit:
1286
2402
 
1287
2403
  # Preferred new style.
1288
2404
  @typing.overload
1289
- def _append(
1290
- self, instruction: CircuitInstruction, _qargs: None = None, _cargs: None = None
1291
- ) -> CircuitInstruction: ...
2405
+ def _append(self, instruction: CircuitInstruction) -> CircuitInstruction: ...
1292
2406
 
1293
2407
  # To-be-deprecated old style.
1294
2408
  @typing.overload
1295
2409
  def _append(
1296
2410
  self,
1297
- operation: Operation,
2411
+ instruction: Operation,
1298
2412
  qargs: Sequence[Qubit],
1299
2413
  cargs: Sequence[Clbit],
1300
2414
  ) -> Operation: ...
1301
2415
 
1302
- def _append(
1303
- self,
1304
- instruction: CircuitInstruction | Instruction,
1305
- qargs: Sequence[Qubit] | None = None,
1306
- cargs: Sequence[Clbit] | None = None,
1307
- ):
2416
+ def _append(self, instruction, qargs=(), cargs=()):
1308
2417
  """Append an instruction to the end of the circuit, modifying the circuit in place.
1309
2418
 
1310
2419
  .. warning::
1311
2420
 
1312
2421
  This is an internal fast-path function, and it is the responsibility of the caller to
1313
2422
  ensure that all the arguments are valid; there is no error checking here. In
1314
- particular, all the qubits and clbits must already exist in the circuit and there can be
1315
- no duplicates in the list.
2423
+ particular:
2424
+
2425
+ * all the qubits and clbits must already exist in the circuit and there can be no
2426
+ duplicates in the list.
2427
+ * any control-flow operations or classically conditioned instructions must act only on
2428
+ variables present in the circuit.
2429
+ * the circuit must not be within a control-flow builder context.
1316
2430
 
1317
2431
  .. note::
1318
2432
 
@@ -1325,12 +2439,18 @@ class QuantumCircuit:
1325
2439
  constructs of the control-flow builder interface.
1326
2440
 
1327
2441
  Args:
1328
- instruction: Operation instance to append
1329
- qargs: Qubits to attach the instruction to.
1330
- cargs: Clbits to attach the instruction to.
2442
+ instruction: A complete well-formed :class:`.CircuitInstruction` of the operation and
2443
+ its context to be added.
2444
+
2445
+ In the legacy compatibility form, this can be a bare :class:`.Operation`, in which
2446
+ case ``qargs`` and ``cargs`` must be explicitly given.
2447
+ qargs: Legacy argument for qubits to attach the bare :class:`.Operation` to. Ignored if
2448
+ the first argument is in the preferential :class:`.CircuitInstruction` form.
2449
+ cargs: Legacy argument for clbits to attach the bare :class:`.Operation` to. Ignored if
2450
+ the first argument is in the preferential :class:`.CircuitInstruction` form.
1331
2451
 
1332
2452
  Returns:
1333
- Operation: a handle to the instruction that was just added
2453
+ CircuitInstruction: a handle to the instruction that was just added.
1334
2454
 
1335
2455
  :meta public:
1336
2456
  """
@@ -1412,6 +2532,11 @@ class QuantumCircuit:
1412
2532
 
1413
2533
  assert qc.get_parameter("my_param", None) is my_param
1414
2534
  assert qc.get_parameter("unknown_param", None) is None
2535
+
2536
+ See also:
2537
+ :meth:`get_var`
2538
+ A similar method, but for :class:`.expr.Var` run-time variables instead of
2539
+ :class:`.Parameter` compile-time parameters.
1415
2540
  """
1416
2541
  if (parameter := self._parameter_table.parameter_from_name(name, None)) is None:
1417
2542
  if default is Ellipsis:
@@ -1433,11 +2558,314 @@ class QuantumCircuit:
1433
2558
  See also:
1434
2559
  :meth:`QuantumCircuit.get_parameter`
1435
2560
  Retrieve the :class:`.Parameter` instance from this circuit by name.
2561
+ :meth:`QuantumCircuit.has_var`
2562
+ A similar method to this, but for run-time :class:`.expr.Var` variables instead of
2563
+ compile-time :class:`.Parameter`\\ s.
1436
2564
  """
1437
2565
  if isinstance(name_or_param, str):
1438
2566
  return self.get_parameter(name_or_param, None) is not None
1439
2567
  return self.get_parameter(name_or_param.name) == name_or_param
1440
2568
 
2569
+ @typing.overload
2570
+ def get_var(self, name: str, default: T) -> Union[expr.Var, T]: ...
2571
+
2572
+ # The builtin `types` module has `EllipsisType`, but only from 3.10+!
2573
+ @typing.overload
2574
+ def get_var(self, name: str, default: type(...) = ...) -> expr.Var: ...
2575
+
2576
+ # We use a _literal_ `Ellipsis` as the marker value to leave `None` available as a default.
2577
+ def get_var(self, name: str, default: typing.Any = ...):
2578
+ """Retrieve a variable that is accessible in this circuit scope by name.
2579
+
2580
+ Args:
2581
+ name: the name of the variable to retrieve.
2582
+ default: if given, this value will be returned if the variable is not present. If it
2583
+ is not given, a :exc:`KeyError` is raised instead.
2584
+
2585
+ Returns:
2586
+ The corresponding variable.
2587
+
2588
+ Raises:
2589
+ KeyError: if no default is given, but the variable does not exist.
2590
+
2591
+ Examples:
2592
+ Retrieve a variable by name from a circuit::
2593
+
2594
+ from qiskit.circuit import QuantumCircuit
2595
+
2596
+ # Create a circuit and create a variable in it.
2597
+ qc = QuantumCircuit()
2598
+ my_var = qc.add_var("my_var", False)
2599
+
2600
+ # We can use 'my_var' as a variable, but let's say we've lost the Python object and
2601
+ # need to retrieve it.
2602
+ my_var_again = qc.get_var("my_var")
2603
+
2604
+ assert my_var is my_var_again
2605
+
2606
+ Get a variable from a circuit by name, returning some default if it is not present::
2607
+
2608
+ assert qc.get_var("my_var", None) is my_var
2609
+ assert qc.get_var("unknown_variable", None) is None
2610
+
2611
+ See also:
2612
+ :meth:`get_parameter`
2613
+ A similar method, but for :class:`.Parameter` compile-time parameters instead of
2614
+ :class:`.expr.Var` run-time variables.
2615
+ """
2616
+ if (out := self._current_scope().get_var(name)) is not None:
2617
+ return out
2618
+ if default is Ellipsis:
2619
+ raise KeyError(f"no variable named '{name}' is present")
2620
+ return default
2621
+
2622
+ def has_var(self, name_or_var: str | expr.Var, /) -> bool:
2623
+ """Check whether a variable is accessible in this scope.
2624
+
2625
+ Args:
2626
+ name_or_var: the variable, or name of a variable to check. If this is a
2627
+ :class:`.expr.Var` node, the variable must be exactly the given one for this
2628
+ function to return ``True``.
2629
+
2630
+ Returns:
2631
+ whether a matching variable is accessible.
2632
+
2633
+ See also:
2634
+ :meth:`QuantumCircuit.get_var`
2635
+ Retrieve the :class:`.expr.Var` instance from this circuit by name.
2636
+ :meth:`QuantumCircuit.has_parameter`
2637
+ A similar method to this, but for compile-time :class:`.Parameter`\\ s instead of
2638
+ run-time :class:`.expr.Var` variables.
2639
+ """
2640
+ if isinstance(name_or_var, str):
2641
+ return self.get_var(name_or_var, None) is not None
2642
+ return self.get_var(name_or_var.name, None) == name_or_var
2643
+
2644
+ def _prepare_new_var(
2645
+ self, name_or_var: str | expr.Var, type_: types.Type | None, /
2646
+ ) -> expr.Var:
2647
+ """The common logic for preparing and validating a new :class:`~.expr.Var` for the circuit.
2648
+
2649
+ The given ``type_`` can be ``None`` if the variable specifier is already a :class:`.Var`,
2650
+ and must be a :class:`~.types.Type` if it is a string. The argument is ignored if the given
2651
+ first argument is a :class:`.Var` already.
2652
+
2653
+ Returns the validated variable, which is guaranteed to be safe to add to the circuit."""
2654
+ if isinstance(name_or_var, str):
2655
+ if type_ is None:
2656
+ raise CircuitError("the type must be known when creating a 'Var' from a string")
2657
+ var = expr.Var.new(name_or_var, type_)
2658
+ else:
2659
+ var = name_or_var
2660
+ if not var.standalone:
2661
+ raise CircuitError(
2662
+ "cannot add variables that wrap `Clbit` or `ClassicalRegister` instances."
2663
+ " Use `add_bits` or `add_register` as appropriate."
2664
+ )
2665
+
2666
+ # The `var` is guaranteed to have a name because we already excluded the cases where it's
2667
+ # wrapping a bit/register.
2668
+ if (previous := self.get_var(var.name, default=None)) is not None:
2669
+ if previous == var:
2670
+ raise CircuitError(f"'{var}' is already present in the circuit")
2671
+ raise CircuitError(f"cannot add '{var}' as its name shadows the existing '{previous}'")
2672
+ return var
2673
+
2674
+ def add_var(self, name_or_var: str | expr.Var, /, initial: typing.Any) -> expr.Var:
2675
+ """Add a classical variable with automatic storage and scope to this circuit.
2676
+
2677
+ The variable is considered to have been "declared" at the beginning of the circuit, but it
2678
+ only becomes initialized at the point of the circuit that you call this method, so it can
2679
+ depend on variables defined before it.
2680
+
2681
+ Args:
2682
+ name_or_var: either a string of the variable name, or an existing instance of
2683
+ :class:`~.expr.Var` to re-use. Variables cannot shadow names that are already in
2684
+ use within the circuit.
2685
+ initial: the value to initialize this variable with. If the first argument was given
2686
+ as a string name, the type of the resulting variable is inferred from the initial
2687
+ expression; to control this more manually, either use :meth:`.Var.new` to manually
2688
+ construct a new variable with the desired type, or use :func:`.expr.cast` to cast
2689
+ the initializer to the desired type.
2690
+
2691
+ This must be either a :class:`~.expr.Expr` node, or a value that can be lifted to
2692
+ one using :class:`.expr.lift`.
2693
+
2694
+ Returns:
2695
+ The created variable. If a :class:`~.expr.Var` instance was given, the exact same
2696
+ object will be returned.
2697
+
2698
+ Raises:
2699
+ CircuitError: if the variable cannot be created due to shadowing an existing variable.
2700
+
2701
+ Examples:
2702
+ Define a new variable given just a name and an initializer expression::
2703
+
2704
+ from qiskit.circuit import QuantumCircuit
2705
+
2706
+ qc = QuantumCircuit(2)
2707
+ my_var = qc.add_var("my_var", False)
2708
+
2709
+ Reuse a variable that may have been taken from a related circuit, or otherwise
2710
+ constructed manually, and initialize it to some more complicated expression::
2711
+
2712
+ from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
2713
+ from qiskit.circuit.classical import expr, types
2714
+
2715
+ my_var = expr.Var.new("my_var", types.Uint(8))
2716
+
2717
+ cr1 = ClassicalRegister(8, "cr1")
2718
+ cr2 = ClassicalRegister(8, "cr2")
2719
+ qc = QuantumCircuit(QuantumRegister(8), cr1, cr2)
2720
+
2721
+ # Get some measurement results into each register.
2722
+ qc.h(0)
2723
+ for i in range(1, 8):
2724
+ qc.cx(0, i)
2725
+ qc.measure(range(8), cr1)
2726
+
2727
+ qc.reset(range(8))
2728
+ qc.h(0)
2729
+ for i in range(1, 8):
2730
+ qc.cx(0, i)
2731
+ qc.measure(range(8), cr2)
2732
+
2733
+ # Now when we add the variable, it is initialized using the real-time state of the
2734
+ # two classical registers we measured into above.
2735
+ qc.add_var(my_var, expr.bit_and(cr1, cr2))
2736
+ """
2737
+ # Validate the initialiser first to catch cases where the variable to be declared is being
2738
+ # used in the initialiser.
2739
+ circuit_scope = self._current_scope()
2740
+ # Convenience method to widen Python integer literals to the right width during the initial
2741
+ # lift, if the type is already known via the variable.
2742
+ if (
2743
+ isinstance(name_or_var, expr.Var)
2744
+ and name_or_var.type.kind is types.Uint
2745
+ and isinstance(initial, int)
2746
+ and not isinstance(initial, bool)
2747
+ ):
2748
+ coerce_type = name_or_var.type
2749
+ else:
2750
+ coerce_type = None
2751
+ initial = _validate_expr(circuit_scope, expr.lift(initial, coerce_type))
2752
+ if isinstance(name_or_var, str):
2753
+ var = expr.Var.new(name_or_var, initial.type)
2754
+ elif not name_or_var.standalone:
2755
+ raise CircuitError(
2756
+ "cannot add variables that wrap `Clbit` or `ClassicalRegister` instances."
2757
+ )
2758
+ else:
2759
+ var = name_or_var
2760
+ circuit_scope.add_uninitialized_var(var)
2761
+ try:
2762
+ # Store is responsible for ensuring the type safety of the initialisation.
2763
+ store = Store(var, initial)
2764
+ except CircuitError:
2765
+ circuit_scope.remove_var(var)
2766
+ raise
2767
+ circuit_scope.append(CircuitInstruction(store, (), ()))
2768
+ return var
2769
+
2770
+ def add_uninitialized_var(self, var: expr.Var, /):
2771
+ """Add a variable with no initializer.
2772
+
2773
+ In most cases, you should use :meth:`add_var` to initialize the variable. To use this
2774
+ function, you must already hold a :class:`~.expr.Var` instance, as the use of the function
2775
+ typically only makes sense in copying contexts.
2776
+
2777
+ .. warning::
2778
+
2779
+ Qiskit makes no assertions about what an uninitialized variable will evaluate to at
2780
+ runtime, and some hardware may reject this as an error.
2781
+
2782
+ You should treat this function with caution, and as a low-level primitive that is useful
2783
+ only in special cases of programmatically rebuilding two like circuits.
2784
+
2785
+ Args:
2786
+ var: the variable to add.
2787
+ """
2788
+ # This function is deliberately meant to be a bit harder to find, to have a long descriptive
2789
+ # name, and to be a bit less ergonomic than `add_var` (i.e. not allowing the (name, type)
2790
+ # overload) to discourage people from using it when they should use `add_var`.
2791
+ #
2792
+ # This function exists so that there is a method to emulate `copy_empty_like`'s behaviour of
2793
+ # adding uninitialised variables, which there's no obvious way around. We need to be sure
2794
+ # that _some_ sort of handling of uninitialised variables is taken into account in our
2795
+ # structures, so that doesn't become a huge edge case, even though we make no assertions
2796
+ # about the _meaning_ if such an expression was run on hardware.
2797
+ if self._control_flow_scopes:
2798
+ raise CircuitError("cannot add an uninitialized variable in a control-flow scope")
2799
+ if not var.standalone:
2800
+ raise CircuitError("cannot add a variable wrapping a bit or register to a circuit")
2801
+ self._builder_api.add_uninitialized_var(var)
2802
+
2803
+ def add_capture(self, var: expr.Var):
2804
+ """Add a variable to the circuit that it should capture from a scope it will be contained
2805
+ within.
2806
+
2807
+ This method requires a :class:`~.expr.Var` node to enforce that you've got a handle to one,
2808
+ because you will need to declare the same variable using the same object into the outer
2809
+ circuit.
2810
+
2811
+ This is a low-level method, which is only really useful if you are manually constructing
2812
+ control-flow operations. You typically will not need to call this method, assuming you
2813
+ are using the builder interface for control-flow scopes (``with`` context-manager statements
2814
+ for :meth:`if_test` and the other scoping constructs). The builder interface will
2815
+ automatically make the inner scopes closures on your behalf by capturing any variables that
2816
+ are used within them.
2817
+
2818
+ Args:
2819
+ var: the variable to capture from an enclosing scope.
2820
+
2821
+ Raises:
2822
+ CircuitError: if the variable cannot be created due to shadowing an existing variable.
2823
+ """
2824
+ if self._control_flow_scopes:
2825
+ # Allow manual capturing. Not sure why it'd be useful, but there's a clear expected
2826
+ # behaviour here.
2827
+ self._control_flow_scopes[-1].use_var(var)
2828
+ return
2829
+ if self._vars_input:
2830
+ raise CircuitError(
2831
+ "circuits with input variables cannot be enclosed, so cannot be closures"
2832
+ )
2833
+ self._vars_capture[var.name] = self._prepare_new_var(var, None)
2834
+
2835
+ @typing.overload
2836
+ def add_input(self, name_or_var: str, type_: types.Type, /) -> expr.Var: ...
2837
+
2838
+ @typing.overload
2839
+ def add_input(self, name_or_var: expr.Var, type_: None = None, /) -> expr.Var: ...
2840
+
2841
+ def add_input( # pylint: disable=missing-raises-doc
2842
+ self, name_or_var: str | expr.Var, type_: types.Type | None = None, /
2843
+ ) -> expr.Var:
2844
+ """Register a variable as an input to the circuit.
2845
+
2846
+ Args:
2847
+ name_or_var: either a string name, or an existing :class:`~.expr.Var` node to use as the
2848
+ input variable.
2849
+ type_: if the name is given as a string, then this must be a :class:`~.types.Type` to
2850
+ use for the variable. If the variable is given as an existing :class:`~.expr.Var`,
2851
+ then this must not be given, and will instead be read from the object itself.
2852
+
2853
+ Returns:
2854
+ the variable created, or the same variable as was passed in.
2855
+
2856
+ Raises:
2857
+ CircuitError: if the variable cannot be created due to shadowing an existing variable.
2858
+ """
2859
+ if self._control_flow_scopes:
2860
+ raise CircuitError("cannot add an input variable in a control-flow scope")
2861
+ if self._vars_capture:
2862
+ raise CircuitError("circuits to be enclosed with captures cannot have input variables")
2863
+ if isinstance(name_or_var, expr.Var) and type_ is not None:
2864
+ raise ValueError("cannot give an explicit type with an existing Var")
2865
+ var = self._prepare_new_var(name_or_var, type_)
2866
+ self._vars_input[var.name] = var
2867
+ return var
2868
+
1441
2869
  def add_register(self, *regs: Register | int | Sequence[Bit]) -> None:
1442
2870
  """Add registers."""
1443
2871
  if not regs:
@@ -1535,24 +2963,52 @@ class QuantumCircuit:
1535
2963
  def find_bit(self, bit: Bit) -> BitLocations:
1536
2964
  """Find locations in the circuit which can be used to reference a given :obj:`~Bit`.
1537
2965
 
2966
+ In particular, this function can find the integer index of a qubit, which corresponds to its
2967
+ hardware index for a transpiled circuit.
2968
+
2969
+ .. note::
2970
+ The circuit index of a :class:`.AncillaQubit` will be its index in :attr:`qubits`, not
2971
+ :attr:`ancillas`.
2972
+
1538
2973
  Args:
1539
2974
  bit (Bit): The bit to locate.
1540
2975
 
1541
2976
  Returns:
1542
2977
  namedtuple(int, List[Tuple(Register, int)]): A 2-tuple. The first element (``index``)
1543
- contains the index at which the ``Bit`` can be found (in either
1544
- :obj:`~QuantumCircuit.qubits`, :obj:`~QuantumCircuit.clbits`, depending on its
1545
- type). The second element (``registers``) is a list of ``(register, index)``
1546
- pairs with an entry for each :obj:`~Register` in the circuit which contains the
1547
- :obj:`~Bit` (and the index in the :obj:`~Register` at which it can be found).
1548
-
1549
- Notes:
1550
- The circuit index of an :obj:`~AncillaQubit` will be its index in
1551
- :obj:`~QuantumCircuit.qubits`, not :obj:`~QuantumCircuit.ancillas`.
2978
+ contains the index at which the ``Bit`` can be found (in either
2979
+ :obj:`~QuantumCircuit.qubits`, :obj:`~QuantumCircuit.clbits`, depending on its
2980
+ type). The second element (``registers``) is a list of ``(register, index)``
2981
+ pairs with an entry for each :obj:`~Register` in the circuit which contains the
2982
+ :obj:`~Bit` (and the index in the :obj:`~Register` at which it can be found).
1552
2983
 
1553
2984
  Raises:
1554
2985
  CircuitError: If the supplied :obj:`~Bit` was of an unknown type.
1555
2986
  CircuitError: If the supplied :obj:`~Bit` could not be found on the circuit.
2987
+
2988
+ Examples:
2989
+ Loop through a circuit, getting the qubit and clbit indices of each operation::
2990
+
2991
+ from qiskit.circuit import QuantumCircuit, Qubit
2992
+
2993
+ qc = QuantumCircuit(3, 3)
2994
+ qc.h(0)
2995
+ qc.cx(0, 1)
2996
+ qc.cx(1, 2)
2997
+ qc.measure([0, 1, 2], [0, 1, 2])
2998
+
2999
+ # The `.qubits` and `.clbits` fields are not integers.
3000
+ assert isinstance(qc.data[0].qubits[0], Qubit)
3001
+ # ... but we can use `find_bit` to retrieve them.
3002
+ assert qc.find_bit(qc.data[0].qubits[0]).index == 0
3003
+
3004
+ simple = [
3005
+ (
3006
+ instruction.operation.name,
3007
+ [qc.find_bit(bit).index for bit in instruction.qubits],
3008
+ [qc.find_bit(bit).index for bit in instruction.clbits],
3009
+ )
3010
+ for instruction in qc.data
3011
+ ]
1556
3012
  """
1557
3013
 
1558
3014
  try:
@@ -1578,18 +3034,22 @@ class QuantumCircuit:
1578
3034
  parameter_map: dict[Parameter, ParameterValueType] | None = None,
1579
3035
  label: str | None = None,
1580
3036
  ) -> Instruction:
1581
- """Create an Instruction out of this circuit.
3037
+ """Create an :class:`~.circuit.Instruction` out of this circuit.
3038
+
3039
+ .. seealso::
3040
+ :func:`circuit_to_instruction`
3041
+ The underlying driver of this method.
1582
3042
 
1583
3043
  Args:
1584
- parameter_map(dict): For parameterized circuits, a mapping from
3044
+ parameter_map: For parameterized circuits, a mapping from
1585
3045
  parameters in the circuit to parameters to be used in the
1586
3046
  instruction. If None, existing circuit parameters will also
1587
3047
  parameterize the instruction.
1588
- label (str): Optional gate label.
3048
+ label: Optional gate label.
1589
3049
 
1590
3050
  Returns:
1591
- qiskit.circuit.Instruction: a composite instruction encapsulating this circuit
1592
- (can be decomposed back)
3051
+ qiskit.circuit.Instruction: a composite instruction encapsulating this circuit (can be
3052
+ decomposed back).
1593
3053
  """
1594
3054
  from qiskit.converters.circuit_to_instruction import circuit_to_instruction
1595
3055
 
@@ -1600,18 +3060,21 @@ class QuantumCircuit:
1600
3060
  parameter_map: dict[Parameter, ParameterValueType] | None = None,
1601
3061
  label: str | None = None,
1602
3062
  ) -> Gate:
1603
- """Create a Gate out of this circuit.
3063
+ """Create a :class:`.Gate` out of this circuit. The circuit must act only qubits and
3064
+ contain only unitary operations.
3065
+
3066
+ .. seealso::
3067
+ :func:`circuit_to_gate`
3068
+ The underlying driver of this method.
1604
3069
 
1605
3070
  Args:
1606
- parameter_map(dict): For parameterized circuits, a mapping from
1607
- parameters in the circuit to parameters to be used in the
1608
- gate. If None, existing circuit parameters will also
1609
- parameterize the gate.
1610
- label (str): Optional gate label.
3071
+ parameter_map: For parameterized circuits, a mapping from parameters in the circuit to
3072
+ parameters to be used in the gate. If ``None``, existing circuit parameters will
3073
+ also parameterize the gate.
3074
+ label : Optional gate label.
1611
3075
 
1612
3076
  Returns:
1613
- Gate: a composite gate encapsulating this circuit
1614
- (can be decomposed back)
3077
+ Gate: a composite gate encapsulating this circuit (can be decomposed back).
1615
3078
  """
1616
3079
  from qiskit.converters.circuit_to_gate import circuit_to_gate
1617
3080
 
@@ -1838,25 +3301,36 @@ class QuantumCircuit:
1838
3301
 
1839
3302
  def depth(
1840
3303
  self,
1841
- filter_function: Callable[..., int] = lambda x: not getattr(
3304
+ filter_function: Callable[[CircuitInstruction], bool] = lambda x: not getattr(
1842
3305
  x.operation, "_directive", False
1843
3306
  ),
1844
3307
  ) -> int:
1845
3308
  """Return circuit depth (i.e., length of critical path).
1846
3309
 
1847
3310
  Args:
1848
- filter_function (callable): A function to filter instructions.
1849
- Should take as input a tuple of (Instruction, list(Qubit), list(Clbit)).
1850
- Instructions for which the function returns False are ignored in the
1851
- computation of the circuit depth.
1852
- By default filters out "directives", such as barrier or snapshot.
3311
+ filter_function: A function to decide which instructions count to increase depth.
3312
+ Should take as a single positional input a :class:`CircuitInstruction`.
3313
+ Instructions for which the function returns ``False`` are ignored in the
3314
+ computation of the circuit depth. By default filters out "directives", such as
3315
+ :class:`.Barrier`.
1853
3316
 
1854
3317
  Returns:
1855
3318
  int: Depth of circuit.
1856
3319
 
1857
- Notes:
1858
- The circuit depth and the DAG depth need not be the
1859
- same.
3320
+ Examples:
3321
+ Simple calculation of total circuit depth::
3322
+
3323
+ from qiskit.circuit import QuantumCircuit
3324
+ qc = QuantumCircuit(4)
3325
+ qc.h(0)
3326
+ qc.cx(0, 1)
3327
+ qc.h(2)
3328
+ qc.cx(2, 3)
3329
+ assert qc.depth() == 2
3330
+
3331
+ Modifying the previous example to only calculate the depth of multi-qubit gates::
3332
+
3333
+ assert qc.depth(lambda instr: len(instr.qubits) > 1) == 1
1860
3334
  """
1861
3335
  # Assign each bit in the circuit a unique integer
1862
3336
  # to index into op_stack.
@@ -2064,7 +3538,7 @@ class QuantumCircuit:
2064
3538
  """
2065
3539
  return self.num_unitary_factors()
2066
3540
 
2067
- def copy(self, name: str | None = None) -> "QuantumCircuit":
3541
+ def copy(self, name: str | None = None) -> typing.Self:
2068
3542
  """Copy the circuit.
2069
3543
 
2070
3544
  Args:
@@ -2100,16 +3574,47 @@ class QuantumCircuit:
2100
3574
  )
2101
3575
  return cpy
2102
3576
 
2103
- def copy_empty_like(self, name: str | None = None) -> "QuantumCircuit":
3577
+ def copy_empty_like(
3578
+ self,
3579
+ name: str | None = None,
3580
+ *,
3581
+ vars_mode: Literal["alike", "captures", "drop"] = "alike",
3582
+ ) -> typing.Self:
2104
3583
  """Return a copy of self with the same structure but empty.
2105
3584
 
2106
3585
  That structure includes:
2107
- * name, calibrations and other metadata
2108
- * global phase
2109
- * all the qubits and clbits, including the registers
3586
+
3587
+ * name, calibrations and other metadata
3588
+ * global phase
3589
+ * all the qubits and clbits, including the registers
3590
+ * the realtime variables defined in the circuit, handled according to the ``vars`` keyword
3591
+ argument.
3592
+
3593
+ .. warning::
3594
+
3595
+ If the circuit contains any local variable declarations (those added by the
3596
+ ``declarations`` argument to the circuit constructor, or using :meth:`add_var`), they
3597
+ may be **uninitialized** in the output circuit. You will need to manually add store
3598
+ instructions for them (see :class:`.Store` and :meth:`.QuantumCircuit.store`) to
3599
+ initialize them.
2110
3600
 
2111
3601
  Args:
2112
- name (str): Name for the copied circuit. If None, then the name stays the same.
3602
+ name: Name for the copied circuit. If None, then the name stays the same.
3603
+ vars_mode: The mode to handle realtime variables in.
3604
+
3605
+ alike
3606
+ The variables in the output circuit will have the same declaration semantics as
3607
+ in the original circuit. For example, ``input`` variables in the source will be
3608
+ ``input`` variables in the output circuit.
3609
+
3610
+ captures
3611
+ All variables will be converted to captured variables. This is useful when you
3612
+ are building a new layer for an existing circuit that you will want to
3613
+ :meth:`compose` onto the base, since :meth:`compose` can inline captures onto
3614
+ the base circuit (but not other variables).
3615
+
3616
+ drop
3617
+ The output circuit will have no variables defined.
2113
3618
 
2114
3619
  Returns:
2115
3620
  QuantumCircuit: An empty copy of self.
@@ -2118,7 +3623,7 @@ class QuantumCircuit:
2118
3623
  raise TypeError(
2119
3624
  f"invalid name for a circuit: '{name}'. The name must be a string or 'None'."
2120
3625
  )
2121
- cpy = copy.copy(self)
3626
+ cpy = _copy.copy(self)
2122
3627
  # copy registers correctly, in copy.copy they are only copied via reference
2123
3628
  cpy.qregs = self.qregs.copy()
2124
3629
  cpy.cregs = self.cregs.copy()
@@ -2127,6 +3632,24 @@ class QuantumCircuit:
2127
3632
  cpy._qubit_indices = self._qubit_indices.copy()
2128
3633
  cpy._clbit_indices = self._clbit_indices.copy()
2129
3634
 
3635
+ if vars_mode == "alike":
3636
+ # Note that this causes the local variables to be uninitialised, because the stores are
3637
+ # not copied. This can leave the circuit in a potentially dangerous state for users if
3638
+ # they don't re-add initialiser stores.
3639
+ cpy._vars_local = self._vars_local.copy()
3640
+ cpy._vars_input = self._vars_input.copy()
3641
+ cpy._vars_capture = self._vars_capture.copy()
3642
+ elif vars_mode == "captures":
3643
+ cpy._vars_local = {}
3644
+ cpy._vars_input = {}
3645
+ cpy._vars_capture = {var.name: var for var in self.iter_vars()}
3646
+ elif vars_mode == "drop":
3647
+ cpy._vars_local = {}
3648
+ cpy._vars_input = {}
3649
+ cpy._vars_capture = {}
3650
+ else: # pragma: no cover
3651
+ raise ValueError(f"unknown vars_mode: '{vars_mode}'")
3652
+
2130
3653
  cpy._parameter_table = ParameterTable()
2131
3654
  for parameter in getattr(cpy.global_phase, "parameters", ()):
2132
3655
  cpy._parameter_table[parameter] = ParameterReferences(
@@ -2134,8 +3657,8 @@ class QuantumCircuit:
2134
3657
  )
2135
3658
  cpy._data = CircuitData(self._data.qubits, self._data.clbits)
2136
3659
 
2137
- cpy._calibrations = copy.deepcopy(self._calibrations)
2138
- cpy._metadata = copy.deepcopy(self._metadata)
3660
+ cpy._calibrations = _copy.deepcopy(self._calibrations)
3661
+ cpy._metadata = _copy.deepcopy(self._metadata)
2139
3662
 
2140
3663
  if name:
2141
3664
  cpy.name = name
@@ -2145,6 +3668,11 @@ class QuantumCircuit:
2145
3668
  """Clear all instructions in self.
2146
3669
 
2147
3670
  Clearing the circuits will keep the metadata and calibrations.
3671
+
3672
+ .. seealso::
3673
+ :meth:`copy_empty_like`
3674
+ A method to produce a new circuit with no instructions and all the same tracking of
3675
+ quantum and classical typed data, but without mutating the original circuit.
2148
3676
  """
2149
3677
  self._data.clear()
2150
3678
  self._parameter_table.clear()
@@ -2184,7 +3712,38 @@ class QuantumCircuit:
2184
3712
  """
2185
3713
  from .reset import Reset
2186
3714
 
2187
- return self.append(Reset(), [qubit], [])
3715
+ return self.append(Reset(), [qubit], [], copy=False)
3716
+
3717
+ def store(self, lvalue: typing.Any, rvalue: typing.Any, /) -> InstructionSet:
3718
+ """Store the result of the given real-time classical expression ``rvalue`` in the memory
3719
+ location defined by ``lvalue``.
3720
+
3721
+ Typically ``lvalue`` will be a :class:`~.expr.Var` node and ``rvalue`` will be some
3722
+ :class:`~.expr.Expr` to write into it, but anything that :func:`.expr.lift` can raise to an
3723
+ :class:`~.expr.Expr` is permissible in both places, and it will be called on them.
3724
+
3725
+ Args:
3726
+ lvalue: a valid specifier for a memory location in the circuit. This will typically be
3727
+ a :class:`~.expr.Var` node, but you can also write to :class:`.Clbit` or
3728
+ :class:`.ClassicalRegister` memory locations if your hardware supports it. The
3729
+ memory location must already be present in the circuit.
3730
+ rvalue: a real-time classical expression whose result should be written into the given
3731
+ memory location.
3732
+
3733
+ .. seealso::
3734
+ :class:`~.circuit.Store`
3735
+ The backing :class:`~.circuit.Instruction` class that represents this operation.
3736
+
3737
+ :meth:`add_var`
3738
+ Create a new variable in the circuit that can be written to with this method.
3739
+ """
3740
+ # As a convenience, lift integer-literal rvalues to the matching width.
3741
+ lvalue = expr.lift(lvalue)
3742
+ rvalue_type = (
3743
+ lvalue.type if isinstance(rvalue, int) and not isinstance(rvalue, bool) else None
3744
+ )
3745
+ rvalue = expr.lift(rvalue, rvalue_type)
3746
+ return self.append(Store(lvalue, rvalue), (), (), copy=False)
2188
3747
 
2189
3748
  def measure(self, qubit: QubitSpecifier, cbit: ClbitSpecifier) -> InstructionSet:
2190
3749
  r"""Measure a quantum bit (``qubit``) in the Z basis into a classical bit (``cbit``).
@@ -2261,7 +3820,7 @@ class QuantumCircuit:
2261
3820
  """
2262
3821
  from .measure import Measure
2263
3822
 
2264
- return self.append(Measure(), [qubit], [cbit])
3823
+ return self.append(Measure(), [qubit], [cbit], copy=False)
2265
3824
 
2266
3825
  def measure_active(self, inplace: bool = True) -> Optional["QuantumCircuit"]:
2267
3826
  """Adds measurement to all non-idle qubits. Creates a new ClassicalRegister with
@@ -2348,6 +3907,28 @@ class QuantumCircuit:
2348
3907
  Measurements and barriers are considered final if they are
2349
3908
  followed by no other operations (aside from other measurements or barriers.)
2350
3909
 
3910
+ .. note::
3911
+ This method has rather complex behavior, particularly around the removal of newly idle
3912
+ classical bits and registers. It is much more efficient to avoid adding unnecessary
3913
+ classical data in the first place, rather than trying to remove it later.
3914
+
3915
+ .. seealso::
3916
+ :class:`.RemoveFinalMeasurements`
3917
+ A transpiler pass that removes final measurements and barriers. This does not
3918
+ remove the classical data. If this is your goal, you can call that with::
3919
+
3920
+ from qiskit.circuit import QuantumCircuit
3921
+ from qiskit.transpiler.passes import RemoveFinalMeasurements
3922
+
3923
+ qc = QuantumCircuit(2, 2)
3924
+ qc.h(0)
3925
+ qc.cx(0, 1)
3926
+ qc.barrier()
3927
+ qc.measure([0, 1], [0, 1])
3928
+
3929
+ pass_ = RemoveFinalMeasurements()
3930
+ just_bell = pass_(qc)
3931
+
2351
3932
  Args:
2352
3933
  inplace (bool): All measurements removed inplace or return new circuit.
2353
3934
 
@@ -2451,7 +4032,7 @@ class QuantumCircuit:
2451
4032
 
2452
4033
  @property
2453
4034
  def global_phase(self) -> ParameterValueType:
2454
- """Return the global phase of the current circuit scope in radians."""
4035
+ """The global phase of the current circuit scope in radians."""
2455
4036
  if self._control_flow_scopes:
2456
4037
  return self._control_flow_scopes[-1].global_phase
2457
4038
  return self._global_phase
@@ -2837,7 +4418,9 @@ class QuantumCircuit:
2837
4418
  if qargs:
2838
4419
  # This uses a `dict` not a `set` to guarantee a deterministic order to the arguments.
2839
4420
  qubits = tuple({q: None for qarg in qargs for q in self.qbit_argument_conversion(qarg)})
2840
- return self.append(CircuitInstruction(Barrier(len(qubits), label=label), qubits, ()))
4421
+ return self.append(
4422
+ CircuitInstruction(Barrier(len(qubits), label=label), qubits, ()), copy=False
4423
+ )
2841
4424
  else:
2842
4425
  qubits = self.qubits.copy()
2843
4426
  return self._current_scope().append(
@@ -2868,7 +4451,7 @@ class QuantumCircuit:
2868
4451
  """
2869
4452
  if qarg is None:
2870
4453
  qarg = self.qubits
2871
- return self.append(Delay(duration, unit=unit), [qarg], [])
4454
+ return self.append(Delay(duration, unit=unit), [qarg], [], copy=False)
2872
4455
 
2873
4456
  def h(self, qubit: QubitSpecifier) -> InstructionSet:
2874
4457
  """Apply :class:`~qiskit.circuit.library.HGate`.
@@ -2883,7 +4466,7 @@ class QuantumCircuit:
2883
4466
  """
2884
4467
  from .library.standard_gates.h import HGate
2885
4468
 
2886
- return self.append(HGate(), [qubit], [])
4469
+ return self.append(HGate(), [qubit], [], copy=False)
2887
4470
 
2888
4471
  def ch(
2889
4472
  self,
@@ -2910,7 +4493,10 @@ class QuantumCircuit:
2910
4493
  from .library.standard_gates.h import CHGate
2911
4494
 
2912
4495
  return self.append(
2913
- CHGate(label=label, ctrl_state=ctrl_state), [control_qubit, target_qubit], []
4496
+ CHGate(label=label, ctrl_state=ctrl_state),
4497
+ [control_qubit, target_qubit],
4498
+ [],
4499
+ copy=False,
2914
4500
  )
2915
4501
 
2916
4502
  def id(self, qubit: QubitSpecifier) -> InstructionSet: # pylint: disable=invalid-name
@@ -2926,7 +4512,7 @@ class QuantumCircuit:
2926
4512
  """
2927
4513
  from .library.standard_gates.i import IGate
2928
4514
 
2929
- return self.append(IGate(), [qubit], [])
4515
+ return self.append(IGate(), [qubit], [], copy=False)
2930
4516
 
2931
4517
  def ms(self, theta: ParameterValueType, qubits: Sequence[QubitSpecifier]) -> InstructionSet:
2932
4518
  """Apply :class:`~qiskit.circuit.library.MSGate`.
@@ -2943,7 +4529,7 @@ class QuantumCircuit:
2943
4529
  # pylint: disable=cyclic-import
2944
4530
  from .library.generalized_gates.gms import MSGate
2945
4531
 
2946
- return self.append(MSGate(len(qubits), theta), qubits)
4532
+ return self.append(MSGate(len(qubits), theta), qubits, copy=False)
2947
4533
 
2948
4534
  def p(self, theta: ParameterValueType, qubit: QubitSpecifier) -> InstructionSet:
2949
4535
  """Apply :class:`~qiskit.circuit.library.PhaseGate`.
@@ -2959,7 +4545,7 @@ class QuantumCircuit:
2959
4545
  """
2960
4546
  from .library.standard_gates.p import PhaseGate
2961
4547
 
2962
- return self.append(PhaseGate(theta), [qubit], [])
4548
+ return self.append(PhaseGate(theta), [qubit], [], copy=False)
2963
4549
 
2964
4550
  def cp(
2965
4551
  self,
@@ -2988,7 +4574,10 @@ class QuantumCircuit:
2988
4574
  from .library.standard_gates.p import CPhaseGate
2989
4575
 
2990
4576
  return self.append(
2991
- CPhaseGate(theta, label=label, ctrl_state=ctrl_state), [control_qubit, target_qubit], []
4577
+ CPhaseGate(theta, label=label, ctrl_state=ctrl_state),
4578
+ [control_qubit, target_qubit],
4579
+ [],
4580
+ copy=False,
2992
4581
  )
2993
4582
 
2994
4583
  def mcp(
@@ -2996,6 +4585,7 @@ class QuantumCircuit:
2996
4585
  lam: ParameterValueType,
2997
4586
  control_qubits: Sequence[QubitSpecifier],
2998
4587
  target_qubit: QubitSpecifier,
4588
+ ctrl_state: str | int | None = None,
2999
4589
  ) -> InstructionSet:
3000
4590
  """Apply :class:`~qiskit.circuit.library.MCPhaseGate`.
3001
4591
 
@@ -3005,6 +4595,9 @@ class QuantumCircuit:
3005
4595
  lam: The angle of the rotation.
3006
4596
  control_qubits: The qubits used as the controls.
3007
4597
  target_qubit: The qubit(s) targeted by the gate.
4598
+ ctrl_state:
4599
+ The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling
4600
+ on the '1' state.
3008
4601
 
3009
4602
  Returns:
3010
4603
  A handle to the instructions created.
@@ -3013,7 +4606,10 @@ class QuantumCircuit:
3013
4606
 
3014
4607
  num_ctrl_qubits = len(control_qubits)
3015
4608
  return self.append(
3016
- MCPhaseGate(lam, num_ctrl_qubits), control_qubits[:] + [target_qubit], []
4609
+ MCPhaseGate(lam, num_ctrl_qubits, ctrl_state=ctrl_state),
4610
+ control_qubits[:] + [target_qubit],
4611
+ [],
4612
+ copy=False,
3017
4613
  )
3018
4614
 
3019
4615
  def r(
@@ -3033,7 +4629,7 @@ class QuantumCircuit:
3033
4629
  """
3034
4630
  from .library.standard_gates.r import RGate
3035
4631
 
3036
- return self.append(RGate(theta, phi), [qubit], [])
4632
+ return self.append(RGate(theta, phi), [qubit], [], copy=False)
3037
4633
 
3038
4634
  def rv(
3039
4635
  self,
@@ -3060,7 +4656,7 @@ class QuantumCircuit:
3060
4656
  """
3061
4657
  from .library.generalized_gates.rv import RVGate
3062
4658
 
3063
- return self.append(RVGate(vx, vy, vz), [qubit], [])
4659
+ return self.append(RVGate(vx, vy, vz), [qubit], [], copy=False)
3064
4660
 
3065
4661
  def rccx(
3066
4662
  self,
@@ -3082,7 +4678,9 @@ class QuantumCircuit:
3082
4678
  """
3083
4679
  from .library.standard_gates.x import RCCXGate
3084
4680
 
3085
- return self.append(RCCXGate(), [control_qubit1, control_qubit2, target_qubit], [])
4681
+ return self.append(
4682
+ RCCXGate(), [control_qubit1, control_qubit2, target_qubit], [], copy=False
4683
+ )
3086
4684
 
3087
4685
  def rcccx(
3088
4686
  self,
@@ -3107,7 +4705,10 @@ class QuantumCircuit:
3107
4705
  from .library.standard_gates.x import RC3XGate
3108
4706
 
3109
4707
  return self.append(
3110
- RC3XGate(), [control_qubit1, control_qubit2, control_qubit3, target_qubit], []
4708
+ RC3XGate(),
4709
+ [control_qubit1, control_qubit2, control_qubit3, target_qubit],
4710
+ [],
4711
+ copy=False,
3111
4712
  )
3112
4713
 
3113
4714
  def rx(
@@ -3127,7 +4728,7 @@ class QuantumCircuit:
3127
4728
  """
3128
4729
  from .library.standard_gates.rx import RXGate
3129
4730
 
3130
- return self.append(RXGate(theta, label=label), [qubit], [])
4731
+ return self.append(RXGate(theta, label=label), [qubit], [], copy=False)
3131
4732
 
3132
4733
  def crx(
3133
4734
  self,
@@ -3156,7 +4757,10 @@ class QuantumCircuit:
3156
4757
  from .library.standard_gates.rx import CRXGate
3157
4758
 
3158
4759
  return self.append(
3159
- CRXGate(theta, label=label, ctrl_state=ctrl_state), [control_qubit, target_qubit], []
4760
+ CRXGate(theta, label=label, ctrl_state=ctrl_state),
4761
+ [control_qubit, target_qubit],
4762
+ [],
4763
+ copy=False,
3160
4764
  )
3161
4765
 
3162
4766
  def rxx(
@@ -3176,7 +4780,7 @@ class QuantumCircuit:
3176
4780
  """
3177
4781
  from .library.standard_gates.rxx import RXXGate
3178
4782
 
3179
- return self.append(RXXGate(theta), [qubit1, qubit2], [])
4783
+ return self.append(RXXGate(theta), [qubit1, qubit2], [], copy=False)
3180
4784
 
3181
4785
  def ry(
3182
4786
  self, theta: ParameterValueType, qubit: QubitSpecifier, label: str | None = None
@@ -3195,7 +4799,7 @@ class QuantumCircuit:
3195
4799
  """
3196
4800
  from .library.standard_gates.ry import RYGate
3197
4801
 
3198
- return self.append(RYGate(theta, label=label), [qubit], [])
4802
+ return self.append(RYGate(theta, label=label), [qubit], [], copy=False)
3199
4803
 
3200
4804
  def cry(
3201
4805
  self,
@@ -3224,7 +4828,10 @@ class QuantumCircuit:
3224
4828
  from .library.standard_gates.ry import CRYGate
3225
4829
 
3226
4830
  return self.append(
3227
- CRYGate(theta, label=label, ctrl_state=ctrl_state), [control_qubit, target_qubit], []
4831
+ CRYGate(theta, label=label, ctrl_state=ctrl_state),
4832
+ [control_qubit, target_qubit],
4833
+ [],
4834
+ copy=False,
3228
4835
  )
3229
4836
 
3230
4837
  def ryy(
@@ -3244,7 +4851,7 @@ class QuantumCircuit:
3244
4851
  """
3245
4852
  from .library.standard_gates.ryy import RYYGate
3246
4853
 
3247
- return self.append(RYYGate(theta), [qubit1, qubit2], [])
4854
+ return self.append(RYYGate(theta), [qubit1, qubit2], [], copy=False)
3248
4855
 
3249
4856
  def rz(self, phi: ParameterValueType, qubit: QubitSpecifier) -> InstructionSet:
3250
4857
  """Apply :class:`~qiskit.circuit.library.RZGate`.
@@ -3260,7 +4867,7 @@ class QuantumCircuit:
3260
4867
  """
3261
4868
  from .library.standard_gates.rz import RZGate
3262
4869
 
3263
- return self.append(RZGate(phi), [qubit], [])
4870
+ return self.append(RZGate(phi), [qubit], [], copy=False)
3264
4871
 
3265
4872
  def crz(
3266
4873
  self,
@@ -3289,7 +4896,10 @@ class QuantumCircuit:
3289
4896
  from .library.standard_gates.rz import CRZGate
3290
4897
 
3291
4898
  return self.append(
3292
- CRZGate(theta, label=label, ctrl_state=ctrl_state), [control_qubit, target_qubit], []
4899
+ CRZGate(theta, label=label, ctrl_state=ctrl_state),
4900
+ [control_qubit, target_qubit],
4901
+ [],
4902
+ copy=False,
3293
4903
  )
3294
4904
 
3295
4905
  def rzx(
@@ -3309,7 +4919,7 @@ class QuantumCircuit:
3309
4919
  """
3310
4920
  from .library.standard_gates.rzx import RZXGate
3311
4921
 
3312
- return self.append(RZXGate(theta), [qubit1, qubit2], [])
4922
+ return self.append(RZXGate(theta), [qubit1, qubit2], [], copy=False)
3313
4923
 
3314
4924
  def rzz(
3315
4925
  self, theta: ParameterValueType, qubit1: QubitSpecifier, qubit2: QubitSpecifier
@@ -3328,7 +4938,7 @@ class QuantumCircuit:
3328
4938
  """
3329
4939
  from .library.standard_gates.rzz import RZZGate
3330
4940
 
3331
- return self.append(RZZGate(theta), [qubit1, qubit2], [])
4941
+ return self.append(RZZGate(theta), [qubit1, qubit2], [], copy=False)
3332
4942
 
3333
4943
  def ecr(self, qubit1: QubitSpecifier, qubit2: QubitSpecifier) -> InstructionSet:
3334
4944
  """Apply :class:`~qiskit.circuit.library.ECRGate`.
@@ -3343,7 +4953,7 @@ class QuantumCircuit:
3343
4953
  """
3344
4954
  from .library.standard_gates.ecr import ECRGate
3345
4955
 
3346
- return self.append(ECRGate(), [qubit1, qubit2], [])
4956
+ return self.append(ECRGate(), [qubit1, qubit2], [], copy=False)
3347
4957
 
3348
4958
  def s(self, qubit: QubitSpecifier) -> InstructionSet:
3349
4959
  """Apply :class:`~qiskit.circuit.library.SGate`.
@@ -3358,7 +4968,7 @@ class QuantumCircuit:
3358
4968
  """
3359
4969
  from .library.standard_gates.s import SGate
3360
4970
 
3361
- return self.append(SGate(), [qubit], [])
4971
+ return self.append(SGate(), [qubit], [], copy=False)
3362
4972
 
3363
4973
  def sdg(self, qubit: QubitSpecifier) -> InstructionSet:
3364
4974
  """Apply :class:`~qiskit.circuit.library.SdgGate`.
@@ -3373,7 +4983,7 @@ class QuantumCircuit:
3373
4983
  """
3374
4984
  from .library.standard_gates.s import SdgGate
3375
4985
 
3376
- return self.append(SdgGate(), [qubit], [])
4986
+ return self.append(SdgGate(), [qubit], [], copy=False)
3377
4987
 
3378
4988
  def cs(
3379
4989
  self,
@@ -3403,6 +5013,7 @@ class QuantumCircuit:
3403
5013
  CSGate(label=label, ctrl_state=ctrl_state),
3404
5014
  [control_qubit, target_qubit],
3405
5015
  [],
5016
+ copy=False,
3406
5017
  )
3407
5018
 
3408
5019
  def csdg(
@@ -3433,6 +5044,7 @@ class QuantumCircuit:
3433
5044
  CSdgGate(label=label, ctrl_state=ctrl_state),
3434
5045
  [control_qubit, target_qubit],
3435
5046
  [],
5047
+ copy=False,
3436
5048
  )
3437
5049
 
3438
5050
  def swap(self, qubit1: QubitSpecifier, qubit2: QubitSpecifier) -> InstructionSet:
@@ -3448,7 +5060,7 @@ class QuantumCircuit:
3448
5060
  """
3449
5061
  from .library.standard_gates.swap import SwapGate
3450
5062
 
3451
- return self.append(SwapGate(), [qubit1, qubit2], [])
5063
+ return self.append(SwapGate(), [qubit1, qubit2], [], copy=False)
3452
5064
 
3453
5065
  def iswap(self, qubit1: QubitSpecifier, qubit2: QubitSpecifier) -> InstructionSet:
3454
5066
  """Apply :class:`~qiskit.circuit.library.iSwapGate`.
@@ -3463,7 +5075,7 @@ class QuantumCircuit:
3463
5075
  """
3464
5076
  from .library.standard_gates.iswap import iSwapGate
3465
5077
 
3466
- return self.append(iSwapGate(), [qubit1, qubit2], [])
5078
+ return self.append(iSwapGate(), [qubit1, qubit2], [], copy=False)
3467
5079
 
3468
5080
  def cswap(
3469
5081
  self,
@@ -3495,6 +5107,7 @@ class QuantumCircuit:
3495
5107
  CSwapGate(label=label, ctrl_state=ctrl_state),
3496
5108
  [control_qubit, target_qubit1, target_qubit2],
3497
5109
  [],
5110
+ copy=False,
3498
5111
  )
3499
5112
 
3500
5113
  def sx(self, qubit: QubitSpecifier) -> InstructionSet:
@@ -3510,7 +5123,7 @@ class QuantumCircuit:
3510
5123
  """
3511
5124
  from .library.standard_gates.sx import SXGate
3512
5125
 
3513
- return self.append(SXGate(), [qubit], [])
5126
+ return self.append(SXGate(), [qubit], [], copy=False)
3514
5127
 
3515
5128
  def sxdg(self, qubit: QubitSpecifier) -> InstructionSet:
3516
5129
  """Apply :class:`~qiskit.circuit.library.SXdgGate`.
@@ -3525,7 +5138,7 @@ class QuantumCircuit:
3525
5138
  """
3526
5139
  from .library.standard_gates.sx import SXdgGate
3527
5140
 
3528
- return self.append(SXdgGate(), [qubit], [])
5141
+ return self.append(SXdgGate(), [qubit], [], copy=False)
3529
5142
 
3530
5143
  def csx(
3531
5144
  self,
@@ -3555,6 +5168,7 @@ class QuantumCircuit:
3555
5168
  CSXGate(label=label, ctrl_state=ctrl_state),
3556
5169
  [control_qubit, target_qubit],
3557
5170
  [],
5171
+ copy=False,
3558
5172
  )
3559
5173
 
3560
5174
  def t(self, qubit: QubitSpecifier) -> InstructionSet:
@@ -3570,7 +5184,7 @@ class QuantumCircuit:
3570
5184
  """
3571
5185
  from .library.standard_gates.t import TGate
3572
5186
 
3573
- return self.append(TGate(), [qubit], [])
5187
+ return self.append(TGate(), [qubit], [], copy=False)
3574
5188
 
3575
5189
  def tdg(self, qubit: QubitSpecifier) -> InstructionSet:
3576
5190
  """Apply :class:`~qiskit.circuit.library.TdgGate`.
@@ -3585,7 +5199,7 @@ class QuantumCircuit:
3585
5199
  """
3586
5200
  from .library.standard_gates.t import TdgGate
3587
5201
 
3588
- return self.append(TdgGate(), [qubit], [])
5202
+ return self.append(TdgGate(), [qubit], [], copy=False)
3589
5203
 
3590
5204
  def u(
3591
5205
  self,
@@ -3609,7 +5223,7 @@ class QuantumCircuit:
3609
5223
  """
3610
5224
  from .library.standard_gates.u import UGate
3611
5225
 
3612
- return self.append(UGate(theta, phi, lam), [qubit], [])
5226
+ return self.append(UGate(theta, phi, lam), [qubit], [], copy=False)
3613
5227
 
3614
5228
  def cu(
3615
5229
  self,
@@ -3647,6 +5261,7 @@ class QuantumCircuit:
3647
5261
  CUGate(theta, phi, lam, gamma, label=label, ctrl_state=ctrl_state),
3648
5262
  [control_qubit, target_qubit],
3649
5263
  [],
5264
+ copy=False,
3650
5265
  )
3651
5266
 
3652
5267
  def x(self, qubit: QubitSpecifier, label: str | None = None) -> InstructionSet:
@@ -3663,7 +5278,7 @@ class QuantumCircuit:
3663
5278
  """
3664
5279
  from .library.standard_gates.x import XGate
3665
5280
 
3666
- return self.append(XGate(label=label), [qubit], [])
5281
+ return self.append(XGate(label=label), [qubit], [], copy=False)
3667
5282
 
3668
5283
  def cx(
3669
5284
  self,
@@ -3691,7 +5306,10 @@ class QuantumCircuit:
3691
5306
  from .library.standard_gates.x import CXGate
3692
5307
 
3693
5308
  return self.append(
3694
- CXGate(label=label, ctrl_state=ctrl_state), [control_qubit, target_qubit], []
5309
+ CXGate(label=label, ctrl_state=ctrl_state),
5310
+ [control_qubit, target_qubit],
5311
+ [],
5312
+ copy=False,
3695
5313
  )
3696
5314
 
3697
5315
  def dcx(self, qubit1: QubitSpecifier, qubit2: QubitSpecifier) -> InstructionSet:
@@ -3708,7 +5326,7 @@ class QuantumCircuit:
3708
5326
  """
3709
5327
  from .library.standard_gates.dcx import DCXGate
3710
5328
 
3711
- return self.append(DCXGate(), [qubit1, qubit2], [])
5329
+ return self.append(DCXGate(), [qubit1, qubit2], [], copy=False)
3712
5330
 
3713
5331
  def ccx(
3714
5332
  self,
@@ -3738,6 +5356,7 @@ class QuantumCircuit:
3738
5356
  CCXGate(ctrl_state=ctrl_state),
3739
5357
  [control_qubit1, control_qubit2, target_qubit],
3740
5358
  [],
5359
+ copy=False,
3741
5360
  )
3742
5361
 
3743
5362
  def mcx(
@@ -3746,6 +5365,7 @@ class QuantumCircuit:
3746
5365
  target_qubit: QubitSpecifier,
3747
5366
  ancilla_qubits: QubitSpecifier | Sequence[QubitSpecifier] | None = None,
3748
5367
  mode: str = "noancilla",
5368
+ ctrl_state: str | int | None = None,
3749
5369
  ) -> InstructionSet:
3750
5370
  """Apply :class:`~qiskit.circuit.library.MCXGate`.
3751
5371
 
@@ -3764,6 +5384,9 @@ class QuantumCircuit:
3764
5384
  target_qubit: The qubit(s) targeted by the gate.
3765
5385
  ancilla_qubits: The qubits used as the ancillae, if the mode requires them.
3766
5386
  mode: The choice of mode, explained further above.
5387
+ ctrl_state:
5388
+ The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling
5389
+ on the '1' state.
3767
5390
 
3768
5391
  Returns:
3769
5392
  A handle to the instructions created.
@@ -3777,14 +5400,16 @@ class QuantumCircuit:
3777
5400
  num_ctrl_qubits = len(control_qubits)
3778
5401
 
3779
5402
  available_implementations = {
3780
- "noancilla": MCXGrayCode(num_ctrl_qubits),
3781
- "recursion": MCXRecursive(num_ctrl_qubits),
3782
- "v-chain": MCXVChain(num_ctrl_qubits, False),
3783
- "v-chain-dirty": MCXVChain(num_ctrl_qubits, dirty_ancillas=True),
5403
+ "noancilla": MCXGrayCode(num_ctrl_qubits, ctrl_state=ctrl_state),
5404
+ "recursion": MCXRecursive(num_ctrl_qubits, ctrl_state=ctrl_state),
5405
+ "v-chain": MCXVChain(num_ctrl_qubits, False, ctrl_state=ctrl_state),
5406
+ "v-chain-dirty": MCXVChain(num_ctrl_qubits, dirty_ancillas=True, ctrl_state=ctrl_state),
3784
5407
  # outdated, previous names
3785
- "advanced": MCXRecursive(num_ctrl_qubits),
3786
- "basic": MCXVChain(num_ctrl_qubits, dirty_ancillas=False),
3787
- "basic-dirty-ancilla": MCXVChain(num_ctrl_qubits, dirty_ancillas=True),
5408
+ "advanced": MCXRecursive(num_ctrl_qubits, ctrl_state=ctrl_state),
5409
+ "basic": MCXVChain(num_ctrl_qubits, dirty_ancillas=False, ctrl_state=ctrl_state),
5410
+ "basic-dirty-ancilla": MCXVChain(
5411
+ num_ctrl_qubits, dirty_ancillas=True, ctrl_state=ctrl_state
5412
+ ),
3788
5413
  }
3789
5414
 
3790
5415
  # check ancilla input
@@ -3831,7 +5456,7 @@ class QuantumCircuit:
3831
5456
  """
3832
5457
  from .library.standard_gates.y import YGate
3833
5458
 
3834
- return self.append(YGate(), [qubit], [])
5459
+ return self.append(YGate(), [qubit], [], copy=False)
3835
5460
 
3836
5461
  def cy(
3837
5462
  self,
@@ -3858,7 +5483,10 @@ class QuantumCircuit:
3858
5483
  from .library.standard_gates.y import CYGate
3859
5484
 
3860
5485
  return self.append(
3861
- CYGate(label=label, ctrl_state=ctrl_state), [control_qubit, target_qubit], []
5486
+ CYGate(label=label, ctrl_state=ctrl_state),
5487
+ [control_qubit, target_qubit],
5488
+ [],
5489
+ copy=False,
3862
5490
  )
3863
5491
 
3864
5492
  def z(self, qubit: QubitSpecifier) -> InstructionSet:
@@ -3874,7 +5502,7 @@ class QuantumCircuit:
3874
5502
  """
3875
5503
  from .library.standard_gates.z import ZGate
3876
5504
 
3877
- return self.append(ZGate(), [qubit], [])
5505
+ return self.append(ZGate(), [qubit], [], copy=False)
3878
5506
 
3879
5507
  def cz(
3880
5508
  self,
@@ -3901,7 +5529,10 @@ class QuantumCircuit:
3901
5529
  from .library.standard_gates.z import CZGate
3902
5530
 
3903
5531
  return self.append(
3904
- CZGate(label=label, ctrl_state=ctrl_state), [control_qubit, target_qubit], []
5532
+ CZGate(label=label, ctrl_state=ctrl_state),
5533
+ [control_qubit, target_qubit],
5534
+ [],
5535
+ copy=False,
3905
5536
  )
3906
5537
 
3907
5538
  def ccz(
@@ -3934,6 +5565,7 @@ class QuantumCircuit:
3934
5565
  CCZGate(label=label, ctrl_state=ctrl_state),
3935
5566
  [control_qubit1, control_qubit2, target_qubit],
3936
5567
  [],
5568
+ copy=False,
3937
5569
  )
3938
5570
 
3939
5571
  def pauli(
@@ -3952,7 +5584,7 @@ class QuantumCircuit:
3952
5584
  """
3953
5585
  from qiskit.circuit.library.generalized_gates.pauli import PauliGate
3954
5586
 
3955
- return self.append(PauliGate(pauli_string), qubits, [])
5587
+ return self.append(PauliGate(pauli_string), qubits, [], copy=False)
3956
5588
 
3957
5589
  def prepare_state(
3958
5590
  self,
@@ -4063,7 +5695,9 @@ class QuantumCircuit:
4063
5695
  num_qubits = len(qubits) if isinstance(state, int) else None
4064
5696
 
4065
5697
  return self.append(
4066
- StatePreparation(state, num_qubits, label=label, normalize=normalize), qubits
5698
+ StatePreparation(state, num_qubits, label=label, normalize=normalize),
5699
+ qubits,
5700
+ copy=False,
4067
5701
  )
4068
5702
 
4069
5703
  def initialize(
@@ -4175,7 +5809,7 @@ class QuantumCircuit:
4175
5809
 
4176
5810
  num_qubits = len(qubits) if isinstance(params, int) else None
4177
5811
 
4178
- return self.append(Initialize(params, num_qubits, normalize), qubits)
5812
+ return self.append(Initialize(params, num_qubits, normalize), qubits, copy=False)
4179
5813
 
4180
5814
  def unitary(
4181
5815
  self,
@@ -4218,7 +5852,7 @@ class QuantumCircuit:
4218
5852
  if isinstance(qubits, (int, Qubit)) or len(qubits) > 1:
4219
5853
  qubits = [qubits]
4220
5854
 
4221
- return self.append(gate, qubits, [])
5855
+ return self.append(gate, qubits, [], copy=False)
4222
5856
 
4223
5857
  def _current_scope(self) -> CircuitScopeInterface:
4224
5858
  if self._control_flow_scopes:
@@ -4400,7 +6034,7 @@ class QuantumCircuit:
4400
6034
  "When using 'while_loop' with a body, you must pass qubits and clbits."
4401
6035
  )
4402
6036
 
4403
- return self.append(WhileLoopOp(condition, body, label), qubits, clbits)
6037
+ return self.append(WhileLoopOp(condition, body, label), qubits, clbits, copy=False)
4404
6038
 
4405
6039
  @typing.overload
4406
6040
  def for_loop(
@@ -4489,18 +6123,12 @@ class QuantumCircuit:
4489
6123
  "When using 'for_loop' with a body, you must pass qubits and clbits."
4490
6124
  )
4491
6125
 
4492
- return self.append(ForLoopOp(indexset, loop_parameter, body, label), qubits, clbits)
6126
+ return self.append(
6127
+ ForLoopOp(indexset, loop_parameter, body, label), qubits, clbits, copy=False
6128
+ )
4493
6129
 
4494
6130
  @typing.overload
4495
- def if_test(
4496
- self,
4497
- condition: tuple[ClassicalRegister | Clbit, int],
4498
- true_body: None,
4499
- qubits: None,
4500
- clbits: None,
4501
- *,
4502
- label: str | None,
4503
- ) -> IfContext: ...
6131
+ def if_test(self, condition: tuple[ClassicalRegister | Clbit, int]) -> IfContext: ...
4504
6132
 
4505
6133
  @typing.overload
4506
6134
  def if_test(
@@ -4554,11 +6182,11 @@ class QuantumCircuit:
4554
6182
  qc.z(2)
4555
6183
 
4556
6184
  Args:
4557
- condition (Tuple[Union[ClassicalRegister, Clbit], int]): A condition to be evaluated at
4558
- circuit runtime which, if true, will trigger the evaluation of ``true_body``. Can be
4559
- specified as either a tuple of a ``ClassicalRegister`` to be tested for equality
4560
- with a given ``int``, or as a tuple of a ``Clbit`` to be compared to either a
4561
- ``bool`` or an ``int``.
6185
+ condition (Tuple[Union[ClassicalRegister, Clbit], int]): A condition to be evaluated in
6186
+ real time during circuit execution, which, if true, will trigger the evaluation of
6187
+ ``true_body``. Can be specified as either a tuple of a ``ClassicalRegister`` to be
6188
+ tested for equality with a given ``int``, or as a tuple of a ``Clbit`` to be
6189
+ compared to either a ``bool`` or an ``int``.
4562
6190
  true_body (Optional[QuantumCircuit]): The circuit body to be run if ``condition`` is
4563
6191
  true.
4564
6192
  qubits (Optional[Sequence[QubitSpecifier]]): The circuit qubits over which the if/else
@@ -4599,7 +6227,7 @@ class QuantumCircuit:
4599
6227
  elif qubits is None or clbits is None:
4600
6228
  raise CircuitError("When using 'if_test' with a body, you must pass qubits and clbits.")
4601
6229
 
4602
- return self.append(IfElseOp(condition, true_body, None, label), qubits, clbits)
6230
+ return self.append(IfElseOp(condition, true_body, None, label), qubits, clbits, copy=False)
4603
6231
 
4604
6232
  def if_else(
4605
6233
  self,
@@ -4630,7 +6258,7 @@ class QuantumCircuit:
4630
6258
  qc.x(0)
4631
6259
 
4632
6260
  Args:
4633
- condition: A condition to be evaluated at circuit runtime which,
6261
+ condition: A condition to be evaluated in real time at circuit execution, which,
4634
6262
  if true, will trigger the evaluation of ``true_body``. Can be
4635
6263
  specified as either a tuple of a ``ClassicalRegister`` to be
4636
6264
  tested for equality with a given ``int``, or as a tuple of a
@@ -4654,7 +6282,9 @@ class QuantumCircuit:
4654
6282
  else:
4655
6283
  condition = (circuit_scope.resolve_classical_resource(condition[0]), condition[1])
4656
6284
 
4657
- return self.append(IfElseOp(condition, true_body, false_body, label), qubits, clbits)
6285
+ return self.append(
6286
+ IfElseOp(condition, true_body, false_body, label), qubits, clbits, copy=False
6287
+ )
4658
6288
 
4659
6289
  @typing.overload
4660
6290
  def switch(
@@ -4745,7 +6375,7 @@ class QuantumCircuit:
4745
6375
 
4746
6376
  if qubits is None or clbits is None:
4747
6377
  raise CircuitError("When using 'switch' with cases, you must pass qubits and clbits.")
4748
- return self.append(SwitchCaseOp(target, cases, label=label), qubits, clbits)
6378
+ return self.append(SwitchCaseOp(target, cases, label=label), qubits, clbits, copy=False)
4749
6379
 
4750
6380
  def break_loop(self) -> InstructionSet:
4751
6381
  """Apply :class:`~qiskit.circuit.BreakLoopOp`.
@@ -4771,8 +6401,10 @@ class QuantumCircuit:
4771
6401
  if self._control_flow_scopes:
4772
6402
  operation = BreakLoopPlaceholder()
4773
6403
  resources = operation.placeholder_resources()
4774
- return self.append(operation, resources.qubits, resources.clbits)
4775
- return self.append(BreakLoopOp(self.num_qubits, self.num_clbits), self.qubits, self.clbits)
6404
+ return self.append(operation, resources.qubits, resources.clbits, copy=False)
6405
+ return self.append(
6406
+ BreakLoopOp(self.num_qubits, self.num_clbits), self.qubits, self.clbits, copy=False
6407
+ )
4776
6408
 
4777
6409
  def continue_loop(self) -> InstructionSet:
4778
6410
  """Apply :class:`~qiskit.circuit.ContinueLoopOp`.
@@ -4798,9 +6430,9 @@ class QuantumCircuit:
4798
6430
  if self._control_flow_scopes:
4799
6431
  operation = ContinueLoopPlaceholder()
4800
6432
  resources = operation.placeholder_resources()
4801
- return self.append(operation, resources.qubits, resources.clbits)
6433
+ return self.append(operation, resources.qubits, resources.clbits, copy=False)
4802
6434
  return self.append(
4803
- ContinueLoopOp(self.num_qubits, self.num_clbits), self.qubits, self.clbits
6435
+ ContinueLoopOp(self.num_qubits, self.num_clbits), self.qubits, self.clbits, copy=False
4804
6436
  )
4805
6437
 
4806
6438
  def add_calibration(
@@ -4996,6 +6628,24 @@ class _OuterCircuitScopeInterface(CircuitScopeInterface):
4996
6628
  raise CircuitError(f"Classical bit index {specifier} is out-of-range.") from None
4997
6629
  raise CircuitError(f"Unknown classical resource specifier: '{specifier}'.")
4998
6630
 
6631
+ def add_uninitialized_var(self, var):
6632
+ var = self.circuit._prepare_new_var(var, None)
6633
+ self.circuit._vars_local[var.name] = var
6634
+
6635
+ def remove_var(self, var):
6636
+ self.circuit._vars_local.pop(var.name)
6637
+
6638
+ def get_var(self, name):
6639
+ if (out := self.circuit._vars_local.get(name)) is not None:
6640
+ return out
6641
+ if (out := self.circuit._vars_capture.get(name)) is not None:
6642
+ return out
6643
+ return self.circuit._vars_input.get(name)
6644
+
6645
+ def use_var(self, var):
6646
+ if self.get_var(var.name) != var:
6647
+ raise CircuitError(f"'{var}' is not present in this circuit")
6648
+
4999
6649
 
5000
6650
  def _validate_expr(circuit_scope: CircuitScopeInterface, node: expr.Expr) -> expr.Expr:
5001
6651
  # This takes the `circuit_scope` object as an argument rather than being a circuit method and