qiskit 1.0.2__cp38-abi3-win_amd64.whl → 1.1.0__cp38-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.
Files changed (263) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +27 -16
  3. qiskit/_accelerate.pyd +0 -0
  4. qiskit/_numpy_compat.py +73 -0
  5. qiskit/assembler/__init__.py +5 -10
  6. qiskit/assembler/disassemble.py +5 -6
  7. qiskit/circuit/__init__.py +1061 -232
  8. qiskit/circuit/_classical_resource_map.py +10 -6
  9. qiskit/circuit/_utils.py +18 -8
  10. qiskit/circuit/annotated_operation.py +21 -0
  11. qiskit/circuit/barrier.py +10 -13
  12. qiskit/circuit/bit.py +0 -1
  13. qiskit/circuit/classical/__init__.py +2 -2
  14. qiskit/circuit/classical/expr/__init__.py +39 -5
  15. qiskit/circuit/classical/expr/constructors.py +84 -1
  16. qiskit/circuit/classical/expr/expr.py +83 -13
  17. qiskit/circuit/classical/expr/visitors.py +83 -0
  18. qiskit/circuit/classical/types/__init__.py +5 -4
  19. qiskit/circuit/classicalfunction/__init__.py +1 -0
  20. qiskit/circuit/commutation_checker.py +86 -51
  21. qiskit/circuit/controlflow/_builder_utils.py +9 -1
  22. qiskit/circuit/controlflow/break_loop.py +8 -22
  23. qiskit/circuit/controlflow/builder.py +116 -1
  24. qiskit/circuit/controlflow/continue_loop.py +8 -22
  25. qiskit/circuit/controlflow/control_flow.py +47 -8
  26. qiskit/circuit/controlflow/for_loop.py +8 -23
  27. qiskit/circuit/controlflow/if_else.py +13 -27
  28. qiskit/circuit/controlflow/switch_case.py +14 -21
  29. qiskit/circuit/controlflow/while_loop.py +9 -23
  30. qiskit/circuit/controlledgate.py +2 -2
  31. qiskit/circuit/delay.py +7 -5
  32. qiskit/circuit/gate.py +20 -7
  33. qiskit/circuit/instruction.py +31 -30
  34. qiskit/circuit/instructionset.py +9 -22
  35. qiskit/circuit/library/__init__.py +3 -13
  36. qiskit/circuit/library/arithmetic/integer_comparator.py +2 -2
  37. qiskit/circuit/library/arithmetic/quadratic_form.py +3 -2
  38. qiskit/circuit/library/blueprintcircuit.py +29 -7
  39. qiskit/circuit/library/data_preparation/state_preparation.py +6 -5
  40. qiskit/circuit/library/generalized_gates/diagonal.py +5 -4
  41. qiskit/circuit/library/generalized_gates/isometry.py +51 -254
  42. qiskit/circuit/library/generalized_gates/pauli.py +2 -2
  43. qiskit/circuit/library/generalized_gates/permutation.py +4 -1
  44. qiskit/circuit/library/generalized_gates/rv.py +15 -11
  45. qiskit/circuit/library/generalized_gates/uc.py +2 -98
  46. qiskit/circuit/library/generalized_gates/unitary.py +9 -4
  47. qiskit/circuit/library/hamiltonian_gate.py +11 -5
  48. qiskit/circuit/library/n_local/efficient_su2.py +5 -5
  49. qiskit/circuit/library/n_local/n_local.py +100 -49
  50. qiskit/circuit/library/n_local/two_local.py +3 -59
  51. qiskit/circuit/library/overlap.py +3 -3
  52. qiskit/circuit/library/phase_oracle.py +1 -1
  53. qiskit/circuit/library/quantum_volume.py +39 -38
  54. qiskit/circuit/library/standard_gates/equivalence_library.py +50 -0
  55. qiskit/circuit/library/standard_gates/global_phase.py +4 -2
  56. qiskit/circuit/library/standard_gates/i.py +1 -2
  57. qiskit/circuit/library/standard_gates/iswap.py +1 -2
  58. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +11 -5
  59. qiskit/circuit/library/standard_gates/p.py +31 -15
  60. qiskit/circuit/library/standard_gates/r.py +4 -3
  61. qiskit/circuit/library/standard_gates/rx.py +7 -4
  62. qiskit/circuit/library/standard_gates/rxx.py +4 -3
  63. qiskit/circuit/library/standard_gates/ry.py +7 -4
  64. qiskit/circuit/library/standard_gates/ryy.py +4 -3
  65. qiskit/circuit/library/standard_gates/rz.py +7 -4
  66. qiskit/circuit/library/standard_gates/rzx.py +4 -3
  67. qiskit/circuit/library/standard_gates/rzz.py +4 -3
  68. qiskit/circuit/library/standard_gates/s.py +4 -8
  69. qiskit/circuit/library/standard_gates/t.py +2 -4
  70. qiskit/circuit/library/standard_gates/u.py +16 -11
  71. qiskit/circuit/library/standard_gates/u1.py +6 -2
  72. qiskit/circuit/library/standard_gates/u2.py +4 -2
  73. qiskit/circuit/library/standard_gates/u3.py +9 -5
  74. qiskit/circuit/library/standard_gates/x.py +22 -11
  75. qiskit/circuit/library/standard_gates/xx_minus_yy.py +4 -3
  76. qiskit/circuit/library/standard_gates/xx_plus_yy.py +7 -5
  77. qiskit/circuit/library/standard_gates/z.py +1 -2
  78. qiskit/circuit/measure.py +4 -1
  79. qiskit/circuit/operation.py +13 -8
  80. qiskit/circuit/parameter.py +11 -6
  81. qiskit/circuit/quantumcircuit.py +1910 -260
  82. qiskit/circuit/quantumcircuitdata.py +2 -2
  83. qiskit/circuit/reset.py +5 -2
  84. qiskit/circuit/store.py +95 -0
  85. qiskit/compiler/assembler.py +22 -22
  86. qiskit/compiler/transpiler.py +63 -112
  87. qiskit/converters/__init__.py +17 -2
  88. qiskit/converters/circuit_to_dag.py +7 -0
  89. qiskit/converters/circuit_to_dagdependency_v2.py +47 -0
  90. qiskit/converters/circuit_to_gate.py +2 -0
  91. qiskit/converters/circuit_to_instruction.py +22 -0
  92. qiskit/converters/dag_to_circuit.py +4 -0
  93. qiskit/converters/dag_to_dagdependency_v2.py +44 -0
  94. qiskit/dagcircuit/collect_blocks.py +15 -10
  95. qiskit/dagcircuit/dagcircuit.py +434 -124
  96. qiskit/dagcircuit/dagdependency.py +19 -12
  97. qiskit/dagcircuit/dagdependency_v2.py +641 -0
  98. qiskit/dagcircuit/dagdepnode.py +19 -16
  99. qiskit/dagcircuit/dagnode.py +14 -4
  100. qiskit/passmanager/passmanager.py +11 -11
  101. qiskit/primitives/__init__.py +22 -12
  102. qiskit/primitives/backend_estimator.py +3 -5
  103. qiskit/primitives/backend_estimator_v2.py +410 -0
  104. qiskit/primitives/backend_sampler_v2.py +287 -0
  105. qiskit/primitives/base/base_estimator.py +4 -9
  106. qiskit/primitives/base/base_sampler.py +2 -2
  107. qiskit/primitives/containers/__init__.py +6 -4
  108. qiskit/primitives/containers/bit_array.py +293 -2
  109. qiskit/primitives/containers/data_bin.py +123 -50
  110. qiskit/primitives/containers/estimator_pub.py +10 -3
  111. qiskit/primitives/containers/observables_array.py +2 -2
  112. qiskit/primitives/containers/pub_result.py +1 -1
  113. qiskit/primitives/containers/sampler_pub.py +19 -3
  114. qiskit/primitives/containers/sampler_pub_result.py +74 -0
  115. qiskit/primitives/containers/shape.py +4 -4
  116. qiskit/primitives/statevector_estimator.py +4 -4
  117. qiskit/primitives/statevector_sampler.py +7 -12
  118. qiskit/providers/__init__.py +65 -34
  119. qiskit/providers/backend.py +2 -2
  120. qiskit/providers/backend_compat.py +8 -10
  121. qiskit/providers/basic_provider/__init__.py +2 -23
  122. qiskit/providers/basic_provider/basic_provider_tools.py +67 -31
  123. qiskit/providers/basic_provider/basic_simulator.py +81 -21
  124. qiskit/providers/fake_provider/__init__.py +1 -1
  125. qiskit/providers/fake_provider/fake_1q.py +1 -1
  126. qiskit/providers/fake_provider/fake_backend.py +3 -408
  127. qiskit/providers/fake_provider/generic_backend_v2.py +26 -14
  128. qiskit/providers/models/__init__.py +2 -2
  129. qiskit/providers/provider.py +16 -0
  130. qiskit/pulse/builder.py +4 -1
  131. qiskit/pulse/parameter_manager.py +60 -4
  132. qiskit/pulse/schedule.py +29 -13
  133. qiskit/pulse/utils.py +61 -20
  134. qiskit/qasm2/__init__.py +1 -5
  135. qiskit/qasm2/parse.py +1 -4
  136. qiskit/qasm3/__init__.py +42 -5
  137. qiskit/qasm3/ast.py +19 -0
  138. qiskit/qasm3/exporter.py +178 -106
  139. qiskit/qasm3/printer.py +27 -5
  140. qiskit/qobj/converters/pulse_instruction.py +6 -6
  141. qiskit/qpy/__init__.py +299 -67
  142. qiskit/qpy/binary_io/circuits.py +216 -47
  143. qiskit/qpy/binary_io/schedules.py +42 -36
  144. qiskit/qpy/binary_io/value.py +201 -22
  145. qiskit/qpy/common.py +1 -1
  146. qiskit/qpy/exceptions.py +20 -0
  147. qiskit/qpy/formats.py +29 -0
  148. qiskit/qpy/type_keys.py +21 -0
  149. qiskit/quantum_info/analysis/distance.py +3 -3
  150. qiskit/quantum_info/analysis/make_observable.py +2 -1
  151. qiskit/quantum_info/analysis/z2_symmetries.py +2 -1
  152. qiskit/quantum_info/operators/channel/chi.py +9 -8
  153. qiskit/quantum_info/operators/channel/choi.py +10 -9
  154. qiskit/quantum_info/operators/channel/kraus.py +2 -1
  155. qiskit/quantum_info/operators/channel/ptm.py +10 -9
  156. qiskit/quantum_info/operators/channel/quantum_channel.py +2 -1
  157. qiskit/quantum_info/operators/channel/stinespring.py +2 -1
  158. qiskit/quantum_info/operators/channel/superop.py +12 -11
  159. qiskit/quantum_info/operators/channel/transformations.py +12 -11
  160. qiskit/quantum_info/operators/dihedral/dihedral.py +5 -4
  161. qiskit/quantum_info/operators/operator.py +43 -30
  162. qiskit/quantum_info/operators/scalar_op.py +10 -9
  163. qiskit/quantum_info/operators/symplectic/base_pauli.py +70 -59
  164. qiskit/quantum_info/operators/symplectic/clifford.py +36 -9
  165. qiskit/quantum_info/operators/symplectic/pauli.py +53 -6
  166. qiskit/quantum_info/operators/symplectic/pauli_list.py +36 -14
  167. qiskit/quantum_info/operators/symplectic/random.py +3 -2
  168. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +61 -36
  169. qiskit/quantum_info/states/densitymatrix.py +13 -13
  170. qiskit/quantum_info/states/stabilizerstate.py +3 -3
  171. qiskit/quantum_info/states/statevector.py +14 -13
  172. qiskit/quantum_info/states/utils.py +5 -3
  173. qiskit/result/__init__.py +6 -0
  174. qiskit/result/mitigation/correlated_readout_mitigator.py +3 -2
  175. qiskit/result/mitigation/local_readout_mitigator.py +2 -1
  176. qiskit/result/mitigation/utils.py +3 -2
  177. qiskit/scheduler/__init__.py +10 -1
  178. qiskit/scheduler/methods/__init__.py +1 -8
  179. qiskit/synthesis/__init__.py +3 -6
  180. qiskit/synthesis/discrete_basis/commutator_decompose.py +2 -2
  181. qiskit/synthesis/evolution/lie_trotter.py +7 -14
  182. qiskit/synthesis/evolution/qdrift.py +3 -4
  183. qiskit/synthesis/linear/cnot_synth.py +1 -3
  184. qiskit/synthesis/linear/linear_circuits_utils.py +1 -1
  185. qiskit/synthesis/linear_phase/cz_depth_lnn.py +4 -18
  186. qiskit/synthesis/permutation/__init__.py +1 -0
  187. qiskit/synthesis/permutation/permutation_reverse_lnn.py +90 -0
  188. qiskit/synthesis/qft/qft_decompose_lnn.py +2 -6
  189. qiskit/synthesis/two_qubit/two_qubit_decompose.py +165 -954
  190. qiskit/synthesis/two_qubit/xx_decompose/circuits.py +13 -12
  191. qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +7 -1
  192. qiskit/synthesis/unitary/aqc/__init__.py +1 -1
  193. qiskit/synthesis/unitary/aqc/cnot_structures.py +2 -1
  194. qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +2 -1
  195. qiskit/synthesis/unitary/qsd.py +3 -2
  196. qiskit/transpiler/__init__.py +7 -3
  197. qiskit/transpiler/layout.py +140 -61
  198. qiskit/transpiler/passes/__init__.py +10 -2
  199. qiskit/transpiler/passes/basis/basis_translator.py +9 -4
  200. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
  201. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
  202. qiskit/transpiler/passes/calibration/rzx_builder.py +2 -1
  203. qiskit/transpiler/passes/layout/apply_layout.py +8 -3
  204. qiskit/transpiler/passes/layout/sabre_layout.py +15 -3
  205. qiskit/transpiler/passes/layout/set_layout.py +1 -1
  206. qiskit/transpiler/passes/optimization/__init__.py +2 -0
  207. qiskit/transpiler/passes/optimization/commutation_analysis.py +2 -2
  208. qiskit/transpiler/passes/optimization/commutative_cancellation.py +1 -1
  209. qiskit/transpiler/passes/optimization/consolidate_blocks.py +1 -1
  210. qiskit/transpiler/passes/optimization/cx_cancellation.py +10 -0
  211. qiskit/transpiler/passes/optimization/elide_permutations.py +114 -0
  212. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +9 -3
  213. qiskit/transpiler/passes/optimization/optimize_annotated.py +248 -12
  214. qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
  215. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +1 -3
  216. qiskit/transpiler/passes/routing/__init__.py +1 -0
  217. qiskit/transpiler/passes/routing/basic_swap.py +13 -2
  218. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +8 -1
  219. qiskit/transpiler/passes/routing/lookahead_swap.py +7 -1
  220. qiskit/transpiler/passes/routing/sabre_swap.py +10 -6
  221. qiskit/transpiler/passes/routing/star_prerouting.py +417 -0
  222. qiskit/transpiler/passes/routing/stochastic_swap.py +24 -8
  223. qiskit/transpiler/passes/scheduling/__init__.py +1 -1
  224. qiskit/transpiler/passes/scheduling/alap.py +1 -2
  225. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +1 -2
  226. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +9 -6
  227. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +8 -0
  228. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +13 -4
  229. qiskit/transpiler/passes/scheduling/asap.py +1 -2
  230. qiskit/transpiler/passes/scheduling/base_scheduler.py +21 -2
  231. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +26 -4
  232. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +24 -2
  233. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +28 -4
  234. qiskit/transpiler/passes/synthesis/aqc_plugin.py +2 -2
  235. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +120 -13
  236. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +162 -55
  237. qiskit/transpiler/passes/utils/gates_basis.py +3 -3
  238. qiskit/transpiler/passmanager.py +44 -1
  239. qiskit/transpiler/preset_passmanagers/__init__.py +3 -3
  240. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +34 -16
  241. qiskit/transpiler/preset_passmanagers/common.py +4 -6
  242. qiskit/transpiler/preset_passmanagers/plugin.py +9 -1
  243. qiskit/utils/__init__.py +3 -2
  244. qiskit/utils/optionals.py +6 -2
  245. qiskit/utils/parallel.py +24 -15
  246. qiskit/visualization/array.py +1 -1
  247. qiskit/visualization/bloch.py +2 -3
  248. qiskit/visualization/circuit/matplotlib.py +44 -14
  249. qiskit/visualization/circuit/text.py +38 -18
  250. qiskit/visualization/counts_visualization.py +3 -6
  251. qiskit/visualization/dag_visualization.py +6 -7
  252. qiskit/visualization/gate_map.py +9 -1
  253. qiskit/visualization/pulse_v2/interface.py +8 -3
  254. qiskit/visualization/state_visualization.py +3 -2
  255. qiskit/visualization/timeline/interface.py +18 -8
  256. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/METADATA +12 -8
  257. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/RECORD +261 -251
  258. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/WHEEL +1 -1
  259. qiskit/_qasm2.pyd +0 -0
  260. qiskit/_qasm3.pyd +0 -0
  261. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/LICENSE.txt +0 -0
  262. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/entry_points.txt +0 -0
  263. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/top_level.txt +0 -0
