qiskit 2.0.1__cp39-abi3-win_amd64.whl → 2.1.0rc1__cp39-abi3-win_amd64.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.pyd +0 -0
- qiskit/circuit/__init__.py +13 -21
- qiskit/circuit/_add_control.py +57 -31
- qiskit/circuit/_classical_resource_map.py +4 -0
- qiskit/circuit/annotation.py +404 -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 +5 -5
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +3 -3
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +7 -3
- 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 +5 -5
- 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 +4 -2
- 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 +168 -98
- 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 +183 -7
- 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/quantum_info/operators/symplectic/sparse_pauli_op.py +1 -1
- 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 +19 -8
- qiskit/transpiler/instruction_durations.py +2 -20
- qiskit/transpiler/passes/__init__.py +4 -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 +13 -1
- qiskit/transpiler/passes/optimization/__init__.py +1 -1
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +6 -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 +12 -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 +472 -92
- 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/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.1.dist-info → qiskit-2.1.0rc1.dist-info}/METADATA +14 -13
- {qiskit-2.0.1.dist-info → qiskit-2.1.0rc1.dist-info}/RECORD +178 -169
- {qiskit-2.0.1.dist-info → qiskit-2.1.0rc1.dist-info}/WHEEL +1 -1
- {qiskit-2.0.1.dist-info → qiskit-2.1.0rc1.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.1.dist-info → qiskit-2.1.0rc1.dist-info}/licenses/LICENSE.txt +0 -0
- {qiskit-2.0.1.dist-info → qiskit-2.1.0rc1.dist-info}/top_level.txt +0 -0
qiskit/VERSION.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.1.0rc1
|
qiskit/__init__.py
CHANGED
@@ -44,6 +44,14 @@ else:
|
|
44
44
|
" See https://qisk.it/packaging-1-0 for more detail."
|
45
45
|
)
|
46
46
|
|
47
|
+
if sys.version_info < (3, 10):
|
48
|
+
warnings.warn(
|
49
|
+
"Using Qiskit with Python 3.9 is deprecated as of the 2.1.0 release. "
|
50
|
+
"Support for running Qiskit with Python 3.9 will be removed in the "
|
51
|
+
"2.3.0 release, which coincides with when Python 3.9 goes end of life.",
|
52
|
+
DeprecationWarning,
|
53
|
+
)
|
54
|
+
|
47
55
|
from . import _accelerate
|
48
56
|
import qiskit._numpy_compat
|
49
57
|
|
@@ -52,10 +60,14 @@ import qiskit._numpy_compat
|
|
52
60
|
# We manually define them on import so people can directly import qiskit._accelerate.* submodules
|
53
61
|
# and not have to rely on attribute access. No action needed for top-level extension packages.
|
54
62
|
sys.modules["qiskit._accelerate.circuit"] = _accelerate.circuit
|
63
|
+
sys.modules["qiskit._accelerate.circuit.classical"] = _accelerate.circuit.classical
|
64
|
+
sys.modules["qiskit._accelerate.circuit.classical.expr"] = _accelerate.circuit.classical.expr
|
65
|
+
sys.modules["qiskit._accelerate.circuit.classical.types"] = _accelerate.circuit.classical.types
|
55
66
|
sys.modules["qiskit._accelerate.circuit_library"] = _accelerate.circuit_library
|
56
67
|
sys.modules["qiskit._accelerate.basis_translator"] = _accelerate.basis_translator
|
57
68
|
sys.modules["qiskit._accelerate.converters"] = _accelerate.converters
|
58
69
|
sys.modules["qiskit._accelerate.dense_layout"] = _accelerate.dense_layout
|
70
|
+
sys.modules["qiskit._accelerate.disjoint_utils"] = _accelerate.disjoint_utils
|
59
71
|
sys.modules["qiskit._accelerate.equivalence"] = _accelerate.equivalence
|
60
72
|
sys.modules["qiskit._accelerate.error_map"] = _accelerate.error_map
|
61
73
|
sys.modules["qiskit._accelerate.gates_in_basis"] = _accelerate.gates_in_basis
|
@@ -64,9 +76,13 @@ sys.modules["qiskit._accelerate.uc_gate"] = _accelerate.uc_gate
|
|
64
76
|
sys.modules["qiskit._accelerate.euler_one_qubit_decomposer"] = (
|
65
77
|
_accelerate.euler_one_qubit_decomposer
|
66
78
|
)
|
79
|
+
sys.modules["qiskit._accelerate.optimize_1q_gates_decomposition"] = (
|
80
|
+
_accelerate.optimize_1q_gates_decomposition
|
81
|
+
)
|
67
82
|
sys.modules["qiskit._accelerate.nlayout"] = _accelerate.nlayout
|
68
83
|
sys.modules["qiskit._accelerate.optimize_1q_gates"] = _accelerate.optimize_1q_gates
|
69
84
|
sys.modules["qiskit._accelerate.pauli_expval"] = _accelerate.pauli_expval
|
85
|
+
sys.modules["qiskit._accelerate.pauli_lindblad_map"] = _accelerate.pauli_lindblad_map
|
70
86
|
sys.modules["qiskit._accelerate.qasm2"] = _accelerate.qasm2
|
71
87
|
sys.modules["qiskit._accelerate.qasm3"] = _accelerate.qasm3
|
72
88
|
sys.modules["qiskit._accelerate.remove_diagonal_gates_before_measure"] = (
|
@@ -77,7 +93,6 @@ sys.modules["qiskit._accelerate.sabre"] = _accelerate.sabre
|
|
77
93
|
sys.modules["qiskit._accelerate.sampled_exp_val"] = _accelerate.sampled_exp_val
|
78
94
|
sys.modules["qiskit._accelerate.sparse_observable"] = _accelerate.sparse_observable
|
79
95
|
sys.modules["qiskit._accelerate.sparse_pauli_op"] = _accelerate.sparse_pauli_op
|
80
|
-
sys.modules["qiskit._accelerate.star_prerouting"] = _accelerate.star_prerouting
|
81
96
|
sys.modules["qiskit._accelerate.elide_permutations"] = _accelerate.elide_permutations
|
82
97
|
sys.modules["qiskit._accelerate.target"] = _accelerate.target
|
83
98
|
sys.modules["qiskit._accelerate.two_qubit_decompose"] = _accelerate.two_qubit_decompose
|
@@ -95,9 +110,11 @@ sys.modules["qiskit._accelerate.commutation_cancellation"] = _accelerate.commuta
|
|
95
110
|
sys.modules["qiskit._accelerate.consolidate_blocks"] = _accelerate.consolidate_blocks
|
96
111
|
sys.modules["qiskit._accelerate.synthesis.linear_phase"] = _accelerate.synthesis.linear_phase
|
97
112
|
sys.modules["qiskit._accelerate.synthesis.evolution"] = _accelerate.synthesis.evolution
|
113
|
+
sys.modules["qiskit._accelerate.synthesis.discrete_basis"] = _accelerate.synthesis.discrete_basis
|
98
114
|
sys.modules["qiskit._accelerate.synthesis.multi_controlled"] = (
|
99
115
|
_accelerate.synthesis.multi_controlled
|
100
116
|
)
|
117
|
+
sys.modules["qiskit._accelerate.synthesis.qft"] = _accelerate.synthesis.qft
|
101
118
|
sys.modules["qiskit._accelerate.split_2q_unitaries"] = _accelerate.split_2q_unitaries
|
102
119
|
sys.modules["qiskit._accelerate.gate_direction"] = _accelerate.gate_direction
|
103
120
|
sys.modules["qiskit._accelerate.inverse_cancellation"] = _accelerate.inverse_cancellation
|
@@ -107,6 +124,7 @@ sys.modules["qiskit._accelerate.twirling"] = _accelerate.twirling
|
|
107
124
|
sys.modules["qiskit._accelerate.high_level_synthesis"] = _accelerate.high_level_synthesis
|
108
125
|
sys.modules["qiskit._accelerate.remove_identity_equiv"] = _accelerate.remove_identity_equiv
|
109
126
|
sys.modules["qiskit._accelerate.circuit_duration"] = _accelerate.circuit_duration
|
127
|
+
sys.modules["qiskit._accelerate.cos_sin_decomp"] = _accelerate.cos_sin_decomp
|
110
128
|
|
111
129
|
from qiskit.exceptions import QiskitError, MissingOptionalLibraryError
|
112
130
|
|
qiskit/_accelerate.pyd
CHANGED
Binary file
|
qiskit/circuit/__init__.py
CHANGED
@@ -269,11 +269,16 @@ circuit. The top-level ones are:
|
|
269
269
|
* :class:`ControlFlowOp`, which has specific subclasses:
|
270
270
|
* :class:`BreakLoopOp`, to break out of the nearest containing loop
|
271
271
|
* :class:`ContinueLoopOp`, to move immediately to the next iteration of the containing loop
|
272
|
+
* :class:`BoxOp`, a simple grouping of instructions
|
272
273
|
* :class:`ForLoopOp`, to loop over a fixed range of values
|
273
274
|
* :class:`IfElseOp`, to conditionally enter one of two subcircuits
|
274
275
|
* :class:`SwitchCaseOp`, to conditionally enter one of many subcircuits
|
275
|
-
* :class:`WhileLoopOp`, to repeat a subcircuit until a condition is falsified
|
276
|
-
|
276
|
+
* :class:`WhileLoopOp`, to repeat a subcircuit until a condition is falsified.
|
277
|
+
|
278
|
+
Certain instructions can be "annotated" with metadata, which is typically intended to be consumed by
|
279
|
+
a compiler pass either locally, or in later backend processing. Currently this is limited to
|
280
|
+
:class:`BoxOp`. These annotations are represented by custom subclasses of :class:`Annotation`, and
|
281
|
+
there is further discussion of the support infrastructure in :mod:`qiskit.circuit.annotation`.
|
277
282
|
|
278
283
|
:ref:`Circuits can include classical expressions that are evaluated in real time
|
279
284
|
<circuit-repr-real-time-classical>`, while the QPU is executing a single shot of the circuit. These
|
@@ -307,6 +312,7 @@ assist compilation workflows. These include:
|
|
307
312
|
There are also utilities for generating random circuits:
|
308
313
|
|
309
314
|
* :func:`random.random_circuit`
|
315
|
+
* :func:`random.random_circuit_from_graph`
|
310
316
|
* :func:`random.random_clifford_circuit`
|
311
317
|
|
312
318
|
Finally, the circuit module has its own exception class, to indicate when things went wrong in
|
@@ -560,8 +566,6 @@ Hardware can be instructed to apply a real-time idle period on a given qubit. A
|
|
560
566
|
|
561
567
|
.. autoclass:: Delay
|
562
568
|
:show-inheritance:
|
563
|
-
.. autoclass:: Duration
|
564
|
-
|
565
569
|
|
566
570
|
The :class:`Barrier` instruction can span an arbitrary number of qubits and clbits, and is a no-op
|
567
571
|
in hardware. During transpilation and optimization, however, it blocks any optimizations from
|
@@ -711,9 +715,9 @@ classes associated to each name.
|
|
711
715
|
.. autofunction:: get_control_flow_name_mapping
|
712
716
|
|
713
717
|
These control-flow operations (:class:`IfElseOp`, :class:`WhileLoopOp`,
|
714
|
-
:class:`SwitchCaseOp
|
715
|
-
|
716
|
-
|
718
|
+
:class:`SwitchCaseOp` and :class:`ForLoopOp`) all have specific state that defines the branching
|
719
|
+
conditions and strategies, but contain all the different subcircuit blocks that might be entered in
|
720
|
+
their :attr:`~ControlFlowOp.blocks` property.
|
717
721
|
|
718
722
|
.. autosummary::
|
719
723
|
:toctree: ../stubs/
|
@@ -722,7 +726,6 @@ might be entered in their :attr:`~ControlFlowOp.blocks` property.
|
|
722
726
|
WhileLoopOp
|
723
727
|
SwitchCaseOp
|
724
728
|
ForLoopOp
|
725
|
-
BoxOp
|
726
729
|
|
727
730
|
The :class:`.SwitchCaseOp` also understands a special value:
|
728
731
|
|
@@ -1053,19 +1056,6 @@ default instances of the :class:`.BasisTranslator`.
|
|
1053
1056
|
:data:`StandardEquivalenceLibrary`.
|
1054
1057
|
|
1055
1058
|
|
1056
|
-
|
1057
|
-
Generating random circuits
|
1058
|
-
--------------------------
|
1059
|
-
|
1060
|
-
..
|
1061
|
-
If we expand these capabilities in the future, it's probably best to move it to its own
|
1062
|
-
module-level documentation page than to expand this "inline" module documentation.
|
1063
|
-
|
1064
|
-
.. currentmodule:: qiskit.circuit.random
|
1065
|
-
.. autofunction:: random_circuit
|
1066
|
-
.. autofunction:: random_clifford_circuit
|
1067
|
-
.. currentmodule:: qiskit.circuit
|
1068
|
-
|
1069
1059
|
Apply Pauli twirling to a circuit
|
1070
1060
|
---------------------------------
|
1071
1061
|
|
@@ -1306,6 +1296,8 @@ from .quantumcircuit import QuantumCircuit
|
|
1306
1296
|
from .gate import Gate
|
1307
1297
|
|
1308
1298
|
# pylint: disable=cyclic-import
|
1299
|
+
from . import annotation
|
1300
|
+
from .annotation import Annotation
|
1309
1301
|
from .controlledgate import ControlledGate
|
1310
1302
|
from . import singleton
|
1311
1303
|
from .instruction import Instruction
|
qiskit/circuit/_add_control.py
CHANGED
@@ -24,21 +24,47 @@ from . import ControlledGate, Gate, QuantumRegister, QuantumCircuit
|
|
24
24
|
from ._utils import _ctrl_state_to_int
|
25
25
|
|
26
26
|
|
27
|
+
# The list of gates whose controlled versions have efficient synthesis algorithms.
|
28
|
+
# For example, a controlled version of X is MCX (with many synthesis algorithms avalable),
|
29
|
+
# and a controlled version of Z is MCX + two Hadamard gates.
|
30
|
+
#
|
31
|
+
# Note: when adding a new gate to this list, also add the decomposition of its controlled
|
32
|
+
# version to apply_basic_controlled_gate.
|
33
|
+
EFFICIENTLY_CONTROLLED_GATES = [
|
34
|
+
"p",
|
35
|
+
"u",
|
36
|
+
"x",
|
37
|
+
"z",
|
38
|
+
"y",
|
39
|
+
"h",
|
40
|
+
"sx",
|
41
|
+
"sxdg",
|
42
|
+
"rx",
|
43
|
+
"ry",
|
44
|
+
"rz",
|
45
|
+
"cx",
|
46
|
+
"cz",
|
47
|
+
]
|
48
|
+
|
49
|
+
|
27
50
|
def add_control(
|
28
51
|
operation: Gate | ControlledGate,
|
29
52
|
num_ctrl_qubits: int,
|
30
53
|
label: str | None,
|
31
54
|
ctrl_state: str | int | None,
|
32
55
|
) -> ControlledGate:
|
33
|
-
"""
|
34
|
-
library, it will be returned (e.g. XGate.control() = CnotGate().
|
56
|
+
"""Return the controlled version of the gate.
|
35
57
|
|
36
|
-
|
37
|
-
|
38
|
-
|
58
|
+
This function first checks whether the gate's name corresponds to a known
|
59
|
+
method for generating its controlled version. Currently, these methods exist
|
60
|
+
for gates in ``EFFICIENTLY_CONTROLLED_GATES``.
|
39
61
|
|
40
|
-
|
41
|
-
|
62
|
+
For gates not in ``EFFICIENTLY_CONTROLLED_GATES``, the function calls the unroller
|
63
|
+
to decompose the gate into gates in ``EFFICIENTLY_CONTROLLED_GATES``,
|
64
|
+
and then generates the controlled version by controlling every gate in this
|
65
|
+
decomposition.
|
66
|
+
|
67
|
+
Open controls are implemented by conjugating the control line with X gates.
|
42
68
|
|
43
69
|
This function is meant to be called from the
|
44
70
|
:method:`qiskit.circuit.gate.Gate.control()` method.
|
@@ -72,11 +98,18 @@ def control(
|
|
72
98
|
label: str | None = None,
|
73
99
|
ctrl_state: str | int | None = None,
|
74
100
|
) -> ControlledGate:
|
75
|
-
"""Return controlled version of gate
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
101
|
+
"""Return the controlled version of the gate.
|
102
|
+
|
103
|
+
This function first checks whether the gate's name corresponds to a known
|
104
|
+
method for generating its controlled version. Currently, these methods exist
|
105
|
+
for gates in ``EFFICIENTLY_CONTROLLED_GATES``.
|
106
|
+
|
107
|
+
For gates not in ``EFFICIENTLY_CONTROLLED_GATES``, the function calls the unroller
|
108
|
+
to decompose the gate into gates in ``EFFICIENTLY_CONTROLLED_GATES``,
|
109
|
+
and then generates the controlled version by controlling every gate in this
|
110
|
+
decomposition.
|
111
|
+
|
112
|
+
Open controls are implemented by conjugating the control line with X gates.
|
80
113
|
|
81
114
|
Args:
|
82
115
|
operation: The gate used to create the ControlledGate.
|
@@ -109,16 +142,14 @@ def control(
|
|
109
142
|
|
110
143
|
global_phase = 0
|
111
144
|
|
112
|
-
|
113
|
-
|
114
|
-
if operation.name in basis:
|
115
|
-
apply_basic_controlled_gate(controlled_circ, operation, q_control, q_target[0])
|
145
|
+
if operation.name in EFFICIENTLY_CONTROLLED_GATES:
|
146
|
+
apply_basic_controlled_gate(controlled_circ, operation, q_control, q_target)
|
116
147
|
else:
|
117
148
|
if isinstance(operation, controlledgate.ControlledGate):
|
118
149
|
operation = operation.to_mutable()
|
119
150
|
operation.ctrl_state = None
|
120
151
|
|
121
|
-
unrolled_gate = _unroll_gate(operation, basis_gates=
|
152
|
+
unrolled_gate = _unroll_gate(operation, basis_gates=EFFICIENTLY_CONTROLLED_GATES)
|
122
153
|
if unrolled_gate.definition.global_phase:
|
123
154
|
global_phase += unrolled_gate.definition.global_phase
|
124
155
|
|
@@ -139,9 +170,6 @@ def control(
|
|
139
170
|
|
140
171
|
apply_basic_controlled_gate(controlled_circ, gate, q_control, target)
|
141
172
|
|
142
|
-
if gate.definition is not None and gate.definition.global_phase and gate.name != "rz":
|
143
|
-
global_phase += gate.definition.global_phase
|
144
|
-
|
145
173
|
# apply controlled global phase
|
146
174
|
if global_phase:
|
147
175
|
if len(q_control) < 2:
|
@@ -185,16 +213,14 @@ def control(
|
|
185
213
|
def apply_basic_controlled_gate(circuit, gate, controls, target):
|
186
214
|
"""Apply a controlled version of ``gate`` to the circuit.
|
187
215
|
|
188
|
-
This implements multi-control operations for
|
189
|
-
|
190
|
-
["p", "u", "x", "z", "y", "h", "sx", "sxdg", "rx", "ry", "rz", "cx"]
|
216
|
+
This implements multi-control operations for every gate in
|
217
|
+
``EFFICIENTLY_CONTROLLED_GATES``.
|
191
218
|
|
192
219
|
"""
|
193
220
|
num_ctrl_qubits = len(controls)
|
194
221
|
|
195
222
|
if gate.name == "x":
|
196
223
|
circuit.mcx(controls, target)
|
197
|
-
|
198
224
|
elif gate.name == "rx":
|
199
225
|
circuit.mcrx(
|
200
226
|
gate.definition.data[0].operation.params[0],
|
@@ -217,7 +243,6 @@ def apply_basic_controlled_gate(circuit, gate, controls, target):
|
|
217
243
|
target,
|
218
244
|
use_basis_gates=False,
|
219
245
|
)
|
220
|
-
# continue
|
221
246
|
elif gate.name == "p":
|
222
247
|
from qiskit.circuit.library import MCPhaseGate
|
223
248
|
|
@@ -230,6 +255,13 @@ def apply_basic_controlled_gate(circuit, gate, controls, target):
|
|
230
255
|
controls[:] + [target[0]], # CX has two targets
|
231
256
|
target[1],
|
232
257
|
)
|
258
|
+
elif gate.name == "cz":
|
259
|
+
circuit.h(target[1])
|
260
|
+
circuit.mcx(
|
261
|
+
controls[:] + [target[0]], # CZ has two targets
|
262
|
+
target[1],
|
263
|
+
)
|
264
|
+
circuit.h(target[1])
|
233
265
|
elif gate.name == "u":
|
234
266
|
theta, phi, lamb = gate.params
|
235
267
|
if num_ctrl_qubits == 1:
|
@@ -254,17 +286,14 @@ def apply_basic_controlled_gate(circuit, gate, controls, target):
|
|
254
286
|
circuit.mcry(theta, controls, target, use_basis_gates=False)
|
255
287
|
circuit.mcrz(phi, controls, target, use_basis_gates=False)
|
256
288
|
circuit.mcp((phi + lamb) / 2, controls[1:], controls[0])
|
257
|
-
|
258
289
|
elif gate.name == "z":
|
259
290
|
circuit.h(target)
|
260
291
|
circuit.mcx(controls, target)
|
261
292
|
circuit.h(target)
|
262
|
-
|
263
293
|
elif gate.name == "y":
|
264
294
|
circuit.sdg(target)
|
265
295
|
circuit.mcx(controls, target)
|
266
296
|
circuit.s(target)
|
267
|
-
|
268
297
|
elif gate.name == "h":
|
269
298
|
circuit.s(target)
|
270
299
|
circuit.h(target)
|
@@ -273,17 +302,14 @@ def apply_basic_controlled_gate(circuit, gate, controls, target):
|
|
273
302
|
circuit.tdg(target)
|
274
303
|
circuit.h(target)
|
275
304
|
circuit.sdg(target)
|
276
|
-
|
277
305
|
elif gate.name == "sx":
|
278
306
|
circuit.h(target)
|
279
307
|
circuit.mcp(pi / 2, controls, target)
|
280
308
|
circuit.h(target)
|
281
|
-
|
282
309
|
elif gate.name == "sxdg":
|
283
310
|
circuit.h(target)
|
284
311
|
circuit.mcp(3 * pi / 2, controls, target)
|
285
312
|
circuit.h(target)
|
286
|
-
|
287
313
|
else:
|
288
314
|
raise CircuitError(f"Gate {gate} not in supported basis.")
|
289
315
|
|
@@ -36,6 +36,10 @@ class VariableMapper(expr.ExprVisitor[expr.Expr]):
|
|
36
36
|
``ValueError`` will be raised instead. The given ``add_register`` callable may choose to raise
|
37
37
|
its own exception."""
|
38
38
|
|
39
|
+
# We don't want docstrings for the inherited visitor methods, which are self-explanatory and
|
40
|
+
# would just be noise.
|
41
|
+
# pylint: disable=missing-function-docstring
|
42
|
+
|
39
43
|
__slots__ = ("target_cregs", "register_map", "bit_map", "var_map", "add_register")
|
40
44
|
|
41
45
|
def __init__(
|