Skip to main content
IBM Quantum Platform

Exakte und verrauschte Simulation mit Qiskit Aer-Primitiven

  • Der Code auf dieser Seite wurde unter Berücksichtigung der folgenden Anforderungen entwickelt. Wir empfehlen die Verwendung dieser oder neuerer Versionen.

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

Die exakte Simulation mit den „ Qiskit SDK “-Primitiven veranschaulicht, wie man die in Qiskit enthaltenen Referenzprimitive nutzt, um eine exakte Simulation von Quantenschaltungen durchzuführen. Derzeitige Quantenprozessoren sind anfällig für Fehler bzw. Rauschen, sodass die Ergebnisse einer exakten Simulation nicht unbedingt den Ergebnissen entsprechen, die man erwarten würde, wenn man Schaltkreise auf echter Hardware ausführen würde. Während die Referenzprimitive in Qiskit keine Rauschmodellierung unterstützen, enthält Qiskit Aer Implementierungen der Primitive, die eine Rauschmodellierung unterstützen. Qiskit Aer ist ein leistungsstarker Quantenkreis-Simulator, den Sie anstelle der Referenzprimitive verwenden können, um eine bessere Leistung und mehr Funktionen zu erzielen. Es ist Teil des Qiskit-Ökosystems. In diesem Artikel veranschaulichen wir die Verwendung von Qiskit Aer-Primitiven für exakte und verrauschte Simulationen.

Hinweise
  • qiskit-aer v0.14 oder später ist erforderlich.
  • Die Qiskit-Aer-Primitiven implementieren zwar die Primitivschnittstellen, bieten jedoch nicht dieselben Optionen wie die Primitive von „ IBM Quantum “. Die Resilienzstufe ist beispielsweise bei den Qiskit Aer-Primitiven nicht verfügbar.
  • Einzelheiten zu den von Aer unterstützten Simulationsmethoden finden Sie in der Dokumentation AerSimulator.

Um die genaue und verrauschte Simulation zu erkunden, erstellen Sie eine Beispielschaltung mit acht Qubits:

from qiskit.circuit.library import efficient_su2

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

Output:

Output of the previous code cell

Diese Schaltung enthält Parameter zur Darstellung der Drehwinkel für die Gatter RyR_y und RzR_z. Bei der Simulation dieser Schaltung müssen wir explizite Werte für diese Parameter angeben. In der nächsten Zelle geben wir einige Werte für diese Parameter an und verwenden das Estimator-Primitiv von Qiskit Aer, um den genauen Erwartungswert der beobachtbaren ZZ⋯ZZZ \cdots Z zu berechnen.

from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_aer import AerSimulator
from qiskit_aer.primitives import EstimatorV2 as Estimator

observable = SparsePauliOp("Z" * n_qubits)
params = [0.1] * circuit.num_parameters

exact_estimator = Estimator()
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(3, AerSimulator())
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

Output:

0.8870140234256602

Initialisieren wir nun ein Rauschmodell, das bei jedem CX-Gate einen Depolarisationsfehler von 2 % berücksichtigt. In der Praxis sind die Fehler, die durch die Zwei-Qubit-Gatter – in diesem Fall CX-Gatter – verursacht werden, die Hauptfehlerquelle bei der Ausführung einer Schaltung. Einen Überblick über die Erstellung von Lärmmodellen in Qiskit Aer finden Sie unter „Lärmmodelle erstellen “.

In der nächsten Zelle konstruieren wir einen Schätzer, der dieses Rauschmodell einbezieht, und verwenden ihn zur Berechnung des Erwartungswerts der Beobachtungsgröße.

from qiskit_aer.noise import NoiseModel, depolarizing_error

noise_model = NoiseModel()
cx_depolarizing_prob = 0.02
noise_model.add_all_qubit_quantum_error(
    depolarizing_error(cx_depolarizing_prob, 2), ["cx"]
)