@@ -15,9 +15,8 @@
15
15
  from typing import Optional, Union
16
16
 
17
17
  import numpy as np
18
- from qiskit.quantum_info.random import random_unitary
19
- from qiskit.circuit import QuantumCircuit
20
- from qiskit.circuit.library.generalized_gates.permutation import Permutation
18
+ from qiskit.circuit import QuantumCircuit, CircuitInstruction
19
+ from qiskit.circuit.library.generalized_gates import PermutationGate, UnitaryGate
21
20
 
22
21
 
23
22
  class QuantumVolume(QuantumCircuit):
@@ -60,6 +59,8 @@ class QuantumVolume(QuantumCircuit):
60
59
  depth: Optional[int] = None,
61
60
  seed: Optional[Union[int, np.random.Generator]] = None,
62
61
  classical_permutation: bool = True,
62
+ *,
63
+ flatten: bool = False,
63
64
  ) -> None:
64
65
  """Create quantum volume model circuit of size num_qubits x depth.
65
66
 
@@ -69,46 +70,46 @@ class QuantumVolume(QuantumCircuit):
69
70
  seed: Random number generator or generator seed.
70
71
  classical_permutation: use classical permutations at every layer,
71
72
  rather than quantum.
73
+ flatten: If ``False`` (the default), construct a circuit that contains a single
74
+ instruction, which in turn has the actual volume structure. If ``True``, construct
75
+ the volume structure directly.
72
76
  """
