Quantenbits, Gates und Schaltkreise
Kifumi Numata (19 Apr 2024)
Klicke hier, um das PDF der Originalvorlesung herunterzuladen. Beachte, dass einige Code-Snippets veraltet sein könnten, da es sich um statische Bilder handelt.
Ungefähre QPU-Zeit für dieses Experiment: 5 Sekunden.
1. Einführung
Bits, Gates und Schaltkreise sind die grundlegenden Bausteine des Quantencomputings. Du wirst Quantenberechnung mit dem Schaltkreismodell unter Verwendung von Quantenbits und Gates erlernen und außerdem Superposition, Messung und Verschränkung wiederholen.
In dieser Lektion lernst du:
- Einzelne Qubit-Gates
- Bloch-Kugel
- Superposition
- Messung
- Zwei-Qubit-Gates und verschränkte Zustände
Am Ende dieser Vorlesung wirst du etwas über die Schaltkreistiefe lernen, die für Quantencomputing im Utility-Scale-Bereich entscheidend ist.
2. Berechnung als Diagramm
Wenn wir Qubits oder Bits verwenden, müssen wir sie manipulieren, um die vorhandenen Eingaben in die benötigten Ausgaben umzuwandeln. Für die einfachsten Programme mit sehr wenigen Bits ist es nützlich, diesen Prozess in einem Diagramm darzustellen, das als Schaltkreisdiagramm bekannt ist.
Die Abbildung unten links zeigt ein Beispiel eines klassischen Schaltkreises, und die Abbildung unten rechts zeigt ein Beispiel eines Quantenschaltkreises. In beiden Fällen befinden sich die Eingaben links und die Ausgaben rechts, während die Operationen durch Symbole dargestellt werden. Die für die Operationen verwendeten Symbole werden hauptsächlich aus historischen Gründen als „Gates" bezeichnet.
3. Einzelnes Qubit-Gate
3.1 Quantenzustand und Bloch-Kugel
Der Zustand eines Qubits wird als Superposition von und dargestellt. Ein beliebiger Quantenzustand wird geschrieben als
wobei und komplexe Zahlen sind, sodass .
und sind Vektoren im zweidimensionalen komplexen Vektorraum:
Daher wird ein beliebiger Quantenzustand auch dargestellt als
Daraus können wir erkennen, dass der Zustand eines Quantenbits ein Einheitsvektor in einem zweidimensionalen komplexen Innenproduktraum mit einer orthonormalen Basis aus und ist. Er ist auf 1 normiert.
|\psi\rangle =\begin\{pmatrix\} \alpha \\ \beta \end\{pmatrix\} wird auch als Zustandsvektor (Statevector) bezeichnet.
Ein einzelner Qubit-Quantenzustand wird auch dargestellt als
wobei und die Winkel der Bloch-Kugel in der folgenden Abbildung sind.
In den nächsten Code-Zellen werden wir grundlegende Berechnungen aus den Bestandteilen in Qiskit aufbauen. Wir konstruieren einen leeren Schaltkreis und fügen dann Quantenoperationen hinzu, wobei wir die Gates besprechen und ihre Auswirkungen visualisieren.
Du kannst die Zelle mit „Shift" + „Enter" ausführen. Importiere zuerst die Bibliotheken.
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-aer qiskit-ibm-runtime
# Import the qiskit library
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
from qiskit.quantum_info import Statevector
from qiskit.visualization import plot_bloch_multivector
from qiskit_ibm_runtime import Sampler
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.visualization import plot_histogram
Vorbereitung des Quantenschaltkreises
Wir erstellen und zeichnen einen Einzelqubit-Schaltkreis.
# Create the single-qubit quantum circuit
qc = QuantumCircuit(1)
# Draw the circuit
qc.draw("mpl")
X-Gate
Das X-Gate ist eine -Rotation um die -Achse der Bloch-Kugel. Die Anwendung des X-Gates auf ergibt , und die Anwendung des X-Gates auf ergibt , sodass es eine Operation ähnlich dem klassischen NOT-Gate ist und auch als Bit-Flip bekannt ist. Die Matrixdarstellung des X-Gates ist unten gezeigt.
qc = QuantumCircuit(1) # Prepare the single-qubit quantum circuit
# Apply a X gate to qubit 0
qc.x(0)
# Draw the circuit
qc.draw("mpl")
Bei IBM Quantum® ist der Anfangszustand auf gesetzt, sodass der obige Quantenschaltkreis in Matrixdarstellung lautet
Als Nächstes führen wir diesen Schaltkreis mit einem Zustandsvektor-Simulator aus.
# See the statevector
out_vector = Statevector(qc)
print(out_vector)
# Draw a Bloch sphere
plot_bloch_multivector(out_vector)
Statevector([0.+0.j, 1.+0.j],
dims=(2,))
Der vertikale Vektor wird als Zeilenvektor angezeigt, mit komplexen Zahlen (der Imaginärteil wird durch indiziert).
H-Gate
Das Hadamard-Gate ist eine -Rotation um eine Achse auf halbem Weg zwischen der - und -Achse auf der Bloch-Kugel. Die Anwendung des H-Gates auf erzeugt einen Superpositionszustand wie . Die Matrixdarstellung des H-Gates ist unten gezeigt.
qc = QuantumCircuit(1) # Create the single-qubit quantum circuit
# Apply an Hadamard gate to qubit 0
qc.h(0)
# Draw the circuit
qc.draw(output="mpl")
# See the statevector
out_vector = Statevector(qc)
print(out_vector)
# Draw a Bloch sphere
plot_bloch_multivector(out_vector)
Statevector([0.70710678+0.j, 0.70710678+0.j],
dims=(2,))
Das ist
Dieser Superpositionszustand ist so häufig und wichtig, dass er sein eigenes Symbol hat:
Durch Anwendung des -Gates auf den haben wir eine Superposition aus und erzeugt, bei der eine Messung in der Rechenbasis (entlang z im Bloch-Kugel-Bild) jeden Zustand mit gleicher Wahrscheinlichkeit ergibt.
-Zustand
Du hast vielleicht vermutet, dass es einen entsprechenden -Zustand gibt:
Um diesen Zustand zu erzeugen, wende zuerst ein X-Gate an, um zu erhalten, und dann ein H-Gate.
qc = QuantumCircuit(1) # Create the single-qubit quantum circuit
# Apply a X gate to qubit 0
qc.x(0)
# Apply an Hadamard gate to qubit 0
qc.h(0)
# draw the circuit
qc.draw(output="mpl")
# See the statevector
out_vector = Statevector(qc)
print(out_vector)
# Draw a Bloch sphere
plot_bloch_multivector(out_vector)
Statevector([ 0.70710678+0.j, -0.70710678+0.j],
dims=(2,))
Das ist
Die Anwendung des -Gates auf ergibt eine gleichmäßige Superposition aus und , aber das Vorzeichen von ist negativ.
3.2 Einzelner Qubit-Quantenzustand und unitäre Evolution
Die Wirkungen aller Gates, die wir bisher gesehen haben, waren unitär, was bedeutet, dass sie durch einen unitären Operator dargestellt werden können. Mit anderen Worten, der Ausgabezustand kann durch Anwendung einer unitären Matrix auf den Anfangszustand erhalten werden:
Eine unitäre Matrix ist eine Matrix, die folgende Bedingung erfüllt
In Bezug auf den Betrieb von Quantencomputern würden wir sagen, dass die Anwendung eines Quanten-Gates auf das Qubit den Quantenzustand entwickelt. Häufige Einzelqubit-Gates umfassen die folgenden.
Pauli-Gates:
wobei das äußere Produkt wie folgt berechnet wurde:
Weitere typische Einzelqubit-Gates:
Die Bedeutung und Verwendung dieser Gates wird im Kurs Grundlagen der Quanteninformation detaillierter beschrieben.
Übung 1
Verwende Qiskit, um Quantenschaltkreise zu erstellen, die die unten beschriebenen Zustände vorbereiten. Führe dann jeden Schaltkreis mit dem Zustandsvektor-Simulator aus und zeige den resultierenden Zustand auf der Bloch-Kugel an. Als Bonus: Versuche vorherzusagen, was der Endzustand basierend auf der Intuition über die Gates und Rotationen in der Bloch-Kugel sein sollte.
(1)
(2)
(3)
Tipps: Das Z-Gate kann wie folgt verwendet werden
qc.z(0)
Lösung:
### (1) XX|0> ###
# Create the single-qubit quantum circuit
qc = QuantumCircuit(1) ##your code goes here##
# Add a X gate to qubit 0
qc.x(0) ##your code goes here##
# Add a X gate to qubit 0
qc.x(0) ##your code goes here##
# Draw a circuit
qc.draw(output="mpl")
# See the statevector
out_vector = Statevector(qc)
print(out_vector)
# Draw a Bloch sphere
plot_bloch_multivector(out_vector)
Statevector([1.+0.j, 0.+0.j],
dims=(2,))
### (2) HH|0> ###
##your code goes here##
qc = QuantumCircuit(1)
qc.h(0)
qc.h(0)
qc.draw("mpl")
# See the statevector
out_vector = Statevector(qc)
print(out_vector)
# Draw a Bloch sphere
plot_bloch_multivector(out_vector)
Statevector([1.+0.j, 0.+0.j],
dims=(2,))
### (3) HZH|0> ###
##your code goes here##
qc = QuantumCircuit(1)
qc.h(0)
qc.z(0)
qc.h(0)
qc.draw("mpl")
# See the statevector
out_vector = Statevector(qc)
print(out_vector)
# Draw a Bloch sphere
plot_bloch_multivector(out_vector)
Statevector([0.+0.j, 1.+0.j],
dims=(2,))
3.3 Messung
Messung ist theoretisch ein sehr kompliziertes Thema. Aber in praktischer Hinsicht zwingt eine Messung entlang (wie es alle IBM®-Quantencomputer tun) den Zustand des Qubits einfach in oder und wir beobachten das Ergebnis.
- ist die Wahrscheinlichkeit, dass wir erhalten, wenn wir messen.
- ist die Wahrscheinlichkeit, dass wir erhalten, wenn wir messen.
Also werden und als Wahrscheinlichkeitsamplituden bezeichnet. (siehe „Born-Regel")
Zum Beispiel hat eine gleiche Wahrscheinlichkeit, bei der Messung zu oder zu werden. hat eine 75%ige Chance, zu zu werden.
Qiskit Aer Simulator
Als Nächstes messen wir einen Schaltkreis, der die obige Superposition mit gleicher Wahrscheinlichkeit vorbereitet. Wir sollten die Mess-Gates hinzufügen, da der Qiskit Aer Simulator standardmäßig eine ideale (rauschfreie) Quantenhardware simuliert. Hinweis: Der Aer Simulator kann auch ein Rauschmodell basierend auf einem echten Quantencomputer anwenden. Wir werden später auf Rauschmodelle zurückkommen.
# Create a new circuit with one qubits (first argument) and one classical bits (second argument)
qc = QuantumCircuit(1, 1)
qc.h(0)
qc.measure(0, 0) # Add the measurement gate
qc.draw(output="mpl")
Wir sind nun bereit, unseren Schaltkreis auf dem Aer Simulator auszuführen. In diesem Beispiel verwenden wir die Standardeinstellung shots=1024, was bedeutet, dass wir 1024 Mal messen. Dann stellen wir diese Zähler in einem Histogramm dar.
# Run the circuit on a simulator to get the results
# Define backend
backend = AerSimulator()
# Transpile to backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)
# Run the job
sampler = Sampler(mode=backend)
job = sampler.run([isa_qc])
result = job.result()
# Print the results
counts = result[0].data.c.get_counts()
print(counts)
# Plot the counts in a histogram
plot_histogram(counts)
{'0': 521, '1': 503}
Wir sehen, dass 0en und 1en jeweils mit einer Wahrscheinlichkeit von fast 50% gemessen wurden. Obwohl hier kein Rauschen simuliert wurde, sind die Zustände dennoch probabilistisch. Obwohl wir ungefähr eine 50-50-Verteilung erwarten, werden wir diese selten genau finden. Genauso wie 100 Münzwürfe selten genau 50 Instanzen jeder Seite ergeben würden.
4. Multi-Qubit-Gate und Verschränkung
4.1 Multi-Qubit-Quantenschaltkreis
Wir können einen Zwei-Qubit-Quantenschaltkreis mit folgendem Code erstellen. Wir werden ein H-Gate auf jedes Qubit anwenden.
# Create the two qubits quantum circuit
qc = QuantumCircuit(2)
# Apply an H gate to qubit 0
qc.h(0)
# Apply an H gate to qubit 1
qc.h(1)
# Draw the circuit
qc.draw(output="mpl")
# See the statevector
out_vector = Statevector(qc)
print(out_vector)
Statevector([0.5+0.j, 0.5+0.j, 0.5+0.j, 0.5+0.j],
dims=(2, 2))
Hinweis: Qiskit-Bit-Reihenfolge
Qiskit verwendet die Little-Endian-Notation bei der Anordnung von Qubits und Bits, was bedeutet, dass Qubit 0 das rechteste Bit in den Bitstrings ist. Beispiel: bedeutet q0 ist und q1 ist . Sei vorsichtig, denn einige Literatur im Quantencomputing verwendet die Big-Endian-Notation (Qubit 0 ist das linkeste Bit), und ein großer Teil der Quantenmechanik-Literatur ebenfalls.
Außerdem ist zu beachten, dass bei der Darstellung eines Quantenschaltkreises immer oben im Schaltkreis platziert wird. Mit diesem Wissen kann der Quantenzustand des obigen Schaltkreises als Tensorprodukt einzelner Qubit-Quantenzustände geschrieben werden.
( )
Der Anfangszustand von Qiskit ist , sodass er sich durch Anwendung von auf jedes Qubit in einen Zustand gleichmäßiger Superposition ändert.
Die Messregel ist dieselbe wie im Einzelqubit-Fall: Die Wahrscheinlichkeit, zu messen, beträgt .
# Draw a Bloch sphere
plot_bloch_multivector(out_vector)

Als Nächstes messen wir diesen Schaltkreis.
# Create a new circuit with two qubits (first argument) and two classical bits (second argument)
qc = QuantumCircuit(2, 2)
# Apply the gates
qc.h(0)
qc.h(1)
# Add the measurement gates
qc.measure(0, 0) # Measure qubit 0 and save the result in bit 0
qc.measure(1, 1) # Measure qubit 1 and save the result in bit 1
# Draw the circuit
qc.draw(output="mpl")
Nun werden wir erneut den Aer Simulator verwenden, um experimentell zu überprüfen, dass die relativen Wahrscheinlichkeiten aller möglichen Ausgabezustände ungefähr gleich sind.
# Run the circuit on a simulator to get the results
# Define backend
backend = AerSimulator()
# Transpile to backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)
# Run the job
sampler = Sampler(mode=backend)
job = sampler.run([isa_qc])
result = job.result()
# Print the results
counts = result[0].data.c.get_counts()
print(counts)
# Plot the counts in a histogram
plot_histogram(counts)
{'10': 262, '01': 246, '00': 265, '11': 251}
Wie erwartet wurden die Zustände , , , jeweils mit fast 25% gemessen.
4.2 Multi-Qubit-Gates
CNOT-Gate
Ein CNOT-Gate („controlled NOT" oder CX) ist ein Zwei-Qubit-Gate, dessen Aktion zwei Qubits gleichzeitig einbezieht: das Steuerqubit und das Zielqubit. Ein CNOT kippt das Zielqubit nur dann, wenn das Steuerqubit ist.
| Eingabe (Ziel,Steuer) | Ausgabe (Ziel,Steuer) |
|---|---|
| 00 | 00 |
| 01 | 11 |
| 10 | 10 |
| 11 | 01 |
Simulieren wir zunächst die Wirkung dieses Zwei-Qubit-Gates, wenn q0 und q1 beide sind, und erhalten den Ausgabe-Zustandsvektor. Die verwendete Qiskit-Syntax lautet qc.cx(control qubit, target qubit).
# Create a circuit with two quantum registers and two classical registers
qc = QuantumCircuit(2, 2)
# Apply the CNOT (cx) gate to a |00> state.
qc.cx(0, 1) # Here the control is set to q0 and the target is set to q1.
# Draw the circuit
qc.draw(output="mpl")
# See the statevector
out_vector = Statevector(qc)
print(out_vector)
Statevector([1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
dims=(2, 2))
Wie erwartet hat die Anwendung eines CNOT-Gates auf den Zustand nicht verändert, da das Steuerqubit im -Zustand war. Kehren wir zu unserer CNOT-Operation zurück. Diesmal wenden wir ein CNOT-Gate auf an und sehen, was passiert.
qc = QuantumCircuit(2, 2)
# q0=1, q1=0
qc.x(0) # Apply a X gate to initialize q0 to 1
qc.cx(0, 1) # Set the control bit to q0 and the target bit to q1.
# Draw the circuit
qc.draw(output="mpl")
# See the statevector
out_vector = Statevector(qc)
print(out_vector)
Statevector([0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
dims=(2, 2))
Durch die Anwendung eines CNOT-Gates ist der -Zustand nun zu geworden.
Verifizieren wir diese Ergebnisse, indem wir den Schaltkreis auf einem Simulator ausführen.
# Add measurements
qc.measure(0, 0)
qc.measure(1, 1)
# Draw the circuit
qc.draw(output="mpl")
# Run the circuit on a simulator to get the results
# Define backend
backend = AerSimulator()
# Transpile to backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)
# Run the job
sampler = Sampler(backend)
job = sampler.run([isa_qc])
result = job.result()
# Print the results
counts = result[0].data.c.get_counts()
print(counts)
# Plot the counts in a histogram
plot_histogram(counts)
{'11': 1024}
Die Ergebnisse sollten zeigen, dass mit 100% Wahrscheinlichkeit gemessen wurde.
4.3 Quantenverschränkung und Ausführung auf einem echten Quantengerät
Beginnen wir mit der Einführung eines bestimmten verschränkten Zustands, der in der Quantenberechnung besonders wichtig ist, und definieren dann den Begriff „verschränkt":
und dieser Zustand wird als Bell-Zustand bezeichnet.
Ein verschränkter Zustand ist ein Zustand , bestehend aus den Quantenzuständen und , der nicht als Tensorprodukt einzelner Quantenzustände dargestellt werden kann.
Wenn unten zwei Zustände und hat;
ist das Tensorprodukt dieser beiden Zustände das Folgende
aber es gibt keine Koeffizienten und , die diese beiden Gleichungen erfüllen. Daher wird nicht als Tensorprodukt einzelner Quantenzustände und dargestellt, und das bedeutet, dass ein verschränkter Zustand ist.
Erstellen wir den Bell-Zustand und führen ihn auf einem echten Quantencomputer aus. Jetzt folgen wir den vier Schritten zum Schreiben eines Quantenprogramms, den sogenannten Qiskit Patterns:
- Problem auf Quantenschaltkreise und Operatoren abbilden
- Für die Zielhardware optimieren
- Auf der Zielhardware ausführen
- Ergebnisse nachbearbeiten
Schritt 1. Problem auf Quantenschaltkreise und Operatoren abbilden
In einem Quantenprogramm sind Quantenschaltkreise das native Format zur Darstellung von Quantenanweisungen. Beim Erstellen eines Schaltkreises erstellst du normalerweise ein neues QuantumCircuit-Objekt und fügst dann nacheinander Anweisungen hinzu.
Die folgende Code-Zelle erstellt einen Schaltkreis, der einen Bell-Zustand erzeugt, den oben beschriebenen spezifischen verschränkten Zwei-Qubit-Zustand.
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure(0, 0)
qc.measure(1, 1)
qc.draw("mpl")
Schritt 2. Für die Zielhardware optimieren
Qiskit wandelt abstrakte Schaltkreise in QISA (Quantum Instruction Set Architecture)-Schaltkreise um, die die Einschränkungen der Zielhardware berücksichtigen, und optimiert die Schaltkreisleistung. Vor der Optimierung legen wir also die Zielhardware fest.
Wenn du qiskit-ibm-runtime nicht hast, musst du dies zuerst installieren. Weitere Informationen über Qiskit Runtime findest du in der API-Referenz.
# Install
# !pip install qiskit-ibm-runtime
Wir legen die Zielhardware fest.
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
service.backends()
# You can specify the device
# backend = service.backend('ibm_kingston')
# You can also identify the least busy device
backend = service.least_busy(operational=True)
print("The least busy device is ", backend)
Das Transpilieren des Schaltkreises ist ein weiterer komplexer Prozess. Sehr kurz zusammengefasst: Es schreibt den Schaltkreis in einen logisch äquivalenten um, der „native Gates" verwendet (Gates, die ein bestimmter Quantencomputer implementieren kann), und bildet die Qubits in deinem Schaltkreis auf optimale reale Qubits auf dem Ziel-Quantencomputer ab. Weitere Informationen zur Transpilation findest du in dieser Dokumentation.
# Transpile the circuit into basis gates executable on the hardware
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
target_circuit = pm.run(qc)
target_circuit.draw("mpl", idle_wires=False)
Du kannst sehen, dass der Schaltkreis bei der Transpilation mit neuen Gates umgeschrieben wurde. Weitere Informationen findest du in der ECRGate-Dokumentation.
Schritt 3. Den Zielschaltkreis ausführen
Jetzt führen wir den Zielschaltkreis auf dem echten Gerät aus.
sampler = Sampler(backend)
job_real = sampler.run([target_circuit])
job_id = job_real.job_id()
print("job id:", job_id)
Die Ausführung auf dem echten Gerät kann eine Wartezeit in einer Warteschlange erfordern, da Quantencomputer wertvolle Ressourcen sind und sehr stark nachgefragt werden. Die job_id wird verwendet, um den Ausführungsstatus und die Ergebnisse des Jobs später zu überprüfen.
# Check the job status (replace the job id below with your own)
job_real.status(job_id)
Du kannst den Job-Status auch über dein IBM Quantum Dashboard überprüfen: https://quantum.cloud.ibm.com/workloads
# If the Notebook session got disconnected you can also check your job status
# by running the following code
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
job_real = service.job(job_id) # Input your job-id between the quotations
job_real.status()
# Execute after job has successfully run
result_real = job_real.result()
print(result_real[0].data.c.get_counts())
Schritt 4. Ergebnisse nachbearbeiten
Schließlich müssen wir unsere Ergebnisse nachbearbeiten, um Ausgaben im erwarteten Format zu erstellen, wie Werte oder Grafiken.
plot_histogram(result_real[0].data.c.get_counts())
Wie du sehen kannst, werden und am häufigsten beobachtet. Es gibt einige Ergebnisse, die von den erwarteten Daten abweichen, und diese sind auf Rauschen und Qubit-Dekohärenz zurückzuführen. Wir werden in späteren Lektionen dieses Kurses mehr über Fehler und Rauschen in Quantencomputern erfahren.
4.4 GHZ-Zustand
Das Konzept der Verschränkung kann auf Systeme mit mehr als zwei Qubits erweitert werden. Der GHZ-Zustand (Greenberger-Horne-Zeilinger-Zustand) ist ein maximal verschränkter Zustand von drei oder mehr Qubits. Der GHZ-Zustand für drei Qubits ist definiert als
Er kann mit dem folgenden Quantenschaltkreis erstellt werden.
qc = QuantumCircuit(3, 3)
qc.h(0)
qc.cx(0, 1)
qc.cx(1, 2)
qc.measure(0, 0)
qc.measure(1, 1)
qc.measure(2, 2)
qc.draw("mpl")
Die „Tiefe" eines Quantenschaltkreises ist eine nützliche und gebräuchliche Metrik zur Beschreibung von Quantenschaltkreisen. Verfolge einen Pfad durch den Quantenschaltkreis von links nach rechts und wechsle nur dann die Qubits, wenn sie durch ein Multi-Qubit-Gate verbunden sind. Zähle die Anzahl der Gates entlang dieses Pfades. Die maximale Anzahl von Gates für jeden solchen Pfad durch einen Schaltkreis ist die Tiefe. In modernen verrauschten Quantencomputern haben Schaltkreise mit geringer Tiefe weniger Fehler und liefern wahrscheinlich gute Ergebnisse. Sehr tiefe Schaltkreise hingegen nicht.
Mit QuantumCircuit.depth() können wir die Tiefe unseres Quantenschaltkreises überprüfen. Die Tiefe des obigen Schaltkreises beträgt 4. Das oberste Qubit hat nur drei Gates einschließlich der Messung. Aber es gibt einen Pfad vom obersten Qubit hinunter zu Qubit 1 oder Qubit 2, der ein weiteres CNOT-Gate einschließt.
qc.depth()
4
Übung 2
Der GHZ-Zustand eines 8-Qubit-Systems ist
Schreibe Code, um diesen Zustand mit dem flachstmöglichen Schaltkreis vorzubereiten. Die Tiefe des flachsten Quantenschaltkreises beträgt 5, einschließlich der Mess-Gates.
Lösung:
# Step 1
qc = QuantumCircuit(8, 8)
##your code goes here##
qc.h(0)
qc.cx(0, 4)
qc.cx(4, 6)
qc.cx(6, 7)
qc.cx(4, 5)
qc.cx(0, 2)
qc.cx(2, 3)
qc.cx(0, 1)
qc.barrier() # for visual separation
# measure
for i in range(8):
qc.measure(i, i)
qc.draw("mpl")
# print(qc.depth())
print(qc.depth())
5
from qiskit.visualization import plot_histogram
# Step 2
# For this exercise, the circuit and operators are simple, so no optimizations are needed.
# Step 3
# Run the circuit on a simulator to get the results
backend = AerSimulator()
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)
sampler = Sampler(mode=backend)
job = sampler.run([isa_qc], shots=1024)
result = job.result()
counts = result[0].data.c.get_counts()
print(counts)
# Step 4
# Plot the counts in a histogram
plot_histogram(counts)
{'11111111': 535, '00000000': 489}
5. Zusammenfassung
Du hast Quantenberechnung mit dem Schaltkreismodell unter Verwendung von Quantenbits und Gates gelernt und Superposition, Messung und Verschränkung wiederholt. Du hast außerdem die Methode gelernt, den Quantenschaltkreis auf dem echten Quantengerät auszuführen.
In der letzten Übung zur Erstellung eines GHZ-Schaltkreises hast du versucht, die Schaltkreistiefe zu reduzieren, was ein wichtiger Faktor für die Erzielung einer Utility-Scale-Lösung auf einem verrauschten Quantencomputer ist. In späteren Lektionen dieses Kurses wirst du mehr über Rauschen und Methoden zur Fehlerminderung im Detail erfahren. In dieser Lektion haben wir als Einführung die Reduzierung der Schaltkreistiefe auf einem idealen Gerät betrachtet, aber in der Realität müssen wir die Einschränkungen des echten Geräts berücksichtigen, wie z.B. die Qubit-Konnektivität. Du wirst in den folgenden Lektionen dieses Kurses mehr darüber erfahren.
# See the version of Qiskit
import qiskit
qiskit.__version__
'2.0.2'