noisy_estimator = Estimator(
    options=dict(backend_options=dict(noise_model=noise_model))
)
job = noisy_estimator.run([pub])
result = job.result()
pub_result = result[0]
noisy_value = float(pub_result.data.evs)
noisy_value

Output:

0.7247404214143529

Wie Sie sehen können, ist der Erwartungswert bei Vorhandensein von Rauschen ziemlich weit vom richtigen Wert entfernt. In der Praxis können Sie eine Vielzahl von Fehlerminderungstechniken einsetzen, um den Auswirkungen des Rauschens entgegenzuwirken, aber eine Diskussion dieser Techniken würde den Rahmen dieses Artikels sprengen.

Um ein grobes Gefühl dafür zu bekommen, wie sich das Rauschen auf das Endergebnis auswirkt, betrachten wir unser Rauschmodell, das jedem CX-Gate einen depolarisierenden Fehler von 2 % hinzufügt. Der depolarisierende Fehler mit der Wahrscheinlichkeit pp ist definiert als ein Quantenkanal EE, der die folgende Wirkung auf eine Dichtematrix ρ\rho hat:

E(ρ)=(1−p)ρ+pI2nE(\rho) = (1 - p) \rho + p\frac{I}{2^n}

wobei nn die Anzahl der Qubits, in diesem Fall 2, ist. Das heißt, mit der Wahrscheinlichkeit pp wird der Zustand durch den vollständig gemischten Zustand ersetzt, und mit der Wahrscheinlichkeit 1−p1 - p wird der Zustand erhalten. Nach mm Anwendungen des depolarisierenden Kanals wäre die Wahrscheinlichkeit, dass der Zustand erhalten bleibt, (1−p)m(1 - p)^m. Daher erwarten wir, dass die Wahrscheinlichkeit, den korrekten Zustand am Ende der Simulation beizubehalten, exponentiell mit der Anzahl der CX-Gatter in unserer Schaltung abnimmt.

Zählen wir die Anzahl der CX-Gatter in unserer Schaltung und berechnen wir (1−p)m(1 - p)^m. Wir rufen count_ops auf, um ein Wörterbuch zu erhalten, das Gatternamen auf Zählungen abbildet, und rufen den Eintrag für das CX-Gatter ab.

cx_count = circuit.count_ops()["cx"]
(1 - cx_depolarizing_prob) ** cx_count

Output:

0.6542558123199923

Dieser Wert, 65 %, gibt eine grobe Schätzung der Wahrscheinlichkeit, dass unser Endzustand korrekt ist. Es handelt sich um eine konservative Schätzung, da der Anfangszustand der Simulation nicht berücksichtigt wird.

Die folgende Codezelle zeigt, wie das Sampler-Primitiv von Qiskit Aer verwendet wird, um den verrauschten Schaltkreis abzutasten. Wir müssen der Schaltung Messungen hinzufügen, bevor wir sie mit dem Sampler-Primitiv ausführen.

from qiskit_aer.primitives import SamplerV2 as Sampler

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

noisy_sampler = Sampler(
    options=dict(backend_options=dict(noise_model=noise_model))
)
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(3, AerSimulator())
isa_circuit = pass_manager.run(measured_circuit)
pub = (isa_circuit, params, 100)
job = noisy_sampler.run([pub])
result = job.result()
pub_result = result[0]
pub_result.data.meas.get_counts()

Output:

{'00000000': 69,
 '00100000': 2,
 '00000110': 1,
 '11000000': 2,
 '00010100': 1,
 '01100000': 2,
 '01010000': 3,
 '00101000': 1,
 '10100000': 2,
 '01100101': 1,
 '00001010': 1,
 '10000000': 2,
 '00000010': 3,
 '01000000': 4,
 '11100000': 1,
 '10000101': 1,
 '00110000': 1,
 '00001100': 1,
 '00011000': 2}

Nächste Schritte

Empfehlungen
War diese Seite hilfreich?
Melden Sie auf GitHub einen Fehler, einen Tippfehler oder fordern Sie Inhalte an.