73
- # Initialize RNG
74
- if seed is None:
75
- rng_set = np.random.default_rng()
76
- seed = rng_set.integers(low=1, high=1000)
77
- if isinstance(seed, np.random.Generator):
78
- rng = seed
79
- else:
80
- rng = np.random.default_rng(seed)
77
+ import scipy.stats
81
78
 
82
79
  # Parameters
83
80
  depth = depth or num_qubits # how many layers of SU(4)
84
- width = int(np.floor(num_qubits / 2)) # how many SU(4)s fit in each layer
85
- name = "quantum_volume_" + str([num_qubits, depth, seed]).replace(" ", "")
81
+ width = num_qubits // 2 # how many SU(4)s fit in each layer
82
+ rng = seed if isinstance(seed, np.random.Generator) else np.random.default_rng(seed)
83
+ if seed is None:
84
+ # Get the internal entropy used to seed the default RNG, if no seed was given. This
85
+ # stays in the output name, so effectively stores a way of regenerating the circuit.
86
+ # This is just best-effort only, for backwards compatibility, and isn't critical (if
87
+ # someone needs full reproducibility, they should be manually controlling the seeding).
88
+ seed = getattr(getattr(rng.bit_generator, "seed_seq", None), "entropy", None)
86
89
 
87
- # Generator random unitary seeds in advance.
88
- # Note that this means we are constructing multiple new generator
89
- # objects from low-entropy integer seeds rather than pass the shared
90
- # generator object to the random_unitary function. This is done so
91
- # that we can use the integer seed as a label for the generated gates.
92
- unitary_seeds = rng.integers(low=1, high=1000, size=[depth, width])
90
+ super().__init__(
91
+ num_qubits, name="quantum_volume_" + str([num_qubits, depth, seed]).replace(" ", "")
92
+ )
93
+ base = self if flatten else QuantumCircuit(num_qubits, name=self.name)
93
94
 
