Zum Hauptinhalt springen

Effiziente Simulation von Stabilizer-Circuits mit Qiskit Aer Primitives

Paketversionen

Der Code auf dieser Seite wurde mit den folgenden Anforderungen entwickelt. Wir empfehlen, diese oder neuere Versionen zu verwenden.

qiskit[all]~=2.3.0
qiskit-aer~=0.17

Diese Seite zeigt, wie du Qiskit Aer Primitives verwendest, um Stabilizer-Circuits effizient zu simulieren, einschließlich solcher, die Pauli-Rauschen unterliegen.

Stabilizer-Circuits, auch bekannt als Clifford-Circuits, sind eine wichtige eingeschränkte Klasse von Quanten-Circuits, die klassisch effizient simuliert werden können. Es gibt mehrere äquivalente Möglichkeiten, Stabilizer-Circuits zu definieren. Eine Definition besagt, dass ein Stabilizer-Circuit ein Quanten-Circuit ist, der ausschließlich aus den folgenden Gates besteht:

Beachte, dass wir mithilfe von Hadamard und S beliebige Pauli-Rotations-Gates (RxR_x, RyR_y und RzR_z) konstruieren können, deren Winkel in der Menge {0,π2,π,3π2}\{0, \frac{\pi}{2}, \pi, \frac{3\pi}{2}\} enthalten sind (bis auf eine globale Phase) – diese Gates können wir daher ebenfalls in die Definition aufnehmen.

Stabilizer-Circuits sind für die Erforschung der Quantenfehlerkorrektur von großer Bedeutung. Ihre klassische Simulierbarkeit macht sie auch zur Überprüfung der Ausgabe von Quantencomputern nützlich. Angenommen, du möchtest einen Quanten-Circuit mit 100 Qubits auf einem Quantencomputer ausführen. Wie kannst du sicherstellen, dass der Quantencomputer korrekt arbeitet? Ein Quanten-Circuit mit 100 Qubits übersteigt die Möglichkeiten der rohen klassischen Simulation. Indem du deinen Circuit so anpasst, dass er ein Stabilizer-Circuit wird, kannst du Circuits auf dem Quantencomputer ausführen, die eine ähnliche Struktur wie dein gewünschter Circuit haben, die du aber auf einem klassischen Computer simulieren kannst. Indem du die Ausgabe des Quantencomputers auf den Stabilizer-Circuits überprüfst, kannst du Vertrauen gewinnen, dass er auch auf den Nicht-Stabilizer-Circuits korrekt funktioniert. Siehe Evidence for the utility of quantum computing before fault tolerance für ein praktisches Beispiel dieser Idee.

Exakte und verrauschte Simulation mit Qiskit Aer Primitives zeigt, wie du Qiskit Aer verwendest, um exakte und verrauschte Simulationen generischer Quanten-Circuits durchzuführen. Betrachte den in diesem Artikel verwendeten Beispiel-Circuit: einen 8-Qubit-Circuit, der mit efficient_su2 erstellt wurde:

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-aer
from qiskit.circuit.library import efficient_su2

n_qubits = 8
circuit = efficient_su2(n_qubits)
circuit.draw("mpl")

Output of the previous code cell

Mit Qiskit Aer konnten wir diesen Circuit problemlos simulieren. Angenommen, wir setzen die Anzahl der Qubits auf 500:

n_qubits = 500
circuit = efficient_su2(n_qubits)
# don't try to draw the circuit because it's too large

Da die Kosten der Simulation von Quanten-Circuits exponentiell mit der Anzahl der Qubits skalieren, würde ein so großer Circuit selbst die Möglichkeiten eines leistungsstarken Simulators wie Qiskit Aer in der Regel überschreiten. Die klassische Simulation generischer Quanten-Circuits wird unrealistisch, sobald die Anzahl der Qubits etwa 50 bis 100 übersteigt. Beachte jedoch, dass der efficient_su2-Circuit durch Winkel auf RyR_y- und RzR_z-Gates parametrisiert ist. Wenn alle diese Winkel in der Menge {0,π2,π,3π2}\{0, \frac{\pi}{2}, \pi, \frac{3\pi}{2}\} enthalten sind, ist der Circuit ein Stabilizer-Circuit und kann effizient simuliert werden!

