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.
Files changed (83) hide show
  1. qiskit_aer/VERSION.txt +1 -0
  2. qiskit_aer/__init__.py +89 -0
  3. qiskit_aer/aererror.py +30 -0
  4. qiskit_aer/aerprovider.py +119 -0
  5. qiskit_aer/backends/__init__.py +20 -0
  6. qiskit_aer/backends/aer_compiler.py +1085 -0
  7. qiskit_aer/backends/aer_simulator.py +1025 -0
  8. qiskit_aer/backends/aerbackend.py +679 -0
  9. qiskit_aer/backends/backend_utils.py +567 -0
  10. qiskit_aer/backends/backendconfiguration.py +395 -0
  11. qiskit_aer/backends/backendproperties.py +590 -0
  12. qiskit_aer/backends/compatibility.py +287 -0
  13. qiskit_aer/backends/controller_wrappers.cp314-win_amd64.pyd +0 -0
  14. qiskit_aer/backends/libopenblas.dll +0 -0
  15. qiskit_aer/backends/name_mapping.py +306 -0
  16. qiskit_aer/backends/qasm_simulator.py +925 -0
  17. qiskit_aer/backends/statevector_simulator.py +330 -0
  18. qiskit_aer/backends/unitary_simulator.py +316 -0
  19. qiskit_aer/jobs/__init__.py +35 -0
  20. qiskit_aer/jobs/aerjob.py +143 -0
  21. qiskit_aer/jobs/utils.py +66 -0
  22. qiskit_aer/library/__init__.py +204 -0
  23. qiskit_aer/library/control_flow_instructions/__init__.py +16 -0
  24. qiskit_aer/library/control_flow_instructions/jump.py +47 -0
  25. qiskit_aer/library/control_flow_instructions/mark.py +30 -0
  26. qiskit_aer/library/control_flow_instructions/store.py +29 -0
  27. qiskit_aer/library/default_qubits.py +44 -0
  28. qiskit_aer/library/instructions_table.csv +21 -0
  29. qiskit_aer/library/save_instructions/__init__.py +44 -0
  30. qiskit_aer/library/save_instructions/save_amplitudes.py +168 -0
  31. qiskit_aer/library/save_instructions/save_clifford.py +63 -0
  32. qiskit_aer/library/save_instructions/save_data.py +129 -0
  33. qiskit_aer/library/save_instructions/save_density_matrix.py +91 -0
  34. qiskit_aer/library/save_instructions/save_expectation_value.py +257 -0
  35. qiskit_aer/library/save_instructions/save_matrix_product_state.py +71 -0
  36. qiskit_aer/library/save_instructions/save_probabilities.py +156 -0
  37. qiskit_aer/library/save_instructions/save_stabilizer.py +70 -0
  38. qiskit_aer/library/save_instructions/save_state.py +79 -0
  39. qiskit_aer/library/save_instructions/save_statevector.py +120 -0
  40. qiskit_aer/library/save_instructions/save_superop.py +62 -0
  41. qiskit_aer/library/save_instructions/save_unitary.py +63 -0
  42. qiskit_aer/library/set_instructions/__init__.py +19 -0
  43. qiskit_aer/library/set_instructions/set_density_matrix.py +78 -0
  44. qiskit_aer/library/set_instructions/set_matrix_product_state.py +83 -0
  45. qiskit_aer/library/set_instructions/set_stabilizer.py +77 -0
  46. qiskit_aer/library/set_instructions/set_statevector.py +78 -0
  47. qiskit_aer/library/set_instructions/set_superop.py +78 -0
  48. qiskit_aer/library/set_instructions/set_unitary.py +78 -0
  49. qiskit_aer/noise/__init__.py +265 -0
  50. qiskit_aer/noise/device/__init__.py +25 -0
  51. qiskit_aer/noise/device/models.py +397 -0
  52. qiskit_aer/noise/device/parameters.py +202 -0
  53. qiskit_aer/noise/errors/__init__.py +30 -0
  54. qiskit_aer/noise/errors/base_quantum_error.py +119 -0
  55. qiskit_aer/noise/errors/pauli_error.py +283 -0
  56. qiskit_aer/noise/errors/pauli_lindblad_error.py +363 -0
  57. qiskit_aer/noise/errors/quantum_error.py +451 -0
  58. qiskit_aer/noise/errors/readout_error.py +355 -0
  59. qiskit_aer/noise/errors/standard_errors.py +498 -0
  60. qiskit_aer/noise/noise_model.py +1231 -0
  61. qiskit_aer/noise/noiseerror.py +30 -0
  62. qiskit_aer/noise/passes/__init__.py +18 -0
  63. qiskit_aer/noise/passes/local_noise_pass.py +160 -0
  64. qiskit_aer/noise/passes/relaxation_noise_pass.py +137 -0
  65. qiskit_aer/primitives/__init__.py +44 -0
  66. qiskit_aer/primitives/estimator.py +751 -0
  67. qiskit_aer/primitives/estimator_v2.py +159 -0
  68. qiskit_aer/primitives/sampler.py +361 -0
  69. qiskit_aer/primitives/sampler_v2.py +256 -0
  70. qiskit_aer/quantum_info/__init__.py +32 -0
  71. qiskit_aer/quantum_info/states/__init__.py +16 -0
  72. qiskit_aer/quantum_info/states/aer_densitymatrix.py +313 -0
  73. qiskit_aer/quantum_info/states/aer_state.py +525 -0
  74. qiskit_aer/quantum_info/states/aer_statevector.py +302 -0
  75. qiskit_aer/utils/__init__.py +44 -0
  76. qiskit_aer/utils/noise_model_inserter.py +66 -0
  77. qiskit_aer/utils/noise_transformation.py +431 -0
  78. qiskit_aer/version.py +86 -0
  79. qiskit_aer-0.17.2.dist-info/METADATA +209 -0
  80. qiskit_aer-0.17.2.dist-info/RECORD +83 -0
  81. qiskit_aer-0.17.2.dist-info/WHEEL +5 -0
  82. qiskit_aer-0.17.2.dist-info/licenses/LICENSE.txt +203 -0
  83. qiskit_aer-0.17.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,302 @@