94
95
  # For each layer, generate a permutation of qubits
95
96
  # Then generate and apply a Haar-random SU(4) to each pair
96
- circuit = QuantumCircuit(num_qubits, name=name)
97
- perm_0 = list(range(num_qubits))
98
- for d in range(depth):
99
- perm = rng.permutation(perm_0)
100
- if not classical_permutation:
101
- layer_perm = Permutation(num_qubits, perm)
102
- circuit.compose(layer_perm, inplace=True)
103
- for w in range(width):
104
- seed_u = unitary_seeds[d][w]
105
- su4 = random_unitary(4, seed=seed_u).to_instruction()
106
- su4.label = "su4_" + str(seed_u)
107
- if classical_permutation:
108
- physical_qubits = int(perm[2 * w]), int(perm[2 * w + 1])
109
- circuit.compose(su4, [physical_qubits[0], physical_qubits[1]], inplace=True)
110
- else:
111
- circuit.compose(su4, [2 * w, 2 * w + 1], inplace=True)
112
-
113
- super().__init__(*circuit.qregs, name=circuit.name)
114
- self.compose(circuit.to_instruction(), qubits=self.qubits, inplace=True)
97
+ unitaries = scipy.stats.unitary_group.rvs(4, depth * width, rng).reshape(depth, width, 4, 4)
98
+ qubits = tuple(base.qubits)
99
+ for row in unitaries:
100
+ perm = rng.permutation(num_qubits)
101
+ if classical_permutation:
102
+ for w, unitary in enumerate(row):
103
+ gate = UnitaryGate(unitary, check_input=False, num_qubits=2)
104
+ qubit = 2 * w
105
+ base._append(
106
+ CircuitInstruction(gate, (qubits[perm[qubit]], qubits[perm[qubit + 1]]))
107
+ )
108
+ else:
109
+ base._append(CircuitInstruction(PermutationGate(perm), qubits))
110
+ for w, unitary in enumerate(row):
111
+ gate = UnitaryGate(unitary, check_input=False, num_qubits=2)
112
+ qubit = 2 * w
113
+ base._append(CircuitInstruction(gate, qubits[qubit : qubit + 2]))
114
+ if not flatten:
115
+ self._append(CircuitInstruction(base.to_instruction(), tuple(self.qubits)))
@@ -850,6 +850,56 @@ for inst, qargs, cargs in [
850
850
  def_swap.append(inst, qargs, cargs)
851
851
  _sel.add_equivalence(SwapGate(), def_swap)
852
852
 
853
+ # SwapGate
854
+ #
855
+ # q_0: ─X─
856
+ # │ ≡
857
+ # q_1: ─X─
858
+ #
859
+ # ┌──────────┐┌──────┐ ┌────┐ ┌──────┐┌──────────┐┌──────┐
860
+ # q_0: ┤ Rz(-π/2) ├┤0 ├───┤ √X ├───┤1 ├┤ Rz(-π/2) ├┤0 ├
861
+ # └──┬────┬──┘│ Ecr │┌──┴────┴──┐│ Ecr │└──┬────┬──┘│ Ecr │
862
+ # q_1: ───┤ √X ├───┤1 ├┤ Rz(-π/2) ├┤0 ├───┤ √X ├───┤1 ├
863
+ # └────┘ └──────┘└──────────┘└──────┘ └────┘ └──────┘
864
+ #
865
+ q = QuantumRegister(2, "q")
866
+ def_swap_ecr = QuantumCircuit(q)
867
+ def_swap_ecr.rz(-pi / 2, 0)
868
+ def_swap_ecr.sx(1)
869
+ def_swap_ecr.ecr(0, 1)
870
+ def_swap_ecr.rz(-pi / 2, 1)
871
+ def_swap_ecr.sx(0)
872
+ def_swap_ecr.ecr(1, 0)
873
+ def_swap_ecr.rz(-pi / 2, 0)
874
+ def_swap_ecr.sx(1)
875
+ def_swap_ecr.ecr(0, 1)
876
+ _sel.add_equivalence(SwapGate(), def_swap_ecr)
877
+
878
+ # SwapGate
879
+ #
880
+ # q_0: ─X─
881
+ # │ ≡
882
+ # q_1: ─X─
883
+ #
884
+ # global phase: 3π/2
885
+ # ┌────┐ ┌────┐ ┌────┐
886
+ # q_0: ┤ √X ├─■─┤ √X ├─■─┤ √X ├─■─
887
+ # ├────┤ │ ├────┤ │ ├────┤ │
888
+ # q_1: ┤ √X ├─■─┤ √X ├─■─┤ √X ├─■─
889
+ # └────┘ └────┘ └────┘
890
+ q = QuantumRegister(2, "q")
891
+ def_swap_cz = QuantumCircuit(q, global_phase=-pi / 2)
892
+ def_swap_cz.sx(0)
893
+ def_swap_cz.sx(1)
894
+ def_swap_cz.cz(0, 1)
895
+ def_swap_cz.sx(0)
896
+ def_swap_cz.sx(1)
897
+ def_swap_cz.cz(0, 1)
898
+ def_swap_cz.sx(0)
899
+ def_swap_cz.sx(1)
900
+ def_swap_cz.cz(0, 1)
901
+ _sel.add_equivalence(SwapGate(), def_swap_cz)
902
+
853
903
  # iSwapGate
854
904
  #
855
905
  # ┌────────┐ ┌───┐┌───┐ ┌───┐
@@ -69,10 +69,12 @@ class GlobalPhaseGate(Gate):
69
69
  """
70
70
  return GlobalPhaseGate(-self.params[0])
71
71
 
72
- def __array__(self, dtype=complex):
72
+ def __array__(self, dtype=None, copy=None):
73
73
  """Return a numpy.array for the global_phase gate."""
74
+ if copy is False:
75
+ raise ValueError("unable to avoid copy while creating an array as requested")
74
76
  theta = self.params[0]
75
- return numpy.array([[numpy.exp(1j * theta)]], dtype=dtype)
77
+ return numpy.array([[numpy.exp(1j * theta)]], dtype=dtype or complex)
76
78
 
77
79
  def __eq__(self, other):
78
80
  if isinstance(other, GlobalPhaseGate):
@@ -65,8 +65,7 @@ class IGate(SingletonGate):
65
65
  ."""
66
66
  return IGate() # self-inverse
67
67
 
68
- def power(self, exponent: float):
69
- """Raise gate to a power."""
68
+ def power(self, exponent: float, annotated: bool = False):
70
69
  return IGate()
71
70
 
72
71
  def __eq__(self, other):
@@ -124,8 +124,7 @@ class iSwapGate(SingletonGate):
124
124
 
125
125
  self.definition = qc
126
126
 
127
- def power(self, exponent: float):
128
- """Raise gate to a power."""
127
+ def power(self, exponent: float, annotated: bool = False):
129
128
  return XXPlusYYGate(-np.pi * exponent)
130
129
 
131
130
  def __eq__(self, other):
@@ -14,6 +14,7 @@ Multiple-Controlled U3 gate. Not using ancillary qubits.
14
14
  """
15
15
 
16
16
  from math import pi
17
+ import math
17
18
  from typing import Optional, Union, Tuple, List
18
19
  import numpy as np
19
20
 
@@ -123,6 +124,9 @@ def _mcsu2_real_diagonal(
123
124
  if not is_unitary_matrix(unitary):
124
125
  raise QiskitError(f"The unitary in must be an unitary matrix, but is {unitary}.")
125
126
 
127
+ if not np.isclose(1.0, np.linalg.det(unitary)):
128
+ raise QiskitError("Invalid Value _mcsu2_real_diagonal requires det(unitary) equal to one.")
129
+
126
130
  is_main_diag_real = np.isclose(unitary[0, 0].imag, 0.0) and np.isclose(unitary[1, 1].imag, 0.0)
127
131
  is_secondary_diag_real = np.isclose(unitary[0, 1].imag, 0.0) and np.isclose(
128
132
  unitary[1, 0].imag, 0.0
@@ -141,18 +145,20 @@ def _mcsu2_real_diagonal(
141
145
  if np.isclose(z, -1):
142
146
  s_op = [[1.0, 0.0], [0.0, 1.0j]]
143
147
  else:
144
- alpha_r = np.sqrt((np.sqrt((z.real + 1.0) / 2.0) + 1.0) / 2.0)
145
- alpha_i = z.imag / (2.0 * np.sqrt((z.real + 1.0) * (np.sqrt((z.real + 1.0) / 2.0) + 1.0)))
148
+ alpha_r = math.sqrt((math.sqrt((z.real + 1.0) / 2.0) + 1.0) / 2.0)
149
+ alpha_i = z.imag / (
150
+ 2.0 * math.sqrt((z.real + 1.0) * (math.sqrt((z.real + 1.0) / 2.0) + 1.0))
151
+ )
146
152
  alpha = alpha_r + 1.0j * alpha_i
147
- beta = x / (2.0 * np.sqrt((z.real + 1.0) * (np.sqrt((z.real + 1.0) / 2.0) + 1.0)))
153
+ beta = x / (2.0 * math.sqrt((z.real + 1.0) * (math.sqrt((z.real + 1.0) / 2.0) + 1.0)))
148
154
 
149
155
  # S gate definition
150
156
  s_op = np.array([[alpha, -np.conj(beta)], [beta, np.conj(alpha)]])
151
157
 
152
158
  s_gate = UnitaryGate(s_op)
153
159
 
154
- k_1 = int(np.ceil(num_controls / 2.0))
155
- k_2 = int(np.floor(num_controls / 2.0))
160
+ k_1 = math.ceil(num_controls / 2.0)
161
+ k_2 = math.floor(num_controls / 2.0)
156
162
 
157
163
  ctrl_state_k_1 = None
158
164
  ctrl_state_k_2 = None
@@ -140,13 +140,14 @@ class PhaseGate(Gate):
140
140
  """
141
141
  return PhaseGate(-self.params[0])
142
142
 
143
- def __array__(self, dtype=None):
143
+ def __array__(self, dtype=None, copy=None):
144
144
  """Return a numpy.array for the Phase gate."""
145
+ if copy is False:
146
+ raise ValueError("unable to avoid copy while creating an array as requested")
145
147
  lam = float(self.params[0])
146
148
  return numpy.array([[1, 0], [0, exp(1j * lam)]], dtype=dtype)
147
149
 
148
- def power(self, exponent: float):
149
- """Raise gate to a power."""
150
+ def power(self, exponent: float, annotated: bool = False):
150
151
  (theta,) = self.params
151
152
  return PhaseGate(exponent * theta)
152
153
 
@@ -280,8 +281,10 @@ class CPhaseGate(ControlledGate):
280
281
  r"""Return inverted CPhase gate (:math:`CPhase(\lambda)^{\dagger} = CPhase(-\lambda)`)"""
281
282
  return CPhaseGate(-self.params[0], ctrl_state=self.ctrl_state)
282
283
 
283
- def __array__(self, dtype=None):
284
+ def __array__(self, dtype=None, copy=None):
284
285
  """Return a numpy.array for the CPhase gate."""
286
+ if copy is False:
287
+ raise ValueError("unable to avoid copy while creating an array as requested")
285
288
  eith = exp(1j * float(self.params[0]))
286
289
  if self.ctrl_state:
287
290
  return numpy.array(
@@ -289,8 +292,7 @@ class CPhaseGate(ControlledGate):
289
292
  )
290
293
  return numpy.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, eith, 0], [0, 0, 0, 1]], dtype=dtype)
