qiskit 2.0.2__cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl → 2.1.0rc1__cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.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 (179) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +19 -1
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/circuit/__init__.py +13 -21
  5. qiskit/circuit/_add_control.py +57 -31
  6. qiskit/circuit/_classical_resource_map.py +4 -0
  7. qiskit/circuit/annotation.py +404 -0
  8. qiskit/circuit/classical/expr/__init__.py +1 -1
  9. qiskit/circuit/classical/expr/expr.py +104 -446
  10. qiskit/circuit/classical/expr/visitors.py +6 -0
  11. qiskit/circuit/classical/types/types.py +7 -130
  12. qiskit/circuit/controlflow/box.py +32 -7
  13. qiskit/circuit/delay.py +11 -9
  14. qiskit/circuit/library/arithmetic/adders/adder.py +5 -5
  15. qiskit/circuit/library/arithmetic/multipliers/multiplier.py +3 -3
  16. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +7 -3
  17. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +23 -15
  18. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +22 -14
  19. qiskit/circuit/library/arithmetic/quadratic_form.py +6 -0
  20. qiskit/circuit/library/arithmetic/weighted_adder.py +43 -24
  21. qiskit/circuit/library/basis_change/qft.py +2 -2
  22. qiskit/circuit/library/blueprintcircuit.py +6 -0
  23. qiskit/circuit/library/boolean_logic/inner_product.py +2 -2
  24. qiskit/circuit/library/boolean_logic/quantum_and.py +2 -2
  25. qiskit/circuit/library/boolean_logic/quantum_or.py +3 -3
  26. qiskit/circuit/library/boolean_logic/quantum_xor.py +2 -2
  27. qiskit/circuit/library/data_preparation/_z_feature_map.py +2 -2
  28. qiskit/circuit/library/data_preparation/_zz_feature_map.py +2 -2
  29. qiskit/circuit/library/data_preparation/pauli_feature_map.py +2 -2
  30. qiskit/circuit/library/fourier_checking.py +2 -2
  31. qiskit/circuit/library/generalized_gates/diagonal.py +5 -1
  32. qiskit/circuit/library/generalized_gates/gms.py +5 -1
  33. qiskit/circuit/library/generalized_gates/linear_function.py +2 -2
  34. qiskit/circuit/library/generalized_gates/permutation.py +5 -1
  35. qiskit/circuit/library/generalized_gates/uc.py +1 -1
  36. qiskit/circuit/library/generalized_gates/unitary.py +21 -2
  37. qiskit/circuit/library/graph_state.py +2 -2
  38. qiskit/circuit/library/grover_operator.py +2 -2
  39. qiskit/circuit/library/hidden_linear_function.py +2 -2
  40. qiskit/circuit/library/iqp.py +2 -2
  41. qiskit/circuit/library/n_local/efficient_su2.py +2 -2
  42. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
  43. qiskit/circuit/library/n_local/excitation_preserving.py +7 -9
  44. qiskit/circuit/library/n_local/n_local.py +4 -3
  45. qiskit/circuit/library/n_local/pauli_two_design.py +2 -2
  46. qiskit/circuit/library/n_local/real_amplitudes.py +2 -2
  47. qiskit/circuit/library/n_local/two_local.py +2 -2
  48. qiskit/circuit/library/overlap.py +2 -2
  49. qiskit/circuit/library/pauli_evolution.py +3 -2
  50. qiskit/circuit/library/phase_estimation.py +2 -2
  51. qiskit/circuit/library/standard_gates/dcx.py +11 -12
  52. qiskit/circuit/library/standard_gates/ecr.py +21 -24
  53. qiskit/circuit/library/standard_gates/equivalence_library.py +232 -96
  54. qiskit/circuit/library/standard_gates/global_phase.py +5 -6
  55. qiskit/circuit/library/standard_gates/h.py +22 -45
  56. qiskit/circuit/library/standard_gates/i.py +1 -1
  57. qiskit/circuit/library/standard_gates/iswap.py +13 -31
  58. qiskit/circuit/library/standard_gates/p.py +19 -26
  59. qiskit/circuit/library/standard_gates/r.py +11 -17
  60. qiskit/circuit/library/standard_gates/rx.py +21 -45
  61. qiskit/circuit/library/standard_gates/rxx.py +7 -22
  62. qiskit/circuit/library/standard_gates/ry.py +21 -39
  63. qiskit/circuit/library/standard_gates/ryy.py +13 -28
  64. qiskit/circuit/library/standard_gates/rz.py +18 -35
  65. qiskit/circuit/library/standard_gates/rzx.py +7 -22
  66. qiskit/circuit/library/standard_gates/rzz.py +7 -19
  67. qiskit/circuit/library/standard_gates/s.py +44 -39
  68. qiskit/circuit/library/standard_gates/swap.py +25 -38
  69. qiskit/circuit/library/standard_gates/sx.py +34 -41
  70. qiskit/circuit/library/standard_gates/t.py +18 -27
  71. qiskit/circuit/library/standard_gates/u.py +8 -24
  72. qiskit/circuit/library/standard_gates/u1.py +28 -52
  73. qiskit/circuit/library/standard_gates/u2.py +9 -9
  74. qiskit/circuit/library/standard_gates/u3.py +24 -40
  75. qiskit/circuit/library/standard_gates/x.py +190 -336
  76. qiskit/circuit/library/standard_gates/xx_minus_yy.py +12 -50
  77. qiskit/circuit/library/standard_gates/xx_plus_yy.py +13 -52
  78. qiskit/circuit/library/standard_gates/y.py +19 -23
  79. qiskit/circuit/library/standard_gates/z.py +31 -38
  80. qiskit/circuit/parameter.py +14 -5
  81. qiskit/circuit/parameterexpression.py +109 -75
  82. qiskit/circuit/quantumcircuit.py +168 -98
  83. qiskit/circuit/quantumcircuitdata.py +1 -0
  84. qiskit/circuit/random/__init__.py +37 -2
  85. qiskit/circuit/random/utils.py +445 -56
  86. qiskit/circuit/tools/pi_check.py +5 -13
  87. qiskit/compiler/transpiler.py +1 -1
  88. qiskit/converters/circuit_to_instruction.py +2 -2
  89. qiskit/dagcircuit/dagnode.py +8 -3
  90. qiskit/primitives/__init__.py +2 -2
  91. qiskit/primitives/base/base_estimator.py +2 -2
  92. qiskit/primitives/containers/data_bin.py +0 -3
  93. qiskit/primitives/containers/observables_array.py +192 -108
  94. qiskit/primitives/primitive_job.py +29 -10
  95. qiskit/providers/fake_provider/generic_backend_v2.py +2 -0
  96. qiskit/qasm3/__init__.py +106 -12
  97. qiskit/qasm3/ast.py +15 -1
  98. qiskit/qasm3/exporter.py +59 -36
  99. qiskit/qasm3/printer.py +12 -0
  100. qiskit/qpy/__init__.py +183 -7
  101. qiskit/qpy/binary_io/circuits.py +256 -24
  102. qiskit/qpy/binary_io/parse_sympy_repr.py +5 -0
  103. qiskit/qpy/binary_io/schedules.py +12 -32
  104. qiskit/qpy/binary_io/value.py +36 -18
  105. qiskit/qpy/common.py +11 -3
  106. qiskit/qpy/formats.py +17 -1
  107. qiskit/qpy/interface.py +52 -12
  108. qiskit/qpy/type_keys.py +7 -1
  109. qiskit/quantum_info/__init__.py +10 -0
  110. qiskit/quantum_info/operators/__init__.py +1 -0
  111. qiskit/quantum_info/operators/symplectic/__init__.py +1 -0
  112. qiskit/quantum_info/operators/symplectic/clifford_circuits.py +26 -0
  113. qiskit/quantum_info/operators/symplectic/pauli.py +2 -2
  114. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +1 -1
  115. qiskit/result/sampled_expval.py +3 -1
  116. qiskit/synthesis/__init__.py +10 -0
  117. qiskit/synthesis/arithmetic/__init__.py +1 -1
  118. qiskit/synthesis/arithmetic/adders/__init__.py +1 -0
  119. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +6 -2
  120. qiskit/synthesis/arithmetic/adders/rv_ripple_carry_adder.py +156 -0
  121. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +14 -126
  122. qiskit/synthesis/discrete_basis/solovay_kitaev.py +161 -121
  123. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  124. qiskit/synthesis/evolution/product_formula.py +10 -7
  125. qiskit/synthesis/evolution/qdrift.py +10 -7
  126. qiskit/synthesis/evolution/suzuki_trotter.py +10 -7
  127. qiskit/synthesis/multi_controlled/__init__.py +4 -0
  128. qiskit/synthesis/multi_controlled/mcx_synthesis.py +402 -178
  129. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +14 -15
  130. qiskit/synthesis/qft/qft_decompose_lnn.py +7 -25
  131. qiskit/synthesis/unitary/qsd.py +80 -9
  132. qiskit/transpiler/__init__.py +19 -8
  133. qiskit/transpiler/instruction_durations.py +2 -20
  134. qiskit/transpiler/passes/__init__.py +4 -2
  135. qiskit/transpiler/passes/layout/dense_layout.py +26 -6
  136. qiskit/transpiler/passes/layout/disjoint_utils.py +1 -166
  137. qiskit/transpiler/passes/layout/sabre_layout.py +22 -3
  138. qiskit/transpiler/passes/layout/sabre_pre_layout.py +1 -1
  139. qiskit/transpiler/passes/layout/vf2_layout.py +49 -13
  140. qiskit/transpiler/passes/layout/vf2_utils.py +13 -1
  141. qiskit/transpiler/passes/optimization/__init__.py +1 -1
  142. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +2 -1
  143. qiskit/transpiler/passes/optimization/optimize_clifford_t.py +68 -0
  144. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +3 -9
  145. qiskit/transpiler/passes/routing/sabre_swap.py +12 -2
  146. qiskit/transpiler/passes/routing/star_prerouting.py +106 -81
  147. qiskit/transpiler/passes/scheduling/__init__.py +1 -1
  148. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
  149. qiskit/transpiler/passes/scheduling/padding/__init__.py +1 -0
  150. qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py +876 -0
  151. qiskit/transpiler/passes/synthesis/__init__.py +1 -0
  152. qiskit/transpiler/passes/synthesis/clifford_unitary_synth_plugin.py +123 -0
  153. qiskit/transpiler/passes/synthesis/hls_plugins.py +472 -92
  154. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +27 -22
  155. qiskit/transpiler/passmanager_config.py +3 -0
  156. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +149 -28
  157. qiskit/transpiler/preset_passmanagers/common.py +101 -0
  158. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +6 -0
  159. qiskit/transpiler/preset_passmanagers/level3.py +2 -2
  160. qiskit/utils/optionals.py +6 -5
  161. qiskit/visualization/circuit/_utils.py +5 -3
  162. qiskit/visualization/circuit/latex.py +9 -2
  163. qiskit/visualization/circuit/matplotlib.py +26 -4
  164. qiskit/visualization/circuit/qcstyle.py +9 -157
  165. qiskit/visualization/dag/__init__.py +13 -0
  166. qiskit/visualization/dag/dagstyle.py +103 -0
  167. qiskit/visualization/dag/styles/__init__.py +13 -0
  168. qiskit/visualization/dag/styles/color.json +10 -0
  169. qiskit/visualization/dag/styles/plain.json +5 -0
  170. qiskit/visualization/dag_visualization.py +169 -98
  171. qiskit/visualization/style.py +223 -0
  172. {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/METADATA +14 -13
  173. {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/RECORD +177 -168
  174. {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/entry_points.txt +6 -0
  175. qiskit/synthesis/discrete_basis/commutator_decompose.py +0 -265
  176. qiskit/synthesis/discrete_basis/gate_sequence.py +0 -421
  177. {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/WHEEL +0 -0
  178. {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/licenses/LICENSE.txt +0 -0
  179. {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/top_level.txt +0 -0
qiskit/VERSION.txt CHANGED
@@ -1 +1 @@
1
- 2.0.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
 
Binary file
@@ -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
- * :class:`BoxOp`, to group a series of instructions for later processing
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`, :class:`ForLoopOp` and :class:`BoxOp`) all have specific state that defines
715
- the branching conditions and strategies, but contain all the different subcircuit blocks that
716
- might be entered in their :attr:`~ControlFlowOp.blocks` property.
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
@@ -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
- """For standard gates, if the controlled version already exists in the
34
- library, it will be returned (e.g. XGate.control() = CnotGate().
56
+ """Return the controlled version of the gate.
35
57
 
36
- For more generic gates, this method implements the controlled
37
- version by first decomposing into the ['u1', 'u3', 'cx'] basis, then
38
- controlling each gate in the decomposition.
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
- Open controls are implemented by conjugating the control line with
41
- X gates. Adds num_ctrl_qubits controls to operation.
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 using controlled rotations. This function
76
- first checks the name of the operation to see if it knows of a method from which
77
- to generate a controlled version. Currently, these are ``x``, ``rx``, ``ry``, and ``rz``.
78
- If a method is not directly known, it calls the unroller to convert to `u1`, `u3`,
79
- and `cx` gates.
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
- basis = ["p", "u", "x", "z", "y", "h", "sx", "sxdg", "rx", "ry", "rz", "cx"]
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=basis)
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 the following basis gates:
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__(