1
+ # This code is part of Qiskit.
2
+ #
3
+ # (C) Copyright IBM 2017, 2019, 2020, 2021, 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
+ """
14
+ Statevector quantum state class.
15
+ """
16
+ import copy
17
+ import numpy as np
18
+
19
+ from qiskit.circuit import QuantumCircuit, Instruction
20
+ from qiskit.quantum_info.states import Statevector
21
+
22
+ from qiskit_aer import AerSimulator
23
+ from .aer_state import AerState
24
+ from ...backends.aerbackend import AerError
25
+ from ...backends.backend_utils import BASIS_GATES
26
+
27
+
28
+ class AerStatevector(Statevector):
29
+ """AerStatevector class
30
+
31
+ This class inherits :class:`Statevector`, which stores probability amplitudes
32
+ in its `ndarray`. class:`AerStatevector` generates this `ndarray` by using the
33
+ same runtime with :class:`AerSimulator`.
34
+ """
35
+
36
+ def __init__(self, data, dims=None, **configs):
37
+ """
38
+ Args:
39
+ data (np.array or list or Statevector or AerStatevector or QuantumCircuit or
40
+ qiskit.circuit.Instruction):
41
+ Data from which the statevector can be constructed. This can be either a complex
42
+ vector, another statevector or a ``QuantumCircuit`` or ``Instruction``
43
+ (``Operator`` is not supported in the current implementation). If the data is
44
+ a circuit or instruction, the statevector is constructed by assuming that all
45
+ qubits are initialized to the zero state.
46
+ dims (int or tuple or list): Optional. The subsystem dimension of
47
+ the state (See additional information).
48
+ configs (kwargs): configurations of :class:`AerSimulator`. `method` configuration must
49
+ be `statevector` or `matrix_product_state`.
50
+
51
+ Raises:
52
+ AerError: if input data is not valid.
53
+
54
+ Additional Information:
55
+ The ``dims`` kwarg is used to ``Statevector`` constructor.
56
+
57
+ """
58
+ if "_aer_state" in configs:
59
+ self._aer_state = configs.pop("_aer_state")
60
+ else:
61
+ if "method" not in configs:
62
+ configs["method"] = "statevector"
63
+ elif configs["method"] not in ("statevector", "matrix_product_state"):
64
+ method = configs["method"]
65
+ raise AerError(f"Method {method} is not supported")
66
+ if isinstance(data, (QuantumCircuit, Instruction)):
67
+ data, aer_state = AerStatevector._from_instruction(data, None, configs)
68
+ elif isinstance(data, list):
69
+ data, aer_state = AerStatevector._from_ndarray(
70
+ np.array(data, dtype=complex), configs
71
+ )
72
+ elif isinstance(data, np.ndarray):
73
+ data, aer_state = AerStatevector._from_ndarray(data, configs)
74
+ elif isinstance(data, AerStatevector):
75
+ aer_state = data._aer_state
76
+ if dims is None:
77
+ dims = data._op_shape._dims_l
78
+ data = data._data.copy()
79
+ elif isinstance(data, Statevector):
80
+ data, aer_state = AerStatevector._from_ndarray(
81
+ np.array(data.data, dtype=complex), configs
82
+ )
83
+ else:
84
+ raise AerError(f"Input data is not supported: type={data.__class__}, data={data}")
85
+
86
+ self._aer_state = aer_state
87
+
88
+ super().__init__(data, dims=dims)
89
+
90
+ self._result = None
91
+ self._configs = configs
92
+
93
+ def seed(self, value=None):
94
+ """Set the seed for the quantum state RNG."""
95
+ if value is None or isinstance(value, int):
96
+ self._aer_state.set_seed(value)
97
+ else:
98
+ raise AerError(f"This seed is not supported: type={value.__class__}, value={value}")
99
+
100
+ def _last_result(self):
101
+ if self._result is None:
102
+ self._result = self._aer_state.last_result()
103
+ return self._result
104
+
105
+ def metadata(self):
106
+ """Return result metadata of an operation that executed lastly."""
107
+ if self._last_result() is None:
108
+ raise AerError("AerState was not used and metadata does not exist.")
109
+ return self._last_result()["metadata"]
110
+
111
+ def __copy__(self):
112
+ return copy.deepcopy(self)
113
+
114
+ def __deepcopy__(self, _memo=None):
115
+ ret = AerStatevector(self._data.copy(), **self._configs)
116
+ ret._op_shape = copy.deepcopy(self._op_shape)
117
+ ret._rng_generator = copy.deepcopy(self._rng_generator)
118
+ return ret
119
+
120
+ def conjugate(self):
121
+ return AerStatevector(np.conj(self._data), dims=self.dims())
122
+
123
+ def sample_memory(self, shots, qargs=None):
124
+ if qargs is None:
125
+ qubits = np.arange(self._aer_state.num_qubits)
126
+ else:
127
+ qubits = np.array(qargs)
128
+ self._aer_state.close()
129
+
130
+ self._aer_state.renew()
131
+ self._aer_state.initialize(self._data, copy=False)
132
+ samples = self._aer_state.sample_memory(qubits, shots)
133
+ self._data = self._aer_state.move_to_ndarray()
134
+ return samples
135
+
136
+ @staticmethod
137
+ def _from_ndarray(init_data, configs):
138
+ do_copy = True
139
+ if not init_data.flags["C_CONTIGUOUS"]:
140
+ init_data = np.ascontiguousarray(init_data)
141
+ do_copy = False
142
+
143
+ aer_state = AerState()
144
+
145
+ options = AerSimulator._default_options()
146
+ for config_key, config_value in configs.items():
147
+ if options.get(config_key):
148
+ aer_state.configure(config_key, config_value)
149
+
150
+ if len(init_data) == 0:
151
+ raise AerError("initial data must be larger than 0")
152
+
153
+ num_qubits = int(np.log2(len(init_data)))
154
+
155
+ aer_state.allocate_qubits(num_qubits)
156
+ aer_state.initialize(data=init_data, copy=do_copy)
157
+
158
+ return aer_state.move_to_ndarray(), aer_state
159
+
160
+ @classmethod
161
+ def from_instruction(cls, instruction):
162
+ return AerStatevector(instruction)
163
+
164
+ @staticmethod
165
+ def _from_instruction(inst, init_data, configs):
166
+ aer_state = AerState()
167
+
168
+ for config_key, config_value in configs.items():
169
+ aer_state.configure(config_key, config_value)
170
+
171
+ if "method" in configs:
172
+ method = configs["method"]
173
+ else:
174
+ method = "statevector"
175
+ aer_state.configure("method", method)
176
+
177
+ basis_gates = BASIS_GATES[method]
178
+ custom_insts = ["reset", "kraus", "barrier"]
179
+ if method == "statevector":
180
+ custom_insts.append("initialize")
181
+
182
+ aer_state.allocate_qubits(inst.num_qubits)
183
+ num_qubits = inst.num_qubits
184
+
185
+ if init_data is not None:
186
+ aer_state.initialize(data=init_data, copy=True)
187
+ else:
188
+ aer_state.initialize()
189
+
190
+ if isinstance(inst, QuantumCircuit) and inst.global_phase != 0:
191
+ aer_state.apply_global_phase(inst.global_phase)
192
+
193
+ if isinstance(inst, QuantumCircuit):
194
+ AerStatevector._aer_evolve_circuit(
195
+ aer_state, inst, range(num_qubits), basis_gates, custom_insts
196
+ )
197
+ else:
198
+ AerStatevector._aer_evolve_instruction(
199
+ aer_state, inst, range(num_qubits), basis_gates, custom_insts
200
+ )
201
+
202
+ return aer_state.move_to_ndarray(), aer_state
203
+
204
+ @staticmethod
205
+ def _aer_evolve_circuit(aer_state, circuit, qubits, basis_gates=None, custom_insts=None):
206
+ """Apply circuit into aer_state"""
207
+ for instruction in circuit.data:
208
+ if instruction.clbits:
209
+ raise AerError(
210
+ f"Cannot apply instruction with classical bits: {instruction.operation.name}"
211
+ )
212
+ inst = instruction.operation
213
+ qargs = instruction.qubits
214
+ AerStatevector._aer_evolve_instruction(
215
+ aer_state,
216
+ inst,
217
+ [qubits[circuit.find_bit(qarg).index] for qarg in qargs],
218
+ basis_gates,
219
+ custom_insts,
220
+ )
221
+
222
+ @staticmethod
223
+ def _aer_evolve_instruction(aer_state, inst, qubits, basis_gates=None, custom_insts=None):
224
+ """Apply instruction into aer_state"""
225
+
226
+ params = inst.params
227
+ applied = True
228
+
229
+ if basis_gates and inst.name in basis_gates:
230
+ if inst.name in ["u3", "u"]:
231
+ aer_state.apply_u(qubits[0], params[0], params[1], params[2])
232
+ elif inst.name == "h":
233
+ aer_state.apply_h(qubits[0])
234
+ elif inst.name == "x":
235
+ aer_state.apply_x(qubits[0])
236
+ elif inst.name == "cx":
237
+ aer_state.apply_cx(qubits[0], qubits[1])
238
+ elif inst.name == "y":
239
+ aer_state.apply_y(qubits[0])
240
+ elif inst.name == "cy":
241
+ aer_state.apply_cy(qubits[0], qubits[1])
242
+ elif inst.name == "z":
243
+ aer_state.apply_z(qubits[0])
244
+ elif inst.name == "cz":
245
+ aer_state.apply_cz(qubits[0], qubits[1])
246
+ elif inst.name == "unitary":
247
+ aer_state.apply_unitary(qubits, inst.params[0])
248
+ elif inst.name == "diagonal":
249
+ aer_state.apply_diagonal(qubits, inst.params)
250
+ elif inst.name == "cu":
251
+ aer_state.apply_cu(qubits[0], qubits[1], params[0], params[1], params[2], params[3])
252
+ elif inst.name == "mcu":
253
+ aer_state.apply_mcu(
254
+ qubits[0 : len(qubits) - 1],
255
+ qubits[len(qubits) - 1],
256
+ params[0],
257
+ params[1],
258
+ params[2],
259
+ params[3],
260
+ )
261
+ elif inst.name in "mcx":
262
+ aer_state.apply_mcx(qubits[0 : len(qubits) - 1], qubits[len(qubits) - 1])
263
+ elif inst.name in "mcy":
264
+ aer_state.apply_mcy(qubits[0 : len(qubits) - 1], qubits[len(qubits) - 1])
265
+ elif inst.name in "mcz":
266
+ aer_state.apply_mcz(qubits[0 : len(qubits) - 1], qubits[len(qubits) - 1])
267
+ elif inst.name == "id":
268
+ pass
269
+ else:
270
+ applied = False
271
+ elif custom_insts and inst.name in custom_insts:
272
+ if inst.name == "initialize":
273
+ aer_state.apply_initialize(qubits, inst.params)
274
+ elif inst.name == "reset":
275
+ aer_state.apply_reset(qubits)
276
+ elif inst.name == "kraus":
277
+ aer_state.apply_kraus(qubits, inst.params)
278
+ elif inst.name == "barrier":
279
+ pass
280
+ else:
281
+ applied = False
282
+ else:
283
+ applied = False
284
+
285
+ if not applied:
286
+ definition = inst.definition
287
+ if definition is inst or definition is None:
288
+ raise AerError("cannot decompose " + inst.name)
289
+ AerStatevector._aer_evolve_circuit(
290
+ aer_state, definition, qubits, basis_gates, custom_insts
291
+ )
292
+
293
+ @classmethod
294
+ def from_label(cls, label):
295
+ return AerStatevector(Statevector.from_label(label)._data)
296
+
297
+ @staticmethod
298
+ def from_int(i, dims):
299
+ size = np.prod(dims)
300
+ state = np.zeros(size, dtype=complex)
301
+ state[i] = 1.0
302
+ return AerStatevector(state, dims=dims)
@@ -0,0 +1,44 @@
1
+ # This code is part of Qiskit.
2
+ #
3
+ # (C) Copyright IBM 2018, 2019.
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
+ """
14
+ =============================================
15
+ Utilities (:mod:`qiskit_aer.utils`)
16
+ =============================================
17
+
18
+ .. currentmodule:: qiskit_aer.utils
19
+
20
+ This module contains utility functions for modifying
21
+ :class:`~qiskit_aer.noise.NoiseModel` objects and ``QuantumCircuits``
22
+ using noise models.
23
+
24
+
25
+ Functions
26
+ =========
27
+
28
+ .. autosummary::
29
+ :toctree: ../stubs/
30
+
31
+ insert_noise
32
+ approximate_quantum_error
33
+ approximate_noise_model
34
+ transform_noise_model
35
+ transpile_noise_model
36
+ transpile_quantum_error
37
+ """
38
+
39
+ from .noise_model_inserter import insert_noise
40
+ from .noise_transformation import approximate_noise_model
41
+ from .noise_transformation import approximate_quantum_error
42
+ from .noise_transformation import transform_noise_model
43
+ from .noise_transformation import transpile_noise_model
44
+ from .noise_transformation import transpile_quantum_error
@@ -0,0 +1,66 @@
1
+ # This code is part of Qiskit.
2
+ #
3
+ # (C) Copyright IBM 2019.
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
+ Noise model inserter module
14
+ The goal of this module is to add QuantumError gates (Kraus gates) to a circuit
15
+ based on a given noise model.
16
+ """
17
+ import qiskit.compiler
18
+
19
+
20
+ def insert_noise(circuits, noise_model, transpile=False):
21
+ """Return a noisy version of a QuantumCircuit.
22
+
23
+ Args:
24
+ circuits (QuantumCircuit or list[QuantumCircuit]): Input noise-free circuits.
25
+ noise_model (NoiseModel): The noise model containing the errors to add
26
+ transpile (Boolean): Should the circuit be transpiled into the noise model basis gates
27
+
28
+ Returns:
29
+ QuantumCircuit: The new circuit with the Kraus noise instructions inserted.
30
+
31
+ Additional Information:
32
+ The noisy circuit return by this function will consist of the
33
+ original circuit with ``Kraus`` instructions inserted after all
34
+ instructions referenced in the ``noise_model``. The resulting circuit
35
+ cannot be ran on a quantum computer but can be executed on the
36
+ :class:`~qiskit_aer.QasmSimulator`.
37
+ """
38
+ is_circuits_list = isinstance(circuits, (list, tuple))
39
+ circuits = circuits if is_circuits_list else [circuits]
40
+ result_circuits = []
41
+ local_errors = noise_model._local_quantum_errors
42
+ default_errors = noise_model._default_quantum_errors
43
+ for circuit in circuits:
44
+ if transpile:
45
+ transpiled_circuit = qiskit.compiler.transpile(
46
+ circuit, basis_gates=noise_model.basis_gates
47
+ )
48
+ else:
49
+ transpiled_circuit = circuit
50
+ qubit_indices = {bit: index for index, bit in enumerate(transpiled_circuit.qubits)}
51
+ result_circuit = transpiled_circuit.copy(name=transpiled_circuit.name + "_with_noise")
52
+ result_circuit.data = []
53
+ for inst in transpiled_circuit.data:
54
+ result_circuit.data.append(inst)
55
+ qubits = tuple(qubit_indices[q] for q in inst.qubits)
56
+ # Priority for error model used:
57
+ # local error > default error
58
+ name = inst.operation.name
59
+ if name in local_errors and qubits in local_errors[name]:
60
+ error = local_errors[name][qubits]
61
+ result_circuit.append(error.to_instruction(), inst.qubits)
62
+ elif name in default_errors.keys():
63
+ error = default_errors[name]
64
+ result_circuit.append(error.to_instruction(), inst.qubits)
65
+ result_circuits.append(result_circuit)
66
+ return result_circuits if is_circuits_list else result_circuits[0]