291
294
 
292
- def power(self, exponent: float):
293
- """Raise gate to a power."""
295
+ def power(self, exponent: float, annotated: bool = False):
294
296
  (theta,) = self.params
295
297
  return CPhaseGate(exponent * theta)
296
298
 
@@ -333,6 +335,7 @@ class MCPhaseGate(ControlledGate):
333
335
  lam: ParameterValueType,
334
336
  num_ctrl_qubits: int,
335
337
  label: str | None = None,
338
+ ctrl_state: str | int | None = None,
336
339
  *,
337
340
  duration=None,
338
341
  unit="dt",
@@ -345,6 +348,7 @@ class MCPhaseGate(ControlledGate):
345
348
  [lam],
346
349
  num_ctrl_qubits=num_ctrl_qubits,
347
350
  label=label,
351
+ ctrl_state=ctrl_state,
348
352
  base_gate=PhaseGate(lam, label=_base_label),
349
353
  duration=duration,
350
354
  unit=unit,
@@ -354,20 +358,32 @@ class MCPhaseGate(ControlledGate):
354
358
  # pylint: disable=cyclic-import
355
359
  from qiskit.circuit.quantumcircuit import QuantumCircuit
356
360
 
357
- q = QuantumRegister(self.num_qubits, "q")
358
- qc = QuantumCircuit(q, name=self.name)
361
+ qr = QuantumRegister(self.num_qubits, "q")
362
+ qc = QuantumCircuit(qr, name=self.name)
359
363
 
