qiskit 1.3.0__cp39-abi3-macosx_10_12_x86_64.whl → 1.3.1__cp39-abi3-macosx_10_12_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qiskit/VERSION.txt +1 -1
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/circuit/add_control.py +110 -92
- qiskit/circuit/library/arithmetic/adders/adder.py +25 -0
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +9 -0
- qiskit/qpy/__init__.py +5 -5
- qiskit/quantum_info/operators/channel/chi.py +9 -9
- qiskit/quantum_info/operators/channel/choi.py +9 -9
- qiskit/quantum_info/operators/channel/ptm.py +9 -9
- qiskit/quantum_info/operators/channel/quantum_channel.py +3 -3
- qiskit/quantum_info/operators/channel/stinespring.py +9 -9
- qiskit/quantum_info/operators/channel/superop.py +5 -9
- qiskit/quantum_info/states/densitymatrix.py +17 -15
- qiskit/quantum_info/states/stabilizerstate.py +7 -6
- qiskit/quantum_info/states/statevector.py +14 -6
- qiskit/transpiler/passes/basis/decompose.py +24 -4
- qiskit/transpiler/passes/synthesis/hls_plugins.py +85 -18
- {qiskit-1.3.0.dist-info → qiskit-1.3.1.dist-info}/METADATA +2 -2
- {qiskit-1.3.0.dist-info → qiskit-1.3.1.dist-info}/RECORD +23 -23
- {qiskit-1.3.0.dist-info → qiskit-1.3.1.dist-info}/entry_points.txt +1 -1
- {qiskit-1.3.0.dist-info → qiskit-1.3.1.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.3.0.dist-info → qiskit-1.3.1.dist-info}/WHEEL +0 -0
- {qiskit-1.3.0.dist-info → qiskit-1.3.1.dist-info}/top_level.txt +0 -0
qiskit/VERSION.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.3.
|
1
|
+
1.3.1
|
qiskit/_accelerate.abi3.so
CHANGED
Binary file
|
qiskit/circuit/add_control.py
CHANGED
@@ -13,6 +13,7 @@
|
|
13
13
|
"""Add control to operation if supported."""
|
14
14
|
from __future__ import annotations
|
15
15
|
|
16
|
+
from math import pi
|
16
17
|
from qiskit.circuit.exceptions import CircuitError
|
17
18
|
from qiskit.circuit.library import UnitaryGate
|
18
19
|
from qiskit.transpiler import PassManager
|
@@ -92,7 +93,6 @@ def control(
|
|
92
93
|
Raises:
|
93
94
|
CircuitError: gate contains non-gate in definition
|
94
95
|
"""
|
95
|
-
from math import pi
|
96
96
|
|
97
97
|
# pylint: disable=cyclic-import
|
98
98
|
from qiskit.circuit import controlledgate
|
@@ -101,22 +101,23 @@ def control(
|
|
101
101
|
|
102
102
|
q_control = QuantumRegister(num_ctrl_qubits, name="control")
|
103
103
|
q_target = QuantumRegister(operation.num_qubits, name="target")
|
104
|
-
q_ancillae = None # TODO: add
|
105
104
|
controlled_circ = QuantumCircuit(q_control, q_target, name=f"c_{operation.name}")
|
106
105
|
if isinstance(operation, controlledgate.ControlledGate):
|
107
106
|
original_ctrl_state = operation.ctrl_state
|
107
|
+
operation = operation.to_mutable()
|
108
|
+
operation.ctrl_state = None
|
109
|
+
|
108
110
|
global_phase = 0
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
global_phase += operation.definition.global_phase
|
111
|
+
|
112
|
+
basis = ["p", "u", "x", "z", "rx", "ry", "rz", "cx"]
|
113
|
+
|
114
|
+
if operation.name in basis:
|
115
|
+
apply_basic_controlled_gate(controlled_circ, operation, q_control, q_target[0])
|
115
116
|
else:
|
116
|
-
basis = ["p", "u", "x", "z", "rx", "ry", "rz", "cx"]
|
117
117
|
if isinstance(operation, controlledgate.ControlledGate):
|
118
118
|
operation = operation.to_mutable()
|
119
119
|
operation.ctrl_state = None
|
120
|
+
|
120
121
|
unrolled_gate = _unroll_gate(operation, basis_gates=basis)
|
121
122
|
if unrolled_gate.definition.global_phase:
|
122
123
|
global_phase += unrolled_gate.definition.global_phase
|
@@ -130,87 +131,17 @@ def control(
|
|
130
131
|
|
131
132
|
for instruction in definition.data:
|
132
133
|
gate, qargs = instruction.operation, instruction.qubits
|
133
|
-
if gate.name == "x":
|
134
|
-
controlled_circ.mcx(q_control, q_target[bit_indices[qargs[0]]], q_ancillae)
|
135
|
-
elif gate.name == "rx":
|
136
|
-
controlled_circ.mcrx(
|
137
|
-
gate.definition.data[0].operation.params[0],
|
138
|
-
q_control,
|
139
|
-
q_target[bit_indices[qargs[0]]],
|
140
|
-
use_basis_gates=False,
|
141
|
-
)
|
142
|
-
elif gate.name == "ry":
|
143
|
-
controlled_circ.mcry(
|
144
|
-
gate.definition.data[0].operation.params[0],
|
145
|
-
q_control,
|
146
|
-
q_target[bit_indices[qargs[0]]],
|
147
|
-
q_ancillae,
|
148
|
-
mode="noancilla",
|
149
|
-
use_basis_gates=False,
|
150
|
-
)
|
151
|
-
elif gate.name == "rz":
|
152
|
-
controlled_circ.mcrz(
|
153
|
-
gate.definition.data[0].operation.params[0],
|
154
|
-
q_control,
|
155
|
-
q_target[bit_indices[qargs[0]]],
|
156
|
-
use_basis_gates=False,
|
157
|
-
)
|
158
|
-
continue
|
159
|
-
elif gate.name == "p":
|
160
|
-
from qiskit.circuit.library import MCPhaseGate
|
161
134
|
|
162
|
-
|
163
|
-
|
164
|
-
q_control[:] + [q_target[bit_indices[qargs[0]]]],
|
165
|
-
)
|
166
|
-
elif gate.name == "cx":
|
167
|
-
controlled_circ.mcx(
|
168
|
-
q_control[:] + [q_target[bit_indices[qargs[0]]]],
|
169
|
-
q_target[bit_indices[qargs[1]]],
|
170
|
-
q_ancillae,
|
171
|
-
)
|
172
|
-
elif gate.name == "u":
|
173
|
-
theta, phi, lamb = gate.params
|
174
|
-
if num_ctrl_qubits == 1:
|
175
|
-
if theta == 0 and phi == 0:
|
176
|
-
controlled_circ.cp(lamb, q_control[0], q_target[bit_indices[qargs[0]]])
|
177
|
-
else:
|
178
|
-
controlled_circ.cu(
|
179
|
-
theta, phi, lamb, 0, q_control[0], q_target[bit_indices[qargs[0]]]
|
180
|
-
)
|
181
|
-
else:
|
182
|
-
if phi == -pi / 2 and lamb == pi / 2:
|
183
|
-
controlled_circ.mcrx(
|
184
|
-
theta, q_control, q_target[bit_indices[qargs[0]]], use_basis_gates=True
|
185
|
-
)
|
186
|
-
elif phi == 0 and lamb == 0:
|
187
|
-
controlled_circ.mcry(
|
188
|
-
theta,
|
189
|
-
q_control,
|
190
|
-
q_target[bit_indices[qargs[0]]],
|
191
|
-
q_ancillae,
|
192
|
-
use_basis_gates=True,
|
193
|
-
)
|
194
|
-
elif theta == 0 and phi == 0:
|
195
|
-
controlled_circ.mcp(lamb, q_control, q_target[bit_indices[qargs[0]]])
|
196
|
-
else:
|
197
|
-
controlled_circ.mcp(lamb, q_control, q_target[bit_indices[qargs[0]]])
|
198
|
-
controlled_circ.mcry(
|
199
|
-
theta,
|
200
|
-
q_control,
|
201
|
-
q_target[bit_indices[qargs[0]]],
|
202
|
-
q_ancillae,
|
203
|
-
use_basis_gates=True,
|
204
|
-
)
|
205
|
-
controlled_circ.mcp(phi, q_control, q_target[bit_indices[qargs[0]]])
|
206
|
-
elif gate.name == "z":
|
207
|
-
controlled_circ.h(q_target[bit_indices[qargs[0]]])
|
208
|
-
controlled_circ.mcx(q_control, q_target[bit_indices[qargs[0]]], q_ancillae)
|
209
|
-
controlled_circ.h(q_target[bit_indices[qargs[0]]])
|
135
|
+
if len(qargs) == 1:
|
136
|
+
target = q_target[bit_indices[qargs[0]]]
|
210
137
|
else:
|
211
|
-
|
212
|
-
|
138
|
+
target = [q_target[bit_indices[qarg]] for qarg in qargs]
|
139
|
+
|
140
|
+
apply_basic_controlled_gate(controlled_circ, gate, q_control, target)
|
141
|
+
|
142
|
+
if gate.definition is not None and gate.definition.global_phase and gate.name != "rz":
|
213
143
|
global_phase += gate.definition.global_phase
|
144
|
+
|
214
145
|
# apply controlled global phase
|
215
146
|
if global_phase:
|
216
147
|
if len(q_control) < 2:
|
@@ -228,6 +159,7 @@ def control(
|
|
228
159
|
new_ctrl_state = ctrl_state
|
229
160
|
base_name = operation.name
|
230
161
|
base_gate = operation
|
162
|
+
|
231
163
|
# In order to maintain some backward compatibility with gate names this
|
232
164
|
# uses a naming convention where if the number of controls is <=2 the gate
|
233
165
|
# is named like "cc<base_gate.name>", else it is named like
|
@@ -250,15 +182,101 @@ def control(
|
|
250
182
|
return cgate
|
251
183
|
|
252
184
|
|
185
|
+
def apply_basic_controlled_gate(circuit, gate, controls, target):
|
186
|
+
"""Apply a controlled version of ``gate`` to the circuit.
|
187
|
+
|
188
|
+
This implements multi-control operations for the following basis gates:
|
189
|
+
|
190
|
+
["p", "u", "x", "z", "rx", "ry", "rz", "cx"]
|
191
|
+
|
192
|
+
"""
|
193
|
+
num_ctrl_qubits = len(controls)
|
194
|
+
|
195
|
+
if gate.name == "x":
|
196
|
+
circuit.mcx(controls, target)
|
197
|
+
|
198
|
+
elif gate.name == "rx":
|
199
|
+
circuit.mcrx(
|
200
|
+
gate.definition.data[0].operation.params[0],
|
201
|
+
controls,
|
202
|
+
target,
|
203
|
+
use_basis_gates=False,
|
204
|
+
)
|
205
|
+
elif gate.name == "ry":
|
206
|
+
circuit.mcry(
|
207
|
+
gate.definition.data[0].operation.params[0],
|
208
|
+
controls,
|
209
|
+
target,
|
210
|
+
mode="noancilla",
|
211
|
+
use_basis_gates=False,
|
212
|
+
)
|
213
|
+
elif gate.name == "rz":
|
214
|
+
circuit.mcrz(
|
215
|
+
gate.definition.data[0].operation.params[0],
|
216
|
+
controls,
|
217
|
+
target,
|
218
|
+
use_basis_gates=False,
|
219
|
+
)
|
220
|
+
# continue
|
221
|
+
elif gate.name == "p":
|
222
|
+
from qiskit.circuit.library import MCPhaseGate
|
223
|
+
|
224
|
+
circuit.append(
|
225
|
+
MCPhaseGate(gate.params[0], num_ctrl_qubits),
|
226
|
+
controls[:] + [target],
|
227
|
+
)
|
228
|
+
elif gate.name == "cx":
|
229
|
+
circuit.mcx(
|
230
|
+
controls[:] + [target[0]], # CX has two targets
|
231
|
+
target[1],
|
232
|
+
)
|
233
|
+
elif gate.name == "u":
|
234
|
+
theta, phi, lamb = gate.params
|
235
|
+
if num_ctrl_qubits == 1:
|
236
|
+
if theta == 0 and phi == 0:
|
237
|
+
circuit.cp(lamb, controls[0], target)
|
238
|
+
else:
|
239
|
+
circuit.cu(theta, phi, lamb, 0, controls[0], target)
|
240
|
+
else:
|
241
|
+
if phi == -pi / 2 and lamb == pi / 2:
|
242
|
+
circuit.mcrx(theta, controls, target, use_basis_gates=True)
|
243
|
+
elif phi == 0 and lamb == 0:
|
244
|
+
circuit.mcry(
|
245
|
+
theta,
|
246
|
+
controls,
|
247
|
+
target,
|
248
|
+
use_basis_gates=True,
|
249
|
+
)
|
250
|
+
elif theta == 0 and phi == 0:
|
251
|
+
circuit.mcp(lamb, controls, target)
|
252
|
+
else:
|
253
|
+
circuit.mcp(lamb, controls, target)
|
254
|
+
circuit.mcry(
|
255
|
+
theta,
|
256
|
+
controls,
|
257
|
+
target,
|
258
|
+
use_basis_gates=True,
|
259
|
+
)
|
260
|
+
circuit.mcp(phi, controls, target)
|
261
|
+
|
262
|
+
elif gate.name == "z":
|
263
|
+
circuit.h(target)
|
264
|
+
circuit.mcx(controls, target)
|
265
|
+
circuit.h(target)
|
266
|
+
|
267
|
+
else:
|
268
|
+
raise CircuitError(f"Gate {gate} not in supported basis.")
|
269
|
+
|
270
|
+
|
253
271
|
def _gate_to_circuit(operation):
|
254
272
|
"""Converts a gate instance to a QuantumCircuit"""
|
255
273
|
if hasattr(operation, "definition") and operation.definition is not None:
|
256
274
|
return operation.definition
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
275
|
+
|
276
|
+
qr = QuantumRegister(operation.num_qubits)
|
277
|
+
qc = QuantumCircuit(qr, name=operation.name)
|
278
|
+
qc.append(operation, qr)
|
279
|
+
return qc
|
262
280
|
|
263
281
|
|
264
282
|
def _unroll_gate(operation, basis_gates):
|
@@ -116,6 +116,15 @@ class HalfAdderGate(Gate):
|
|
116
116
|
"""
|
117
117
|
return self._num_state_qubits
|
118
118
|
|
119
|
+
def _define(self):
|
120
|
+
"""Populates self.definition with some decomposition of this gate."""
|
121
|
+
from qiskit.synthesis.arithmetic import adder_qft_d00
|
122
|
+
|
123
|
+
# This particular decomposition does not use any ancilla qubits.
|
124
|
+
# Note that the transpiler may choose a different decomposition
|
125
|
+
# based on the number of ancilla qubits available.
|
126
|
+
self.definition = adder_qft_d00(self.num_state_qubits, kind="half")
|
127
|
+
|
119
128
|
|
120
129
|
class ModularAdderGate(Gate):
|
121
130
|
r"""Compute the sum modulo :math:`2^n` of two :math:`n`-sized qubit registers.
|
@@ -162,6 +171,15 @@ class ModularAdderGate(Gate):
|
|
162
171
|
"""
|
163
172
|
return self._num_state_qubits
|
164
173
|
|
174
|
+
def _define(self):
|
175
|
+
"""Populates self.definition with some decomposition of this gate."""
|
176
|
+
from qiskit.synthesis.arithmetic import adder_qft_d00
|
177
|
+
|
178
|
+
# This particular decomposition does not use any ancilla qubits.
|
179
|
+
# Note that the transpiler may choose a different decomposition
|
180
|
+
# based on the number of ancilla qubits available.
|
181
|
+
self.definition = adder_qft_d00(self.num_state_qubits, kind="fixed")
|
182
|
+
|
165
183
|
|
166
184
|
class FullAdderGate(Gate):
|
167
185
|
r"""Compute the sum of two :math:`n`-sized qubit registers, including carry-in and -out bits.
|
@@ -208,3 +226,10 @@ class FullAdderGate(Gate):
|
|
208
226
|
The number of state qubits.
|
209
227
|
"""
|
210
228
|
return self._num_state_qubits
|
229
|
+
|
230
|
+
def _define(self):
|
231
|
+
"""Populates self.definition with a decomposition of this gate."""
|
232
|
+
from qiskit.synthesis.arithmetic import adder_ripple_c04
|
233
|
+
|
234
|
+
# In the case of a full adder, this method does not use any ancilla qubits
|
235
|
+
self.definition = adder_ripple_c04(self.num_state_qubits, kind="full")
|
@@ -190,3 +190,12 @@ class MultiplierGate(Gate):
|
|
190
190
|
The number of result qubits.
|
191
191
|
"""
|
192
192
|
return self._num_result_qubits
|
193
|
+
|
194
|
+
def _define(self):
|
195
|
+
"""Populates self.definition with some decomposition of this gate."""
|
196
|
+
from qiskit.synthesis.arithmetic import multiplier_qft_r17
|
197
|
+
|
198
|
+
# This particular decomposition does not use any ancilla qubits.
|
199
|
+
# Note that the transpiler may choose a different decomposition
|
200
|
+
# based on the number of ancilla qubits available.
|
201
|
+
self.definition = multiplier_qft_r17(self.num_state_qubits)
|
qiskit/qpy/__init__.py
CHANGED
@@ -447,10 +447,10 @@ characters:
|
|
447
447
|
* - ``u``
|
448
448
|
- substitution
|
449
449
|
|
450
|
-
If the type value is ``f``
|
450
|
+
If the type value is ``f``, ``c``, or ``i``, the corresponding ``lhs`` or ``rhs``
|
451
451
|
field widths are 128 bits each. In the case of floats, the literal value is encoded as a double
|
452
452
|
with 0 padding, while complex numbers are encoded as real part followed by imaginary part,
|
453
|
-
taking up 64 bits each. For ``i
|
453
|
+
taking up 64 bits each. For ``i``, the value is encoded as a 64 bit signed integer with 0 padding
|
454
454
|
for the full 128 bit width. ``n`` is used to represent a ``None`` and typically isn't directly used
|
455
455
|
as it indicates an argument that's not used. For ``p`` the data is the UUID for the
|
456
456
|
:class:`.Parameter` which can be looked up in the symbol map described in the
|
@@ -546,7 +546,7 @@ Type code Meaning
|
|
546
546
|
Changes to EXPR_VAR
|
547
547
|
~~~~~~~~~~~~~~~~~~~
|
548
548
|
|
549
|
-
The EXPR_VAR variable has gained a new type code and payload, in addition to the pre-existing ones:
|
549
|
+
The ``EXPR_VAR`` variable has gained a new type code and payload, in addition to the pre-existing ones:
|
550
550
|
|
551
551
|
=========================== ========= ============================================================
|
552
552
|
Python class Type code Payload
|
@@ -693,9 +693,9 @@ Each of these are described in the following table:
|
|
693
693
|
====================== ========= ======================================================= ========
|
694
694
|
Qiskit class Type code Payload Children
|
695
695
|
====================== ========= ======================================================= ========
|
696
|
-
:class:`~.expr.Var` ``x`` One EXPR_VAR
|
696
|
+
:class:`~.expr.Var` ``x`` One ``EXPR_VAR``. 0
|
697
697
|
|
698
|
-
:class:`~.expr.Value` ``v`` One EXPR_VALUE
|
698
|
+
:class:`~.expr.Value` ``v`` One ``EXPR_VALUE``. 0
|
699
699
|
|
700
700
|
:class:`~.expr.Cast` ``c`` One ``_Bool`` that corresponds to the value of 1
|
701
701
|
``implicit``.
|
@@ -18,6 +18,8 @@ Chi-matrix representation of a Quantum Channel.
|
|
18
18
|
from __future__ import annotations
|
19
19
|
import copy as _copy
|
20
20
|
import math
|
21
|
+
from typing import TYPE_CHECKING
|
22
|
+
|
21
23
|
import numpy as np
|
22
24
|
|
23
25
|
from qiskit import _numpy_compat
|
@@ -31,6 +33,9 @@ from qiskit.quantum_info.operators.channel.transformations import _to_chi
|
|
31
33
|
from qiskit.quantum_info.operators.mixins import generate_apidocs
|
32
34
|
from qiskit.quantum_info.operators.base_operator import BaseOperator
|
33
35
|
|
36
|
+
if TYPE_CHECKING:
|
37
|
+
from qiskit import circuit
|
38
|
+
|
34
39
|
|
35
40
|
class Chi(QuantumChannel):
|
36
41
|
r"""Pauli basis Chi-matrix representation of a quantum channel.
|
@@ -59,21 +64,16 @@ class Chi(QuantumChannel):
|
|
59
64
|
|
60
65
|
def __init__(
|
61
66
|
self,
|
62
|
-
data: QuantumCircuit | Instruction | BaseOperator | np.ndarray,
|
67
|
+
data: QuantumCircuit | circuit.instruction.Instruction | BaseOperator | np.ndarray,
|
63
68
|
input_dims: int | tuple | None = None,
|
64
69
|
output_dims: int | tuple | None = None,
|
65
70
|
):
|
66
71
|
"""Initialize a quantum channel Chi-matrix operator.
|
67
72
|
|
68
73
|
Args:
|
69
|
-
data
|
70
|
-
|
71
|
-
|
72
|
-
matrix): data to initialize superoperator.
|
73
|
-
input_dims (tuple): the input subsystem dimensions.
|
74
|
-
[Default: None]
|
75
|
-
output_dims (tuple): the output subsystem dimensions.
|
76
|
-
[Default: None]
|
74
|
+
data: data to initialize superoperator.
|
75
|
+
input_dims: the input subsystem dimensions.
|
76
|
+
output_dims: the output subsystem dimensions.
|
77
77
|
|
78
78
|
Raises:
|
79
79
|
QiskitError: if input data is not an N-qubit channel or
|
@@ -18,6 +18,8 @@ Choi-matrix representation of a Quantum Channel.
|
|
18
18
|
from __future__ import annotations
|
19
19
|
import copy as _copy
|
20
20
|
import math
|
21
|
+
from typing import TYPE_CHECKING
|
22
|
+
|
21
23
|
import numpy as np
|
22
24
|
|
23
25
|
from qiskit import _numpy_compat
|
@@ -32,6 +34,9 @@ from qiskit.quantum_info.operators.channel.transformations import _bipartite_ten
|
|
32
34
|
from qiskit.quantum_info.operators.mixins import generate_apidocs
|
33
35
|
from qiskit.quantum_info.operators.base_operator import BaseOperator
|
34
36
|
|
37
|
+
if TYPE_CHECKING:
|
38
|
+
from qiskit import circuit
|
39
|
+
|
35
40
|
|
36
41
|
class Choi(QuantumChannel):
|
37
42
|
r"""Choi-matrix representation of a Quantum Channel.
|
@@ -64,21 +69,16 @@ class Choi(QuantumChannel):
|
|
64
69
|
|
65
70
|
def __init__(
|
66
71
|
self,
|
67
|
-
data: QuantumCircuit | Instruction | BaseOperator | np.ndarray,
|
72
|
+
data: QuantumCircuit | circuit.instruction.Instruction | BaseOperator | np.ndarray,
|
68
73
|
input_dims: int | tuple | None = None,
|
69
74
|
output_dims: int | tuple | None = None,
|
70
75
|
):
|
71
76
|
"""Initialize a quantum channel Choi matrix operator.
|
72
77
|
|
73
78
|
Args:
|
74
|
-
data
|
75
|
-
|
76
|
-
|
77
|
-
matrix): data to initialize superoperator.
|
78
|
-
input_dims (tuple): the input subsystem dimensions.
|
79
|
-
[Default: None]
|
80
|
-
output_dims (tuple): the output subsystem dimensions.
|
81
|
-
[Default: None]
|
79
|
+
data: data to initialize superoperator.
|
80
|
+
input_dims: the input subsystem dimensions.
|
81
|
+
output_dims: the output subsystem dimensions.
|
82
82
|
|
83
83
|
Raises:
|
84
84
|
QiskitError: if input data cannot be initialized as a
|
@@ -18,6 +18,8 @@ Pauli Transfer Matrix (PTM) representation of a Quantum Channel.
|
|
18
18
|
from __future__ import annotations
|
19
19
|
import copy as _copy
|
20
20
|
import math
|
21
|
+
from typing import TYPE_CHECKING
|
22
|
+
|
21
23
|
import numpy as np
|
22
24
|
|
23
25
|
from qiskit import _numpy_compat
|
@@ -30,6 +32,9 @@ from qiskit.quantum_info.operators.channel.transformations import _to_ptm
|
|
30
32
|
from qiskit.quantum_info.operators.mixins import generate_apidocs
|
31
33
|
from qiskit.quantum_info.operators.base_operator import BaseOperator
|
32
34
|
|
35
|
+
if TYPE_CHECKING:
|
36
|
+
from qiskit import circuit
|
37
|
+
|
33
38
|
|
34
39
|
class PTM(QuantumChannel):
|
35
40
|
r"""Pauli Transfer Matrix (PTM) representation of a Quantum Channel.
|
@@ -67,21 +72,16 @@ class PTM(QuantumChannel):
|
|
67
72
|
|
68
73
|
def __init__(
|
69
74
|
self,
|
70
|
-
data: QuantumCircuit | Instruction | BaseOperator | np.ndarray,
|
75
|
+
data: QuantumCircuit | circuit.instruction.Instruction | BaseOperator | np.ndarray,
|
71
76
|
input_dims: int | tuple | None = None,
|
72
77
|
output_dims: int | tuple | None = None,
|
73
78
|
):
|
74
79
|
"""Initialize a PTM quantum channel operator.
|
75
80
|
|
76
81
|
Args:
|
77
|
-
data
|
78
|
-
|
79
|
-
|
80
|
-
matrix): data to initialize superoperator.
|
81
|
-
input_dims (tuple): the input subsystem dimensions.
|
82
|
-
[Default: None]
|
83
|
-
output_dims (tuple): the output subsystem dimensions.
|
84
|
-
[Default: None]
|
82
|
+
data: data to initialize superoperator.
|
83
|
+
input_dims: the input subsystem dimensions.
|
84
|
+
output_dims: the output subsystem dimensions.
|
85
85
|
|
86
86
|
Raises:
|
87
87
|
QiskitError: if input data is not an N-qubit channel or
|
@@ -53,9 +53,9 @@ class QuantumChannel(LinearOp):
|
|
53
53
|
"""Initialize a quantum channel Superoperator operator.
|
54
54
|
|
55
55
|
Args:
|
56
|
-
data
|
57
|
-
op_shape
|
58
|
-
num_qubits
|
56
|
+
data: quantum channel data array.
|
57
|
+
op_shape: the operator shape of the channel.
|
58
|
+
num_qubits: the number of qubits if the channel is N-qubit.
|
59
59
|
|
60
60
|
Raises:
|
61
61
|
QiskitError: if arguments are invalid.
|
@@ -17,6 +17,8 @@ from __future__ import annotations
|
|
17
17
|
import copy
|
18
18
|
import math
|
19
19
|
from numbers import Number
|
20
|
+
from typing import TYPE_CHECKING
|
21
|
+
|
20
22
|
import numpy as np
|
21
23
|
|
22
24
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
@@ -32,6 +34,9 @@ from qiskit.quantum_info.operators.channel.transformations import _to_stinesprin
|
|
32
34
|
from qiskit.quantum_info.operators.mixins import generate_apidocs
|
33
35
|
from qiskit.quantum_info.operators.base_operator import BaseOperator
|
34
36
|
|
37
|
+
if TYPE_CHECKING:
|
38
|
+
from qiskit import circuit
|
39
|
+
|
35
40
|
|
36
41
|
class Stinespring(QuantumChannel):
|
37
42
|
r"""Stinespring representation of a quantum channel.
|
@@ -64,21 +69,16 @@ class Stinespring(QuantumChannel):
|
|
64
69
|
|
65
70
|
def __init__(
|
66
71
|
self,
|
67
|
-
data: QuantumCircuit | Instruction | BaseOperator | np.ndarray,
|
72
|
+
data: QuantumCircuit | circuit.instruction.Instruction | BaseOperator | np.ndarray,
|
68
73
|
input_dims: int | tuple | None = None,
|
69
74
|
output_dims: int | tuple | None = None,
|
70
75
|
):
|
71
76
|
"""Initialize a quantum channel Stinespring operator.
|
72
77
|
|
73
78
|
Args:
|
74
|
-
data
|
75
|
-
|
76
|
-
|
77
|
-
matrix): data to initialize superoperator.
|
78
|
-
input_dims (tuple): the input subsystem dimensions.
|
79
|
-
[Default: None]
|
80
|
-
output_dims (tuple): the output subsystem dimensions.
|
81
|
-
[Default: None]
|
79
|
+
data: data to initialize superoperator.
|
80
|
+
input_dims: the input subsystem dimensions.
|
81
|
+
output_dims: the output subsystem dimensions.
|
82
82
|
|
83
83
|
Raises:
|
84
84
|
QiskitError: if input data cannot be initialized as a
|
@@ -33,6 +33,7 @@ from qiskit.quantum_info.operators.op_shape import OpShape
|
|
33
33
|
from qiskit.quantum_info.operators.operator import Operator
|
34
34
|
|
35
35
|
if TYPE_CHECKING:
|
36
|
+
from qiskit import circuit
|
36
37
|
from qiskit.quantum_info.states.densitymatrix import DensityMatrix
|
37
38
|
from qiskit.quantum_info.states.statevector import Statevector
|
38
39
|
|
@@ -62,21 +63,16 @@ class SuperOp(QuantumChannel):
|
|
62
63
|
|
63
64
|
def __init__(
|
64
65
|
self,
|
65
|
-
data: QuantumCircuit | Instruction | BaseOperator | np.ndarray,
|
66
|
+
data: QuantumCircuit | circuit.instruction.Instruction | BaseOperator | np.ndarray,
|
66
67
|
input_dims: tuple | None = None,
|
67
68
|
output_dims: tuple | None = None,
|
68
69
|
):
|
69
70
|
"""Initialize a quantum channel Superoperator operator.
|
70
71
|
|
71
72
|
Args:
|
72
|
-
data
|
73
|
-
|
74
|
-
|
75
|
-
matrix): data to initialize superoperator.
|
76
|
-
input_dims (tuple): the input subsystem dimensions.
|
77
|
-
[Default: None]
|
78
|
-
output_dims (tuple): the output subsystem dimensions.
|
79
|
-
[Default: None]
|
73
|
+
data: data to initialize superoperator.
|
74
|
+
input_dims: the input subsystem dimensions.
|
75
|
+
output_dims: the output subsystem dimensions.
|
80
76
|
|
81
77
|
Raises:
|
82
78
|
QiskitError: if input data cannot be initialized as a
|
@@ -17,6 +17,8 @@ DensityMatrix quantum state class.
|
|
17
17
|
from __future__ import annotations
|
18
18
|
import copy as _copy
|
19
19
|
from numbers import Number
|
20
|
+
from typing import TYPE_CHECKING
|
21
|
+
|
20
22
|
import numpy as np
|
21
23
|
|
22
24
|
from qiskit import _numpy_compat
|
@@ -37,27 +39,27 @@ from qiskit.quantum_info.operators.channel.superop import SuperOp
|
|
37
39
|
from qiskit._accelerate.pauli_expval import density_expval_pauli_no_x, density_expval_pauli_with_x
|
38
40
|
from qiskit.quantum_info.states.statevector import Statevector
|
39
41
|
|
42
|
+
if TYPE_CHECKING:
|
43
|
+
from qiskit import circuit
|
44
|
+
|
40
45
|
|
41
46
|
class DensityMatrix(QuantumState, TolerancesMixin):
|
42
47
|
"""DensityMatrix class"""
|
43
48
|
|
44
49
|
def __init__(
|
45
50
|
self,
|
46
|
-
data: np.ndarray | list | QuantumCircuit | Instruction | QuantumState,
|
51
|
+
data: np.ndarray | list | QuantumCircuit | circuit.instruction.Instruction | QuantumState,
|
47
52
|
dims: int | tuple | list | None = None,
|
48
53
|
):
|
49
54
|
"""Initialize a density matrix object.
|
50
55
|
|
51
56
|
Args:
|
52
|
-
data
|
53
|
-
qiskit.circuit.Instruction):
|
54
|
-
A statevector, quantum instruction or an object with a ``to_operator`` or
|
57
|
+
data: A statevector, quantum instruction or an object with a ``to_operator`` or
|
55
58
|
``to_matrix`` method from which the density matrix can be constructed.
|
56
59
|
If a vector the density matrix is constructed as the projector of that vector.
|
57
60
|
If a quantum instruction, the density matrix is constructed by assuming all
|
58
61
|
qubits are initialized in the zero state.
|
59
|
-
dims
|
60
|
-
of the state (See additional information).
|
62
|
+
dims: The subsystem dimension of the state (See additional information).
|
61
63
|
|
62
64
|
Raises:
|
63
65
|
QiskitError: if input data is not valid.
|
@@ -303,19 +305,17 @@ class DensityMatrix(QuantumState, TolerancesMixin):
|
|
303
305
|
|
304
306
|
def evolve(
|
305
307
|
self,
|
306
|
-
other: Operator | QuantumChannel | Instruction | QuantumCircuit,
|
308
|
+
other: Operator | QuantumChannel | circuit.instruction.Instruction | QuantumCircuit,
|
307
309
|
qargs: list[int] | None = None,
|
308
310
|
) -> DensityMatrix:
|
309
311
|
"""Evolve a quantum state by an operator.
|
310
312
|
|
311
313
|
Args:
|
312
|
-
other
|
313
|
-
|
314
|
-
qargs (list): a list of QuantumState subsystem positions to apply
|
315
|
-
the operator on.
|
314
|
+
other: The operator to evolve by.
|
315
|
+
qargs: a list of QuantumState subsystem positions to apply the operator on.
|
316
316
|
|
317
317
|
Returns:
|
318
|
-
|
318
|
+
The output density matrix.
|
319
319
|
|
320
320
|
Raises:
|
321
321
|
QiskitError: if the operator dimension does not match the
|
@@ -598,7 +598,9 @@ class DensityMatrix(QuantumState, TolerancesMixin):
|
|
598
598
|
return DensityMatrix(state, dims=dims)
|
599
599
|
|
600
600
|
@classmethod
|
601
|
-
def from_instruction(
|
601
|
+
def from_instruction(
|
602
|
+
cls, instruction: circuit.instruction.Instruction | QuantumCircuit
|
603
|
+
) -> DensityMatrix:
|
602
604
|
"""Return the output density matrix of an instruction.
|
603
605
|
|
604
606
|
The statevector is initialized in the state :math:`|{0,\\ldots,0}\\rangle` of
|
@@ -606,10 +608,10 @@ class DensityMatrix(QuantumState, TolerancesMixin):
|
|
606
608
|
by the input instruction, and the output statevector returned.
|
607
609
|
|
608
610
|
Args:
|
609
|
-
instruction
|
611
|
+
instruction: instruction or circuit
|
610
612
|
|
611
613
|
Returns:
|
612
|
-
|
614
|
+
The final density matrix.
|
613
615
|
|
614
616
|
Raises:
|
615
617
|
QiskitError: if the instruction contains invalid instructions for
|
@@ -17,6 +17,7 @@ Stabilizer state class.
|
|
17
17
|
from __future__ import annotations
|
18
18
|
|
19
19
|
from collections.abc import Collection
|
20
|
+
from typing import TYPE_CHECKING
|
20
21
|
|
21
22
|
import numpy as np
|
22
23
|
|
@@ -28,6 +29,9 @@ from qiskit.quantum_info.operators.symplectic.clifford_circuits import _append_x
|
|
28
29
|
from qiskit.quantum_info.states.quantum_state import QuantumState
|
29
30
|
from qiskit.circuit import QuantumCircuit, Instruction
|
30
31
|
|
32
|
+
if TYPE_CHECKING:
|
33
|
+
from qiskit import circuit
|
34
|
+
|
31
35
|
|
32
36
|
class StabilizerState(QuantumState):
|
33
37
|
"""StabilizerState class.
|
@@ -79,17 +83,14 @@ class StabilizerState(QuantumState):
|
|
79
83
|
|
80
84
|
def __init__(
|
81
85
|
self,
|
82
|
-
data: StabilizerState | Clifford | Pauli | QuantumCircuit | Instruction,
|
86
|
+
data: StabilizerState | Clifford | Pauli | QuantumCircuit | circuit.instruction.Instruction,
|
83
87
|
validate: bool = True,
|
84
88
|
):
|
85
89
|
"""Initialize a StabilizerState object.
|
86
90
|
|
87
91
|
Args:
|
88
|
-
data
|
89
|
-
|
90
|
-
Data from which the stabilizer state can be constructed.
|
91
|
-
validate (boolean): validate that the stabilizer state data is
|
92
|
-
a valid Clifford.
|
92
|
+
data: Data from which the stabilizer state can be constructed.
|
93
|
+
validate: validate that the stabilizer state data is a valid Clifford.
|
93
94
|
"""
|
94
95
|
|
95
96
|
# Initialize from another StabilizerState
|
@@ -18,6 +18,7 @@ import copy as _copy
|
|
18
18
|
import math
|
19
19
|
import re
|
20
20
|
from numbers import Number
|
21
|
+
from typing import TYPE_CHECKING
|
21
22
|
|
22
23
|
import numpy as np
|
23
24
|
|
@@ -37,27 +38,34 @@ from qiskit._accelerate.pauli_expval import (
|
|
37
38
|
expval_pauli_with_x,
|
38
39
|
)
|
39
40
|
|
41
|
+
if TYPE_CHECKING:
|
42
|
+
from qiskit import circuit
|
43
|
+
|
40
44
|
|
41
45
|
class Statevector(QuantumState, TolerancesMixin):
|
42
46
|
"""Statevector class"""
|
43
47
|
|
44
48
|
def __init__(
|
45
49
|
self,
|
46
|
-
data:
|
50
|
+
data: (
|
51
|
+
np.ndarray
|
52
|
+
| list
|
53
|
+
| Statevector
|
54
|
+
| Operator
|
55
|
+
| QuantumCircuit
|
56
|
+
| circuit.instruction.Instruction
|
57
|
+
),
|
47
58
|
dims: int | tuple | list | None = None,
|
48
59
|
):
|
49
60
|
"""Initialize a statevector object.
|
50
61
|
|
51
62
|
Args:
|
52
|
-
data
|
53
|
-
qiskit.circuit.Instruction):
|
54
|
-
Data from which the statevector can be constructed. This can be either a complex
|
63
|
+
data: Data from which the statevector can be constructed. This can be either a complex
|
55
64
|
vector, another statevector, a ``Operator`` with only one column or a
|
56
65
|
``QuantumCircuit`` or ``Instruction``. If the data is a circuit or instruction,
|
57
66
|
the statevector is constructed by assuming that all qubits are initialized to the
|
58
67
|
zero state.
|
59
|
-
dims
|
60
|
-
the state (See additional information).
|
68
|
+
dims: The subsystem dimension of the state (See additional information).
|
61
69
|
|
62
70
|
Raises:
|
63
71
|
QiskitError: if input data is not valid.
|
@@ -17,8 +17,10 @@ from __future__ import annotations
|
|
17
17
|
from collections.abc import Sequence
|
18
18
|
from typing import Type
|
19
19
|
from fnmatch import fnmatch
|
20
|
+
import warnings
|
20
21
|
|
21
22
|
from qiskit.transpiler.basepasses import TransformationPass
|
23
|
+
from qiskit.transpiler.passes.utils import control_flow
|
22
24
|
from qiskit.dagcircuit.dagnode import DAGOpNode
|
23
25
|
from qiskit.dagcircuit.dagcircuit import DAGCircuit
|
24
26
|
from qiskit.converters.circuit_to_dag import circuit_to_dag
|
@@ -58,7 +60,7 @@ class Decompose(TransformationPass):
|
|
58
60
|
output dag where ``gate`` was expanded.
|
59
61
|
"""
|
60
62
|
# We might use HLS to synthesize objects that do not have a definition
|
61
|
-
hls = HighLevelSynthesis() if self.apply_synthesis else None
|
63
|
+
hls = HighLevelSynthesis(qubits_initially_zero=False) if self.apply_synthesis else None
|
62
64
|
|
63
65
|
# Walk through the DAG and expand each non-basis node
|
64
66
|
for node in dag.op_nodes():
|
@@ -66,12 +68,18 @@ class Decompose(TransformationPass):
|
|
66
68
|
if not self._should_decompose(node):
|
67
69
|
continue
|
68
70
|
|
69
|
-
if
|
71
|
+
if node.is_control_flow():
|
72
|
+
decomposition = control_flow.map_blocks(self.run, node.op)
|
73
|
+
dag.substitute_node(node, decomposition, inplace=True)
|
74
|
+
|
75
|
+
elif getattr(node.op, "definition", None) is None:
|
70
76
|
# if we try to synthesize, turn the node into a DAGCircuit and run HLS
|
71
77
|
if self.apply_synthesis:
|
78
|
+
# note that node_as_dag does not include the condition, which will
|
79
|
+
# be propagated in ``substitute_node_with_dag``
|
72
80
|
node_as_dag = _node_to_dag(node)
|
73
81
|
synthesized = hls.run(node_as_dag)
|
74
|
-
dag.substitute_node_with_dag(node, synthesized)
|
82
|
+
dag.substitute_node_with_dag(node, synthesized, propagate_condition=True)
|
75
83
|
|
76
84
|
# else: no definition and synthesis not enabled, so we do nothing
|
77
85
|
else:
|
@@ -123,9 +131,21 @@ class Decompose(TransformationPass):
|
|
123
131
|
|
124
132
|
|
125
133
|
def _node_to_dag(node: DAGOpNode) -> DAGCircuit:
|
134
|
+
# Control flow is already handled separately, however that does not capture
|
135
|
+
# c_if, which we are treating here. We explicitly ignore the condition attribute,
|
136
|
+
# which will be handled by ``substitute_node_with_dag``, so we create a copy of the node
|
137
|
+
# and set the condition to None. Once ``c_if`` is removed for 2.0, this block can go, too.
|
138
|
+
with warnings.catch_warnings():
|
139
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
140
|
+
if getattr(node.op, "condition", None) is not None:
|
141
|
+
op = node.op.copy()
|
142
|
+
op.condition = None
|
143
|
+
node = DAGOpNode(op, node.qargs, node.cargs)
|
144
|
+
|
145
|
+
# create new dag and apply the operation
|
126
146
|
dag = DAGCircuit()
|
127
147
|
dag.add_qubits(node.qargs)
|
128
148
|
dag.add_clbits(node.cargs)
|
129
|
-
|
130
149
|
dag.apply_operation_back(node.op, node.qargs, node.cargs)
|
150
|
+
|
131
151
|
return dag
|
@@ -300,6 +300,10 @@ Modular Adder Synthesis
|
|
300
300
|
- :class:`.ModularAdderSynthesisD00`
|
301
301
|
- 0
|
302
302
|
- a QFT-based adder
|
303
|
+
* - ``"default"``
|
304
|
+
- :class:`~.ModularAdderSynthesisDefault`
|
305
|
+
- any
|
306
|
+
- chooses the best algorithm based on the ancillas available
|
303
307
|
|
304
308
|
.. autosummary::
|
305
309
|
:toctree: ../stubs/
|
@@ -307,6 +311,7 @@ Modular Adder Synthesis
|
|
307
311
|
ModularAdderSynthesisC04
|
308
312
|
ModularAdderSynthesisD00
|
309
313
|
ModularAdderSynthesisV95
|
314
|
+
ModularAdderSynthesisDefault
|
310
315
|
|
311
316
|
Half Adder Synthesis
|
312
317
|
''''''''''''''''''''
|
@@ -330,6 +335,10 @@ Half Adder Synthesis
|
|
330
335
|
- :class:`.HalfAdderSynthesisD00`
|
331
336
|
- 0
|
332
337
|
- a QFT-based adder
|
338
|
+
* - ``"default"``
|
339
|
+
- :class:`~.HalfAdderSynthesisDefault`
|
340
|
+
- any
|
341
|
+
- chooses the best algorithm based on the ancillas available
|
333
342
|
|
334
343
|
.. autosummary::
|
335
344
|
:toctree: ../stubs/
|
@@ -337,6 +346,7 @@ Half Adder Synthesis
|
|
337
346
|
HalfAdderSynthesisC04
|
338
347
|
HalfAdderSynthesisD00
|
339
348
|
HalfAdderSynthesisV95
|
349
|
+
HalfAdderSynthesisDefault
|
340
350
|
|
341
351
|
Full Adder Synthesis
|
342
352
|
''''''''''''''''''''
|
@@ -356,12 +366,17 @@ Full Adder Synthesis
|
|
356
366
|
- :class:`.FullAdderSynthesisV95`
|
357
367
|
- :math:`n-1`, for :math:`n`-bit numbers
|
358
368
|
- a ripple-carry adder
|
369
|
+
* - ``"default"``
|
370
|
+
- :class:`~.FullAdderSynthesisDefault`
|
371
|
+
- any
|
372
|
+
- chooses the best algorithm based on the ancillas available
|
359
373
|
|
360
374
|
.. autosummary::
|
361
375
|
:toctree: ../stubs/
|
362
376
|
|
363
377
|
FullAdderSynthesisC04
|
364
378
|
FullAdderSynthesisV95
|
379
|
+
FullAdderSynthesisDefault
|
365
380
|
|
366
381
|
|
367
382
|
Multiplier Synthesis
|
@@ -1212,10 +1227,26 @@ class ModularAdderSynthesisDefault(HighLevelSynthesisPlugin):
|
|
1212
1227
|
if not isinstance(high_level_object, ModularAdderGate):
|
1213
1228
|
return None
|
1214
1229
|
|
1215
|
-
|
1216
|
-
|
1230
|
+
# For up to 5 qubits, the QFT-based adder is best
|
1231
|
+
if high_level_object.num_state_qubits <= 5:
|
1232
|
+
decomposition = ModularAdderSynthesisD00().run(
|
1233
|
+
high_level_object, coupling_map, target, qubits, **options
|
1234
|
+
)
|
1235
|
+
if decomposition is not None:
|
1236
|
+
return decomposition
|
1217
1237
|
|
1218
|
-
|
1238
|
+
# Otherwise, the following decomposition is best (if there are enough ancillas)
|
1239
|
+
if (
|
1240
|
+
decomposition := ModularAdderSynthesisC04().run(
|
1241
|
+
high_level_object, coupling_map, target, qubits, **options
|
1242
|
+
)
|
1243
|
+
) is not None:
|
1244
|
+
return decomposition
|
1245
|
+
|
1246
|
+
# Otherwise, use the QFT-adder again
|
1247
|
+
return ModularAdderSynthesisD00().run(
|
1248
|
+
high_level_object, coupling_map, target, qubits, **options
|
1249
|
+
)
|
1219
1250
|
|
1220
1251
|
|
1221
1252
|
class ModularAdderSynthesisC04(HighLevelSynthesisPlugin):
|
@@ -1264,8 +1295,8 @@ class ModularAdderSynthesisV95(HighLevelSynthesisPlugin):
|
|
1264
1295
|
|
1265
1296
|
num_state_qubits = high_level_object.num_state_qubits
|
1266
1297
|
|
1267
|
-
#
|
1268
|
-
if num_state_qubits
|
1298
|
+
# The synthesis method needs n-1 clean ancilla qubits
|
1299
|
+
if num_state_qubits - 1 > options.get("num_clean_ancillas", 0):
|
1269
1300
|
return None
|
1270
1301
|
|
1271
1302
|
return adder_ripple_v95(num_state_qubits, kind="fixed")
|
@@ -1309,10 +1340,26 @@ class HalfAdderSynthesisDefault(HighLevelSynthesisPlugin):
|
|
1309
1340
|
if not isinstance(high_level_object, HalfAdderGate):
|
1310
1341
|
return None
|
1311
1342
|
|
1312
|
-
|
1313
|
-
|
1343
|
+
# For up to 3 qubits, ripple_v95 is better (if there are enough ancilla qubits)
|
1344
|
+
if high_level_object.num_state_qubits <= 3:
|
1345
|
+
decomposition = HalfAdderSynthesisV95().run(
|
1346
|
+
high_level_object, coupling_map, target, qubits, **options
|
1347
|
+
)
|
1348
|
+
if decomposition is not None:
|
1349
|
+
return decomposition
|
1314
1350
|
|
1315
|
-
|
1351
|
+
# The next best option is to use ripple_c04 (if there are enough ancilla qubits)
|
1352
|
+
if (
|
1353
|
+
decomposition := HalfAdderSynthesisC04().run(
|
1354
|
+
high_level_object, coupling_map, target, qubits, **options
|
1355
|
+
)
|
1356
|
+
) is not None:
|
1357
|
+
return decomposition
|
1358
|
+
|
1359
|
+
# The QFT-based adder does not require ancilla qubits and should always succeed
|
1360
|
+
return HalfAdderSynthesisD00().run(
|
1361
|
+
high_level_object, coupling_map, target, qubits, **options
|
1362
|
+
)
|
1316
1363
|
|
1317
1364
|
|
1318
1365
|
class HalfAdderSynthesisC04(HighLevelSynthesisPlugin):
|
@@ -1360,8 +1407,8 @@ class HalfAdderSynthesisV95(HighLevelSynthesisPlugin):
|
|
1360
1407
|
|
1361
1408
|
num_state_qubits = high_level_object.num_state_qubits
|
1362
1409
|
|
1363
|
-
#
|
1364
|
-
if num_state_qubits
|
1410
|
+
# The synthesis method needs n-1 clean ancilla qubits
|
1411
|
+
if num_state_qubits - 1 > options.get("num_clean_ancillas", 0):
|
1365
1412
|
return None
|
1366
1413
|
|
1367
1414
|
return adder_ripple_v95(num_state_qubits, kind="half")
|
@@ -1381,18 +1428,38 @@ class HalfAdderSynthesisD00(HighLevelSynthesisPlugin):
|
|
1381
1428
|
return adder_qft_d00(high_level_object.num_state_qubits, kind="half")
|
1382
1429
|
|
1383
1430
|
|
1384
|
-
class
|
1431
|
+
class FullAdderSynthesisDefault(HighLevelSynthesisPlugin):
|
1385
1432
|
"""A ripple-carry adder with a carry-in and a carry-out bit.
|
1386
1433
|
|
1387
|
-
This plugin name is:``FullAdder.
|
1434
|
+
This plugin name is:``FullAdder.default`` which can be used as the key on
|
1388
1435
|
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
1436
|
+
"""
|
1389
1437
|
|
1390
|
-
|
1438
|
+
def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
|
1439
|
+
if not isinstance(high_level_object, FullAdderGate):
|
1440
|
+
return None
|
1391
1441
|
|
1392
|
-
|
1442
|
+
# FullAdderSynthesisC04 requires no ancilla qubits and returns better results
|
1443
|
+
# than FullAdderSynthesisV95 in all cases except for n=1.
|
1444
|
+
if high_level_object.num_state_qubits == 1:
|
1445
|
+
decomposition = FullAdderSynthesisV95().run(
|
1446
|
+
high_level_object, coupling_map, target, qubits, **options
|
1447
|
+
)
|
1448
|
+
if decomposition is not None:
|
1449
|
+
return decomposition
|
1450
|
+
|
1451
|
+
return FullAdderSynthesisC04().run(
|
1452
|
+
high_level_object, coupling_map, target, qubits, **options
|
1453
|
+
)
|
1393
1454
|
|
1394
|
-
* ``num_clean_ancillas``: The number of clean auxiliary qubits available.
|
1395
1455
|
|
1456
|
+
class FullAdderSynthesisC04(HighLevelSynthesisPlugin):
|
1457
|
+
"""A ripple-carry adder with a carry-in and a carry-out bit.
|
1458
|
+
|
1459
|
+
This plugin name is:``FullAdder.ripple_c04`` which can be used as the key on
|
1460
|
+
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
1461
|
+
|
1462
|
+
This plugin requires no auxiliary qubits.
|
1396
1463
|
"""
|
1397
1464
|
|
1398
1465
|
def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
|
@@ -1409,7 +1476,7 @@ class FullAdderSynthesisV95(HighLevelSynthesisPlugin):
|
|
1409
1476
|
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
1410
1477
|
|
1411
1478
|
For an adder on 2 registers with :math:`n` qubits each, this plugin requires at
|
1412
|
-
least :math:`n-1` clean auxiliary
|
1479
|
+
least :math:`n-1` clean auxiliary qubits.
|
1413
1480
|
|
1414
1481
|
The plugin supports the following plugin-specific options:
|
1415
1482
|
|
@@ -1422,8 +1489,8 @@ class FullAdderSynthesisV95(HighLevelSynthesisPlugin):
|
|
1422
1489
|
|
1423
1490
|
num_state_qubits = high_level_object.num_state_qubits
|
1424
1491
|
|
1425
|
-
#
|
1426
|
-
if num_state_qubits
|
1492
|
+
# The synthesis method needs n-1 clean ancilla qubits
|
1493
|
+
if num_state_qubits - 1 > options.get("num_clean_ancillas", 0):
|
1427
1494
|
return None
|
1428
1495
|
|
1429
1496
|
return adder_ripple_v95(num_state_qubits, kind="full")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: qiskit
|
3
|
-
Version: 1.3.
|
3
|
+
Version: 1.3.1
|
4
4
|
Summary: An open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
|
5
5
|
Author-email: Qiskit Development Team <qiskit@us.ibm.com>
|
6
6
|
License: Apache 2.0
|
@@ -124,7 +124,7 @@ from qiskit.primitives import StatevectorSampler
|
|
124
124
|
sampler = StatevectorSampler()
|
125
125
|
job = sampler.run([qc_measured], shots=1000)
|
126
126
|
result = job.result()
|
127
|
-
print(f" > Counts: {result[0].meas.get_counts()}")
|
127
|
+
print(f" > Counts: {result[0].data["meas"].get_counts()}")
|
128
128
|
```
|
129
129
|
Running this will give an outcome similar to `{'000': 497, '111': 503}` which is `000` 50% of the time and `111` 50% of the time up to statistical fluctuations.
|
130
130
|
To illustrate the power of Estimator, we now use the quantum information toolbox to create the operator $XXY+XYX+YXX-YYY$ and pass it to the `run()` function, along with our quantum circuit. Note the Estimator requires a circuit _**without**_ measurement, so we use the `qc_example` circuit we created earlier.
|
@@ -1,10 +1,10 @@
|
|
1
1
|
qiskit/version.py,sha256=MiraFeJt5GQEspFyvP3qJedHen2C1e8dNEttzg0u7YU,2498
|
2
2
|
qiskit/__init__.py,sha256=MHSxG7bMhoESBIzoz9DdWdolCdPTwnwHJ80zjWMoRd4,7483
|
3
|
-
qiskit/_accelerate.abi3.so,sha256=
|
3
|
+
qiskit/_accelerate.abi3.so,sha256=RMO66v3IrohUFG-LRG-Akp8SmERAtPuJXMwNTgJr5DY,9496568
|
4
4
|
qiskit/user_config.py,sha256=I7QCF9W2IDpleWunxDjgYGySsVUlq57gfj_137o0Dac,10109
|
5
5
|
qiskit/_numpy_compat.py,sha256=ZlnDTF2KBTKcVF489ZuxoBk6r9KLsMuhAlozFhOn0a8,2815
|
6
6
|
qiskit/exceptions.py,sha256=78bbfww9680_v4CaNgepavY5DwGTN7_j47Ckob3lLPM,5619
|
7
|
-
qiskit/VERSION.txt,sha256=
|
7
|
+
qiskit/VERSION.txt,sha256=EOLhF7AVI4kconGmFa426dXlI0j9fWQvZnJ2AsG43L4,6
|
8
8
|
qiskit/visualization/circuit_visualization.py,sha256=6R-A96Uwb_RZOovsSB0LGVsC7lP5IhtLNp6VP2yVBwE,698
|
9
9
|
qiskit/visualization/counts_visualization.py,sha256=rgoEqV0gucL9Auz33wf1LiRWR3yFQzjK94zzBF830iY,16791
|
10
10
|
qiskit/visualization/pass_manager_visualization.py,sha256=19m4pUdYG0csZgQbuxfFP-zfoVGnk0pJr0HVToD1Y04,10886
|
@@ -181,7 +181,7 @@ qiskit/transpiler/passes/utils/gates_basis.py,sha256=9AQ8uKi4CmiGF0CBnLQfc07ca_H
|
|
181
181
|
qiskit/transpiler/passes/utils/barrier_before_final_measurements.py,sha256=1N8OMvteNo9UpRPn7aST62D56u8ikSTYK8ZFZWKOYGE,1530
|
182
182
|
qiskit/transpiler/passes/utils/fixed_point.py,sha256=AiwkNvu-SLHvodddJRKfFEl7FPC62u1f3CB9lRne9eY,1773
|
183
183
|
qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py,sha256=xM0KHNaH8N9-tn5rhC5tAGc5-faID8GvVFbH6HCqnsE,11052
|
184
|
-
qiskit/transpiler/passes/synthesis/hls_plugins.py,sha256=
|
184
|
+
qiskit/transpiler/passes/synthesis/hls_plugins.py,sha256=4iWj6k4UDBTtRjjPU-mbXUzCuDXLJepb2JHqWmo4-Zg,60946
|
185
185
|
qiskit/transpiler/passes/synthesis/__init__.py,sha256=VYO9Sl_SJyoZ_bLronrkvK9u8kL-LW9G93LbWyWNEaM,925
|
186
186
|
qiskit/transpiler/passes/synthesis/plugin.py,sha256=LnvGzGJ8Q5gSPKSJNmJ7fvnUub8lzG5iGGTqOTODpes,30806
|
187
187
|
qiskit/transpiler/passes/synthesis/linear_functions_synthesis.py,sha256=Q1r-52HMETK_7iWTMmJKGU39rNws-MrmGDHh7TgQVj4,1407
|
@@ -205,7 +205,7 @@ qiskit/transpiler/passes/routing/algorithms/util.py,sha256=0mZFWUKp8z-8K2HjPRxwu
|
|
205
205
|
qiskit/transpiler/passes/routing/algorithms/__init__.py,sha256=xqgItNZmE9Asul94FzsBbUdU2d6h7j9bOY5p7q0QKYc,1403
|
206
206
|
qiskit/transpiler/passes/routing/algorithms/types.py,sha256=9yX3_8JFvA4T5_tXWb3T304EscCnETkoFY0_Q_Gzr-A,1708
|
207
207
|
qiskit/transpiler/passes/routing/algorithms/token_swapper.py,sha256=_Xxnk5rasIJ5DIQqR6AwMVdxTe5xgJ_bA_RL2FCGfs0,4118
|
208
|
-
qiskit/transpiler/passes/basis/decompose.py,sha256=
|
208
|
+
qiskit/transpiler/passes/basis/decompose.py,sha256=_P9TuT8Ui75OhTi-iROcdtGKrThvY-FcatS05gjT6dc,6123
|
209
209
|
qiskit/transpiler/passes/basis/translate_parameterized.py,sha256=jNekE2530Pj-WGlxDPfCa8bErISDFhRUsC3j0GtrxCs,7425
|
210
210
|
qiskit/transpiler/passes/basis/__init__.py,sha256=JF0s79eUZOJo-8T8rFUlq0nvF7Q-FS7sqjB1A2Jy7Yo,783
|
211
211
|
qiskit/transpiler/passes/basis/unroll_3q_or_more.py,sha256=g2Fsuv5WCgufdh7tw0hMQUUQFkyeExIU9ENaWGqTZpo,3726
|
@@ -267,7 +267,7 @@ qiskit/circuit/classicalregister.py,sha256=oLKotR8jFREs6i2M1K7Jrvm5rrfG7TzLgaB0-
|
|
267
267
|
qiskit/circuit/operation.py,sha256=ecfuw_bkQYFsHyEPdf1z-vJhY99NYSFLYps_X1DF3jc,2015
|
268
268
|
qiskit/circuit/quantumregister.py,sha256=S_4lTalKmDI0LiVq3WJUyqDQwrx7-7mVDOMO-YIs4qI,2032
|
269
269
|
qiskit/circuit/parameterexpression.py,sha256=INJe0jYbeujGltUQIoJ-70s3nRmCtd1ECL_gLUJ_adA,27041
|
270
|
-
qiskit/circuit/add_control.py,sha256=
|
270
|
+
qiskit/circuit/add_control.py,sha256=jT_PaSowKSFa3g_upN0PP0qCLIKsFpkP4h11H-T55js,10308
|
271
271
|
qiskit/circuit/delay.py,sha256=4tWlJU86nifIvZfb0q5m6F25Ckf9kRQPIBxh6IYm1hc,4926
|
272
272
|
qiskit/circuit/twirling.py,sha256=HmpR4EzfKEkI5hW50gstzg2S6f464jF6MbtGquyGbG8,6213
|
273
273
|
qiskit/circuit/gate.py,sha256=62_KeRCnxEk1m7WffSWSmEaONuNTkiNi5pB7uISLPYU,10242
|
@@ -354,8 +354,8 @@ qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py,sha256=hSk8Yi
|
|
354
354
|
qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py,sha256=6_t_r2qB9Ancp24EnrZ8bOB0k9W-_akT7rcRDmPz-CE,7460
|
355
355
|
qiskit/circuit/library/arithmetic/adders/__init__.py,sha256=PRrSLxGAtAMm-9L6UIFnL3ta0NSYUIhEklpf_i9bE5s,743
|
356
356
|
qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py,sha256=bUV7q1nbQoftKVjX0D-HcW_kyJqWrJpP8muXnV7SeRU,6039
|
357
|
-
qiskit/circuit/library/arithmetic/adders/adder.py,sha256=
|
358
|
-
qiskit/circuit/library/arithmetic/multipliers/multiplier.py,sha256=
|
357
|
+
qiskit/circuit/library/arithmetic/adders/adder.py,sha256=DM0FmgeGK8S9cOmX_E_Nyk9Q1H_fnJ3vxUMvwp1Ar-E,7887
|
358
|
+
qiskit/circuit/library/arithmetic/multipliers/multiplier.py,sha256=L487WCWB6YN9EAACm2Aih6e0GhuQaYk-mbA_ACWeP9Q,7409
|
359
359
|
qiskit/circuit/library/arithmetic/multipliers/__init__.py,sha256=vRtcHF2PRcyK_lfBQFqsWlpeaGwkcK3PK1KeduHvfOE,672
|
360
360
|
qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py,sha256=oJIWVc2wFLz-GbU06jurKU3xcyxWdd7AbsH7SVMu0-c,6850
|
361
361
|
qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py,sha256=fhFUM0wTyK8X8CLDQEKs05Ezzos5uS_kybCoj9zSeuw,6215
|
@@ -737,7 +737,7 @@ qiskit/primitives/base/estimator_result.py,sha256=YUNMS8uKaHVGBn4j2QKJBijh3nsQkE
|
|
737
737
|
qiskit/primitives/base/base_primitive_job.py,sha256=E9JZPlHeDU-Zx2ccje73dpEAkt0rCYD1yrMb-WEmgbk,2834
|
738
738
|
qiskit/primitives/base/validation.py,sha256=KMWbPhGUSyr1XYSoh11YgNBabjgtgVpbTFYu9-0TvjU,8846
|
739
739
|
qiskit/qpy/interface.py,sha256=Cd089X6aInCjNEz3GA3Ea75A_Lo09Vkx43aQBsEVdkU,14131
|
740
|
-
qiskit/qpy/__init__.py,sha256=
|
740
|
+
qiskit/qpy/__init__.py,sha256=pG7qBgFVy8vtin_5adA6mrgcANR1AXcXaLe4MqesLz8,63073
|
741
741
|
qiskit/qpy/common.py,sha256=kKcrLZAdEbXssanEPCHQ693FznmtNmucmmApDnd1e9I,12258
|
742
742
|
qiskit/qpy/type_keys.py,sha256=_2FKRgX1H6B5L6UOt3RCBzbeecNh0LPISZUr75felQg,15761
|
743
743
|
qiskit/qpy/formats.py,sha256=E9I8sxK1Zj5Nhk5-BbyHbSaBrdsj15AR3DGoVvTrL0k,11520
|
@@ -806,31 +806,31 @@ qiskit/quantum_info/operators/utils/anti_commutator.py,sha256=mn8j5qsW4ZRED8OMcZ
|
|
806
806
|
qiskit/quantum_info/operators/utils/__init__.py,sha256=E-Z7NJUaWRxqJN1lcYdDqSupLLKE1QUejl9ttQ8_04U,704
|
807
807
|
qiskit/quantum_info/operators/utils/double_commutator.py,sha256=fXW2YPgzPyzHOSbPW0HQZ6WYzjHHD1zd0sJunMzpvOc,1978
|
808
808
|
qiskit/quantum_info/operators/utils/commutator.py,sha256=BR7lgW4tD6SZKxiQIQE7CQSCYGKRaqPFzWaO03QLuY8,957
|
809
|
-
qiskit/quantum_info/operators/channel/ptm.py,sha256=
|
809
|
+
qiskit/quantum_info/operators/channel/ptm.py,sha256=23HzPAj5ondGqxSnunQJaSbL1ogtVJjWef1-oHIVQcc,7790
|
810
810
|
qiskit/quantum_info/operators/channel/transformations.py,sha256=vtNroGYrTtABB1ERI8dNjSBwM3FzaI-nLNSwyoVXGGA,17624
|
811
|
-
qiskit/quantum_info/operators/channel/choi.py,sha256=
|
812
|
-
qiskit/quantum_info/operators/channel/stinespring.py,sha256=
|
811
|
+
qiskit/quantum_info/operators/channel/choi.py,sha256=O_8a2M2zL8z_mxcq0LChINwrl2XzGMHsM5D8vmU681Q,8461
|
812
|
+
qiskit/quantum_info/operators/channel/stinespring.py,sha256=QgSMgc6ZFs_dUu3rFgTS43G468SU4arLZKxErQEkUvk,11439
|
813
813
|
qiskit/quantum_info/operators/channel/__init__.py,sha256=CeahSP9rvIa-dgQNQkTqI7MTRMLebR19jmLhOEhr5Ps,940
|
814
|
-
qiskit/quantum_info/operators/channel/superop.py,sha256=
|
814
|
+
qiskit/quantum_info/operators/channel/superop.py,sha256=1UvaRfApud0rOw2QyuD-u5J-OIyBfdWQxDTnCgS-sSQ,15685
|
815
815
|
qiskit/quantum_info/operators/channel/kraus.py,sha256=P_pB739LfvC9n13L9LwMVzLXLmsNoOk53CaD3pEsENo,13259
|
816
|
-
qiskit/quantum_info/operators/channel/chi.py,sha256=
|
817
|
-
qiskit/quantum_info/operators/channel/quantum_channel.py,sha256=
|
818
|
-
qiskit/quantum_info/states/stabilizerstate.py,sha256=
|
819
|
-
qiskit/quantum_info/states/statevector.py,sha256=
|
816
|
+
qiskit/quantum_info/operators/channel/chi.py,sha256=eGgaPgaVXe38LLdPdJuep6uRnxJzv4PIg3uv3ngDXMk,7661
|
817
|
+
qiskit/quantum_info/operators/channel/quantum_channel.py,sha256=eRVP5rBJ_TdURD83UrU7YSY7hLDkGosLm3N03c9tFUQ,13949
|
818
|
+
qiskit/quantum_info/states/stabilizerstate.py,sha256=7af0aYkdH1f8mAKDvhLNH_x_OJFKtQLymCUddhWQkoQ,29669
|
819
|
+
qiskit/quantum_info/states/statevector.py,sha256=_SwAGdUOmzwu__VSCNBOPywU4vS1GnIRb4G28S12iGs,36796
|
820
820
|
qiskit/quantum_info/states/__init__.py,sha256=Zepc7tCs93UIRVkLJYks3FH3pCoIe48f-rVtQ0X6qoQ,897
|
821
821
|
qiskit/quantum_info/states/random.py,sha256=oxQWWdCpZVxTnbrBUfdRodVKhRhhFD-pW4zcxUt5dM0,5062
|
822
822
|
qiskit/quantum_info/states/measures.py,sha256=9YvouvJ5I9D8_BZBe3oiyrQwdtOIapV12bhCYCuWZUo,9753
|
823
823
|
qiskit/quantum_info/states/utils.py,sha256=Trw5T6EX3FHpjgKoQm6788wZwe4JtFJIvD4V-MA0Qwg,8758
|
824
|
-
qiskit/quantum_info/states/densitymatrix.py,sha256=
|
824
|
+
qiskit/quantum_info/states/densitymatrix.py,sha256=fTpAa2Cq1hspA1vWCe8cdJsGSShZLu6jQPNfKD2EsGg,32694
|
825
825
|
qiskit/quantum_info/states/quantum_state.py,sha256=v__EAFkAu2aJwafAfaVDce5_525fTkTrTaJdrdQhAr0,17774
|
826
826
|
qiskit/compiler/sequencer.py,sha256=uvwF1e3R8gLpf91zD3Fr7UzgfQw9mcv_orHsYVhSOz0,3210
|
827
827
|
qiskit/compiler/__init__.py,sha256=Far4-zXOyDGCqdNmFP4Q8zV47meApMw6sbIdd1t_wM4,989
|
828
828
|
qiskit/compiler/assembler.py,sha256=nsF7XRgHJVgBrJ5BIj44YsGpNsN5OpqvTYCrGVl9IlY,27813
|
829
829
|
qiskit/compiler/transpiler.py,sha256=dJ_MpUw1COntDag6pefwoVB09zk4sg-5taNEaKiQzO8,26504
|
830
830
|
qiskit/compiler/scheduler.py,sha256=RYwAaSym3Y4GwRhbx356FtsvF_JN_rhOLwKP84nUp9E,4532
|
831
|
-
qiskit-1.3.
|
832
|
-
qiskit-1.3.
|
833
|
-
qiskit-1.3.
|
834
|
-
qiskit-1.3.
|
835
|
-
qiskit-1.3.
|
836
|
-
qiskit-1.3.
|
831
|
+
qiskit-1.3.1.dist-info/RECORD,,
|
832
|
+
qiskit-1.3.1.dist-info/WHEEL,sha256=fPibiktQBtnf1UkmTu0XozqWjXXNjrtDnO8fj2jMx3k,109
|
833
|
+
qiskit-1.3.1.dist-info/entry_points.txt,sha256=8f4O6ZbFAIr5AzsP3wWosbp6n4_WI-sYGkgID9Y9JSE,5673
|
834
|
+
qiskit-1.3.1.dist-info/top_level.txt,sha256=_vjFXLv7qrHyJJOC2-JXfG54o4XQygW9GuQPxgtSt9Q,7
|
835
|
+
qiskit-1.3.1.dist-info/LICENSE.txt,sha256=IXrBXbzaJ4LgBPUVKIbYR5iMY2eqoMT8jDVTY8Ib0iQ,11416
|
836
|
+
qiskit-1.3.1.dist-info/METADATA,sha256=3u8vll5ehxG_o8KlC2Im1VjUmXlI7BOWnkyZngPjk_s,12948
|
@@ -1,5 +1,5 @@
|
|
1
1
|
[qiskit.synthesis]
|
2
|
-
FullAdder.default = qiskit.transpiler.passes.synthesis.hls_plugins:
|
2
|
+
FullAdder.default = qiskit.transpiler.passes.synthesis.hls_plugins:FullAdderSynthesisDefault
|
3
3
|
FullAdder.ripple_c04 = qiskit.transpiler.passes.synthesis.hls_plugins:FullAdderSynthesisC04
|
4
4
|
FullAdder.ripple_v95 = qiskit.transpiler.passes.synthesis.hls_plugins:FullAdderSynthesisV95
|
5
5
|
HalfAdder.default = qiskit.transpiler.passes.synthesis.hls_plugins:HalfAdderSynthesisDefault
|
File without changes
|
File without changes
|
File without changes
|