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.
Files changed (180) 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 +104 -20
  5. qiskit/circuit/_add_control.py +57 -31
  6. qiskit/circuit/_classical_resource_map.py +4 -0
  7. qiskit/circuit/annotation.py +504 -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 +4 -4
  15. qiskit/circuit/library/arithmetic/multipliers/multiplier.py +2 -2
  16. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +8 -4
  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 +172 -99
  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 +182 -6
  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/result/sampled_expval.py +3 -1
  115. qiskit/synthesis/__init__.py +10 -0
  116. qiskit/synthesis/arithmetic/__init__.py +1 -1
  117. qiskit/synthesis/arithmetic/adders/__init__.py +1 -0
  118. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +6 -2
  119. qiskit/synthesis/arithmetic/adders/rv_ripple_carry_adder.py +156 -0
  120. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +14 -126
  121. qiskit/synthesis/discrete_basis/solovay_kitaev.py +161 -121
  122. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  123. qiskit/synthesis/evolution/product_formula.py +10 -7
  124. qiskit/synthesis/evolution/qdrift.py +10 -7
  125. qiskit/synthesis/evolution/suzuki_trotter.py +10 -7
  126. qiskit/synthesis/multi_controlled/__init__.py +4 -0
  127. qiskit/synthesis/multi_controlled/mcx_synthesis.py +402 -178
  128. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +14 -15
  129. qiskit/synthesis/qft/qft_decompose_lnn.py +7 -25
  130. qiskit/synthesis/unitary/qsd.py +80 -9
  131. qiskit/transpiler/__init__.py +10 -3
  132. qiskit/transpiler/instruction_durations.py +2 -20
  133. qiskit/transpiler/passes/__init__.py +5 -2
  134. qiskit/transpiler/passes/layout/dense_layout.py +26 -6
  135. qiskit/transpiler/passes/layout/disjoint_utils.py +1 -166
  136. qiskit/transpiler/passes/layout/sabre_layout.py +22 -3
  137. qiskit/transpiler/passes/layout/sabre_pre_layout.py +1 -1
  138. qiskit/transpiler/passes/layout/vf2_layout.py +49 -13
  139. qiskit/transpiler/passes/layout/vf2_utils.py +10 -0
  140. qiskit/transpiler/passes/optimization/__init__.py +1 -1
  141. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +2 -1
  142. qiskit/transpiler/passes/optimization/optimize_clifford_t.py +68 -0
  143. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +3 -9
  144. qiskit/transpiler/passes/routing/sabre_swap.py +4 -2
  145. qiskit/transpiler/passes/routing/star_prerouting.py +106 -81
  146. qiskit/transpiler/passes/scheduling/__init__.py +1 -1
  147. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
  148. qiskit/transpiler/passes/scheduling/padding/__init__.py +1 -0
  149. qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py +876 -0
  150. qiskit/transpiler/passes/synthesis/__init__.py +1 -0
  151. qiskit/transpiler/passes/synthesis/clifford_unitary_synth_plugin.py +123 -0
  152. qiskit/transpiler/passes/synthesis/hls_plugins.py +494 -93
  153. qiskit/transpiler/passes/synthesis/plugin.py +4 -0
  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/transpiler/target.py +15 -2
  161. qiskit/utils/optionals.py +6 -5
  162. qiskit/visualization/circuit/_utils.py +5 -3
  163. qiskit/visualization/circuit/latex.py +9 -2
  164. qiskit/visualization/circuit/matplotlib.py +26 -4
  165. qiskit/visualization/circuit/qcstyle.py +9 -157
  166. qiskit/visualization/dag/__init__.py +13 -0
  167. qiskit/visualization/dag/dagstyle.py +103 -0
  168. qiskit/visualization/dag/styles/__init__.py +13 -0
  169. qiskit/visualization/dag/styles/color.json +10 -0
  170. qiskit/visualization/dag/styles/plain.json +5 -0
  171. qiskit/visualization/dag_visualization.py +169 -98
  172. qiskit/visualization/style.py +223 -0
  173. {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/METADATA +7 -6
  174. {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/RECORD +178 -169
  175. {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/entry_points.txt +6 -0
  176. qiskit/synthesis/discrete_basis/commutator_decompose.py +0 -265
  177. qiskit/synthesis/discrete_basis/gate_sequence.py +0 -421
  178. {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/WHEEL +0 -0
  179. {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/licenses/LICENSE.txt +0 -0
  180. {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/top_level.txt +0 -0
@@ -9,6 +9,7 @@
9
9
  # Any modifications or derivative works of this code must retain this
10
10
  # copyright notice, and modified files need to carry a notice indicating
11
11
  # that they have been altered from the originals.
12
+ # pylint: disable=missing-function-docstring
12
13
 
13
14
  """A wrapper class for the purposes of validating modifications to
14
15
  QuantumCircuit.data while maintaining the interface of a python list."""
@@ -10,6 +10,41 @@
10
10
  # copyright notice, and modified files need to carry a notice indicating
11
11
  # that they have been altered from the originals.
12
12
 
13
- """Method for generating random circuits."""
13
+ """
14
+ ==============================================
15
+ Random Circuits (:mod:`qiskit.circuit.random`)
16
+ ==============================================
14
17
 
15
- from .utils import random_circuit, random_clifford_circuit
18
+ .. currentmodule:: qiskit.circuit.random
19
+
20
+ Overview
21
+ ========
22
+
23
+ The :mod:`qiskit.circuit.random` module offers functions that can be used for generating
24
+ arbitrary circuits with gates randomly selected from a given set of gates.
25
+
26
+ These circuits can be used for benchmarking existing quantum hardware and estimating
27
+ the performance of quantum circuit transpilers and software infrastructure.
28
+ The functions below can generate bespoke quantum circuits respecting various properties
29
+ such as number of qubits, depth of the circuit, coupling map, gate set, etc.
30
+
31
+ Generating arbitrary circuits
32
+ ------------------------------------
33
+
34
+ .. autofunction:: random_circuit
35
+
36
+
37
+ Generating arbitrary circuits respecting qubit-coupling
38
+ --------------------------------------------------------------
39
+
40
+ .. autofunction:: random_circuit_from_graph
41
+
42
+
43
+ Generating arbitrary circuits with clifford gates
44
+ --------------------------------------------------------
45
+
46
+ .. autofunction:: random_clifford_circuit
47
+
48
+ """
49
+
50
+ from .utils import random_circuit, random_clifford_circuit, random_circuit_from_graph
@@ -11,15 +11,451 @@
11
11
  # that they have been altered from the originals.
12
12
 
13
13
  """Utility functions for generating random circuits."""
14
-
15
14
  import numpy as np
15
+ from rustworkx import PyDiGraph
16
16
 
17
- from qiskit.circuit import ClassicalRegister, QuantumCircuit, CircuitInstruction
17
+ from qiskit.circuit import (
18
+ ClassicalRegister,
19
+ QuantumCircuit,
20
+ CircuitInstruction,
21
+ )
18
22
  from qiskit.circuit import Reset
19
23
  from qiskit.circuit.library import standard_gates
20
24
  from qiskit.circuit.exceptions import CircuitError
21
25
  from qiskit.quantum_info.operators.symplectic.clifford_circuits import _BASIS_1Q, _BASIS_2Q
22
26
 
27
+ # (Gate class, number of qubits, number of parameters)
28
+ gates_1q_data = [
29
+ (standard_gates.IGate, 1, 0),
30
+ (standard_gates.SXGate, 1, 0),
31
+ (standard_gates.XGate, 1, 0),
32
+ (standard_gates.RZGate, 1, 1),
33
+ (standard_gates.RGate, 1, 2),
34
+ (standard_gates.HGate, 1, 0),
35
+ (standard_gates.PhaseGate, 1, 1),
36
+ (standard_gates.RXGate, 1, 1),
37
+ (standard_gates.RYGate, 1, 1),
38
+ (standard_gates.SGate, 1, 0),
39
+ (standard_gates.SdgGate, 1, 0),
40
+ (standard_gates.SXdgGate, 1, 0),
41
+ (standard_gates.TGate, 1, 0),
42
+ (standard_gates.TdgGate, 1, 0),
43
+ (standard_gates.UGate, 1, 3),
44
+ (standard_gates.U1Gate, 1, 1),
45
+ (standard_gates.U2Gate, 1, 2),
46
+ (standard_gates.U3Gate, 1, 3),
47
+ (standard_gates.YGate, 1, 0),
48
+ (standard_gates.ZGate, 1, 0),
49
+ ]
50
+
51
+ gates_2q_data = [
52
+ (standard_gates.CXGate, 2, 0),
53
+ (standard_gates.DCXGate, 2, 0),
54
+ (standard_gates.CHGate, 2, 0),
55
+ (standard_gates.CPhaseGate, 2, 1),
56
+ (standard_gates.CRXGate, 2, 1),
57
+ (standard_gates.CRYGate, 2, 1),
58
+ (standard_gates.CRZGate, 2, 1),
59
+ (standard_gates.CSXGate, 2, 0),
60
+ (standard_gates.CUGate, 2, 4),
61
+ (standard_gates.CU1Gate, 2, 1),
62
+ (standard_gates.CU3Gate, 2, 3),
63
+ (standard_gates.CYGate, 2, 0),
64
+ (standard_gates.CZGate, 2, 0),
65
+ (standard_gates.RXXGate, 2, 1),
66
+ (standard_gates.RYYGate, 2, 1),
67
+ (standard_gates.RZZGate, 2, 1),
68
+ (standard_gates.RZXGate, 2, 1),
69
+ (standard_gates.XXMinusYYGate, 2, 2),
70
+ (standard_gates.XXPlusYYGate, 2, 2),
71
+ (standard_gates.ECRGate, 2, 0),
72
+ (standard_gates.CSGate, 2, 0),
73
+ (standard_gates.CSdgGate, 2, 0),
74
+ (standard_gates.SwapGate, 2, 0),
75
+ (standard_gates.iSwapGate, 2, 0),
76
+ ]
77
+
78
+
79
+ def random_circuit_from_graph(
80
+ interaction_graph,
81
+ min_2q_gate_per_edge=1,
82
+ max_operands=2,
83
+ measure=False,
84
+ conditional=False,
85
+ reset=False,
86
+ seed=None,
87
+ insert_1q_oper=True,
88
+ prob_conditional=0.1,
89
+ prob_reset=0.1,
90
+ ):
91
+ """Generate random circuit of arbitrary size and form which strictly respects the interaction
92
+ graph passed as argument. Interaction Graph is a graph G=(V, E) where V are the qubits in the
93
+ circuit, and, E is the set of two-qubit gate interactions between two particular qubits in the
94
+ circuit.
95
+
96
+ This function will generate a random circuit by randomly selecting 1Q and 2Q gates from the set
97
+ of standard gates in :mod:`qiskit.circuit.library.standard_gates`. The user can attach a numerical
98
+ value as a metadata to the edge of the graph indicating the edge weight for that particular edge,
99
+ These edge weights would be normalized to the probabilities of the edges getting selected.
100
+ If all the edge weights are passed as `None`, then the probability of each qubit-pair of getting
101
+ selected is set to 1/N, where `N` is the number of edges in the `interaction_graph` passed in,
102
+ i.e each edge is drawn uniformly. If any weight of an edge is set as zero, that particular
103
+ edge will not be included in the output circuit.
104
+
105
+ Passing a list of tuples of control qubit, target qubit and associated probability is also
106
+ acceptable as a way to specify an interaction graph.
107
+
108
+ If numerical values are present as probabilities but some/any are None, or negative, when
109
+ `max_operands=2` this will raise a ValueError.
110
+
111
+ If `max_operands` is set to 1, then there are no 2Q operations, so no need to take care
112
+ of the edges, in such case the function will return a circuit from the `random_circuit` function,
113
+ which would be passed with the `max_operands` as 1.
114
+
115
+ If `max_operands` is set to 2, then in every while-iteration 2Q gates are chosen randomly, and
116
+ qubit-pairs which exist in the input interaction graph are also chosen randomly based on the
117
+ probability attached to the qubit-pair. Then in a for-iteration 2Q gates are applied to the
118
+ randomly chosen qubit-pairs with the aim to reach the count of 2Q on any qubit-pair to
119
+ `min_2q_gate_per_edge` criteria as soon as possible within a particular iteration. Now, if
120
+ some qubits are still idle after applying 2Q gates for that particular iteration, then randomly
121
+ chosen 1Q gates are applied to those idle qubits if `insert_1q_oper` is set to True.
122
+
123
+ Example:
124
+
125
+ .. plot::
126
+ :alt: Pass in interaction graph and minimum 2Q gate per edge as a bare minimum.
127
+ :include-source:
128
+
129
+ from qiskit.circuit.random.utils import random_circuit_from_graph
130
+ import rustworkx as rx
131
+ pydi_graph = rx.PyDiGraph()
132
+ pydi_graph.add_nodes_from(range(7))
133
+ cp_map = [(0, 1, 0.18), (1, 2, 0.15), (2, 3, 0.15), (3, 4, 0.22), (4, 5, 0.13), (5, 6, 0.17)]
134
+ pydi_graph.add_edges_from(cp_map)
135
+ # cp_map can be passed in directly as interaction_graph
136
+ qc = random_circuit_from_graph(pydi_graph, min_2q_gate_per_edge=2, seed=12345)
137
+ qc.draw(output='mpl')
138
+
139
+ Args:
140
+ interaction_graph (PyGraph | PyDiGraph | List[Tuple[int, int, float]]): Interaction Graph
141
+ min_2q_gate_per_edge (int): Minimum number of times every qubit-pair must be used
142
+ in the random circuit. (optional, default:1)
143
+ max_operands (int): maximum qubit operands of each gate(should be 1 or 2)
144
+ (optional, default:2)
145
+ measure (bool): if True, measure all qubits at the end. (optional, default: False)
146
+ conditional (bool): if True, insert middle measurements and conditionals.
147
+ (optional, default: False)
148
+ reset (bool): if True, insert middle resets. (optional, default: False)
149
+ seed (int): sets random seed. (If `None`, a random seed is chosen) (optional)
150
+ insert_1q_oper (bool): Insert 1Q operations to the circuit. (optional, default: True)
151
+ prob_conditional (float): Probability less than 1.0, this is used to control the occurrence
152
+ of conditionals in the circuit. (optional, default: 0.1)
153
+ prob_reset (float): Probability less than 1.0, this is used to control the occurrence of
154
+ reset in the circuit. (optional, default: 0.1)
155
+
156
+ Returns:
157
+ QuantumCircuit: constructed circuit
158
+
159
+ Raises:
160
+ CircuitError: When `max_operands` is not 1 or 2.
161
+ CircuitError: When `max_operands` is set to 1, but no 1Q operations are allowed by setting
162
+ `insert_1q_oper` to false.
163
+ CircuitError: When the interaction graph has no edges, so only 1Q gates are possible in
164
+ the circuit, but `insert_1q_oper` is set to False.
165
+ CircuitError: When an invalid interaction graph object is passed.
166
+ ValueError: Given `max_operands=2`, when any edge have probability `None` but not all, or any
167
+ of the probabilities are negative.
168
+ """
169
+
170
+ # max_operands should be 1 or 2
171
+ if max_operands not in {1, 2}:
172
+ raise CircuitError("`max_operands` should be either 1 or 2")
173
+
174
+ if max_operands == 1 and not insert_1q_oper:
175
+ raise CircuitError(
176
+ "`max_operands` of 1 means only 1Q gates are allowed, but `insert_1q_oper` is False"
177
+ )
178
+
179
+ # Declaring variables so lint doesn't complaint.
180
+ num_qubits = 0
181
+ num_edges = None
182
+ edge_list = None
183
+ edges_probs = None
184
+
185
+ if isinstance(interaction_graph, list):
186
+ num_edges = len(interaction_graph)
187
+ edge_list = []
188
+ edges_probs = []
189
+ for ctrl, trgt, prob in interaction_graph:
190
+ edge_list.append((ctrl, trgt))
191
+ edges_probs.append(prob)
192
+
193
+ if ctrl > num_qubits:
194
+ num_qubits = ctrl
195
+
196
+ if trgt > num_qubits:
197
+ num_qubits = trgt
198
+
199
+ num_qubits += 1 # ctrl, trgt are qubit indices.
200
+ edge_list = np.array(edge_list)
201
+ edges_probs = np.array(edges_probs)
202
+ elif isinstance(interaction_graph, PyDiGraph):
203
+ num_qubits = interaction_graph.num_nodes()
204
+ num_edges = interaction_graph.num_edges()
205
+ edge_list = np.array(interaction_graph.edge_list())
206
+ edges_probs = np.array(interaction_graph.edges())
207
+ else:
208
+ raise CircuitError("Invalid interaction graph object has been passed")
209
+
210
+ if num_qubits == 0:
211
+ return QuantumCircuit()
212
+
213
+ max_operands = max_operands if num_qubits > max_operands else num_qubits
214
+
215
+ if num_edges == 0 and not insert_1q_oper:
216
+ raise CircuitError(
217
+ "There are no edges in the `interaction_graph` so, there could be only 1Q gates, "
218
+ "however `insert_1q_oper` is set to `False`"
219
+ )
220
+
221
+ if num_edges == 0 or max_operands == 1:
222
+ # If there is no edge then there could be no 2Q operation
223
+ # or, if only 1Q operations are allowed, then there is no
224
+ # point in considering edges.
225
+ return random_circuit(
226
+ num_qubits=num_qubits,
227
+ depth=min_2q_gate_per_edge,
228
+ max_operands=1,
229
+ measure=measure,
230
+ conditional=conditional,
231
+ reset=reset,
232
+ seed=seed,
233
+ )
234
+
235
+ # If any edge weight is zero, just remove that edge from the edge_list
236
+ if 0 in edges_probs:
237
+ _mask = edges_probs != 0
238
+ edges_probs = edges_probs[_mask]
239
+ edge_list = edge_list[_mask]
240
+
241
+ # Update 'num_edges'
242
+ num_edges = len(edge_list)
243
+
244
+ # Now, zeros are filtered out in above if-block.
245
+ # Now, If none of the edges_probs are `None`
246
+ if all(edges_probs):
247
+
248
+ # edge weights in interaction_graph must be positive
249
+ for prob in edges_probs:
250
+ if prob < 0:
251
+ raise ValueError("Probabilities cannot be negative")
252
+
253
+ # Normalize edge weights if not already normalized.
254
+ probs_sum = edges_probs.sum()
255
+ if not np.isclose(probs_sum, 1.000, rtol=0.001):
256
+ edges_probs = edges_probs / probs_sum
257
+ # If any of the values of the probability is None, then it would raise an error.
258
+ elif any(edges_probs):
259
+ raise ValueError(
260
+ "Some of the probabilities of a qubit-pair getting selected is `None`"
261
+ " It should either be all `None` or all positive numerical weights. "
262
+ )
263
+
264
+ # If all edge weights are none, assume the weight of each edge to be 1/N.
265
+ elif None in edges_probs:
266
+ edges_probs = np.ones(num_edges) / num_edges
267
+
268
+ gates_2q = np.array(
269
+ gates_2q_data,
270
+ dtype=[("class", object), ("num_qubits", np.int64), ("num_params", np.int64)],
271
+ )
272
+
273
+ if insert_1q_oper:
274
+ gates_1q = np.array(gates_1q_data, dtype=gates_2q.dtype)
275
+
276
+ qc = QuantumCircuit(num_qubits)
277
+
278
+ if measure or conditional:
279
+ cr = ClassicalRegister(num_qubits, "c")
280
+ qc.add_register(cr)
281
+
282
+ if seed is None:
283
+ seed = np.random.randint(0, np.iinfo(np.int32).max)
284
+ rng = np.random.default_rng(seed)
285
+
286
+ qubits = np.array(qc.qubits, dtype=object, copy=True)
287
+
288
+ edges_used = {tuple(edge): 0 for edge in edge_list}
289
+
290
+ # Declaring variables, so that lint doesn't complaint.
291
+ reset_2q = None
292
+ cond_val_2q = None
293
+ cond_val_1q = None
294
+
295
+ # If conditional is not required, there is no need to calculate random numbers.
296
+ # But, since the variables are required in the for-loop so let's get an array of false.
297
+ if not conditional:
298
+ cond_1q = np.zeros(num_qubits, dtype=bool)
299
+ cond_2q = np.zeros(num_edges, dtype=bool)
300
+
301
+ # Similarly, if resets are not required, then since, the variable is required
302
+ # in the for-loop, let's get an array of false.
303
+ if not reset:
304
+ reset_2q = np.zeros(num_edges, dtype=bool)
305
+
306
+ # This loop will keep on applying gates to qubits until every qubit-pair
307
+ # has 2Q operations applied at-least `min_2q_gate_per_edge` times.
308
+ while edges_used:
309
+
310
+ # For any given while-iteration, this is a set of qubits not having any 2Q gates.
311
+ # Qubits in this set will have 1Q gates, if `insert_1q_oper` is True.
312
+ qubit_idx_idle = set(range(num_qubits))
313
+
314
+ # normalized edge weights represent the probability with which each qubit-pair
315
+ # is inserted into the circuit.
316
+ edge_choices = rng.choice(
317
+ edge_list,
318
+ size=num_edges,
319
+ replace=True,
320
+ p=edges_probs,
321
+ )
322
+ gate_choices = rng.choice(gates_2q, size=num_edges, replace=True)
323
+
324
+ cumsum_params = np.cumsum(gate_choices["num_params"], dtype=np.int64)
325
+ parameters = rng.uniform(0, 2 * np.pi, size=cumsum_params[-1])
326
+
327
+ # If reset is required, then, generating a random boolean matrix of
328
+ # num_edges x 2, corresponding to probable reset on both control and
329
+ # target qubits of the edge from the edge_list.
330
+ if reset:
331
+ reset_2q = rng.random(size=(num_edges, 2)) < prob_reset
332
+
333
+ if conditional:
334
+ cond_2q = rng.random(size=len(gate_choices)) < prob_conditional
335
+ cond_val_2q = rng.integers(0, 1 << min(num_qubits, 63), size=np.count_nonzero(cond_2q))
336
+ clbit_2q_idx = 0
337
+
338
+ for gate, num_gate_params, edge, is_cond_2q, is_rst in zip(
339
+ gate_choices["class"],
340
+ gate_choices["num_params"],
341
+ edge_choices,
342
+ cond_2q,
343
+ reset_2q,
344
+ ):
345
+
346
+ control_qubit, target_qubit = tuple(edge)
347
+
348
+ # For every edge there are two probabilistically generated boolean values corresponding
349
+ # to control, target qubits of the edge
350
+ # an idle qubit for a particular iteration on which reset is applied is considered idle.
351
+
352
+ if reset:
353
+ is_rst_control, is_rst_target = is_rst
354
+ rst_oper = Reset()
355
+ if is_rst_control:
356
+ qc._append(
357
+ CircuitInstruction(
358
+ operation=rst_oper,
359
+ qubits=[qubits[control_qubit]],
360
+ )
361
+ )
362
+
363
+ if is_rst_target:
364
+ qc._append(
365
+ CircuitInstruction(
366
+ operation=rst_oper,
367
+ qubits=[qubits[target_qubit]],
368
+ )
369
+ )
370
+
371
+ params = parameters[:num_gate_params]
372
+ parameters = parameters[num_gate_params:]
373
+ current_instr = gate(*params)
374
+
375
+ if is_cond_2q:
376
+ qc.measure(qc.qubits, cr)
377
+ # The condition values are required to be bigints, not Numpy's fixed-width type.
378
+ with qc.if_test((cr, int(cond_val_2q[clbit_2q_idx]))):
379
+ clbit_2q_idx += 1
380
+ qc.append(
381
+ CircuitInstruction(
382
+ operation=current_instr,
383
+ qubits=[qubits[control_qubit], qubits[target_qubit]],
384
+ )
385
+ )
386
+ else:
387
+ qc._append(
388
+ CircuitInstruction(
389
+ operation=current_instr,
390
+ qubits=[qubits[control_qubit], qubits[target_qubit]],
391
+ )
392
+ )
393
+
394
+ # Removing the qubits that have been applied with 2Q gates from the
395
+ # set of idle qubits for that while-iteration.
396
+ qubit_idx_idle = qubit_idx_idle - set(edge)
397
+
398
+ # Update the number of occurrences of the edge in the circuit.
399
+ _temp_edge = (control_qubit, target_qubit)
400
+ if _temp_edge in edges_used:
401
+ edges_used[_temp_edge] += 1
402
+ if edges_used[_temp_edge] >= min_2q_gate_per_edge:
403
+ del edges_used[_temp_edge]
404
+
405
+ if insert_1q_oper:
406
+ num_unused_qubits = len(qubit_idx_idle)
407
+ if not num_unused_qubits == 0:
408
+
409
+ # Calculating for conditionals to make even the 1Q operations
410
+ # probabilistically conditional.
411
+ if conditional:
412
+ cond_1q = rng.random(size=num_unused_qubits) < prob_conditional
413
+ cond_val_1q = rng.integers(
414
+ 0, 1 << min(num_qubits, 63), size=np.count_nonzero(cond_1q)
415
+ )
416
+ clbit_1q_idx = 0
417
+
418
+ # Some extra 1Q Gate in to fill qubits which are still idle for this
419
+ # particular while iteration.
420
+ extra_1q_gates = rng.choice(gates_1q, size=num_unused_qubits, replace=True)
421
+
422
+ cumsum_params = np.cumsum(extra_1q_gates["num_params"], dtype=np.int64)
423
+ parameters_1q = rng.uniform(0, 2 * np.pi, size=cumsum_params[-1])
424
+
425
+ for gate_1q, num_gate_params, qubit_idx, is_cond_1q in zip(
426
+ extra_1q_gates["class"],
427
+ extra_1q_gates["num_params"],
428
+ qubit_idx_idle,
429
+ cond_1q,
430
+ ):
431
+ params_1q = parameters_1q[:num_gate_params]
432
+ parameters_1q = parameters_1q[num_gate_params:]
433
+ current_instr = gate_1q(*params_1q)
434
+
435
+ if is_cond_1q:
436
+ qc.measure(qc.qubits, cr)
437
+ # The condition values are required to be bigints, not Numpy's fixed-width type.
438
+ with qc.if_test((cr, int(cond_val_1q[clbit_1q_idx]))):
439
+ clbit_1q_idx += 1
440
+ qc.append(
441
+ CircuitInstruction(
442
+ operation=current_instr,
443
+ qubits=[qubits[qubit_idx]],
444
+ )
445
+ )
446
+ else:
447
+ qc._append(
448
+ CircuitInstruction(
449
+ operation=current_instr,
450
+ qubits=[qubits[qubit_idx]],
451
+ )
452
+ )
453
+
454
+ if measure:
455
+ qc.measure(qc.qubits, cr)
456
+
457
+ return qc
458
+
23
459
 
24
460
  def random_circuit(
25
461
  num_qubits,
@@ -97,72 +533,24 @@ def random_circuit(
97
533
  if num_qubits == 0:
98
534
  return QuantumCircuit()
99
535
 
100
- gates_1q = [
101
- # (Gate class, number of qubits, number of parameters)
102
- (standard_gates.IGate, 1, 0),
103
- (standard_gates.SXGate, 1, 0),
104
- (standard_gates.XGate, 1, 0),
105
- (standard_gates.RZGate, 1, 1),
106
- (standard_gates.RGate, 1, 2),
107
- (standard_gates.HGate, 1, 0),
108
- (standard_gates.PhaseGate, 1, 1),
109
- (standard_gates.RXGate, 1, 1),
110
- (standard_gates.RYGate, 1, 1),
111
- (standard_gates.SGate, 1, 0),
112
- (standard_gates.SdgGate, 1, 0),
113
- (standard_gates.SXdgGate, 1, 0),
114
- (standard_gates.TGate, 1, 0),
115
- (standard_gates.TdgGate, 1, 0),
116
- (standard_gates.UGate, 1, 3),
117
- (standard_gates.U1Gate, 1, 1),
118
- (standard_gates.U2Gate, 1, 2),
119
- (standard_gates.U3Gate, 1, 3),
120
- (standard_gates.YGate, 1, 0),
121
- (standard_gates.ZGate, 1, 0),
122
- ]
123
- if reset:
124
- gates_1q.append((Reset, 1, 0))
125
- gates_2q = [
126
- (standard_gates.CXGate, 2, 0),
127
- (standard_gates.DCXGate, 2, 0),
128
- (standard_gates.CHGate, 2, 0),
129
- (standard_gates.CPhaseGate, 2, 1),
130
- (standard_gates.CRXGate, 2, 1),
131
- (standard_gates.CRYGate, 2, 1),
132
- (standard_gates.CRZGate, 2, 1),
133
- (standard_gates.CSXGate, 2, 0),
134
- (standard_gates.CUGate, 2, 4),
135
- (standard_gates.CU1Gate, 2, 1),
136
- (standard_gates.CU3Gate, 2, 3),
137
- (standard_gates.CYGate, 2, 0),
138
- (standard_gates.CZGate, 2, 0),
139
- (standard_gates.RXXGate, 2, 1),
140
- (standard_gates.RYYGate, 2, 1),
141
- (standard_gates.RZZGate, 2, 1),
142
- (standard_gates.RZXGate, 2, 1),
143
- (standard_gates.XXMinusYYGate, 2, 2),
144
- (standard_gates.XXPlusYYGate, 2, 2),
145
- (standard_gates.ECRGate, 2, 0),
146
- (standard_gates.CSGate, 2, 0),
147
- (standard_gates.CSdgGate, 2, 0),
148
- (standard_gates.SwapGate, 2, 0),
149
- (standard_gates.iSwapGate, 2, 0),
150
- ]
151
536
  gates_3q = [
152
537
  (standard_gates.CCXGate, 3, 0),
153
538
  (standard_gates.CSwapGate, 3, 0),
154
539
  (standard_gates.CCZGate, 3, 0),
155
540
  (standard_gates.RCCXGate, 3, 0),
156
541
  ]
542
+
157
543
  gates_4q = [
158
544
  (standard_gates.C3SXGate, 4, 0),
159
545
  (standard_gates.RC3XGate, 4, 0),
160
546
  ]
161
547
 
162
548
  gates_1q = np.array(
163
- gates_1q, dtype=[("class", object), ("num_qubits", np.int64), ("num_params", np.int64)]
549
+ gates_1q_data + [(Reset, 1, 0)] if reset else gates_1q_data,
550
+ dtype=[("class", object), ("num_qubits", np.int64), ("num_params", np.int64)],
164
551
  )
165
- gates_2q = np.array(gates_2q, dtype=gates_1q.dtype)
552
+
553
+ gates_2q = np.array(gates_2q_data, dtype=gates_1q.dtype)
166
554
  gates_3q = np.array(gates_3q, dtype=gates_1q.dtype)
167
555
  gates_4q = np.array(gates_4q, dtype=gates_1q.dtype)
168
556
 
@@ -271,12 +659,13 @@ def random_circuit(
271
659
  is_conditional,
272
660
  ):
273
661
  operation = gate(*parameters[p_start:p_end])
662
+
274
663
  if is_cond:
275
664
  qc.measure(qc.qubits, cr)
276
665
  # The condition values are required to be bigints, not Numpy's fixed-width type.
277
666
  with qc.if_test((cr, int(condition_values[c_ptr]))):
278
667
  c_ptr += 1
279
- qc._append(
668
+ qc.append(
280
669
  CircuitInstruction(operation=operation, qubits=qubits[q_start:q_end])
281
670
  )
282
671
  else:
@@ -48,23 +48,15 @@ def pi_check(inpt, eps=1e-9, output="text", ndigits=None):
48
48
  """
49
49
  if isinstance(inpt, ParameterExpression):
50
50
  param_str = str(inpt)
51
- from sympy import sympify
52
- import symengine
53
-
54
- if not isinstance(inpt._symbol_expr, symengine.Basic):
55
- raise QiskitError("Invalid ParameterExpression provided")
56
- expr = sympify(inpt._symbol_expr)
57
- syms = expr.atoms()
58
- for sym in syms:
59
- if not sym.is_number:
60
- continue
61
- pi = pi_check(abs(float(sym)), eps=eps, output=output, ndigits=ndigits)
51
+ values = inpt._symbol_expr.values()
52
+ for val in values:
53
+ pi = pi_check(abs(float(val)), eps=eps, output=output, ndigits=ndigits)
62
54
  try:
63
55
  _ = float(pi)
64
56
  except (ValueError, TypeError):
65
- from sympy import sstr
57
+ import qiskit._accelerate.circuit
66
58
 
67
- sym_str = sstr(abs(sym), full_prec=False)
59
+ sym_str = str(qiskit._accelerate.circuit.ParameterExpression.Value(abs(val)))
68
60
  param_str = param_str.replace(sym_str, pi)
69
61
  return param_str
70
62
  elif isinstance(inpt, str):
@@ -249,7 +249,7 @@ def transpile( # pylint: disable=too-many-return-statements
249
249
  start_time = time()
250
250
 
251
251
  if optimization_level is None:
252
- # Take optimization level from the configuration or 1 as default.
252
+ # Take optimization level from the configuration or 2 as default.
253
253
  config = user_config.get_config()
254
254
  optimization_level = config.get("transpile_optimization_level", 2)
255
255
 
@@ -11,7 +11,6 @@
11
11
  # that they have been altered from the originals.
12
12
 
13
13
  """Helper function for converting a circuit to an instruction."""
14
- from qiskit.circuit.controlflow import CONTROL_FLOW_OP_NAMES
15
14
  from qiskit.exceptions import QiskitError
16
15
  from qiskit.circuit.instruction import Instruction
17
16
  from qiskit.circuit import QuantumRegister
@@ -84,7 +83,8 @@ def circuit_to_instruction(circuit, parameter_map=None, equivalence_library=None
84
83
  "Circuits with internal variables cannot yet be converted to instructions."
85
84
  " You may be able to use `QuantumCircuit.compose` to inline this circuit into another."
86
85
  )
87
- if CONTROL_FLOW_OP_NAMES.intersection(circuit.count_ops()):
86
+
87
+ if circuit.has_control_flow_op():
88
88
  raise QiskitError(
89
89
  "Circuits with control flow operations cannot be converted to an instruction."
90
90
  )
@@ -172,9 +172,14 @@ def _for_loop_eq(node1, node2, bit_indices1, bit_indices2):
172
172
 
173
173
 
174
174
  def _box_eq(node1, node2, bit_indices1, bit_indices2):
175
- return node1.op.duration == node2.op.duration and _circuit_to_dag(
176
- node1.op.blocks[0], node1.qargs, node1.cargs, bit_indices1
177
- ) == _circuit_to_dag(node2.op.blocks[0], node2.qargs, node2.cargs, bit_indices2)
175
+ return (
176
+ (node1.op.duration == node2.op.duration)
177
+ and (
178
+ _circuit_to_dag(node1.op.blocks[0], node1.qargs, node1.cargs, bit_indices1)
179
+ == _circuit_to_dag(node2.op.blocks[0], node2.qargs, node2.cargs, bit_indices2)
180
+ )
181
+ and (node1.op.annotations == node2.op.annotations)
182
+ )
178
183
 
179
184
 
180
185
  _SEMANTIC_EQ_CONTROL_FLOW = {
@@ -51,8 +51,8 @@ define a computation unit of work for the estimator to complete:
51
51
  define as :math:`\psi(\theta)`,
52
52
 
53
53
  * one or more observables (specified as any :class:`~.ObservablesArrayLike`, including
54
- :class:`~.Pauli`, :class:`~.SparsePauliOp`, ``str``) that specify which expectation values to
55
- estimate, denoted :math:`H_j`, and
54
+ :class:`~.quantum_info.Pauli`, :class:`~.SparsePauliOp`, ``str``) that specify which expectation
55
+ values to estimate, denoted :math:`H_j`, and
56
56
 
57
57
  * a collection parameter value sets to bind the circuit against, :math:`\theta_k`.
58
58