360
364
  if self.num_ctrl_qubits == 0:
361
365
  qc.p(self.params[0], 0)
362
366
  if self.num_ctrl_qubits == 1:
363
367
  qc.cp(self.params[0], 0, 1)
364
368
  else:
365
- from .u3 import _gray_code_chain
366
-
367
- scaled_lam = self.params[0] / (2 ** (self.num_ctrl_qubits - 1))
368
- bottom_gate = CPhaseGate(scaled_lam)
369
- for operation, qubits, clbits in _gray_code_chain(q, self.num_ctrl_qubits, bottom_gate):
370
- qc._append(operation, qubits, clbits)
369
+ lam = self.params[0]
370
+ if type(lam) in [float, int]:
371
+ q_controls = list(range(self.num_ctrl_qubits))
372
+ q_target = self.num_ctrl_qubits
373
+ new_target = q_target
374
+ for k in range(self.num_ctrl_qubits):
375
+ qc.mcrz(lam / (2**k), q_controls, new_target, use_basis_gates=True)
376
+ new_target = q_controls.pop()
377
+ qc.p(lam / (2**self.num_ctrl_qubits), new_target)
378
+ else: # in this case type(lam) is ParameterValueType
379
+ from .u3 import _gray_code_chain
380
+
381
+ scaled_lam = self.params[0] / (2 ** (self.num_ctrl_qubits - 1))
382
+ bottom_gate = CPhaseGate(scaled_lam)
383
+ for operation, qubits, clbits in _gray_code_chain(
384
+ qr, self.num_ctrl_qubits, bottom_gate
385
+ ):
386
+ qc._append(operation, qubits, clbits)
371
387
  self.definition = qc
372
388
 