In der folgenden Zelle führen wir den Circuit mit dem Sampler Primitive aus, das vom Stabilizer-Circuit-Simulator unterstützt wird. Die Parameter werden dabei zufällig so gewählt, dass der Circuit garantiert ein Stabilizer-Circuit ist.

import numpy as np
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_aer import AerSimulator
from qiskit_aer.primitives import SamplerV2 as Sampler

measured_circuit = circuit.copy()
measured_circuit.measure_all()

rng = np.random.default_rng(1234)
params = rng.choice(
[0, np.pi / 2, np.pi, 3 * np.pi / 2],
size=circuit.num_parameters,
)

# Initialize a Sampler backed by the stabilizer circuit simulator
exact_sampler = Sampler(
options=dict(backend_options=dict(method="stabilizer"))
)
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(
1, AerSimulator(method="stabilizer")
)
isa_circuit = pass_manager.run(measured_circuit)
pub = (isa_circuit, params)
job = exact_sampler.run([pub])
result = job.result()
pub_result = result[0]
counts = pub_result.data.meas.get_counts()

Der Stabilizer-Circuit-Simulator unterstützt auch verrauschte Simulationen, jedoch nur für eine eingeschränkte Klasse von Rauschmodellen. Konkret muss jedes Quantenrauschen durch einen Pauli-Fehler-Kanal charakterisiert sein. Depolarisierungsfehler fallen in diese Kategorie und können daher ebenfalls simuliert werden. Klassische Rauschkanäle wie Auslesefehler können ebenfalls simuliert werden.

Die folgende Code-Zelle führt dieselbe Simulation wie zuvor durch, gibt diesmal jedoch ein Rauschmodell an, das jedem CX-Gate einen Depolarisierungsfehler von 2 % hinzufügt sowie einen Auslesefehler, der jedes gemessene Bit mit einer Wahrscheinlichkeit von 5 % umkehrt.

from qiskit_aer.noise import NoiseModel, depolarizing_error, ReadoutError

noise_model = NoiseModel()
cx_depolarizing_prob = 0.02
bit_flip_prob = 0.05
noise_model.add_all_qubit_quantum_error(
depolarizing_error(cx_depolarizing_prob, 2), ["cx"]
)
noise_model.add_all_qubit_readout_error(
ReadoutError(
[
[1 - bit_flip_prob, bit_flip_prob],
[bit_flip_prob, 1 - bit_flip_prob],
]
)
)

noisy_sampler = Sampler(
options=dict(
backend_options=dict(method="stabilizer", noise_model=noise_model)
)
)
job = noisy_sampler.run([pub])
result = job.result()
pub_result = result[0]
counts = pub_result.data.meas.get_counts()

Nun verwenden wir das Estimator Primitive, das vom Stabilizer-Simulator unterstützt wird, um den Erwartungswert des Observablen ZZZZZ \cdots Z zu berechnen. Aufgrund der besonderen Struktur von Stabilizer-Circuits ist das Ergebnis sehr wahrscheinlich 0.

from qiskit.quantum_info import SparsePauliOp
from qiskit_aer.primitives import EstimatorV2 as Estimator

observable = SparsePauliOp("Z" * n_qubits)

exact_estimator = Estimator(
options=dict(backend_options=dict(method="stabilizer")),
)
isa_circuit = pass_manager.run(circuit)
pub = (isa_circuit, observable, params)
job = exact_estimator.run([pub])
result = job.result()
pub_result = result[0]
exact_value = float(pub_result.data.evs)
exact_value
0.0

Nächste Schritte

Empfehlungen