qiskit 2.0.3__cp39-abi3-macosx_11_0_arm64.whl → 2.1.0__cp39-abi3-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qiskit/VERSION.txt +1 -1
- qiskit/__init__.py +19 -1
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/circuit/__init__.py +104 -20
- qiskit/circuit/_add_control.py +57 -31
- qiskit/circuit/_classical_resource_map.py +4 -0
- qiskit/circuit/annotation.py +504 -0
- qiskit/circuit/classical/expr/__init__.py +1 -1
- qiskit/circuit/classical/expr/expr.py +104 -446
- qiskit/circuit/classical/expr/visitors.py +6 -0
- qiskit/circuit/classical/types/types.py +7 -130
- qiskit/circuit/controlflow/box.py +32 -7
- qiskit/circuit/delay.py +11 -9
- qiskit/circuit/library/arithmetic/adders/adder.py +4 -4
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +2 -2
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +8 -4
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +23 -15
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +22 -14
- qiskit/circuit/library/arithmetic/quadratic_form.py +6 -0
- qiskit/circuit/library/arithmetic/weighted_adder.py +43 -24
- qiskit/circuit/library/basis_change/qft.py +2 -2
- qiskit/circuit/library/blueprintcircuit.py +6 -0
- qiskit/circuit/library/boolean_logic/inner_product.py +2 -2
- qiskit/circuit/library/boolean_logic/quantum_and.py +2 -2
- qiskit/circuit/library/boolean_logic/quantum_or.py +3 -3
- qiskit/circuit/library/boolean_logic/quantum_xor.py +2 -2
- qiskit/circuit/library/data_preparation/_z_feature_map.py +2 -2
- qiskit/circuit/library/data_preparation/_zz_feature_map.py +2 -2
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +2 -2
- qiskit/circuit/library/fourier_checking.py +2 -2
- qiskit/circuit/library/generalized_gates/diagonal.py +5 -1
- qiskit/circuit/library/generalized_gates/gms.py +5 -1
- qiskit/circuit/library/generalized_gates/linear_function.py +2 -2
- qiskit/circuit/library/generalized_gates/permutation.py +5 -1
- qiskit/circuit/library/generalized_gates/uc.py +1 -1
- qiskit/circuit/library/generalized_gates/unitary.py +21 -2
- qiskit/circuit/library/graph_state.py +2 -2
- qiskit/circuit/library/grover_operator.py +2 -2
- qiskit/circuit/library/hidden_linear_function.py +2 -2
- qiskit/circuit/library/iqp.py +2 -2
- qiskit/circuit/library/n_local/efficient_su2.py +2 -2
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
- qiskit/circuit/library/n_local/excitation_preserving.py +7 -9
- qiskit/circuit/library/n_local/n_local.py +4 -3
- qiskit/circuit/library/n_local/pauli_two_design.py +2 -2
- qiskit/circuit/library/n_local/real_amplitudes.py +2 -2
- qiskit/circuit/library/n_local/two_local.py +2 -2
- qiskit/circuit/library/overlap.py +2 -2
- qiskit/circuit/library/pauli_evolution.py +3 -2
- qiskit/circuit/library/phase_estimation.py +2 -2
- qiskit/circuit/library/standard_gates/dcx.py +11 -12
- qiskit/circuit/library/standard_gates/ecr.py +21 -24
- qiskit/circuit/library/standard_gates/equivalence_library.py +232 -96
- qiskit/circuit/library/standard_gates/global_phase.py +5 -6
- qiskit/circuit/library/standard_gates/h.py +22 -45
- qiskit/circuit/library/standard_gates/i.py +1 -1
- qiskit/circuit/library/standard_gates/iswap.py +13 -31
- qiskit/circuit/library/standard_gates/p.py +19 -26
- qiskit/circuit/library/standard_gates/r.py +11 -17
- qiskit/circuit/library/standard_gates/rx.py +21 -45
- qiskit/circuit/library/standard_gates/rxx.py +7 -22
- qiskit/circuit/library/standard_gates/ry.py +21 -39
- qiskit/circuit/library/standard_gates/ryy.py +13 -28
- qiskit/circuit/library/standard_gates/rz.py +18 -35
- qiskit/circuit/library/standard_gates/rzx.py +7 -22
- qiskit/circuit/library/standard_gates/rzz.py +7 -19
- qiskit/circuit/library/standard_gates/s.py +44 -39
- qiskit/circuit/library/standard_gates/swap.py +25 -38
- qiskit/circuit/library/standard_gates/sx.py +34 -41
- qiskit/circuit/library/standard_gates/t.py +18 -27
- qiskit/circuit/library/standard_gates/u.py +8 -24
- qiskit/circuit/library/standard_gates/u1.py +28 -52
- qiskit/circuit/library/standard_gates/u2.py +9 -9
- qiskit/circuit/library/standard_gates/u3.py +24 -40
- qiskit/circuit/library/standard_gates/x.py +190 -336
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +12 -50
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +13 -52
- qiskit/circuit/library/standard_gates/y.py +19 -23
- qiskit/circuit/library/standard_gates/z.py +31 -38
- qiskit/circuit/parameter.py +14 -5
- qiskit/circuit/parameterexpression.py +109 -75
- qiskit/circuit/quantumcircuit.py +172 -99
- qiskit/circuit/quantumcircuitdata.py +1 -0
- qiskit/circuit/random/__init__.py +37 -2
- qiskit/circuit/random/utils.py +445 -56
- qiskit/circuit/tools/pi_check.py +5 -13
- qiskit/compiler/transpiler.py +1 -1
- qiskit/converters/circuit_to_instruction.py +2 -2
- qiskit/dagcircuit/dagnode.py +8 -3
- qiskit/primitives/__init__.py +2 -2
- qiskit/primitives/base/base_estimator.py +2 -2
- qiskit/primitives/containers/data_bin.py +0 -3
- qiskit/primitives/containers/observables_array.py +192 -108
- qiskit/primitives/primitive_job.py +29 -10
- qiskit/providers/fake_provider/generic_backend_v2.py +2 -0
- qiskit/qasm3/__init__.py +106 -12
- qiskit/qasm3/ast.py +15 -1
- qiskit/qasm3/exporter.py +59 -36
- qiskit/qasm3/printer.py +12 -0
- qiskit/qpy/__init__.py +182 -6
- qiskit/qpy/binary_io/circuits.py +256 -24
- qiskit/qpy/binary_io/parse_sympy_repr.py +5 -0
- qiskit/qpy/binary_io/schedules.py +12 -32
- qiskit/qpy/binary_io/value.py +36 -18
- qiskit/qpy/common.py +11 -3
- qiskit/qpy/formats.py +17 -1
- qiskit/qpy/interface.py +52 -12
- qiskit/qpy/type_keys.py +7 -1
- qiskit/quantum_info/__init__.py +10 -0
- qiskit/quantum_info/operators/__init__.py +1 -0
- qiskit/quantum_info/operators/symplectic/__init__.py +1 -0
- qiskit/quantum_info/operators/symplectic/clifford_circuits.py +26 -0
- qiskit/quantum_info/operators/symplectic/pauli.py +2 -2
- qiskit/result/sampled_expval.py +3 -1
- qiskit/synthesis/__init__.py +10 -0
- qiskit/synthesis/arithmetic/__init__.py +1 -1
- qiskit/synthesis/arithmetic/adders/__init__.py +1 -0
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +6 -2
- qiskit/synthesis/arithmetic/adders/rv_ripple_carry_adder.py +156 -0
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +14 -126
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +161 -121
- qiskit/synthesis/evolution/lie_trotter.py +10 -7
- qiskit/synthesis/evolution/product_formula.py +10 -7
- qiskit/synthesis/evolution/qdrift.py +10 -7
- qiskit/synthesis/evolution/suzuki_trotter.py +10 -7
- qiskit/synthesis/multi_controlled/__init__.py +4 -0
- qiskit/synthesis/multi_controlled/mcx_synthesis.py +402 -178
- qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +14 -15
- qiskit/synthesis/qft/qft_decompose_lnn.py +7 -25
- qiskit/synthesis/unitary/qsd.py +80 -9
- qiskit/transpiler/__init__.py +10 -3
- qiskit/transpiler/instruction_durations.py +2 -20
- qiskit/transpiler/passes/__init__.py +5 -2
- qiskit/transpiler/passes/layout/dense_layout.py +26 -6
- qiskit/transpiler/passes/layout/disjoint_utils.py +1 -166
- qiskit/transpiler/passes/layout/sabre_layout.py +22 -3
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +1 -1
- qiskit/transpiler/passes/layout/vf2_layout.py +49 -13
- qiskit/transpiler/passes/layout/vf2_utils.py +10 -0
- qiskit/transpiler/passes/optimization/__init__.py +1 -1
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +2 -1
- qiskit/transpiler/passes/optimization/optimize_clifford_t.py +68 -0
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +3 -9
- qiskit/transpiler/passes/routing/sabre_swap.py +4 -2
- qiskit/transpiler/passes/routing/star_prerouting.py +106 -81
- qiskit/transpiler/passes/scheduling/__init__.py +1 -1
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/__init__.py +1 -0
- qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py +876 -0
- qiskit/transpiler/passes/synthesis/__init__.py +1 -0
- qiskit/transpiler/passes/synthesis/clifford_unitary_synth_plugin.py +123 -0
- qiskit/transpiler/passes/synthesis/hls_plugins.py +494 -93
- qiskit/transpiler/passes/synthesis/plugin.py +4 -0
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +27 -22
- qiskit/transpiler/passmanager_config.py +3 -0
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +149 -28
- qiskit/transpiler/preset_passmanagers/common.py +101 -0
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +6 -0
- qiskit/transpiler/preset_passmanagers/level3.py +2 -2
- qiskit/transpiler/target.py +15 -2
- qiskit/utils/optionals.py +6 -5
- qiskit/visualization/circuit/_utils.py +5 -3
- qiskit/visualization/circuit/latex.py +9 -2
- qiskit/visualization/circuit/matplotlib.py +26 -4
- qiskit/visualization/circuit/qcstyle.py +9 -157
- qiskit/visualization/dag/__init__.py +13 -0
- qiskit/visualization/dag/dagstyle.py +103 -0
- qiskit/visualization/dag/styles/__init__.py +13 -0
- qiskit/visualization/dag/styles/color.json +10 -0
- qiskit/visualization/dag/styles/plain.json +5 -0
- qiskit/visualization/dag_visualization.py +169 -98
- qiskit/visualization/style.py +223 -0
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/METADATA +7 -6
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/RECORD +178 -169
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/entry_points.txt +6 -0
- qiskit/synthesis/discrete_basis/commutator_decompose.py +0 -265
- qiskit/synthesis/discrete_basis/gate_sequence.py +0 -421
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/WHEEL +0 -0
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/licenses/LICENSE.txt +0 -0
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/top_level.txt +0 -0
qiskit/circuit/quantumcircuit.py
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
|
17
17
|
from __future__ import annotations
|
18
18
|
|
19
|
+
import warnings
|
19
20
|
import collections.abc
|
20
21
|
import copy as _copy
|
21
22
|
|
@@ -48,7 +49,7 @@ from qiskit.circuit.instruction import Instruction
|
|
48
49
|
from qiskit.circuit.gate import Gate
|
49
50
|
from qiskit.circuit.parameter import Parameter
|
50
51
|
from qiskit.circuit.exceptions import CircuitError
|
51
|
-
from qiskit.utils import deprecate_func
|
52
|
+
from qiskit.utils import deprecate_func, deprecate_arg
|
52
53
|
from . import ( # pylint: disable=cyclic-import
|
53
54
|
Bit,
|
54
55
|
QuantumRegister,
|
@@ -80,11 +81,12 @@ from .delay import Delay
|
|
80
81
|
from .store import Store
|
81
82
|
|
82
83
|
|
83
|
-
if typing.TYPE_CHECKING:
|
84
|
-
import qiskit
|
85
|
-
from qiskit.
|
84
|
+
if typing.TYPE_CHECKING: # pylint: disable=cyclic-import
|
85
|
+
import qiskit
|
86
|
+
from qiskit.circuit import Annotation
|
87
|
+
from qiskit.transpiler.layout import TranspileLayout
|
86
88
|
from qiskit.quantum_info.operators.base_operator import BaseOperator
|
87
|
-
from qiskit.quantum_info.states.statevector import Statevector
|
89
|
+
from qiskit.quantum_info.states.statevector import Statevector
|
88
90
|
|
89
91
|
|
90
92
|
# The following types are not marked private to avoid leaking this "private/public" abstraction out
|
@@ -826,6 +828,9 @@ class QuantumCircuit:
|
|
826
828
|
a block, even though it has no operations defined. In this case, you can use the :meth:`noop`
|
827
829
|
method.
|
828
830
|
|
831
|
+
To check whether a circuit contains a :class:`.ControlFlowOp` you can use the helper method
|
832
|
+
:meth:`.QuantumCircuit.has_control_flow_op`.
|
833
|
+
|
829
834
|
..
|
830
835
|
TODO: expand the examples of the builder interface.
|
831
836
|
|
@@ -838,6 +843,7 @@ class QuantumCircuit:
|
|
838
843
|
.. automethod:: switch
|
839
844
|
.. automethod:: while_loop
|
840
845
|
.. automethod:: noop
|
846
|
+
.. automethod:: has_control_flow_op
|
841
847
|
|
842
848
|
|
843
849
|
Converting circuits to single objects
|
@@ -1099,7 +1105,7 @@ class QuantumCircuit:
|
|
1099
1105
|
self._base_name = None
|
1100
1106
|
self.name: str
|
1101
1107
|
"""A human-readable name for the circuit.
|
1102
|
-
|
1108
|
+
|
1103
1109
|
Example:
|
1104
1110
|
|
1105
1111
|
.. plot::
|
@@ -1177,7 +1183,7 @@ class QuantumCircuit:
|
|
1177
1183
|
|
1178
1184
|
Qiskit will not examine the content of this mapping, but it will pass it through the
|
1179
1185
|
transpiler and reattach it to the output, so you can track your own metadata.
|
1180
|
-
|
1186
|
+
|
1181
1187
|
Example:
|
1182
1188
|
|
1183
1189
|
.. plot::
|
@@ -2718,6 +2724,8 @@ class QuantumCircuit:
|
|
2718
2724
|
if copy and is_parameter:
|
2719
2725
|
operation = _copy.deepcopy(operation)
|
2720
2726
|
if isinstance(operation, ControlFlowOp):
|
2727
|
+
if operation.name == "box" and operation.unit == "expr":
|
2728
|
+
_validate_expr(circuit_scope, operation.duration)
|
2721
2729
|
# Verify that any variable bindings are valid. Control-flow ops are already enforced
|
2722
2730
|
# by the class not to contain 'input' variables.
|
2723
2731
|
if bad_captures := {
|
@@ -4802,7 +4810,7 @@ class QuantumCircuit:
|
|
4802
4810
|
target._name_update()
|
4803
4811
|
|
4804
4812
|
if isinstance(parameters, collections.abc.Mapping):
|
4805
|
-
raw_mapping = parameters if flat_input else self._unroll_param_dict(parameters)
|
4813
|
+
raw_mapping = parameters if flat_input else self._unroll_param_dict(parameters, strict)
|
4806
4814
|
if strict and (
|
4807
4815
|
extras := [
|
4808
4816
|
parameter for parameter in raw_mapping if not self.has_parameter(parameter)
|
@@ -4819,8 +4827,13 @@ class QuantumCircuit:
|
|
4819
4827
|
|
4820
4828
|
return None if inplace else target
|
4821
4829
|
|
4830
|
+
def has_control_flow_op(self) -> bool:
|
4831
|
+
"""Checks whether the circuit has an instance of :class:`.ControlFlowOp`
|
4832
|
+
present amongst its operations."""
|
4833
|
+
return self._data.has_control_flow_op()
|
4834
|
+
|
4822
4835
|
def _unroll_param_dict(
|
4823
|
-
self, parameter_binds: Mapping[Parameter, ParameterValueType]
|
4836
|
+
self, parameter_binds: Mapping[Parameter, ParameterValueType], strict: bool = True
|
4824
4837
|
) -> Mapping[Parameter, ParameterValueType]:
|
4825
4838
|
out = {}
|
4826
4839
|
for parameter, value in parameter_binds.items():
|
@@ -4832,7 +4845,10 @@ class QuantumCircuit:
|
|
4832
4845
|
)
|
4833
4846
|
out.update(zip(parameter, value))
|
4834
4847
|
elif isinstance(parameter, str):
|
4835
|
-
|
4848
|
+
if strict:
|
4849
|
+
out[self.get_parameter(parameter)] = value
|
4850
|
+
if not strict and self.has_parameter(parameter):
|
4851
|
+
out[self.get_parameter(parameter)] = value
|
4836
4852
|
else:
|
4837
4853
|
out[parameter] = value
|
4838
4854
|
return out
|
@@ -4904,7 +4920,7 @@ class QuantumCircuit:
|
|
4904
4920
|
Returns:
|
4905
4921
|
A handle to the instructions created.
|
4906
4922
|
"""
|
4907
|
-
return self._append_standard_gate(StandardGate.
|
4923
|
+
return self._append_standard_gate(StandardGate.H, [qubit], ())
|
4908
4924
|
|
4909
4925
|
def ch(
|
4910
4926
|
self,
|
@@ -4931,7 +4947,7 @@ class QuantumCircuit:
|
|
4931
4947
|
# if the control state is |1> use the fast Rust version of the gate
|
4932
4948
|
if ctrl_state is None or ctrl_state in ["1", 1]:
|
4933
4949
|
return self._append_standard_gate(
|
4934
|
-
StandardGate.
|
4950
|
+
StandardGate.CH, [control_qubit, target_qubit], (), label=label
|
4935
4951
|
)
|
4936
4952
|
|
4937
4953
|
from .library.standard_gates.h import CHGate
|
@@ -4954,7 +4970,7 @@ class QuantumCircuit:
|
|
4954
4970
|
Returns:
|
4955
4971
|
A handle to the instructions created.
|
4956
4972
|
"""
|
4957
|
-
return self._append_standard_gate(StandardGate.
|
4973
|
+
return self._append_standard_gate(StandardGate.I, [qubit], ())
|
4958
4974
|
|
4959
4975
|
def ms(self, theta: ParameterValueType, qubits: Sequence[QubitSpecifier]) -> InstructionSet:
|
4960
4976
|
"""Apply :class:`~qiskit.circuit.library.MSGate`.
|
@@ -4985,7 +5001,7 @@ class QuantumCircuit:
|
|
4985
5001
|
Returns:
|
4986
5002
|
A handle to the instructions created.
|
4987
5003
|
"""
|
4988
|
-
return self._append_standard_gate(StandardGate.
|
5004
|
+
return self._append_standard_gate(StandardGate.Phase, [qubit], (theta,))
|
4989
5005
|
|
4990
5006
|
def cp(
|
4991
5007
|
self,
|
@@ -5014,7 +5030,7 @@ class QuantumCircuit:
|
|
5014
5030
|
# if the control state is |1> use the fast Rust version of the gate
|
5015
5031
|
if ctrl_state is None or ctrl_state in ["1", 1]:
|
5016
5032
|
return self._append_standard_gate(
|
5017
|
-
StandardGate.
|
5033
|
+
StandardGate.CPhase, [control_qubit, target_qubit], (theta,), label=label
|
5018
5034
|
)
|
5019
5035
|
|
5020
5036
|
from .library.standard_gates.p import CPhaseGate
|
@@ -5142,7 +5158,6 @@ class QuantumCircuit:
|
|
5142
5158
|
"""
|
5143
5159
|
# pylint: disable=cyclic-import
|
5144
5160
|
from .library.standard_gates.ry import RYGate
|
5145
|
-
from .library.standard_gates.x import MCXGate
|
5146
5161
|
from qiskit.synthesis.multi_controlled import (
|
5147
5162
|
_apply_cu,
|
5148
5163
|
_apply_mcu_graycode,
|
@@ -5161,17 +5176,33 @@ class QuantumCircuit:
|
|
5161
5176
|
# auto-select the best mode
|
5162
5177
|
if mode is None:
|
5163
5178
|
# if enough ancillary qubits are provided, use the 'v-chain' method
|
5164
|
-
additional_vchain =
|
5179
|
+
additional_vchain = max(0, len(control_qubits) - 2)
|
5165
5180
|
if len(ancillary_qubits) >= additional_vchain:
|
5166
5181
|
mode = "basic"
|
5167
5182
|
else:
|
5168
5183
|
mode = "noancilla"
|
5169
5184
|
|
5170
5185
|
if mode == "basic":
|
5186
|
+
from qiskit.synthesis.multi_controlled import synth_mcx_n_clean_m15
|
5187
|
+
|
5171
5188
|
self.ry(theta / 2, q_target)
|
5172
|
-
|
5189
|
+
if len(control_qubits) == 1:
|
5190
|
+
self.cx(control_qubits[0], q_target)
|
5191
|
+
elif len(control_qubits) == 2:
|
5192
|
+
self.ccx(control_qubits[0], control_qubits[1], q_target)
|
5193
|
+
else:
|
5194
|
+
qubits = control_qubits + [target_qubit] + ancillary_qubits
|
5195
|
+
mcx = synth_mcx_n_clean_m15(len(control_qubits))
|
5196
|
+
self.compose(mcx, qubits, inplace=True)
|
5173
5197
|
self.ry(-theta / 2, q_target)
|
5174
|
-
|
5198
|
+
if len(control_qubits) == 1:
|
5199
|
+
self.cx(control_qubits[0], q_target)
|
5200
|
+
elif len(control_qubits) == 2:
|
5201
|
+
self.ccx(control_qubits[0], control_qubits[1], q_target)
|
5202
|
+
else:
|
5203
|
+
qubits = control_qubits + [target_qubit] + ancillary_qubits
|
5204
|
+
mcx = synth_mcx_n_clean_m15(len(control_qubits))
|
5205
|
+
self.compose(mcx, qubits, inplace=True)
|
5175
5206
|
elif mode == "noancilla":
|
5176
5207
|
n_c = len(control_qubits)
|
5177
5208
|
if n_c == 1: # cu
|
@@ -5265,7 +5296,7 @@ class QuantumCircuit:
|
|
5265
5296
|
Returns:
|
5266
5297
|
A handle to the instructions created.
|
5267
5298
|
"""
|
5268
|
-
return self._append_standard_gate(StandardGate.
|
5299
|
+
return self._append_standard_gate(StandardGate.R, [qubit], [theta, phi])
|
5269
5300
|
|
5270
5301
|
def rv(
|
5271
5302
|
self,
|
@@ -5313,7 +5344,7 @@ class QuantumCircuit:
|
|
5313
5344
|
A handle to the instructions created.
|
5314
5345
|
"""
|
5315
5346
|
return self._append_standard_gate(
|
5316
|
-
StandardGate.
|
5347
|
+
StandardGate.RCCX, [control_qubit1, control_qubit2, target_qubit], ()
|
5317
5348
|
)
|
5318
5349
|
|
5319
5350
|
def rcccx(
|
@@ -5337,7 +5368,7 @@ class QuantumCircuit:
|
|
5337
5368
|
A handle to the instructions created.
|
5338
5369
|
"""
|
5339
5370
|
return self._append_standard_gate(
|
5340
|
-
StandardGate.
|
5371
|
+
StandardGate.RC3X,
|
5341
5372
|
[control_qubit1, control_qubit2, control_qubit3, target_qubit],
|
5342
5373
|
(),
|
5343
5374
|
)
|
@@ -5357,7 +5388,7 @@ class QuantumCircuit:
|
|
5357
5388
|
Returns:
|
5358
5389
|
A handle to the instructions created.
|
5359
5390
|
"""
|
5360
|
-
return self._append_standard_gate(StandardGate.
|
5391
|
+
return self._append_standard_gate(StandardGate.RX, [qubit], [theta], label=label)
|
5361
5392
|
|
5362
5393
|
def crx(
|
5363
5394
|
self,
|
@@ -5386,7 +5417,7 @@ class QuantumCircuit:
|
|
5386
5417
|
# if the control state is |1> use the fast Rust version of the gate
|
5387
5418
|
if ctrl_state is None or ctrl_state in ["1", 1]:
|
5388
5419
|
return self._append_standard_gate(
|
5389
|
-
StandardGate.
|
5420
|
+
StandardGate.CRX, [control_qubit, target_qubit], [theta], label=label
|
5390
5421
|
)
|
5391
5422
|
|
5392
5423
|
from .library.standard_gates.rx import CRXGate
|
@@ -5413,7 +5444,7 @@ class QuantumCircuit:
|
|
5413
5444
|
Returns:
|
5414
5445
|
A handle to the instructions created.
|
5415
5446
|
"""
|
5416
|
-
return self._append_standard_gate(StandardGate.
|
5447
|
+
return self._append_standard_gate(StandardGate.RXX, [qubit1, qubit2], [theta])
|
5417
5448
|
|
5418
5449
|
def ry(
|
5419
5450
|
self, theta: ParameterValueType, qubit: QubitSpecifier, label: str | None = None
|
@@ -5430,7 +5461,7 @@ class QuantumCircuit:
|
|
5430
5461
|
Returns:
|
5431
5462
|
A handle to the instructions created.
|
5432
5463
|
"""
|
5433
|
-
return self._append_standard_gate(StandardGate.
|
5464
|
+
return self._append_standard_gate(StandardGate.RY, [qubit], [theta], label=label)
|
5434
5465
|
|
5435
5466
|
def cry(
|
5436
5467
|
self,
|
@@ -5459,7 +5490,7 @@ class QuantumCircuit:
|
|
5459
5490
|
# if the control state is |1> use the fast Rust version of the gate
|
5460
5491
|
if ctrl_state is None or ctrl_state in ["1", 1]:
|
5461
5492
|
return self._append_standard_gate(
|
5462
|
-
StandardGate.
|
5493
|
+
StandardGate.CRY, [control_qubit, target_qubit], [theta], label=label
|
5463
5494
|
)
|
5464
5495
|
|
5465
5496
|
from .library.standard_gates.ry import CRYGate
|
@@ -5486,7 +5517,7 @@ class QuantumCircuit:
|
|
5486
5517
|
Returns:
|
5487
5518
|
A handle to the instructions created.
|
5488
5519
|
"""
|
5489
|
-
return self._append_standard_gate(StandardGate.
|
5520
|
+
return self._append_standard_gate(StandardGate.RYY, [qubit1, qubit2], [theta])
|
5490
5521
|
|
5491
5522
|
def rz(self, phi: ParameterValueType, qubit: QubitSpecifier) -> InstructionSet:
|
5492
5523
|
"""Apply :class:`~qiskit.circuit.library.RZGate`.
|
@@ -5500,7 +5531,7 @@ class QuantumCircuit:
|
|
5500
5531
|
Returns:
|
5501
5532
|
A handle to the instructions created.
|
5502
5533
|
"""
|
5503
|
-
return self._append_standard_gate(StandardGate.
|
5534
|
+
return self._append_standard_gate(StandardGate.RZ, [qubit], [phi])
|
5504
5535
|
|
5505
5536
|
def crz(
|
5506
5537
|
self,
|
@@ -5529,7 +5560,7 @@ class QuantumCircuit:
|
|
5529
5560
|
# if the control state is |1> use the fast Rust version of the gate
|
5530
5561
|
if ctrl_state is None or ctrl_state in ["1", 1]:
|
5531
5562
|
return self._append_standard_gate(
|
5532
|
-
StandardGate.
|
5563
|
+
StandardGate.CRZ, [control_qubit, target_qubit], [theta], label=label
|
5533
5564
|
)
|
5534
5565
|
|
5535
5566
|
from .library.standard_gates.rz import CRZGate
|
@@ -5556,7 +5587,7 @@ class QuantumCircuit:
|
|
5556
5587
|
Returns:
|
5557
5588
|
A handle to the instructions created.
|
5558
5589
|
"""
|
5559
|
-
return self._append_standard_gate(StandardGate.
|
5590
|
+
return self._append_standard_gate(StandardGate.RZX, [qubit1, qubit2], [theta])
|
5560
5591
|
|
5561
5592
|
def rzz(
|
5562
5593
|
self, theta: ParameterValueType, qubit1: QubitSpecifier, qubit2: QubitSpecifier
|
@@ -5573,7 +5604,7 @@ class QuantumCircuit:
|
|
5573
5604
|
Returns:
|
5574
5605
|
A handle to the instructions created.
|
5575
5606
|
"""
|
5576
|
-
return self._append_standard_gate(StandardGate.
|
5607
|
+
return self._append_standard_gate(StandardGate.RZZ, [qubit1, qubit2], [theta])
|
5577
5608
|
|
5578
5609
|
def ecr(self, qubit1: QubitSpecifier, qubit2: QubitSpecifier) -> InstructionSet:
|
5579
5610
|
"""Apply :class:`~qiskit.circuit.library.ECRGate`.
|
@@ -5586,7 +5617,7 @@ class QuantumCircuit:
|
|
5586
5617
|
Returns:
|
5587
5618
|
A handle to the instructions created.
|
5588
5619
|
"""
|
5589
|
-
return self._append_standard_gate(StandardGate.
|
5620
|
+
return self._append_standard_gate(StandardGate.ECR, [qubit1, qubit2], ())
|
5590
5621
|
|
5591
5622
|
def s(self, qubit: QubitSpecifier) -> InstructionSet:
|
5592
5623
|
"""Apply :class:`~qiskit.circuit.library.SGate`.
|
@@ -5599,7 +5630,7 @@ class QuantumCircuit:
|
|
5599
5630
|
Returns:
|
5600
5631
|
A handle to the instructions created.
|
5601
5632
|
"""
|
5602
|
-
return self._append_standard_gate(StandardGate.
|
5633
|
+
return self._append_standard_gate(StandardGate.S, [qubit], ())
|
5603
5634
|
|
5604
5635
|
def sdg(self, qubit: QubitSpecifier) -> InstructionSet:
|
5605
5636
|
"""Apply :class:`~qiskit.circuit.library.SdgGate`.
|
@@ -5612,7 +5643,7 @@ class QuantumCircuit:
|
|
5612
5643
|
Returns:
|
5613
5644
|
A handle to the instructions created.
|
5614
5645
|
"""
|
5615
|
-
return self._append_standard_gate(StandardGate.
|
5646
|
+
return self._append_standard_gate(StandardGate.Sdg, [qubit], ())
|
5616
5647
|
|
5617
5648
|
def cs(
|
5618
5649
|
self,
|
@@ -5639,7 +5670,7 @@ class QuantumCircuit:
|
|
5639
5670
|
# if the control state is |1> use the fast Rust version of the gate
|
5640
5671
|
if ctrl_state is None or ctrl_state in ["1", 1]:
|
5641
5672
|
return self._append_standard_gate(
|
5642
|
-
StandardGate.
|
5673
|
+
StandardGate.CS, [control_qubit, target_qubit], (), label=label
|
5643
5674
|
)
|
5644
5675
|
|
5645
5676
|
from .library.standard_gates.s import CSGate
|
@@ -5676,7 +5707,7 @@ class QuantumCircuit:
|
|
5676
5707
|
# if the control state is |1> use the fast Rust version of the gate
|
5677
5708
|
if ctrl_state is None or ctrl_state in ["1", 1]:
|
5678
5709
|
return self._append_standard_gate(
|
5679
|
-
StandardGate.
|
5710
|
+
StandardGate.CSdg, [control_qubit, target_qubit], (), label=label
|
5680
5711
|
)
|
5681
5712
|
|
5682
5713
|
from .library.standard_gates.s import CSdgGate
|
@@ -5700,7 +5731,7 @@ class QuantumCircuit:
|
|
5700
5731
|
A handle to the instructions created.
|
5701
5732
|
"""
|
5702
5733
|
return self._append_standard_gate(
|
5703
|
-
StandardGate.
|
5734
|
+
StandardGate.Swap,
|
5704
5735
|
[qubit1, qubit2],
|
5705
5736
|
(),
|
5706
5737
|
)
|
@@ -5716,7 +5747,7 @@ class QuantumCircuit:
|
|
5716
5747
|
Returns:
|
5717
5748
|
A handle to the instructions created.
|
5718
5749
|
"""
|
5719
|
-
return self._append_standard_gate(StandardGate.
|
5750
|
+
return self._append_standard_gate(StandardGate.ISwap, [qubit1, qubit2], ())
|
5720
5751
|
|
5721
5752
|
def cswap(
|
5722
5753
|
self,
|
@@ -5745,7 +5776,7 @@ class QuantumCircuit:
|
|
5745
5776
|
# if the control state is |1> use the fast Rust version of the gate
|
5746
5777
|
if ctrl_state is None or ctrl_state in ["1", 1]:
|
5747
5778
|
return self._append_standard_gate(
|
5748
|
-
StandardGate.
|
5779
|
+
StandardGate.CSwap,
|
5749
5780
|
[control_qubit, target_qubit1, target_qubit2],
|
5750
5781
|
(),
|
5751
5782
|
label=label,
|
@@ -5771,7 +5802,7 @@ class QuantumCircuit:
|
|
5771
5802
|
Returns:
|
5772
5803
|
A handle to the instructions created.
|
5773
5804
|
"""
|
5774
|
-
return self._append_standard_gate(StandardGate.
|
5805
|
+
return self._append_standard_gate(StandardGate.SX, [qubit], ())
|
5775
5806
|
|
5776
5807
|
def sxdg(self, qubit: QubitSpecifier) -> InstructionSet:
|
5777
5808
|
"""Apply :class:`~qiskit.circuit.library.SXdgGate`.
|
@@ -5784,7 +5815,7 @@ class QuantumCircuit:
|
|
5784
5815
|
Returns:
|
5785
5816
|
A handle to the instructions created.
|
5786
5817
|
"""
|
5787
|
-
return self._append_standard_gate(StandardGate.
|
5818
|
+
return self._append_standard_gate(StandardGate.SXdg, [qubit], ())
|
5788
5819
|
|
5789
5820
|
def csx(
|
5790
5821
|
self,
|
@@ -5811,7 +5842,7 @@ class QuantumCircuit:
|
|
5811
5842
|
# if the control state is |1> use the fast Rust version of the gate
|
5812
5843
|
if ctrl_state is None or ctrl_state in ["1", 1]:
|
5813
5844
|
return self._append_standard_gate(
|
5814
|
-
StandardGate.
|
5845
|
+
StandardGate.CSX, [control_qubit, target_qubit], (), label=label
|
5815
5846
|
)
|
5816
5847
|
|
5817
5848
|
from .library.standard_gates.sx import CSXGate
|
@@ -5834,7 +5865,7 @@ class QuantumCircuit:
|
|
5834
5865
|
Returns:
|
5835
5866
|
A handle to the instructions created.
|
5836
5867
|
"""
|
5837
|
-
return self._append_standard_gate(StandardGate.
|
5868
|
+
return self._append_standard_gate(StandardGate.T, [qubit], ())
|
5838
5869
|
|
5839
5870
|
def tdg(self, qubit: QubitSpecifier) -> InstructionSet:
|
5840
5871
|
"""Apply :class:`~qiskit.circuit.library.TdgGate`.
|
@@ -5847,7 +5878,7 @@ class QuantumCircuit:
|
|
5847
5878
|
Returns:
|
5848
5879
|
A handle to the instructions created.
|
5849
5880
|
"""
|
5850
|
-
return self._append_standard_gate(StandardGate.
|
5881
|
+
return self._append_standard_gate(StandardGate.Tdg, [qubit], ())
|
5851
5882
|
|
5852
5883
|
def u(
|
5853
5884
|
self,
|
@@ -5869,7 +5900,7 @@ class QuantumCircuit:
|
|
5869
5900
|
Returns:
|
5870
5901
|
A handle to the instructions created.
|
5871
5902
|
"""
|
5872
|
-
return self._append_standard_gate(StandardGate.
|
5903
|
+
return self._append_standard_gate(StandardGate.U, [qubit], [theta, phi, lam])
|
5873
5904
|
|
5874
5905
|
def cu(
|
5875
5906
|
self,
|
@@ -5904,7 +5935,7 @@ class QuantumCircuit:
|
|
5904
5935
|
# if the control state is |1> use the fast Rust version of the gate
|
5905
5936
|
if ctrl_state is None or ctrl_state in ["1", 1]:
|
5906
5937
|
return self._append_standard_gate(
|
5907
|
-
StandardGate.
|
5938
|
+
StandardGate.CU,
|
5908
5939
|
[control_qubit, target_qubit],
|
5909
5940
|
[theta, phi, lam, gamma],
|
5910
5941
|
label=label,
|
@@ -5931,7 +5962,7 @@ class QuantumCircuit:
|
|
5931
5962
|
Returns:
|
5932
5963
|
A handle to the instructions created.
|
5933
5964
|
"""
|
5934
|
-
return self._append_standard_gate(StandardGate.
|
5965
|
+
return self._append_standard_gate(StandardGate.X, [qubit], (), label=label)
|
5935
5966
|
|
5936
5967
|
def cx(
|
5937
5968
|
self,
|
@@ -5958,7 +5989,7 @@ class QuantumCircuit:
|
|
5958
5989
|
# if the control state is |1> use the fast Rust version of the gate
|
5959
5990
|
if ctrl_state is None or ctrl_state in ["1", 1]:
|
5960
5991
|
return self._append_standard_gate(
|
5961
|
-
StandardGate.
|
5992
|
+
StandardGate.CX,
|
5962
5993
|
[control_qubit, target_qubit],
|
5963
5994
|
(),
|
5964
5995
|
label=label,
|
@@ -5985,7 +6016,7 @@ class QuantumCircuit:
|
|
5985
6016
|
Returns:
|
5986
6017
|
A handle to the instructions created.
|
5987
6018
|
"""
|
5988
|
-
return self._append_standard_gate(StandardGate.
|
6019
|
+
return self._append_standard_gate(StandardGate.DCX, [qubit1, qubit2], ())
|
5989
6020
|
|
5990
6021
|
def ccx(
|
5991
6022
|
self,
|
@@ -6012,7 +6043,7 @@ class QuantumCircuit:
|
|
6012
6043
|
# if the control state is |11> use the fast Rust version of the gate
|
6013
6044
|
if ctrl_state is None or ctrl_state in ["11", 3]:
|
6014
6045
|
return self._append_standard_gate(
|
6015
|
-
StandardGate.
|
6046
|
+
StandardGate.CCX,
|
6016
6047
|
[control_qubit1, control_qubit2, target_qubit],
|
6017
6048
|
(),
|
6018
6049
|
)
|
@@ -6026,12 +6057,21 @@ class QuantumCircuit:
|
|
6026
6057
|
copy=False,
|
6027
6058
|
)
|
6028
6059
|
|
6060
|
+
@deprecate_arg(
|
6061
|
+
name="mode",
|
6062
|
+
since="2.1",
|
6063
|
+
additional_msg=(
|
6064
|
+
"Instead, add a generic MCXGate to the circuit and specify the synthesis method "
|
6065
|
+
"via the ``hls_config`` in the transpilation. Alternatively, specific decompositions "
|
6066
|
+
"are available at https://qisk.it/mcx."
|
6067
|
+
),
|
6068
|
+
)
|
6029
6069
|
def mcx(
|
6030
6070
|
self,
|
6031
6071
|
control_qubits: Sequence[QubitSpecifier],
|
6032
6072
|
target_qubit: QubitSpecifier,
|
6033
6073
|
ancilla_qubits: QubitSpecifier | Sequence[QubitSpecifier] | None = None,
|
6034
|
-
mode: str =
|
6074
|
+
mode: str | None = None,
|
6035
6075
|
ctrl_state: str | int | None = None,
|
6036
6076
|
) -> InstructionSet:
|
6037
6077
|
"""Apply :class:`~qiskit.circuit.library.MCXGate`.
|
@@ -6067,46 +6107,62 @@ class QuantumCircuit:
|
|
6067
6107
|
num_ctrl_qubits = len(control_qubits)
|
6068
6108
|
|
6069
6109
|
available_implementations = {
|
6070
|
-
"noancilla"
|
6071
|
-
"recursion"
|
6072
|
-
"v-chain"
|
6073
|
-
"v-chain-dirty"
|
6074
|
-
|
6075
|
-
"
|
6076
|
-
"basic"
|
6077
|
-
"basic-dirty-ancilla": MCXVChain(
|
6078
|
-
num_ctrl_qubits, dirty_ancillas=True, ctrl_state=ctrl_state
|
6079
|
-
),
|
6110
|
+
"noancilla",
|
6111
|
+
"recursion",
|
6112
|
+
"v-chain",
|
6113
|
+
"v-chain-dirty",
|
6114
|
+
"advanced",
|
6115
|
+
"basic",
|
6116
|
+
"basic-dirty-ancilla",
|
6080
6117
|
}
|
6081
6118
|
|
6082
6119
|
# check ancilla input
|
6083
6120
|
if ancilla_qubits:
|
6084
6121
|
_ = self._qbit_argument_conversion(ancilla_qubits)
|
6085
6122
|
|
6086
|
-
|
6087
|
-
gate =
|
6088
|
-
|
6089
|
-
|
6123
|
+
if mode is None:
|
6124
|
+
gate = MCXGate(num_ctrl_qubits, ctrl_state=ctrl_state)
|
6125
|
+
elif mode in available_implementations:
|
6126
|
+
if mode == "noancilla":
|
6127
|
+
gate = MCXGate(num_ctrl_qubits, ctrl_state=ctrl_state)
|
6128
|
+
elif mode in ["recursion", "advanced"]:
|
6129
|
+
gate = MCXRecursive(num_ctrl_qubits, ctrl_state=ctrl_state)
|
6130
|
+
elif mode in ["v-chain", "basic"]:
|
6131
|
+
gate = MCXVChain(num_ctrl_qubits, False, ctrl_state=ctrl_state)
|
6132
|
+
elif mode in ["v-chain-dirty", "basic-dirty-ancilla"]:
|
6133
|
+
gate = MCXVChain(num_ctrl_qubits, dirty_ancillas=True, ctrl_state=ctrl_state)
|
6134
|
+
else:
|
6135
|
+
raise ValueError("unreachable.")
|
6136
|
+
# else is unreachable, we exhausted all options
|
6137
|
+
else:
|
6090
6138
|
raise ValueError(
|
6091
|
-
f"Unsupported mode ({mode}) selected, choose one of {
|
6092
|
-
)
|
6093
|
-
|
6094
|
-
if hasattr(gate, "num_ancilla_qubits") and gate.num_ancilla_qubits > 0:
|
6095
|
-
required = gate.num_ancilla_qubits
|
6096
|
-
if ancilla_qubits is None:
|
6097
|
-
raise AttributeError(f"No ancillas provided, but {required} are needed!")
|
6098
|
-
|
6099
|
-
# convert ancilla qubits to a list if they were passed as int or qubit
|
6100
|
-
if not hasattr(ancilla_qubits, "__len__"):
|
6101
|
-
ancilla_qubits = [ancilla_qubits]
|
6139
|
+
f"Unsupported mode ({mode}) selected, choose one of {available_implementations}"
|
6140
|
+
)
|
6102
6141
|
|
6103
|
-
|
6104
|
-
actually = len(ancilla_qubits)
|
6105
|
-
raise ValueError(f"At least {required} ancillas required, but {actually} given.")
|
6106
|
-
# size down if too many ancillas were provided
|
6107
|
-
ancilla_qubits = ancilla_qubits[:required]
|
6108
|
-
else:
|
6142
|
+
if mode is None or not hasattr(gate, "num_ancilla_qubits"):
|
6109
6143
|
ancilla_qubits = []
|
6144
|
+
else:
|
6145
|
+
with warnings.catch_warnings():
|
6146
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning, module="qiskit")
|
6147
|
+
required = gate.num_ancilla_qubits
|
6148
|
+
|
6149
|
+
if required > 0:
|
6150
|
+
if ancilla_qubits is None:
|
6151
|
+
raise AttributeError(f"No ancillas provided, but {required} are needed!")
|
6152
|
+
|
6153
|
+
# convert ancilla qubits to a list if they were passed as int or qubit
|
6154
|
+
if not hasattr(ancilla_qubits, "__len__"):
|
6155
|
+
ancilla_qubits = [ancilla_qubits]
|
6156
|
+
|
6157
|
+
if len(ancilla_qubits) < required:
|
6158
|
+
actually = len(ancilla_qubits)
|
6159
|
+
raise ValueError(
|
6160
|
+
f"At least {required} ancillas required, but {actually} given."
|
6161
|
+
)
|
6162
|
+
# size down if too many ancillas were provided
|
6163
|
+
ancilla_qubits = ancilla_qubits[:required]
|
6164
|
+
else:
|
6165
|
+
ancilla_qubits = []
|
6110
6166
|
|
6111
6167
|
return self.append(gate, control_qubits[:] + [target_qubit] + ancilla_qubits[:], [])
|
6112
6168
|
|
@@ -6121,7 +6177,7 @@ class QuantumCircuit:
|
|
6121
6177
|
Returns:
|
6122
6178
|
A handle to the instructions created.
|
6123
6179
|
"""
|
6124
|
-
return self._append_standard_gate(StandardGate.
|
6180
|
+
return self._append_standard_gate(StandardGate.Y, [qubit], ())
|
6125
6181
|
|
6126
6182
|
def cy(
|
6127
6183
|
self,
|
@@ -6148,7 +6204,7 @@ class QuantumCircuit:
|
|
6148
6204
|
# if the control state is |1> use the fast Rust version of the gate
|
6149
6205
|
if ctrl_state is None or ctrl_state in ["1", 1]:
|
6150
6206
|
return self._append_standard_gate(
|
6151
|
-
StandardGate.
|
6207
|
+
StandardGate.CY,
|
6152
6208
|
[control_qubit, target_qubit],
|
6153
6209
|
(),
|
6154
6210
|
label=label,
|
@@ -6174,7 +6230,7 @@ class QuantumCircuit:
|
|
6174
6230
|
Returns:
|
6175
6231
|
A handle to the instructions created.
|
6176
6232
|
"""
|
6177
|
-
return self._append_standard_gate(StandardGate.
|
6233
|
+
return self._append_standard_gate(StandardGate.Z, [qubit], ())
|
6178
6234
|
|
6179
6235
|
def cz(
|
6180
6236
|
self,
|
@@ -6201,7 +6257,7 @@ class QuantumCircuit:
|
|
6201
6257
|
# if the control state is |1> use the fast Rust version of the gate
|
6202
6258
|
if ctrl_state is None or ctrl_state in ["1", 1]:
|
6203
6259
|
return self._append_standard_gate(
|
6204
|
-
StandardGate.
|
6260
|
+
StandardGate.CZ, [control_qubit, target_qubit], (), label=label
|
6205
6261
|
)
|
6206
6262
|
|
6207
6263
|
from .library.standard_gates.z import CZGate
|
@@ -6240,7 +6296,7 @@ class QuantumCircuit:
|
|
6240
6296
|
# if the control state is |11> use the fast Rust version of the gate
|
6241
6297
|
if ctrl_state is None or ctrl_state in ["11", 3]:
|
6242
6298
|
return self._append_standard_gate(
|
6243
|
-
StandardGate.
|
6299
|
+
StandardGate.CCZ,
|
6244
6300
|
[control_qubit1, control_qubit2, target_qubit],
|
6245
6301
|
(),
|
6246
6302
|
label=label,
|
@@ -6663,16 +6719,15 @@ class QuantumCircuit:
|
|
6663
6719
|
|
6664
6720
|
def box(
|
6665
6721
|
self,
|
6666
|
-
|
6667
|
-
# allow `annotations` to be passed as the positional argument in the context-manager form.
|
6668
|
-
body: QuantumCircuit | None = None,
|
6722
|
+
body_or_annotations: QuantumCircuit | typing.Iterable[Annotation] = ...,
|
6669
6723
|
/,
|
6670
6724
|
qubits: Sequence[QubitSpecifier] | None = None,
|
6671
6725
|
clbits: Sequence[ClbitSpecifier] | None = None,
|
6672
6726
|
*,
|
6673
6727
|
label: str | None = None,
|
6674
6728
|
duration: None = None,
|
6675
|
-
unit: Literal["dt", "s", "ms", "us", "ns", "ps"] =
|
6729
|
+
unit: Literal["dt", "s", "ms", "us", "ns", "ps", "expr"] | None = None,
|
6730
|
+
annotations: typing.Iterable[Annotation] = ...,
|
6676
6731
|
):
|
6677
6732
|
"""Create a ``box`` of operations on this circuit that are treated atomically in the greater
|
6678
6733
|
context.
|
@@ -6701,13 +6756,16 @@ class QuantumCircuit:
|
|
6701
6756
|
|
6702
6757
|
.. code-block:: python
|
6703
6758
|
|
6704
|
-
from qiskit.circuit import QuantumCircuit
|
6759
|
+
from qiskit.circuit import QuantumCircuit, Annotation
|
6760
|
+
|
6761
|
+
class MyAnnotation(Annotation):
|
6762
|
+
namespace = "my.namespace"
|
6705
6763
|
|
6706
6764
|
qc = QuantumCircuit(9)
|
6707
6765
|
with qc.box():
|
6708
6766
|
qc.cz(0, 1)
|
6709
6767
|
qc.cz(2, 3)
|
6710
|
-
with qc.box():
|
6768
|
+
with qc.box([MyAnnotation()]):
|
6711
6769
|
qc.cz(4, 5)
|
6712
6770
|
qc.cz(6, 7)
|
6713
6771
|
qc.noop(8)
|
@@ -6735,8 +6793,11 @@ class QuantumCircuit:
|
|
6735
6793
|
qc.box(body_1, [4, 5, 6, 7, 8], [])
|
6736
6794
|
|
6737
6795
|
Args:
|
6738
|
-
|
6739
|
-
|
6796
|
+
body_or_annotations: the first positional argument is unnamed. If a
|
6797
|
+
:class:`QuantumCircuit` is passed positionally, it is immediately used as the body
|
6798
|
+
of the box, and ``qubits`` and ``clbits`` must also be specified. If not given, or
|
6799
|
+
if given an iterable of :class:`.Annotation` objects, the context-manager form of
|
6800
|
+
this method is triggered.
|
6740
6801
|
qubits: the qubits to apply the :class:`.BoxOp` to, in the explicit form.
|
6741
6802
|
clbits: the qubits to apply the :class:`.BoxOp` to, in the explicit form.
|
6742
6803
|
label: an optional string label for the instruction.
|
@@ -6744,23 +6805,35 @@ class QuantumCircuit:
|
|
6744
6805
|
constrained to schedule the contained scope to match a given duration, including
|
6745
6806
|
delay insertion if required.
|
6746
6807
|
unit: the unit of the ``duration``.
|
6808
|
+
annotations: any :class:`.Annotation` objects the box should have. When this method is
|
6809
|
+
used in context-manager form, this argument can instead be passed as the only
|
6810
|
+
positional argument.
|
6747
6811
|
"""
|
6748
|
-
if isinstance(
|
6812
|
+
if isinstance(body_or_annotations, QuantumCircuit):
|
6749
6813
|
# Explicit-body form.
|
6814
|
+
body = body_or_annotations
|
6750
6815
|
if qubits is None or clbits is None:
|
6751
6816
|
raise CircuitError("When using 'box' with a body, you must pass qubits and clbits.")
|
6817
|
+
if annotations is Ellipsis:
|
6818
|
+
annotations = []
|
6752
6819
|
return self.append(
|
6753
|
-
BoxOp(body, duration=duration, unit=unit, label=label),
|
6820
|
+
BoxOp(body, duration=duration, unit=unit, label=label, annotations=annotations),
|
6754
6821
|
qubits,
|
6755
6822
|
clbits,
|
6756
6823
|
copy=False,
|
6757
6824
|
)
|
6825
|
+
if body_or_annotations is ...:
|
6826
|
+
annotations = () if annotations is ... else annotations
|
6827
|
+
elif annotations is not ...:
|
6828
|
+
raise TypeError("QuantumCircuit.box() got multiple values for argument 'annotations'")
|
6829
|
+
else:
|
6830
|
+
annotations = body_or_annotations
|
6758
6831
|
# Context-manager form.
|
6759
6832
|
if qubits is not None or clbits is not None:
|
6760
6833
|
raise CircuitError(
|
6761
6834
|
"When using 'box' as a context manager, you cannot pass qubits or clbits."
|
6762
6835
|
)
|
6763
|
-
return BoxContext(self, duration=duration, unit=unit, label=label)
|
6836
|
+
return BoxContext(self, duration=duration, unit=unit, label=label, annotations=annotations)
|
6764
6837
|
|
6765
6838
|
@typing.overload
|
6766
6839
|
def while_loop(
|