373
389
  def control(
@@ -407,5 +423,5 @@ class MCPhaseGate(ControlledGate):
407
423
  return gate
408
424
 
409
425
  def inverse(self, annotated: bool = False):
410
- r"""Return inverted MCU1 gate (:math:`MCU1(\lambda)^{\dagger} = MCU1(-\lambda)`)"""
426
+ r"""Return inverted MCPhase gate (:math:`MCPhase(\lambda)^{\dagger} = MCPhase(-\lambda)`)"""
411
427
  return MCPhaseGate(-self.params[0], self.num_ctrl_qubits)
@@ -93,8 +93,10 @@ class RGate(Gate):
93
93
  """
94
94
  return RGate(-self.params[0], self.params[1])
95
95
 
96
- def __array__(self, dtype=None):
96
+ def __array__(self, dtype=None, copy=None):
97
97
  """Return a numpy.array for the R gate."""
98
+ if copy is False:
99
+ raise ValueError("unable to avoid copy while creating an array as requested")
98
100
  theta, phi = float(self.params[0]), float(self.params[1])
99
101
  cos = math.cos(theta / 2)
100
102
  sin = math.sin(theta / 2)
@@ -102,8 +104,7 @@ class RGate(Gate):
102
104
  exp_p = exp(1j * phi)
103
105
  return numpy.array([[cos, -1j * exp_m * sin], [-1j * exp_p * sin, cos]], dtype=dtype)
104
106
 
105
- def power(self, exponent: float):
106
- """Raise gate to a power."""
107
+ def power(self, exponent: float, annotated: bool = False):
107
108
  theta, phi = self.params
108
109
  return RGate(exponent * theta, phi)
109
110
 
@@ -120,14 +120,15 @@ class RXGate(Gate):
120
120
  """
121
121
  return RXGate(-self.params[0])
122
122
 
123
- def __array__(self, dtype=None):
123
+ def __array__(self, dtype=None, copy=None):
124
124
  """Return a numpy.array for the RX gate."""
125
+ if copy is False:
126
+ raise ValueError("unable to avoid copy while creating an array as requested")
125
127
  cos = math.cos(self.params[0] / 2)
126
128
  sin = math.sin(self.params[0] / 2)
127
129
  return numpy.array([[cos, -1j * sin], [-1j * sin, cos]], dtype=dtype)
128
130
 
129
- def power(self, exponent: float):
130
- """Raise gate to a power."""
131
+ def power(self, exponent: float, annotated: bool = False):
131
132
  (theta,) = self.params
132
133
  return RXGate(exponent * theta)
133
134
 
@@ -264,8 +265,10 @@ class CRXGate(ControlledGate):
264
265
  """
265
266
  return CRXGate(-self.params[0], ctrl_state=self.ctrl_state)
266
267
 
267
- def __array__(self, dtype=None):
268
+ def __array__(self, dtype=None, copy=None):
268
269
  """Return a numpy.array for the CRX gate."""
270
+ if copy is False:
271
+ raise ValueError("unable to avoid copy while creating an array as requested")
269
272
  half_theta = float(self.params[0]) / 2
270
273
  cos = math.cos(half_theta)
271
274
  isin = 1j * math.sin(half_theta)
@@ -122,8 +122,10 @@ class RXXGate(Gate):
122
122
  """
123
123
  return RXXGate(-self.params[0])
124
124
 
125
- def __array__(self, dtype=None):
125
+ def __array__(self, dtype=None, copy=None):
126
126
  """Return a Numpy.array for the RXX gate."""
127
+ if copy is False:
128
+ raise ValueError("unable to avoid copy while creating an array as requested")
127
129
  theta2 = float(self.params[0]) / 2
128
130
  cos = math.cos(theta2)
129
131
  isin = 1j * math.sin(theta2)
@@ -132,8 +134,7 @@ class RXXGate(Gate):
132
134
  dtype=dtype,
133
135
  )
134
136
 
135
- def power(self, exponent: float):
136
- """Raise gate to a power."""
137
+ def power(self, exponent: float, annotated: bool = False):
137
138
  (theta,) = self.params
138
139
  return RXXGate(exponent * theta)
139
140
 
@@ -119,14 +119,15 @@ class RYGate(Gate):
119
119
  """
120
120
  return RYGate(-self.params[0])
121
121
 
122
- def __array__(self, dtype=None):
122
+ def __array__(self, dtype=None, copy=None):
123
123
  """Return a numpy.array for the RY gate."""
124
+ if copy is False:
125
+ raise ValueError("unable to avoid copy while creating an array as requested")
124
126
  cos = math.cos(self.params[0] / 2)
125
127
  sin = math.sin(self.params[0] / 2)
126
128
  return numpy.array([[cos, -sin], [sin, cos]], dtype=dtype)
127
129
 
128
- def power(self, exponent: float):
129
- """Raise gate to a power."""
130
+ def power(self, exponent: float, annotated: bool = False):
130
131
  (theta,) = self.params
131
132
  return RYGate(exponent * theta)
132
133
 
@@ -259,8 +260,10 @@ class CRYGate(ControlledGate):
259
260
  ."""
260
261
  return CRYGate(-self.params[0], ctrl_state=self.ctrl_state)
261
262
 
262
- def __array__(self, dtype=None):
263
+ def __array__(self, dtype=None, copy=None):
263
264
  """Return a numpy.array for the CRY gate."""
265
+ if copy is False:
266
+ raise ValueError("unable to avoid copy while creating an array as requested")
264
267
  half_theta = float(self.params[0]) / 2
265
268
  cos = math.cos(half_theta)
266
269
  sin = math.sin(half_theta)
@@ -122,8 +122,10 @@ class RYYGate(Gate):
122
122
  """
123
123
  return RYYGate(-self.params[0])
124
124
 
125
- def __array__(self, dtype=None):
125
+ def __array__(self, dtype=None, copy=None):
126
126
  """Return a numpy.array for the RYY gate."""
127
+ if copy is False:
128
+ raise ValueError("unable to avoid copy while creating an array as requested")
127
129
  theta = float(self.params[0])
128
130
  cos = math.cos(theta / 2)
129
131
  isin = 1j * math.sin(theta / 2)
@@ -132,8 +134,7 @@ class RYYGate(Gate):
132
134
  dtype=dtype,
133
135
  )
134
136
 
135
- def power(self, exponent: float):
136
- """Raise gate to a power."""
137
+ def power(self, exponent: float, annotated: bool = False):
137
138
  (theta,) = self.params
138
139
  return RYYGate(exponent * theta)
139
140
 
@@ -130,15 +130,16 @@ class RZGate(Gate):
130
130
  """
