qiskit 1.3.0rc2__cp39-abi3-win32.whl → 1.3.1__cp39-abi3-win32.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.pyd +0 -0
- qiskit/circuit/add_control.py +110 -92
- qiskit/circuit/library/arithmetic/adders/adder.py +25 -0
- qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
- qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +1 -1
- qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +1 -1
- 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/optimization/inverse_cancellation.py +2 -0
- qiskit/transpiler/passes/synthesis/hls_plugins.py +89 -21
- {qiskit-1.3.0rc2.dist-info → qiskit-1.3.1.dist-info}/METADATA +12 -12
- {qiskit-1.3.0rc2.dist-info → qiskit-1.3.1.dist-info}/RECORD +27 -27
- {qiskit-1.3.0rc2.dist-info → qiskit-1.3.1.dist-info}/entry_points.txt +1 -1
- {qiskit-1.3.0rc2.dist-info → qiskit-1.3.1.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.3.0rc2.dist-info → qiskit-1.3.1.dist-info}/WHEEL +0 -0
- {qiskit-1.3.0rc2.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.pyd
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")
|
@@ -84,7 +84,7 @@ class CDKMRippleCarryAdder(Adder):
|
|
84
84
|
:class:`.ModularAdderGate`: A generic inplace adder, modulo :math:`2^n`. This
|
85
85
|
is functionally equivalent to ``kind="fixed"``.
|
86
86
|
|
87
|
-
:class:`.
|
87
|
+
:class:`.HalfAdderGate`: A generic inplace adder. This
|
88
88
|
is functionally equivalent to ``kind="half"``.
|
89
89
|
|
90
90
|
:class:`.FullAdderGate`: A generic inplace adder, with a carry-in bit. This
|
@@ -54,7 +54,7 @@ class DraperQFTAdder(Adder):
|
|
54
54
|
:class:`.ModularAdderGate`: A generic inplace adder, modulo :math:`2^n`. This
|
55
55
|
is functionally equivalent to ``kind="fixed"``.
|
56
56
|
|
57
|
-
:class:`.
|
57
|
+
:class:`.HalfAdderGate`: A generic inplace adder. This
|
58
58
|
is functionally equivalent to ``kind="half"``.
|
59
59
|
|
60
60
|
**References:**
|
@@ -60,7 +60,7 @@ class VBERippleCarryAdder(Adder):
|
|
60
60
|
:class:`.ModularAdderGate`: A generic inplace adder, modulo :math:`2^n`. This
|
61
61
|
is functionally equivalent to ``kind="fixed"``.
|
62
62
|
|
63
|
-
:class:`.
|
63
|
+
:class:`.HalfAdderGate`: A generic inplace adder. This
|
64
64
|
is functionally equivalent to ``kind="half"``.
|
65
65
|
|
66
66
|
:class:`.FullAdderGate`: A generic inplace adder, with a carry-in bit. This
|
@@ -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
|