qiskit-aer 0.17.2__cp314-cp314-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.
- qiskit_aer/VERSION.txt +1 -0
- qiskit_aer/__init__.py +89 -0
- qiskit_aer/aererror.py +30 -0
- qiskit_aer/aerprovider.py +119 -0
- qiskit_aer/backends/__init__.py +20 -0
- qiskit_aer/backends/aer_compiler.py +1085 -0
- qiskit_aer/backends/aer_simulator.py +1025 -0
- qiskit_aer/backends/aerbackend.py +679 -0
- qiskit_aer/backends/backend_utils.py +567 -0
- qiskit_aer/backends/backendconfiguration.py +395 -0
- qiskit_aer/backends/backendproperties.py +590 -0
- qiskit_aer/backends/compatibility.py +287 -0
- qiskit_aer/backends/controller_wrappers.cp314-win_amd64.pyd +0 -0
- qiskit_aer/backends/libopenblas.dll +0 -0
- qiskit_aer/backends/name_mapping.py +306 -0
- qiskit_aer/backends/qasm_simulator.py +925 -0
- qiskit_aer/backends/statevector_simulator.py +330 -0
- qiskit_aer/backends/unitary_simulator.py +316 -0
- qiskit_aer/jobs/__init__.py +35 -0
- qiskit_aer/jobs/aerjob.py +143 -0
- qiskit_aer/jobs/utils.py +66 -0
- qiskit_aer/library/__init__.py +204 -0
- qiskit_aer/library/control_flow_instructions/__init__.py +16 -0
- qiskit_aer/library/control_flow_instructions/jump.py +47 -0
- qiskit_aer/library/control_flow_instructions/mark.py +30 -0
- qiskit_aer/library/control_flow_instructions/store.py +29 -0
- qiskit_aer/library/default_qubits.py +44 -0
- qiskit_aer/library/instructions_table.csv +21 -0
- qiskit_aer/library/save_instructions/__init__.py +44 -0
- qiskit_aer/library/save_instructions/save_amplitudes.py +168 -0
- qiskit_aer/library/save_instructions/save_clifford.py +63 -0
- qiskit_aer/library/save_instructions/save_data.py +129 -0
- qiskit_aer/library/save_instructions/save_density_matrix.py +91 -0
- qiskit_aer/library/save_instructions/save_expectation_value.py +257 -0
- qiskit_aer/library/save_instructions/save_matrix_product_state.py +71 -0
- qiskit_aer/library/save_instructions/save_probabilities.py +156 -0
- qiskit_aer/library/save_instructions/save_stabilizer.py +70 -0
- qiskit_aer/library/save_instructions/save_state.py +79 -0
- qiskit_aer/library/save_instructions/save_statevector.py +120 -0
- qiskit_aer/library/save_instructions/save_superop.py +62 -0
- qiskit_aer/library/save_instructions/save_unitary.py +63 -0
- qiskit_aer/library/set_instructions/__init__.py +19 -0
- qiskit_aer/library/set_instructions/set_density_matrix.py +78 -0
- qiskit_aer/library/set_instructions/set_matrix_product_state.py +83 -0
- qiskit_aer/library/set_instructions/set_stabilizer.py +77 -0
- qiskit_aer/library/set_instructions/set_statevector.py +78 -0
- qiskit_aer/library/set_instructions/set_superop.py +78 -0
- qiskit_aer/library/set_instructions/set_unitary.py +78 -0
- qiskit_aer/noise/__init__.py +265 -0
- qiskit_aer/noise/device/__init__.py +25 -0
- qiskit_aer/noise/device/models.py +397 -0
- qiskit_aer/noise/device/parameters.py +202 -0
- qiskit_aer/noise/errors/__init__.py +30 -0
- qiskit_aer/noise/errors/base_quantum_error.py +119 -0
- qiskit_aer/noise/errors/pauli_error.py +283 -0
- qiskit_aer/noise/errors/pauli_lindblad_error.py +363 -0
- qiskit_aer/noise/errors/quantum_error.py +451 -0
- qiskit_aer/noise/errors/readout_error.py +355 -0
- qiskit_aer/noise/errors/standard_errors.py +498 -0
- qiskit_aer/noise/noise_model.py +1231 -0
- qiskit_aer/noise/noiseerror.py +30 -0
- qiskit_aer/noise/passes/__init__.py +18 -0
- qiskit_aer/noise/passes/local_noise_pass.py +160 -0
- qiskit_aer/noise/passes/relaxation_noise_pass.py +137 -0
- qiskit_aer/primitives/__init__.py +44 -0
- qiskit_aer/primitives/estimator.py +751 -0
- qiskit_aer/primitives/estimator_v2.py +159 -0
- qiskit_aer/primitives/sampler.py +361 -0
- qiskit_aer/primitives/sampler_v2.py +256 -0
- qiskit_aer/quantum_info/__init__.py +32 -0
- qiskit_aer/quantum_info/states/__init__.py +16 -0
- qiskit_aer/quantum_info/states/aer_densitymatrix.py +313 -0
- qiskit_aer/quantum_info/states/aer_state.py +525 -0
- qiskit_aer/quantum_info/states/aer_statevector.py +302 -0
- qiskit_aer/utils/__init__.py +44 -0
- qiskit_aer/utils/noise_model_inserter.py +66 -0
- qiskit_aer/utils/noise_transformation.py +431 -0
- qiskit_aer/version.py +86 -0
- qiskit_aer-0.17.2.dist-info/METADATA +209 -0
- qiskit_aer-0.17.2.dist-info/RECORD +83 -0
- qiskit_aer-0.17.2.dist-info/WHEEL +5 -0
- qiskit_aer-0.17.2.dist-info/licenses/LICENSE.txt +203 -0
- qiskit_aer-0.17.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
# This code is part of Qiskit.
|
|
2
|
+
#
|
|
3
|
+
# (C) Copyright IBM 2022
|
|
4
|
+
#
|
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
|
8
|
+
#
|
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
|
11
|
+
# that they have been altered from the originals.
|
|
12
|
+
"""
|
|
13
|
+
State class that handles internal C++ state safely
|
|
14
|
+
"""
|
|
15
|
+
from enum import Enum
|
|
16
|
+
import numpy as np
|
|
17
|
+
|
|
18
|
+
# pylint: disable=import-error, no-name-in-module
|
|
19
|
+
from qiskit_aer.backends.controller_wrappers import AerStateWrapper
|
|
20
|
+
from ...backends.aerbackend import AerError
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class _STATE(Enum):
|
|
24
|
+
INITIALIZING = 1
|
|
25
|
+
ALLOCATED = 2
|
|
26
|
+
MAPPED = 3
|
|
27
|
+
MOVED = 4
|
|
28
|
+
RELEASED = 5
|
|
29
|
+
CLOSED = 6
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class AerState:
|
|
33
|
+
"""Internal class to access state of Aer."""
|
|
34
|
+
|
|
35
|
+
_data_in_use = {}
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def _in_use(data):
|
|
39
|
+
AerState._data_in_use[id(data)] = data
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def _not_in_use(data):
|
|
43
|
+
del AerState._data_in_use[id(data)]
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def _is_in_use(data):
|
|
47
|
+
return id(data) in AerState._data_in_use
|
|
48
|
+
|
|
49
|
+
def __init__(self, **kwargs):
|
|
50
|
+
"""State that handles cpp quantum state safely"""
|
|
51
|
+
self._state = _STATE.INITIALIZING
|
|
52
|
+
self._native_state = AerStateWrapper()
|
|
53
|
+
self._init_data = None
|
|
54
|
+
self._moved_data = None
|
|
55
|
+
self._last_qubit = -1
|
|
56
|
+
self._configs = {}
|
|
57
|
+
|
|
58
|
+
self._method = None
|
|
59
|
+
|
|
60
|
+
for key, value in kwargs.items():
|
|
61
|
+
self.configure(key, value)
|
|
62
|
+
|
|
63
|
+
def renew(self):
|
|
64
|
+
"""Renew AerState for reuse"""
|
|
65
|
+
self._assert_closed()
|
|
66
|
+
self._state = _STATE.INITIALIZING
|
|
67
|
+
self._init_data = None
|
|
68
|
+
self._moved_data = None
|
|
69
|
+
self._last_qubit = -1
|
|
70
|
+
|
|
71
|
+
def _assert_initializing(self):
|
|
72
|
+
if self._state != _STATE.INITIALIZING:
|
|
73
|
+
raise AerError("AerState was already initialized.")
|
|
74
|
+
|
|
75
|
+
def _assert_allocated_or_mapped_or_moved(self):
|
|
76
|
+
if self._state == _STATE.INITIALIZING:
|
|
77
|
+
raise AerError("AerState has not been initialized yet.")
|
|
78
|
+
if self._state == _STATE.CLOSED:
|
|
79
|
+
raise AerError("AerState has already been closed.")
|
|
80
|
+
|
|
81
|
+
def _assert_allocated_or_mapped(self):
|
|
82
|
+
if self._state == _STATE.INITIALIZING:
|
|
83
|
+
raise AerError("AerState has not been initialized yet.")
|
|
84
|
+
if self._state == _STATE.MOVED:
|
|
85
|
+
raise AerError("AerState has already been moved.")
|
|
86
|
+
if self._state == _STATE.CLOSED:
|
|
87
|
+
raise AerError("AerState has already been closed.")
|
|
88
|
+
|
|
89
|
+
def _assert_mapped_or_moved(self):
|
|
90
|
+
if self._state == _STATE.INITIALIZING:
|
|
91
|
+
raise AerError("AerState has not been initialized yet.")
|
|
92
|
+
if self._state == _STATE.ALLOCATED:
|
|
93
|
+
raise AerError("AerState has not been moved yet.")
|
|
94
|
+
if self._state == _STATE.CLOSED:
|
|
95
|
+
raise AerError("AerState has already been closed.")
|
|
96
|
+
|
|
97
|
+
def _assert_closed(self):
|
|
98
|
+
if self._state != _STATE.CLOSED:
|
|
99
|
+
raise AerError("AerState is not closed.")
|
|
100
|
+
|
|
101
|
+
def _allocated(self):
|
|
102
|
+
if self._state != _STATE.INITIALIZING:
|
|
103
|
+
raise AerError("unexpected state transition: {self._state}->{_STATE.ALLOCATED}")
|
|
104
|
+
self._state = _STATE.ALLOCATED
|
|
105
|
+
|
|
106
|
+
def _mapped(self):
|
|
107
|
+
if self._state != _STATE.INITIALIZING:
|
|
108
|
+
raise AerError("unexpected state transition: {self._state}->{_STATE.MAPPED}")
|
|
109
|
+
self._state = _STATE.MAPPED
|
|
110
|
+
|
|
111
|
+
def _released(self):
|
|
112
|
+
if self._state != _STATE.MAPPED:
|
|
113
|
+
raise AerError("unexpected state transition: {self._state}->{_STATE.RELEASED}")
|
|
114
|
+
self._state = _STATE.RELEASED
|
|
115
|
+
|
|
116
|
+
def _moved(self):
|
|
117
|
+
if self._state != _STATE.ALLOCATED:
|
|
118
|
+
raise AerError("unexpected state transition: {self._state}->{_STATE.MOVED}")
|
|
119
|
+
self._state = _STATE.MOVED
|
|
120
|
+
|
|
121
|
+
def _closed(self):
|
|
122
|
+
if self._state not in (_STATE.MOVED, _STATE.MAPPED, _STATE.RELEASED):
|
|
123
|
+
raise AerError("unexpected state transition: {self._state}->{_STATE.CLOSED}")
|
|
124
|
+
self._state = _STATE.CLOSED
|
|
125
|
+
|
|
126
|
+
def configure(self, key, value):
|
|
127
|
+
"""configure AerState with options of `AerSimulator`."""
|
|
128
|
+
self._assert_initializing()
|
|
129
|
+
|
|
130
|
+
if not isinstance(key, str):
|
|
131
|
+
raise AerError("AerState is configured with a str key")
|
|
132
|
+
if not isinstance(value, str):
|
|
133
|
+
value = str(value)
|
|
134
|
+
|
|
135
|
+
self._configs[key] = value
|
|
136
|
+
self._native_state.configure(key, value)
|
|
137
|
+
|
|
138
|
+
if key == "method":
|
|
139
|
+
self._method = value
|
|
140
|
+
|
|
141
|
+
def configuration(self):
|
|
142
|
+
"""return configuration"""
|
|
143
|
+
return self._configs.copy()
|
|
144
|
+
|
|
145
|
+
def initialize(self, data=None, copy=True):
|
|
146
|
+
"""initialize state."""
|
|
147
|
+
self._assert_initializing()
|
|
148
|
+
|
|
149
|
+
if not self._method:
|
|
150
|
+
raise AerError("method is not configured yet.")
|
|
151
|
+
|
|
152
|
+
if data is None:
|
|
153
|
+
self._native_state.initialize()
|
|
154
|
+
self._allocated()
|
|
155
|
+
return True
|
|
156
|
+
elif isinstance(data, np.ndarray):
|
|
157
|
+
return self._initialize_with_ndarray(data, copy)
|
|
158
|
+
else:
|
|
159
|
+
raise AerError(f"unsupported init data: {data.__class__}")
|
|
160
|
+
|
|
161
|
+
def _initialize_with_ndarray(self, data, copy):
|
|
162
|
+
if AerState._is_in_use(data) and not copy:
|
|
163
|
+
raise AerError("another AerState owns this data")
|
|
164
|
+
|
|
165
|
+
num_of_qubits = int(np.log2(len(data)))
|
|
166
|
+
if len(data) != np.power(2, num_of_qubits):
|
|
167
|
+
raise AerError("length of init data must be power of two")
|
|
168
|
+
|
|
169
|
+
init = False
|
|
170
|
+
if self._method == "statevector":
|
|
171
|
+
init = self._native_state.initialize_statevector(num_of_qubits, data, copy)
|
|
172
|
+
elif self._method == "density_matrix":
|
|
173
|
+
if data.shape != (len(data), len(data)):
|
|
174
|
+
raise AerError("shape of init data must be a pair of power of two")
|
|
175
|
+
init = self._native_state.initialize_density_matrix(num_of_qubits, data, copy)
|
|
176
|
+
|
|
177
|
+
if init:
|
|
178
|
+
if not copy:
|
|
179
|
+
self._init_data = data
|
|
180
|
+
AerState._in_use(data)
|
|
181
|
+
self._mapped()
|
|
182
|
+
else:
|
|
183
|
+
self._allocated()
|
|
184
|
+
else:
|
|
185
|
+
# slow path
|
|
186
|
+
self._native_state.reallocate_qubits(num_of_qubits)
|
|
187
|
+
self._native_state.initialize()
|
|
188
|
+
if not data.flags.c_contiguous and not data.flags.f_contiguous:
|
|
189
|
+
data = np.ascontiguousarray(data)
|
|
190
|
+
if self._method == "statevector":
|
|
191
|
+
self._native_state.apply_initialize(range(num_of_qubits), data)
|
|
192
|
+
elif self._method == "density_matrix":
|
|
193
|
+
self._native_state.set_density_matrix(range(num_of_qubits), data)
|
|
194
|
+
else:
|
|
195
|
+
self._native_state.apply_initialize(range(num_of_qubits), data)
|
|
196
|
+
self._allocated()
|
|
197
|
+
copy = True
|
|
198
|
+
|
|
199
|
+
self._last_qubit = num_of_qubits - 1
|
|
200
|
+
return copy
|
|
201
|
+
|
|
202
|
+
def method(self):
|
|
203
|
+
"""return method to simulate"""
|
|
204
|
+
return self._method
|
|
205
|
+
|
|
206
|
+
def set_seed(self, value=None):
|
|
207
|
+
"""initialize seed with a specified value"""
|
|
208
|
+
if value is None:
|
|
209
|
+
self._native_state.set_random_seed()
|
|
210
|
+
else:
|
|
211
|
+
self._native_state.set_seed(value)
|
|
212
|
+
|
|
213
|
+
def close(self):
|
|
214
|
+
"""Safely release all releated memory."""
|
|
215
|
+
self._assert_allocated_or_mapped_or_moved()
|
|
216
|
+
if self._state == _STATE.ALLOCATED:
|
|
217
|
+
self._native_state.move_to_ndarray()
|
|
218
|
+
|
|
219
|
+
self._assert_mapped_or_moved()
|
|
220
|
+
if self._state == _STATE.MAPPED:
|
|
221
|
+
# native memory will be freed when self._init_data is collected.
|
|
222
|
+
# this call of move_to_buffer() is to avoid free in C++
|
|
223
|
+
self._native_state.move_to_buffer()
|
|
224
|
+
AerState._not_in_use(self._init_data)
|
|
225
|
+
|
|
226
|
+
self._native_state.clear()
|
|
227
|
+
self._closed()
|
|
228
|
+
|
|
229
|
+
def move_to_ndarray(self):
|
|
230
|
+
"""move memory to ndarray if it is allocated, otherwise return mapped ndarray."""
|
|
231
|
+
self._assert_allocated_or_mapped_or_moved()
|
|
232
|
+
|
|
233
|
+
if self._state == _STATE.MAPPED:
|
|
234
|
+
ret = self._init_data
|
|
235
|
+
# native memory will be freed when self._init_data is collected.
|
|
236
|
+
# this call of move_to_buffer() is to avoid free in C++
|
|
237
|
+
self._native_state.move_to_buffer()
|
|
238
|
+
AerState._not_in_use(self._init_data)
|
|
239
|
+
self._released()
|
|
240
|
+
elif self._state == _STATE.RELEASED:
|
|
241
|
+
ret = self._init_data
|
|
242
|
+
elif self._state == _STATE.MOVED:
|
|
243
|
+
ret = self._moved_data
|
|
244
|
+
else:
|
|
245
|
+
if self._method == "density_matrix":
|
|
246
|
+
self._moved_data = self._native_state.move_to_matrix()
|
|
247
|
+
else:
|
|
248
|
+
self._moved_data = self._native_state.move_to_ndarray()
|
|
249
|
+
ret = self._moved_data
|
|
250
|
+
self._moved()
|
|
251
|
+
return ret
|
|
252
|
+
|
|
253
|
+
def allocate_qubits(self, num_of_qubits):
|
|
254
|
+
"""allocate qubits."""
|
|
255
|
+
self._assert_initializing()
|
|
256
|
+
if num_of_qubits <= 0:
|
|
257
|
+
raise AerError(f"invalid number of qubits: {num_of_qubits}")
|
|
258
|
+
allocated = self._native_state.allocate_qubits(num_of_qubits)
|
|
259
|
+
self._last_qubit = allocated[len(allocated) - 1]
|
|
260
|
+
|
|
261
|
+
def _assert_in_allocated_qubits(self, qubit):
|
|
262
|
+
if hasattr(qubit, "__iter__"):
|
|
263
|
+
for q in qubit:
|
|
264
|
+
self._assert_in_allocated_qubits(q)
|
|
265
|
+
elif qubit < 0 or qubit > self._last_qubit:
|
|
266
|
+
raise AerError(f"invalid qubit: index={qubit}")
|
|
267
|
+
|
|
268
|
+
@property
|
|
269
|
+
def num_qubits(self):
|
|
270
|
+
"""return a number of allocate qubits."""
|
|
271
|
+
return self._last_qubit + 1
|
|
272
|
+
|
|
273
|
+
def flush(self):
|
|
274
|
+
"""apply all buffered operations.
|
|
275
|
+
Some gate operations are not evaluated immediately.
|
|
276
|
+
This method guarantees that all called operations are evaluated.
|
|
277
|
+
"""
|
|
278
|
+
self._assert_allocated_or_mapped()
|
|
279
|
+
return self._native_state.flush()
|
|
280
|
+
|
|
281
|
+
def last_result(self):
|
|
282
|
+
"""return a result of a operation fluhsed in the last."""
|
|
283
|
+
self._assert_allocated_or_mapped_or_moved()
|
|
284
|
+
return self._native_state.last_result()
|
|
285
|
+
|
|
286
|
+
def apply_global_phase(self, phase):
|
|
287
|
+
"""apply global phase"""
|
|
288
|
+
self._assert_allocated_or_mapped()
|
|
289
|
+
self._native_state.apply_global_phase(phase)
|
|
290
|
+
|
|
291
|
+
def apply_unitary(self, qubits, data):
|
|
292
|
+
"""apply a unitary gate."""
|
|
293
|
+
self._assert_allocated_or_mapped()
|
|
294
|
+
self._assert_in_allocated_qubits(qubits)
|
|
295
|
+
# Convert to numpy array in case not already an array
|
|
296
|
+
data = np.array(data, dtype=complex)
|
|
297
|
+
# Check input is N-qubit matrix
|
|
298
|
+
input_dim = data.shape[0]
|
|
299
|
+
output_dim = data.shape[1]
|
|
300
|
+
num_qubits = int(np.log2(input_dim))
|
|
301
|
+
if input_dim != output_dim or 2**num_qubits != input_dim:
|
|
302
|
+
raise AerError("Input matrix is not an N-qubit operator.")
|
|
303
|
+
if len(qubits) != num_qubits:
|
|
304
|
+
raise AerError("Input matrix and qubits are insonsistent.")
|
|
305
|
+
# update state
|
|
306
|
+
self._native_state.apply_unitary(qubits, data)
|
|
307
|
+
|
|
308
|
+
def apply_multiplexer(self, control_qubits, target_qubits, mats):
|
|
309
|
+
"""apply a multiplexer operation."""
|
|
310
|
+
self._assert_allocated_or_mapped()
|
|
311
|
+
self._assert_in_allocated_qubits(control_qubits)
|
|
312
|
+
self._assert_in_allocated_qubits(target_qubits)
|
|
313
|
+
if not isinstance(mats, list):
|
|
314
|
+
raise AerError("Input must be a list of ndarray.")
|
|
315
|
+
if len(mats) != (2 ** len(control_qubits)):
|
|
316
|
+
raise AerError("Input length must be 2 ** number of control gates.")
|
|
317
|
+
# Convert to np array in case not already an array
|
|
318
|
+
mats = [np.array(mat, dtype=complex) for mat in mats]
|
|
319
|
+
# Check input is N-qubit matrix
|
|
320
|
+
input_dim, output_dim = mats[0].shape
|
|
321
|
+
num_target_qubits = int(np.log2(input_dim))
|
|
322
|
+
if input_dim != output_dim or 2**num_target_qubits != input_dim:
|
|
323
|
+
raise AerError("Input matrix is not an N-qubit operator.")
|
|
324
|
+
for mat in mats[1:]:
|
|
325
|
+
if mat.shape != mats[0].shape:
|
|
326
|
+
raise AerError("Input matrix is not an N-qubit operator.")
|
|
327
|
+
if len(target_qubits) != num_target_qubits:
|
|
328
|
+
raise AerError("Input matrix and qubits are insonsistent.")
|
|
329
|
+
# update state
|
|
330
|
+
self._native_state.apply_multiplexer(control_qubits, target_qubits, mats)
|
|
331
|
+
|
|
332
|
+
def apply_diagonal(self, qubits, diag):
|
|
333
|
+
"""apply a diagonal matrix operation."""
|
|
334
|
+
self._assert_allocated_or_mapped()
|
|
335
|
+
self._assert_in_allocated_qubits(qubits)
|
|
336
|
+
# Convert to numpy array in case not already an array
|
|
337
|
+
diag = np.array(diag, dtype=complex)
|
|
338
|
+
# Check input is N-qubit vector
|
|
339
|
+
input_dim = diag.shape[0]
|
|
340
|
+
num_qubits = int(np.log2(input_dim))
|
|
341
|
+
if 2**num_qubits != input_dim:
|
|
342
|
+
raise AerError("Input vector is not an N-qubit operator.")
|
|
343
|
+
if len(qubits) != num_qubits:
|
|
344
|
+
raise AerError("Input vector and qubits are insonsistent.")
|
|
345
|
+
# update state
|
|
346
|
+
self._native_state.apply_diagonal(qubits, diag)
|
|
347
|
+
|
|
348
|
+
def apply_x(self, target_qubit):
|
|
349
|
+
"""apply a x operation."""
|
|
350
|
+
self._assert_allocated_or_mapped()
|
|
351
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
352
|
+
# update state
|
|
353
|
+
self._native_state.apply_x(target_qubit)
|
|
354
|
+
|
|
355
|
+
def apply_cx(self, control_qubit, target_qubit):
|
|
356
|
+
"""apply a cx operation."""
|
|
357
|
+
self._assert_allocated_or_mapped()
|
|
358
|
+
self._assert_in_allocated_qubits(control_qubit)
|
|
359
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
360
|
+
# update state
|
|
361
|
+
self._native_state.apply_cx([control_qubit, target_qubit])
|
|
362
|
+
|
|
363
|
+
def apply_mcx(self, control_qubits, target_qubit):
|
|
364
|
+
"""apply a mcx operation."""
|
|
365
|
+
self._assert_allocated_or_mapped()
|
|
366
|
+
self._assert_in_allocated_qubits(control_qubits)
|
|
367
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
368
|
+
# update state
|
|
369
|
+
self._native_state.apply_mcx(control_qubits + [target_qubit])
|
|
370
|
+
|
|
371
|
+
def apply_y(self, target_qubit):
|
|
372
|
+
"""apply a y operation."""
|
|
373
|
+
self._assert_allocated_or_mapped()
|
|
374
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
375
|
+
# update state
|
|
376
|
+
self._native_state.apply_y(target_qubit)
|
|
377
|
+
|
|
378
|
+
def apply_cy(self, control_qubit, target_qubit):
|
|
379
|
+
"""apply a cy operation."""
|
|
380
|
+
self._assert_allocated_or_mapped()
|
|
381
|
+
self._assert_in_allocated_qubits(control_qubit)
|
|
382
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
383
|
+
# update state
|
|
384
|
+
self._native_state.apply_cy([control_qubit, target_qubit])
|
|
385
|
+
|
|
386
|
+
def apply_mcy(self, control_qubits, target_qubit):
|
|
387
|
+
"""apply a mcy operation."""
|
|
388
|
+
self._assert_allocated_or_mapped()
|
|
389
|
+
self._assert_in_allocated_qubits(control_qubits)
|
|
390
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
391
|
+
# update state
|
|
392
|
+
self._native_state.apply_mcy(control_qubits + [target_qubit])
|
|
393
|
+
|
|
394
|
+
def apply_z(self, target_qubit):
|
|
395
|
+
"""apply a z operation."""
|
|
396
|
+
self._assert_allocated_or_mapped()
|
|
397
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
398
|
+
# update state
|
|
399
|
+
self._native_state.apply_z(target_qubit)
|
|
400
|
+
|
|
401
|
+
def apply_cz(self, control_qubit, target_qubit):
|
|
402
|
+
"""apply a cz operation."""
|
|
403
|
+
self._assert_allocated_or_mapped()
|
|
404
|
+
self._assert_in_allocated_qubits(control_qubit)
|
|
405
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
406
|
+
# update state
|
|
407
|
+
self._native_state.apply_cz([control_qubit, target_qubit])
|
|
408
|
+
|
|
409
|
+
def apply_mcz(self, control_qubits, target_qubit):
|
|
410
|
+
"""apply a mcz operation."""
|
|
411
|
+
self._assert_allocated_or_mapped()
|
|
412
|
+
self._assert_in_allocated_qubits(control_qubits)
|
|
413
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
414
|
+
# update state
|
|
415
|
+
self._native_state.apply_mcz(control_qubits + [target_qubit])
|
|
416
|
+
|
|
417
|
+
def apply_mcphase(self, control_qubits, target_qubit, phase):
|
|
418
|
+
"""apply a mcphase operation."""
|
|
419
|
+
self._assert_allocated_or_mapped()
|
|
420
|
+
self._assert_in_allocated_qubits(control_qubits)
|
|
421
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
422
|
+
# update state
|
|
423
|
+
self._native_state.apply_mcphase(control_qubits + [target_qubit], phase)
|
|
424
|
+
|
|
425
|
+
def apply_h(self, target_qubit):
|
|
426
|
+
"""apply a h operation."""
|
|
427
|
+
self._assert_allocated_or_mapped()
|
|
428
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
429
|
+
# update state
|
|
430
|
+
self._native_state.apply_h(target_qubit)
|
|
431
|
+
|
|
432
|
+
def apply_u(self, target_qubit, theta, phi, lamb):
|
|
433
|
+
"""apply a u operation."""
|
|
434
|
+
self._assert_allocated_or_mapped()
|
|
435
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
436
|
+
# update state
|
|
437
|
+
self._native_state.apply_u(target_qubit, theta, phi, lamb)
|
|
438
|
+
|
|
439
|
+
def apply_cu(self, control_qubit, target_qubit, theta, phi, lamb, gamma):
|
|
440
|
+
"""apply a cu operation."""
|
|
441
|
+
self._assert_allocated_or_mapped()
|
|
442
|
+
self._assert_in_allocated_qubits(control_qubit)
|
|
443
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
444
|
+
# update state
|
|
445
|
+
self._native_state.apply_cu([control_qubit, target_qubit], theta, phi, lamb, gamma)
|
|
446
|
+
|
|
447
|
+
def apply_mcu(self, control_qubits, target_qubit, theta, phi, lamb, gamma):
|
|
448
|
+
"""apply a mcu operation."""
|
|
449
|
+
self._assert_allocated_or_mapped()
|
|
450
|
+
self._assert_in_allocated_qubits(control_qubits)
|
|
451
|
+
self._assert_in_allocated_qubits(target_qubit)
|
|
452
|
+
# update state
|
|
453
|
+
self._native_state.apply_mcu(control_qubits + [target_qubit], theta, phi, lamb, gamma)
|
|
454
|
+
|
|
455
|
+
def apply_mcswap(self, control_qubits, qubit0, qubit1):
|
|
456
|
+
"""apply a mcswap operation."""
|
|
457
|
+
self._assert_allocated_or_mapped()
|
|
458
|
+
self._assert_in_allocated_qubits(control_qubits)
|
|
459
|
+
self._assert_in_allocated_qubits(qubit0)
|
|
460
|
+
self._assert_in_allocated_qubits(qubit1)
|
|
461
|
+
# update state
|
|
462
|
+
self._native_state.apply_mcswap(control_qubits + [qubit0, qubit1])
|
|
463
|
+
|
|
464
|
+
def apply_measure(self, qubits):
|
|
465
|
+
"""apply a measure operation."""
|
|
466
|
+
self._assert_allocated_or_mapped()
|
|
467
|
+
self._assert_in_allocated_qubits(qubits)
|
|
468
|
+
# measure and update state
|
|
469
|
+
return self._native_state.apply_measure(qubits)
|
|
470
|
+
|
|
471
|
+
def apply_initialize(self, qubits, vec):
|
|
472
|
+
"""apply an initialize operation."""
|
|
473
|
+
self._assert_allocated_or_mapped()
|
|
474
|
+
self._assert_in_allocated_qubits(qubits)
|
|
475
|
+
# update state
|
|
476
|
+
return self._native_state.apply_initialize(qubits, vec)
|
|
477
|
+
|
|
478
|
+
def apply_reset(self, qubits):
|
|
479
|
+
"""apply a reset operation."""
|
|
480
|
+
self._assert_allocated_or_mapped()
|
|
481
|
+
self._assert_in_allocated_qubits(qubits)
|
|
482
|
+
# update state
|
|
483
|
+
return self._native_state.apply_reset(qubits)
|
|
484
|
+
|
|
485
|
+
def apply_kraus(self, qubits, krausops):
|
|
486
|
+
"""apply a kraus operation."""
|
|
487
|
+
self._assert_allocated_or_mapped()
|
|
488
|
+
self._assert_in_allocated_qubits(qubits)
|
|
489
|
+
# update state
|
|
490
|
+
return self._native_state.apply_kraus(qubits, krausops)
|
|
491
|
+
|
|
492
|
+
def probability(self, outcome):
|
|
493
|
+
"""return a probability of `outcome`."""
|
|
494
|
+
self._assert_allocated_or_mapped()
|
|
495
|
+
# retrieve probability
|
|
496
|
+
return self._native_state.probability(outcome)
|
|
497
|
+
|
|
498
|
+
def probabilities(self, qubits=None):
|
|
499
|
+
"""return probabilities of `qubits`."""
|
|
500
|
+
self._assert_allocated_or_mapped()
|
|
501
|
+
if qubits is None:
|
|
502
|
+
qubits = range(self._last_qubit + 1)
|
|
503
|
+
else:
|
|
504
|
+
self._assert_in_allocated_qubits(qubits)
|
|
505
|
+
|
|
506
|
+
# retrieve probability
|
|
507
|
+
return self._native_state.probabilities(qubits)
|
|
508
|
+
|
|
509
|
+
def sample_counts(self, qubits=None, shots=1024):
|
|
510
|
+
"""samples all the qubits."""
|
|
511
|
+
self._assert_allocated_or_mapped()
|
|
512
|
+
if qubits is None:
|
|
513
|
+
qubits = range(self._last_qubit + 1)
|
|
514
|
+
else:
|
|
515
|
+
self._assert_in_allocated_qubits(qubits)
|
|
516
|
+
return self._native_state.sample_counts(qubits, shots)
|
|
517
|
+
|
|
518
|
+
def sample_memory(self, qubits=None, shots=1024):
|
|
519
|
+
"""samples all the qubits."""
|
|
520
|
+
self._assert_allocated_or_mapped()
|
|
521
|
+
if qubits is None:
|
|
522
|
+
qubits = range(self._last_qubit + 1)
|
|
523
|
+
else:
|
|
524
|
+
self._assert_in_allocated_qubits(qubits)
|
|
525
|
+
return self._native_state.sample_memory(qubits, shots)
|