131
131
  return RZGate(-self.params[0])
132
132
 
133
- def __array__(self, dtype=None):
133
+ def __array__(self, dtype=None, copy=None):
134
134
  """Return a numpy.array for the RZ gate."""
135
135
  import numpy as np
136
136
 
137
+ if copy is False:
138
+ raise ValueError("unable to avoid copy while creating an array as requested")
137
139
  ilam2 = 0.5j * float(self.params[0])
138
140
  return np.array([[exp(-ilam2), 0], [0, exp(ilam2)]], dtype=dtype)
139
141
 
140
- def power(self, exponent: float):
141
- """Raise gate to a power."""
142
+ def power(self, exponent: float, annotated: bool = False):
142
143
  (theta,) = self.params
143
144
  return RZGate(exponent * theta)
144
145
 
@@ -277,10 +278,12 @@ class CRZGate(ControlledGate):
277
278
  """
278
279
  return CRZGate(-self.params[0], ctrl_state=self.ctrl_state)
279
280
 
280
- def __array__(self, dtype=None):
281
+ def __array__(self, dtype=None, copy=None):
281
282
  """Return a numpy.array for the CRZ gate."""
282
283
  import numpy
283
284
 
285
+ if copy is False:
286
+ raise ValueError("unable to avoid copy while creating an array as requested")
284
287
  arg = 1j * float(self.params[0]) / 2
285
288
  if self.ctrl_state:
286
289
  return numpy.array(
@@ -166,10 +166,12 @@ class RZXGate(Gate):
166
166
  """
167
167
  return RZXGate(-self.params[0])
168
168
 
169
- def __array__(self, dtype=None):
169
+ def __array__(self, dtype=None, copy=None):
170
170
  """Return a numpy.array for the RZX gate."""
171
171
  import numpy
172
172
 
173
+ if copy is False:
174
+ raise ValueError("unable to avoid copy while creating an array as requested")
173
175
  half_theta = float(self.params[0]) / 2
174
176
  cos = math.cos(half_theta)
175
177
  isin = 1j * math.sin(half_theta)
@@ -178,8 +180,7 @@ class RZXGate(Gate):
178
180
  dtype=dtype,
179
181
  )
180
182
 
181
- def power(self, exponent: float):
182
- """Raise gate to a power."""
183
+ def power(self, exponent: float, annotated: bool = False):
183
184
  (theta,) = self.params
184
185
  return RZXGate(exponent * theta)
185
186
 
@@ -130,10 +130,12 @@ class RZZGate(Gate):
130
130
  """
131
131
  return RZZGate(-self.params[0])
132
132
 
133
- def __array__(self, dtype=None):
133
+ def __array__(self, dtype=None, copy=None):
134
134
  """Return a numpy.array for the RZZ gate."""
135
135
  import numpy
136
136
 
137
+ if copy is False:
138
+ raise ValueError("unable to avoid copy while creating an array as requested")
137
139
  itheta2 = 1j * float(self.params[0]) / 2
138
140
  return numpy.array(
139
141
  [
@@ -145,8 +147,7 @@ class RZZGate(Gate):
145
147
  dtype=dtype,
146
148
  )
147
149
 
148
- def power(self, exponent: float):
149
- """Raise gate to a power."""
150
+ def power(self, exponent: float, annotated: bool = False):
150
151
  (theta,) = self.params
151
152
  return RZZGate(exponent * theta)
152
153
 
@@ -94,8 +94,7 @@ class SGate(SingletonGate):
94
94
  """
95
95
  return SdgGate()
96
96
 
97
- def power(self, exponent: float):
98
- """Raise gate to a power."""
97
+ def power(self, exponent: float, annotated: bool = False):
99
98
  from .p import PhaseGate
100
99
 
101
100
  return PhaseGate(0.5 * numpy.pi * exponent)
@@ -172,8 +171,7 @@ class SdgGate(SingletonGate):
172
171
  """
173
172
  return SGate()
174
173
 
175
- def power(self, exponent: float):
176
- """Raise gate to a power."""
174
+ def power(self, exponent: float, annotated: bool = False):
177
175
  from .p import PhaseGate
178
176
 
179
177
  return PhaseGate(-0.5 * numpy.pi * exponent)
@@ -259,8 +257,7 @@ class CSGate(SingletonControlledGate):
259
257
  """
260
258
  return CSdgGate(ctrl_state=self.ctrl_state)
261
259
 
262
- def power(self, exponent: float):
263
- """Raise gate to a power."""
260
+ def power(self, exponent: float, annotated: bool = False):
264
261
  from .p import CPhaseGate
265
262
 
266
263
  return CPhaseGate(0.5 * numpy.pi * exponent)
@@ -345,8 +342,7 @@ class CSdgGate(SingletonControlledGate):
345
342
  """
346
343
  return CSGate(ctrl_state=self.ctrl_state)
347
344
 
348
- def power(self, exponent: float):
349
- """Raise gate to a power."""
345
+ def power(self, exponent: float, annotated: bool = False):
350
346
  from .p import CPhaseGate
351
347
 
352
348
  return CPhaseGate(-0.5 * numpy.pi * exponent)
@@ -92,8 +92,7 @@ class TGate(SingletonGate):
92
92
  """
93
93
  return TdgGate()
94
94
 
95
- def power(self, exponent: float):
96
- """Raise gate to a power."""
95
+ def power(self, exponent: float, annotated: bool = False):
97
96
  return PhaseGate(0.25 * numpy.pi * exponent)
98
97
 
99
98
  def __eq__(self, other):
@@ -168,8 +167,7 @@ class TdgGate(SingletonGate):
168
167
  """
169
168
  return TGate()
170
169
 
171
- def power(self, exponent: float):
172
- """Raise gate to a power."""
170
+ def power(self, exponent: float, annotated: bool = False):
173
171
  return PhaseGate(-0.25 * numpy.pi * exponent)
174
172
 
175
173
  def __eq__(self, other):