Mit Qiskit im Unterricht starten
Für dieses Modul „Qiskit im Unterricht" benötigen Schülerinnen und Schüler eine funktionierende Python-Umgebung mit den folgenden installierten Paketen:
qiskitv2.1.0 oder neuerqiskit-ibm-runtimev0.40.1 oder neuerqiskit-aerv0.17.0 oder neuerqiskit.visualizationnumpypylatexenc
Eine Anleitung zur Installation der oben genannten Pakete findest du im Qiskit installieren-Leitfaden. Um Jobs auf echten Quantencomputern ausführen zu können, müssen Schülerinnen und Schüler ein Konto bei IBM Quantum® einrichten, indem sie den Schritten im Leitfaden Dein IBM Cloud®-Konto einrichten folgen.
Dieses Modul wurde getestet und hat 2 Sekunden QPU-Zeit auf einem Heron-v2-Prozessor verbraucht. Dies ist nur eine Schätzung. Deine tatsächliche Nutzung kann abweichen.
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-aer qiskit-ibm-runtime
# Uncomment and modify this line as needed to install dependencies
#!pip install 'qiskit>=2.1.0' 'qiskit-ibm-runtime>=0.40.1' 'qiskit-aer>=0.17.0' 'numpy' 'pylatexenc'
Einführung
In den „Qiskit im Unterricht"-Modulen hast du die Möglichkeit, einen Quantencomputer zu nutzen, um verschiedene Konzepte aus quantencomputingnahen Bereichen wie Quantenmechanik, Informatik, Chemie und mehr zu erkunden. Dieses Modul dient als Voraussetzung für alle anderen – es führt in die Grundlagen des Quantencomputings ein und zeigt dir, wie du Qiskit verwendest, um Quantenschaltungen auszuführen.
Zunächst geben wir dir einen kurzen Überblick darüber, wie ein klassischer Computer funktioniert, dann zeigen wir dir, wie diese Konzepte an das Quantencomputing-Paradigma angepasst werden. Schließlich zeigen wir dir, wie du diese Konzepte zusammenführst, um deine erste Quantenschaltung zu bauen und auszuführen.
Klassische Computer
Du bist wahrscheinlich mit den Grundlagen der Funktionsweise klassischer Computer vertraut, aber hier heben wir einige der wichtigsten Merkmale hervor, damit wir dann einen Vergleich zu Quantencomputern ziehen können.
Die grundlegenden Informationseinheiten: Bits
Klassische Computer verarbeiten klassische Informationen, und die grundlegende Einheit klassischer Information ist das Bit. Ein einzelnes Bit kann die Antwort auf eine „Ja/Nein"-Frage speichern. Die zwei Binärzustände eines Bits werden üblicherweise als „0" und „1" dargestellt.
Wiederholung der Binärzahlen
Die Kombination von Bits ermöglicht es dir, mehr Informationen zu speichern. Wenn du beispielsweise eine Zahl von 0 bis 15 speichern möchtest, könntest du dies mit vier Bits auf folgende Weise tun:
| 0 = 0000 | 4 = 0100 | 8 = 1000 | 12 = 1100 |
| 1 = 0001 | 5 = 0101 | 9 = 1001 | 13 = 1101 |
| 2 = 0010 | 6 = 0110 | 10 = 1010 | 14 = 1110 |
| 3 = 0011 | 7 = 0111 | 11 = 1011 | 15 = 1111 |
Um eine Binärzahl mit Bits in eine vertraute Dezimalzahl (Basis 10) umzurechnen, multiplizierst du das am wenigsten signifikante (rechteste) Bit mit , das nächste Bit links davon mit , dann das nächste mit und so weiter, bis du das bedeutendste (linkste) Bit erreichst, das du mit multiplizierst.
Das bedeutet also, dass Bits in einem von verschiedenen möglichen Zuständen sein können.
Verständnisfragen
Lies die folgende(n) Frage(n), denke über deine Antwort nach und klicke dann auf das Dreieck, um die Lösung anzuzeigen.
Wie viele Bits brauchst du, um die Zahl 86 darzustellen? Schreibe den Bitstring auf, der diese Zahl im Binärformat kodiert.
Antwort:
Denke daran: Mit Bits kannst du die Zahlen bis darstellen. Mit sechs Bits kommen wir also bis . Das reicht nicht ganz. Wir fügen ein weiteres Bit hinzu, um bis zu gelangen. Nun zerlegen wir 86 in Zweierpotenzen:
Grundlegende Operationen: Gates
Ein Computer muss in der Lage sein, etwas mit den Bits zu tun, um – nun ja – zu rechnen. Binäre Gates sind die Operationen, die die grundlegenden Bausteine aller komplizierteren Algorithmen und Programme bilden.
Einzel-Bit-Gate:
NOT
Bei einem einzelnen Bit gibt es nur eine Möglichkeit, seinen Zustand zu verändern: den Zustand von 0 auf 1 oder von 1 auf 0 umzukehren. Dies nennen wir das „NOT"-Gate. Die Wirkung dieses Gates – und der übrigen Gates, die wir weiter unten besprechen – lässt sich in einer sogenannten „Wahrheitstabelle" darstellen, mit Spalten für die Eingangs- und Ausgangszustände der Qubits. Die Wahrheitstabelle für das NOT-Gate lautet:
| Eingang | Ausgang |
|---|---|
| 0 | 1 |
| 1 | 0 |
Mehrbit-Gates:
AND
AND ist ein Zwei-Bit-Gate, das zwei Eingangsbits entgegennimmt und ein einzelnes Bit ausgibt. Es gibt 1 aus, wenn beide Eingangsbits 1 sind, und andernfalls 0:
| Eingang | Ausgang |
|---|---|
| 00 | 0 |
| 01 | 0 |
| 10 | 0 |
| 11 | 1 |
OR
OR ist ein weiteres Zwei-Bit-Gate mit einem einzelnen Ausgangsbit. Es gibt 1 aus, wenn eines der Bits 1 ist:
| Eingang | Ausgang |
|---|---|
| 00 | 0 |
| 01 | 1 |
| 10 | 1 |
| 11 | 1 |
XOR
XOR steht für „exklusives OR" und funktioniert wie das OR-Gate, gibt aber 1 aus, wenn genau eines der Eingangsbits 1 ist. Es gibt 0 aus, wenn beide 1 oder beide 0 sind:
| Eingang | Ausgang |
|---|---|
| 00 | 0 |
| 01 | 1 |
| 10 | 1 |
| 11 | 0 |
Messungen:
Beim Lernen über klassisches Computing wird dem Prozess des Auslesens des Bit-Zustands typischerweise wenig Aufmerksamkeit gewidmet. Dies liegt daran, dass es aus konzeptioneller Sicht nicht sehr komplex ist. Du kannst die Bits jederzeit vor, während oder nach einer Berechnung messen, ohne das Ergebnis zu beeinflussen. Im Quantencomputing ist das anders, wie wir weiter unten erörtern werden.
Schaltungen:
Durch die Kombination der obigen Gates kannst du beliebige Operationen auf einem Computer durchführen. Nehmen wir ein einfaches Beispiel: Mit den AND- und XOR-Gates kannst du die Halb-Addierer-Schaltung aufbauen, die die Summe zweier Bits berechnet. Dies wird in einem logischen Schaltkreisdiagramm dargestellt, in dem die Leitungen die Bits und die auf den Bits operierenden Gates als Symbole auf den entsprechenden Leitungen dargestellt werden:
Die zwei Bits werden also kopiert und durch ein AND-Gate und ein XOR-Gate geleitet. Das Ergebnis des XOR-Gates ist das „Summen-Bit" (S), das an der Einerstelle der Binärzahl verbleibt, und das Ergebnis des AND-Gates ist das „Übertrags-Bit" (C), das den Wert der nächst höherwertigen Stelle in der Binärzahl darstellt. Hier ist die Wahrheitstabelle:
| Summe () | Übertrag () | ||
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 1 | 0 |
| 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 1 |
Verständnisfragen
Lies die folgende(n) Frage(n), denke über deine Antwort nach und klicke dann auf das Dreieck, um die Lösung anzuzeigen.
Überprüfe, dass die obige Wahrheitstabelle das korrekte Ergebnis für eine Addierer-Schaltung liefert. Überprüfe also für jede der vier Kombinationen von A und B, dass gilt.
Antwort:
Quantencomputer
Bits Qubits
So wie Bits die grundlegenden Einheiten klassischer Information sind, sind Quanten-Bits, oder „Qubits", die grundlegenden Einheiten quantenmechanischer Information. Wie das klassische Bit kann der Zustand eines Qubits entweder 0 oder 1 sein, was wir üblicherweise als und bezeichnen. Aber anders als das klassische Bit kann ein Quanten-Bit auch in einer Superposition des -Zustands und des -Zustands gleichzeitig sein. Im Allgemeinen kann ein Qubit in einem beliebigen Zustand der Form sein:
wobei und komplexe Amplituden mit sind.
Die Quantenphase
Da und komplex sind, kann jedes als geschrieben werden, wobei als Phase bezeichnet wird. Wenn wir den gesamten Zustand mit demselben globalen Phasenfaktor multiplizieren, ändert sich physikalisch nichts – dies wird als globale Phase bezeichnet und hat keine beobachtbaren Konsequenzen.
Aus diesem Grund ist es üblich, „herauszufaktorisieren", was ergibt:
wobei die relative Phase des Quantenzustands ist, die tatsächlich beobachtbare Konsequenzen hat.
Diese Phase spielt eine sehr wichtige Rolle im Quantencomputing, und du wirst ihre verschiedenen Auswirkungen in den nachfolgenden „Qiskit im Unterricht"-Modulen erkunden.
Mehrere Qubits
Während der Zustand mehrerer Bits einfach als eine Folge von 0en und 1en ausgedrückt werden konnte, wird der Zustand mehrerer Qubits etwas komplizierter aufgrund der Prinzipien der Superposition und Verschränkung.
Erinnere dich daran, dass Bits in einem von möglichen Zuständen sein konnten, von Binärzahlen 000...000 bis 111...111. Aber jetzt, aufgrund des Superpositionsprinzips, können Qubits in einer Superposition von allen diesen Zuständen gleichzeitig sein!
Dies lässt sich ausdrücken als
wobei, wie im klassischen Fall, der Zustand dem Zustand entspricht, in dem jedes Qubit in der richtigen Kombination aus 0en und 1en ist, um die Binärzahl zu ergeben. Diese werden als „Rechenbasis-Zustände" des Quantensystems bezeichnet. Zum Beispiel kann ein Drei-Qubit-Zustand als Superposition seiner acht Rechenbasis-Zustände geschrieben werden:
Jedes Qubit im System wird mit einem Index bis bezeichnet. Die Konvention ist, die Qubit-Zustände von rechts nach links zu lesen, so dass der Zustand von Qubit der am weitesten rechts stehende Zustand und der Zustand von Qubit der am weitesten links stehende ist. Dies ist als „Little-Endian"-Notation bekannt und mag zunächst kontraintuitiv erscheinen, da wir es gewohnt sind, von links nach rechts zu lesen.
Verständnisfragen
Lies die folgende(n) Frage(n), denke über deine Antwort nach und klicke dann auf das Dreieck, um die Lösung anzuzeigen.
Auf den ersten Blick mag es kontraintuitiv erscheinen, Qubits wie in der Little-Endian-Notation von rechts nach links zu ordnen, aber es ist eigentlich eine sehr logische Sache! Erkläre warum. (Erinnere dich an unsere obige Diskussion der Binär-zu-Dezimal-Umrechnung.)
Antwort:
Wenn wir Qubits von rechts nach links ordnen, so dass Qubit 0 ganz rechts und Qubit N-1 ganz links steht, ist es logisch, Qubit mit dem am wenigsten signifikanten Bit zu assoziieren, das mit multipliziert wird, und Qubit mit dem bedeutendsten Bit, das mit multipliziert wird.
Verschränkung
Wie wir zuvor erwähnt haben, ist ein weiteres wichtiges Merkmal von Qubits, dass sie miteinander verschränkt sein können. Nehmen wir ein Beispiel eines Zwei-Qubit-Zustands, bei dem und :
Der Zustand von Qubit 0 kann also entweder oder mit gleicher Wahrscheinlichkeit sein, und dasselbe gilt für den Zustand von Qubit 1. Aber diese Wahrscheinlichkeiten sind nicht mehr voneinander unabhängig. Wenn wir den Zustand von Qubit 0 als feststellen, dann wissen wir, dass Qubit 1 ebenfalls in sein wird. Dies gilt unabhängig davon, wie weit sie voneinander entfernt sind, weshalb der Akt der Messung eines verschränkten Zustands manchmal als „spukhafte Fernwirkung" bezeichnet wird.
Verschränkung kann auch andere Formen annehmen. Zum Beispiel erzeugt der Zustand
jedes Mal entgegengesetzte Ergebnisse: Wenn ein Qubit als gemessen wird, ist das andere garantiert im Zustand .
Verständnisfragen
Lies die folgende(n) Frage(n), denke über deine Antwort nach und klicke dann auf das Dreieck, um die Lösung anzuzeigen.
Ist der Zustand verschränkt? Warum oder warum nicht?
Antwort:
Er ist nicht verschränkt. Obwohl die Ergebnisse beim Messen beider Qubits immer gleich sind, liegt das nur daran, dass jedes Qubit immer im Zustand fixiert ist. Das Ergebnis der Messung eines Qubits hängt nicht wirklich vom anderen ab – beide sind einfach immer .
Im Allgemeinen, wenn du den Zustand jedes Qubits separat beschreiben und dann so miteinander multiplizieren kannst:
Dann ist er als „Produktzustand" bekannt und ist nicht verschränkt.
Vektornotation
Es ist oft hilfreich, Vektoren und Matrizen zu verwenden, um zu sehen, wie sich der Quantenzustand unter verschiedenen Operationen verändert. In dieser Darstellung sind unsere Quantenzustände Vektoren, und unsere Quanten-Gates (im nächsten Abschnitt besprochen) sind Matrizen, die die Vektoren transformieren.
F ür ein einzelnes Qubit werden die Vektordarlstellungen der Zustände wie folgt gewählt: Auf diese Weise kann ein beliebiger Zustand als geschrieben werden.
Für einen allgemeinen -Qubit-Zustand benötigen wir einen -dimensionalen Vektor, mit Basiszuständen in aufsteigender Binärwert-Reihenfolge:
Mit dieser Vektornotation können wir nun die benötigten Quanten-Gates, ihre Auswirkungen auf Quantenzustände und ihre Matrixdarstellungen einführen.
Verständnisfragen
Lies die folgende(n) Frage(n), denke über deine Antwort nach und klicke dann auf das Dreieck, um die Lösung anzuzeigen.
Für ein Zwei-Qubit-System gibt es vier Rechenbasis-Zustände. Schreibe jeden in Ket- und Vektornotation auf.
Antwort:
Gates Quanten-Gates
So wie klassische Gates wie NOT, AND, OR und XOR kombiniert werden können, um beliebige klassische Schaltungen zu bauen, spielen Quanten-Gates dieselbe Rolle im Quantencomputing. Da Qubits zusätzliche quantenmechanische Eigenschaften haben, sind Quanten-Gates entsprechend reichhaltiger. Während wir ihre Wirkung auf die Basiszustände und noch immer mit einer Wahrheitstabelle beschreiben können, erfasst dies nicht das vollständige Bild. Für Quanten-Gates ist es oft natürlicher, eine Matrixdarstellung zu verwenden, da sie auch auf Superpositionen von Basiszuständen wirken.
Im Folgenden stellen wir die häufigsten Quanten-Gates vor und erläutern, wie sie die Qubits transformieren, mit denen sie interagieren. Wo zutreffend, verbinden wir sie mit vertrauten klassischen Gates.
Einzel-Qubit-Gates
-Gate: Dies ist das quantenmechanische Äquivalent einer NOT-Operation. Seine Wahrheitstabelle sieht genauso aus wie das klassische NOT-Gate:
| Eingang | Ausgang |
|---|---|
Und die Matrixdarstellung:
In Qiskit sieht die Erstellung einer Schaltung mit einem -Gate so aus:
from qiskit import QuantumCircuit
qc = QuantumCircuit(1)
qc.x(0)
qc.draw("mpl")
In diesem sehr einfachen Schaltkreisdiagramm wird das Qubit durch einen Draht, die schwarze horizontale Linie, dargestellt, und das Gate erscheint als Box auf diesem Draht.
Hadamard-Gate: Erzeugt einen Superpositionszustand. Wahrheitstabelle:
| Eingang | Ausgang |
|---|---|
Matrixdarstellung:
Eine Schaltung mit einem Hadamard-Gate wird wie folgt erstellt:
from qiskit import QuantumCircuit
qc = QuantumCircuit(1)
qc.h(0)
qc.draw("mpl")
-Gate: Fügt dem -Zustand eine Phasenverschiebung von hinzu:
| Eingang | Ausgang |
|---|---|
In Qiskit sieht die Erstellung einer Schaltung mit einem -Gate so aus:
qc = QuantumCircuit(1)
qc.z(0)
qc.draw("mpl")
-Gate: Fügt dem -Zustand eine Phasenverschiebung von hinzu:
| Eingang | Ausgang |
|---|---|
In Qiskit sieht die Erstellung einer Schaltung mit einem -Gate so aus:
qc = QuantumCircuit(1)
qc.t(0)
qc.draw("mpl")
Multi-Qubit-Gates
Zwei-Qubit-Gates ähneln klassischen Zwei-Bit-Gattern, haben jedoch einen wichtigen Unterschied: Alle Quantengatter müssen reversibel sein. In der linearen Algebra bedeutet das, dass sie durch unitäre Matrizen dargestellt werden. Zwei Eingangs-Qubits werden also immer auf zwei Ausgangs-Qubits abgebildet, und die Operation lässt sich prinzipiell rückgängig machen. Das steht im Gegensatz zu den klassischen Gattern wie AND oder OR, die Informationen verlieren und irreversibel sind – aus einem Ausgang kann man den Eingang nicht eindeutig rekonstruieren.
CNOT-Gate (Controlled-NOT): Die zwei Eingangs-Qubits heißen „Kontroll"-Qubit und „Ziel"-Qubit. Das Kontroll-Qubit bleibt unverändert, aber sein Zustand bestimmt, was mit dem Ziel-Qubit geschieht. Befindet sich das Kontroll-Qubit im Zustand , wird ein -Gate auf das Ziel-Qubit angewendet; ist das Kontroll-Qubit im Zustand , bleibt alles unverändert. In der folgenden Notation ist Qubit (ganz rechts) das Kontroll-Qubit und Qubit (ganz links) das Ziel-Qubit. Es gilt die Schreibweise
| Eingang | Ausgang |
|---|---|
Die Matrix, die diese Wirkung darstellt, lautet:
qc = QuantumCircuit(2)
qc.cx(0, 1)
qc.draw("mpl")
Dies ist das erste Circuit-Diagramm mit zwei Qubits, die durch die zwei Leitungen dargestellt werden. Das CNOT-Gate wird zwischen den beiden Qubits angewendet, wobei das Kontroll-Qubit und das Ziel-Qubit ist.
Teste dein Verständnis
Lies die folgende Frage, überlege dir eine Antwort und klicke dann auf das Dreieck, um die Lösung aufzudecken.
Die meisten Gates haben in Qiskit dieselbe Matrixform wie anderswo. Beim CNOT-Gate, das auf zwei Qubits wirkt, spielen jedoch Qubit-Reihenfolge-Konventionen plötzlich eine Rolle. Texte, die Qubits in der Reihenfolge anordnen, zeigen eine andere Matrixform für ihre CNOT-Gates. Überprüfe durch explizite Matrixmultiplikation, dass die obige CNOT-Matrix die korrekte Wirkung auf den Zustand hat.
Antwort:
SWAP-Gate: Dieses Gate tauscht die Zustände zweier Qubits. Wahrheitstabelle:
| Eingang | Ausgang |
|---|---|
Die Matrix, die diese Wirkung darstellt, lautet:
qc = QuantumCircuit(2)
qc.swap(0, 1)
qc.draw("mpl")
Das SWAP-Gate lässt sich tatsächlich aus drei CNOTs aufbauen. Um das nachzuvollziehen, können wir das Gate in Qiskit mit decompose() zerlegen:
qc = QuantumCircuit(2)
qc.swap(0, 1)
qc.decompose().draw("mpl")
Hier sehen wir zum ersten Mal, wie mehrere Gates in einem Circuit-Diagramm dargestellt werden. Man liest es von links nach rechts, das heißt, das am weitesten links stehende Gate wird zuerst angewendet.
Teste dein Verständnis
Lies die folgende Frage, überlege dir eine Antwort und klicke dann auf das Dreieck, um die Lösung aufzudecken.
Überprüfe, dass die obige Kombination von CNOTs tatsächlich ein SWAP-Gate ergibt. Du kannst dies durch Matrixmultiplikation oder eine andere Methode zeigen.
Antwort:
Mit Matrixmultiplikation:
Mit einer Wahrheitstabelle lässt sich verfolgen, wie sich die Zustände bei jedem CNOT ändern. In der letzten Spalte sollten die Zustände der „Ausgang"-Spalte der SWAP-Wahrheitstabelle entsprechen:
| Eingang | CNOT(A,B) | CNOT(B,A) | CNOT(A,B) |
|---|---|---|---|
Toffoli-Gate (auch „Controlled-Controlled-NOT" (CCNOT)): Dies ist ein Drei-Qubit-Gate. Der Name „Controlled-Controlled-NOT" verrät bereits seine Funktionsweise: Es gibt zwei Kontroll-Qubits und ein Ziel-Qubit, und der Zustand des Ziel-Qubits wird nur dann umgekehrt, wenn beide Kontroll-Qubits im Zustand sind. Wir behalten die Reihenfolge-Konvention bei, die wir beim CNOT verwendet haben:
Die Wahrheitstabelle lautet:
| Eingang | Ausgang |
|---|---|
Und die entsprechende Matrix lautet:
qc = QuantumCircuit(3)
qc.ccx(0, 1, 2)
qc.draw("mpl")
Auch das Toffoli-Gate lässt sich in CNOTs und weitere Gates zerlegen. Die Zerlegung ist jedoch deutlich komplizierter als beim SWAP-Gate und wird daher als optionale Aufgabe am Ende des Moduls zur Erkundung und Überprüfung überlassen.
Messungen
Messungen spielen im Quantencomputing eine besondere Rolle – eine, die kein klassisches Pendant hat. Während du in der klassischen Informatik deine Bits jederzeit ablesen kannst, musst du im Quantencomputing sehr gezielt auswählen, wann du deine Qubits betrachtest. Eine Messung kollabiert nämlich den Zustand und zerstört die Superposition, die den Qubits ihre rechnerische Leistungsfähigkeit verleiht.
Konkret gilt: Gegeben ein -Qubit-Quantenzustand , kollabiert eine Messung den Zustand auf eine der Basisfunktionen mit einer Wahrscheinlichkeit von .
Dieser destruktive Effekt einer Messung ist jedoch nicht immer ein Hindernis. Er ist tatsächlich eine wichtige Ressource in bestimmten Algorithmen und Protokollen, wie etwa der Quantenteleportation und der Quantenschlüsselverteilung.
In Qiskit wird das Messergebnis, wenn eine Messung durchgeführt wird, an ein klassisches Register übertragen und dort als klassisches Bit gespeichert. So sieht ein Circuit mit einer Messung aus:
qc = QuantumCircuit(
1, 1
) # the second number is the number of classical bits in the circuit
qc.measure(0, 0)
qc.draw("mpl")
Circuits
Jetzt, wo wir wissen, wie Qubits, Gates und Messungen funktionieren, bauen und führen wir unseren eigenen Quantencircuit aus! Dazu stellen wir dir einen nützlichen Arbeitsablauf vor: die Qiskit-Patterns.
Das Qiskit-Patterns-Framework
Das Qiskit-Patterns-Framework ist eine allgemeine Vorgehensweise, um Probleme mit einem Quantencomputer anzugehen und zu lösen. Es besteht aus vier Schritten:
- Abbilden unseres Problems auf Quantencircuits und Operatoren
- Optimieren des Circuits für die Zielhardware
- Ausführen auf der Zielhardware
- Nachverarbeiten unserer Ergebnisse
Um diese Schritte zu veranschaulichen, implementieren wir eine Quanten-Version des oben besprochenen Halbaddierer-Circuits.
1. Abbilden
Der klassische Addierer-Circuit verwendet ein XOR- und ein AND-Gate, um die Summe bzw. den Übertrag zu berechnen. Wir können diese Gates in den Quantenkontext übertragen, um den Quanten-Halbaddierer zu bauen. Da Quantengatter reversibel sind, können wir die Eingaben nicht einfach überschreiben. Stattdessen führen wir zwei Hilfs-Qubits ein, die mit initialisiert werden, um die Summe und den Übertrag zu speichern. Unser vollständiger Quantenzustand besteht also aus den Qubits und sowie den Summen- und Übertrags-Qubits, die wir und nennen:
Nun brauchen wir Quantengatter, die dasselbe leisten wie die XOR- und AND-Gates im klassischen Circuit.
Summe:
Für das XOR wenden wir zwei CNOTs an, jeweils mit den Kontroll-Qubits und und dem Ziel-Qubit für beide. Wenn und verschieden sind, kippt einer der CNOT-Gates in den Zustand . Wenn und beide sind, bleibt unverändert im Zustand . Wenn und beide sind, wird zweimal umgekehrt und kehrt damit in den Zustand zurück.
Übertrag:
Für den Übertrag brauchen wir etwas, das wie das klassische AND-Gate funktioniert.
Teste dein Verständnis
Lies die folgende Frage, überlege dir eine Antwort und klicke dann auf das Dreieck, um die Lösung aufzudecken.
Schau dir die besprochenen Gates noch einmal an und überlege, welches Quantengate wir anstelle des klassischen AND-Gates verwenden könnten:
Antwort:
Es ist das Toffoli-Gate! Zur Erinnerung: Das Toffoli- bzw. Controlled-Controlled-NOT-Gate kippt den Zielzustand genau dann, wenn Kontroll-Qubit 0 UND Kontroll-Qubit 1 beide im Zustand sind. Wenn das Ziel-Qubit mit dem Zustand startet, verhält es sich also genauso wie das AND-Gate.
Wir haben jetzt alle Zutaten, um den Quantencircuit zu bauen:
# qubits: a, b, sum, carry
qc = QuantumCircuit(4)
# Choose values for A and B:
a = 0
b = 0
# Prepare A and B qubits according to selected values:
if a:
qc.x(0)
if b:
qc.x(1)
# XOR (sum) into qubit 2
qc.cx(0, 2)
qc.cx(1, 2)
# AND (carry) into qubit 3
qc.ccx(0, 1, 3) # a AND b
# measure
qc.measure_all()
qc.draw("mpl")
Oben ist das Circuit-Diagramm für den Quanten-Halbaddierer-Circuit. Wie bereits erwähnt, stellen die Leitungen die Qubits bis von oben nach unten dar, und das klassische Bitregister ist die untere doppelt gezeichnete Leitung. Von links nach rechts lesend sieht man, wie die Gates auf jedes Qubit angewendet werden, indem man nachverfolgt, wo die Boxen auf den entsprechenden Leitungen erscheinen. Am Ende sind die Messungen dargestellt. Diese kollabieren die Qubit-Zustände in definitive - oder -Werte, und die Ergebnisse werden an ein klassisches Register übertragen.
Ein wichtiger Hinweis: Obwohl das Circuit-Diagramm von links nach rechts gezeichnet wird, liest man beim Aufschreiben des entsprechenden Matrixausdrucks von rechts nach links. Das liegt daran, dass bei der Matrixmultiplikation der Operator, der am nächsten am Zustandsvektor steht (also ganz rechts), zuerst wirkt. Der obige Circuit (ohne die Messungen) würde zum Beispiel so geschrieben:
2. Optimieren
Als Nächstes müssen wir den Circuit für die Ausführung auf der Quantenhardware optimieren. Diese Optimierung übernimmt der Transpiler, der den abstrakten Circuit von oben in Anweisungen übersetzt, die der Quantencomputer versteht. Er ordnet die logischen Qubits von oben realen, physischen Qubits auf dem Prozessor zu und schreibt die Gates in die nativen Gatter um, die für den jeweiligen Quantencomputer optimiert wurden. Schließlich implementiert der Transpiler auch sogenannte „Fehlerunterdrückung und -mitigation", um den Einfluss von Fehlern auf das Ergebnis zu minimieren. Für unseren sehr einfachen Circuit ist das noch nicht so wichtig, aber wenn du auf deinem Weg im Quantencomputing komplexere Circuits ausführst, wirst du den Wert von Fehlerunterdrückung und -mitigation bald erkennen. Mehr dazu findest du in Olivia Lanes Kurs Quantum Computing in Practice.
Zunächst laden wir die Pakete, die für die Kommunikation mit IBM®-Quantencomputern erforderlich sind, und wählen ein Backend aus. Wir können entweder das am wenigsten ausgelastete Backend auswählen oder ein bestimmtes Backend wählen, dessen Eigenschaften wir kennen.
Im folgenden Code findest du Anweisungen, wie du deine Zugangsdaten beim ersten Mal speicherst. Achte darauf, diese Informationen aus dem Notebook zu löschen, nachdem du sie in deiner Umgebung gespeichert hast, damit deine Zugangsdaten beim Teilen des Notebooks nicht versehentlich weitergegeben werden. Weitere Hinweise findest du unter IBM Cloud-Konto einrichten und Dienst in einer nicht vertrauenswürdigen Umgebung initialisieren.
# Load the Qiskit Runtime service
from qiskit_ibm_runtime import QiskitRuntimeService
# Load the Qiskit Runtime service
# Syntax for first saving your token. Delete these lines after saving your credentials.
# QiskitRuntimeService.save_account(channel='ibm_quantum_platform', instance = '<YOUR_IBM_INSTANCE_CRN>', token='<YOUR-API_KEY>', overwrite=True, set_as_default=True)
# service = QiskitRuntimeService(channel='ibm_quantum_platform')
# Load saved credentials
service = QiskitRuntimeService()
# Use the least busy backend, or uncomment the loading of a specific backend like "ibm_brisbane".
backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)
# backend = service.backend("ibm_brisbane")
print(backend.name)
ibm_fez
Nun verwenden wir den Transpiler, um den Circuit zu optimieren. Wir können den Optimierungsgrad von 0 (keine Optimierung) bis 3 (höchste Optimierung) wählen. Was die einzelnen Stufen beinhalten, erfährst du im Leitfaden Transpiler-Optimierungsstufe festlegen. Der resultierende Circuit sieht deutlich anders aus als der logische Circuit, den wir im Abbildungsschritt erstellt haben.
# Transpile the circuit and optimize for running on the quantum computer selected
# Step 2: Transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
qc_isa.draw("mpl")
Ein „Sampler" ist ein Primitiv, das darauf ausgelegt ist, mögliche Zustände aus einem Quantencircuit zu samplen und Statistiken darüber zu sammeln, welche Zustände mit welcher Wahrscheinlichkeit gemessen werden könnten. Hier importieren wir den Qiskit Runtime Sampler:
# Load the Runtime primitive and session
from qiskit_ibm_runtime import SamplerV2 as Sampler
sampler = Sampler(mode=backend)
Falls du dein verfügbares Kontingent auf echten Quantencomputern aufgebraucht hast oder keine Internetverbindung besteht, kannst du auch einen Simulator verwenden. Führe dazu die folgende Zelle aus und kommentiere die entsprechende Zeile im Schritt „Ausführen" ein.
# Load the backend sampler
from qiskit.primitives import BackendSamplerV2
# Load the Aer simulator and generate a noise model based on the currently-selected backend.
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel
noise_model = NoiseModel.from_backend(backend)
# Define a simulator using Aer, and use it in Sampler.
backend_sim = AerSimulator(noise_model=noise_model)
sampler_sim = BackendSamplerV2(backend=backend_sim)
# Alternatively, load a fake backend with generic properties and define a simulator.
# backend_gen = GenericBackendV2(num_qubits=18)
# sampler_gen = BackendSamplerV2(backend=backend_gen)
3. Ausführen
Nachdem wir den Circuit vorbereitet haben, können wir ihn jetzt auf dem Quantencomputer ausführen!
job = sampler.run([qc_isa], shots=100)
# job = sampler_sim.run([qc_isa]) # uncomment if you want to run on a simulator
res = job.result()
counts = res[0].data.meas.get_counts()
4. Nachverarbeiten
Jetzt können wir unsere Ergebnisse betrachten! Wir zeigen ein Histogramm der 100 Messungen des Circuits an.
from qiskit.visualization import plot_histogram
print("counts = ", counts)
plot_histogram(counts)
counts = {'0000': 90, '0100': 4, '1100': 3, '0010': 3}
Das obige Histogramm zeigt die Messergebnisse aller vier Qubits am Ende des Circuits. Ein idealer Quantencomputer ohne Rauschen würde die Qubits immer mit denselben Werten messen. In der Realität sorgt Rauschen jedoch dafür, dass einige der Messungen Fehler produzieren.
Teste dein Verständnis
Lies die folgende Frage, überlege dir eine Antwort und klicke dann auf das Dreieck, um die Lösung aufzudecken.
Nutze den Bitstring mit den meisten Zählwerten als Werte für , , und und überprüfe, ob der Quanten-Addierer-Circuit korrekt funktioniert hat.
Antwort:
Wir müssen überprüfen, dass gilt. Zur Erinnerung: Die Bitstring-Reihenfolge folgt der Little-Endian-Notation, wird also als CSBA gelesen.
Aus dem obigen Histogramm sehen wir, dass der Bitstring 0000 der häufigste ist.
Gehe zurück und ändere die Werte von und auf und , und führe die Qiskit-Patterns-Schritte erneut durch, um den Circuit nochmals auszuführen. Überprüfe, dass der Addierer-Circuit wieder korrekt funktioniert.
Antwort:
Du solltest ein Histogramm erhalten, bei dem der dominante Bitstring 1011 ist:
Einer der Vorteile des Quanten-Halbaddierers gegenüber dem klassischen Halbaddierer ist, dass er mit Quanten-Eingaben arbeiten kann. Das heißt, er kann Qubits und auch dann „addieren", wenn sie sich in Superpositionszuständen befinden. Im Abschnitt „Herausforderungsfragen" weiter unten wirst du gebeten, die Qubits in Superpositionen vorzubereiten und zu beobachten, was passiert!
Fazit
Dieses Modul soll dir ein solides Grundverständnis der Grundprinzipien des Quantencomputings vermitteln, indem es Vergleiche mit der klassischen Informatik zieht. Wir haben uns den klassischen Halbaddierer-Circuit angeschaut und dann gezeigt, wie er sich auf Qubits anpassen lässt, um auf einem Quantencomputer ausgeführt zu werden. Jetzt bist du bereit, die anderen Qiskit in the Classroom-Module zu erkunden!
Zentrale Konzepte:
- Im Gegensatz zu klassischen Bits, die nur die Werte 0 und 1 annehmen können, können Qubits auch Superpositionen beider Werte sein.
- Mehrere Qubits können sich in einer Superposition über die klassisch erlaubten Bitstrings, den sogenannten Rechenbasisstzuständen, befinden.
- Mehrere Qubits können verschränkt sein, sodass der Zustand des einen vom Zustand des anderen abhängt.
- Die Qiskit-Konvention verwendet die Little-Endian-Notation, bei der das am wenigsten signifikante Qubit, , an der rechtesten Position und das signifikanteste Qubit, , an der linksten Position steht.
- Quantengatter sind reversible Operationen, die durch unitäre Matrizen dargestellt werden und auf die Quantenzustandsvektoren wirken. In dieser Notation wirkt die Matrix, die dem Vektor am nächsten ist (also ganz rechts), zuerst.
- Messungen kollabieren einen Quantensuperpositionszustand in einen der klassisch erlaubten Zustände, mit einer Wahrscheinlichkeit gleich dem Quadrat der Amplitude des entsprechenden Rechenbasisstands in der Superposition.
- Quantencircuits werden oft durch Quantencircuit-Diagramme dargestellt, bei denen Qubits als horizontale Leitungen und Quantengatter entlang dieser Leitungen von links nach rechts dargestellt werden.
- Um einen Quantencircuit auszuführen, verwenden wir die vier Schritte des Qiskit-Patterns-Arbeitsablaufs: Abbilden, Optimieren, Ausführen, Nachverarbeiten.
Aufgaben
Wahr/Falsch-Fragen
-
Ein einzelnes Bit in einem klassischen Computer kann nur den Wert 0 oder 1 speichern.
-
Verschränkung bedeutet, dass der Zustand eines Qubits unabhängig vom Zustand eines anderen ist.
-
Quantengatter sind im Allgemeinen irreversible Operationen.
-
Die Qiskit-Konvention platziert das am wenigsten signifikante Qubit, , an der linksten Position.
-
Eine Messung eines Quantenzustands liefert bei wiederholter Durchführung immer dasselbe Ergebnis.
-
Das Hadamard-Gate erzeugt Superposition in einem einzelnen Qubit.
-
Quantencircuits können Messoperationen enthalten, die den Superpositionszustand in einen der klassisch erlaubten Zustände kollabieren.
-
Die Anzahl möglicher klassischer Zustände für Bits beträgt .
-
Die Wahrscheinlichkeiten für Quantenmessungen werden durch die quadrierten Amplituden der klassisch messbaren Basiszustände angegeben.
Kurzantwort-Fragen
-
Was sind wesentliche Unterschiede zwischen einem Bit und einem Qubit?
-
Was passiert mit einem Quantenzustand, wenn er gemessen wird?
-
Warum verwenden wir in Qiskit die Little-Endian-Notation?
-
Was sind die vier Schritte des Qiskit-Patterns-Arbeitsablaufs?
Herausforderungsfragen:
-
Im Modul haben wir den Addierer nur für klassisch erlaubte Zustände von und verwendet. Aber wir können und auch in Superpositionen vorbereiten! Ändere den Code so, dass jedes Qubit in eine gleiche Superposition aus 0 und 1 gebracht wird, führe dann den neuen Circuit aus und erstelle ein neues Histogramm. Was siehst du? Erkläre, was passiert.
-
Toffoli-Gate-Zerlegung. Verwende
decompose(), um zu zeigen, wie das Toffoli-Gate in Einzel- und Zwei-Qubit-Gates zerlegt wird, und überprüfe diese Konstruktion dann mit Matrixmultiplikation. Beachte: Obwohl Circuit-Diagramme von links nach rechts gelesen werden, werden Matrizen auf Quantenzustände von rechts nach links angewendet!