Zum Hauptinhalt springen

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:

  • qiskit v2.1.0 oder neuer
  • qiskit-ibm-runtime v0.40.1 oder neuer
  • qiskit-aer v0.17.0 oder neuer
  • qiskit.visualization
  • numpy
  • pylatexenc

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 = 00004 = 01008 = 100012 = 1100
1 = 00015 = 01019 = 100113 = 1101
2 = 00106 = 011010 = 101014 = 1110
3 = 00117 = 011111 = 101115 = 1111

Um eine Binärzahl mit NN Bits in eine vertraute Dezimalzahl (Basis 10) umzurechnen, multiplizierst du das am wenigsten signifikante (rechteste) Bit mit 20=12^0 = 1, das nächste Bit links davon mit 21=22^1 = 2, dann das nächste mit 22=42^2 = 4 und so weiter, bis du das bedeutendste (linkste) Bit erreichst, das du mit 2N12^{N-1} multiplizierst.

Das bedeutet also, dass NN Bits in einem von 2N2^N 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 NN Bits kannst du die Zahlen 00 bis 2N12^N - 1 darstellen. Mit sechs Bits kommen wir also bis 261=632^6 - 1 = 63. Das reicht nicht ganz. Wir fügen ein weiteres Bit hinzu, um bis 271=1272^7 - 1 = 127 zu gelangen. Nun zerlegen wir 86 in Zweierpotenzen:

86=64+16+4+2=26×1+25×0+24×1+23×0+22×1+21×1+20×0=1010110\begin{aligned} 86 &= 64 + 16 + 4 + 2 \\ &= 2^6 \times 1 + 2^5 \times 0 + 2^4 \times 1 + 2^3 \times 0 + 2^2 \times 1 + 2^1 \times 1 + 2^0 \times 0 \\ &= 1010110 \end{aligned}

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:

EingangAusgang
01
10

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:

EingangAusgang
000
010
100
111

OR

OR ist ein weiteres Zwei-Bit-Gate mit einem einzelnen Ausgangsbit. Es gibt 1 aus, wenn eines der Bits 1 ist:

EingangAusgang
000
011
101
111

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:

EingangAusgang
000
011
101
110

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:

Klassisches Schaltkreisdiagramm für die Halb-Addierer-Schaltung. Ein XOR-Gate erzeugt das Sum-Ausgangsbit und ein AND-Gate erzeugt das Carry-Ausgangsbit.

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:

AABBSumme (ABA \oplus B)Übertrag (ABA \wedge B)
0000
0110
1010
1101

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 A+B=S+2×CA+B=S+2 \times C gilt.

Antwort:

0+0=0+0=0 0+1=1+0=1 1+0=1+0=1 1+1=0+2=2 \begin{aligned} 0+0 &= 0+0 = 0 ~\checkmark \\ 0+1 &= 1+0 = 1 ~\checkmark \\ 1+0 &= 1+0 = 1 ~\checkmark \\ 1+1 &= 0+2 = 2 ~\checkmark \\ \end{aligned}

Quantencomputer

Bits \rightarrow 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 0\vert 0\rangle und 1\vert 1\rangle bezeichnen. Aber anders als das klassische Bit kann ein Quanten-Bit auch in einer Superposition des 0\vert 0\rangle-Zustands und des 1\vert 1\rangle-Zustands gleichzeitig sein. Im Allgemeinen kann ein Qubit in einem beliebigen Zustand ψ\vert \psi\rangle der Form sein:

ψ=c00+c11\vert \psi\rangle = c_0 \vert 0\rangle + c_1 \vert 1\rangle

wobei c0c_0 und c1c_1 komplexe Amplituden mit c02+c12=1\vert c_0 \vert ^2+\vert c_1\vert ^2=1 sind.

Die Quantenphase

Da c0c_0 und c1c_1 komplex sind, kann jedes als ci=cieiϕic_i = \vert c_i\vert e^{i\phi_i} geschrieben werden, wobei ϕi\phi_i 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, eiϕ0e^{i\phi_0} „herauszufaktorisieren", was ergibt:

ψ=c00+c1eiϕ1\vert \psi\rangle = \vert c_0\vert \vert 0\rangle + \vert c_1\vert e^{i\phi}\vert 1\rangle

wobei ϕ=ϕ1ϕ0\phi = \phi_1-\phi_0 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 NN Bits in einem von 2N2^N möglichen Zuständen sein konnten, von Binärzahlen 000...000 bis 111...111. Aber jetzt, aufgrund des Superpositionsprinzips, können NN Qubits in einer Superposition von allen diesen Zuständen gleichzeitig sein!

Dies lässt sich ausdrücken als

ψN=i=02N1cii\psi_N = \sum_{i=0}^{2^N-1} c_i \vert i\rangle

wobei, wie im klassischen Fall, der Zustand i\vert i\rangle dem Zustand entspricht, in dem jedes Qubit in der richtigen Kombination aus 0en und 1en ist, um die Binärzahl ii 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:

ψ3=c0000+c1001+c2010+c3011+c4100+c5101+c6110+c7111\psi_3 = c_0 \vert 000\rangle + c_1 \vert 001\rangle + c_2 \vert 010\rangle + c_3 \vert 011\rangle + c_4 \vert 100\rangle + c_5 \vert 101\rangle + c_6 \vert 110\rangle + c_7 \vert 111\rangle

Jedes Qubit im System wird mit einem Index 00 bis N1N-1 bezeichnet. Die Konvention ist, die Qubit-Zustände von rechts nach links zu lesen, so dass der Zustand von Qubit 00 der am weitesten rechts stehende Zustand und der Zustand von Qubit N1N-1 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 00 mit dem am wenigsten signifikanten Bit zu assoziieren, das mit 202^0 multipliziert wird, und Qubit N1N-1 mit dem bedeutendsten Bit, das mit 2N12^{N-1} 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 c0=c3=12c_0 = c_3 = \frac{1}{\sqrt{2}} und c1=c2=0c_1 = c_2 = 0:

ψ=12(00+11)\vert \psi\rangle = \frac{1}{\sqrt{2}}(\vert 00\rangle + \vert 11\rangle)

Der Zustand von Qubit 0 kann also entweder 0\vert 0\rangle oder 1\vert 1\rangle 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 0\vert 0\rangle feststellen, dann wissen wir, dass Qubit 1 ebenfalls in 0\vert 0\rangle 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

ψ=12(01+10)\vert \psi\rangle = \frac{1}{\sqrt{2}}(\vert 01\rangle + \vert 10\rangle)

jedes Mal entgegengesetzte Ergebnisse: Wenn ein Qubit als 0\vert 0\rangle gemessen wird, ist das andere garantiert im Zustand 1\vert 1\rangle.

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 ψ=11\vert \psi\rangle = \vert 11\rangle 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 1\vert 1\rangle fixiert ist. Das Ergebnis der Messung eines Qubits hängt nicht wirklich vom anderen ab – beide sind einfach immer 1\vert 1\rangle.

Im Allgemeinen, wenn du den Zustand jedes Qubits separat beschreiben und dann so miteinander multiplizieren kannst:

ψ=ψ1ψ0\vert \psi\rangle = \vert \psi_1\rangle \vert \psi_0\rangle

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: 0=(10)\vert 0\rangle = \begin{pmatrix}1 \\ 0\end{pmatrix} 1=(01)\vert 1\rangle = \begin{pmatrix}0 \\ 1\end{pmatrix} Auf diese Weise kann ein beliebiger Zustand ψ=a0+b1\vert \psi\rangle = a\vert 0\rangle+b\vert 1\rangle als ψ=(ab)\vert \psi\rangle =\begin{pmatrix}a \\ b\end{pmatrix} geschrieben werden.

Für einen allgemeinen nn-Qubit-Zustand benötigen wir einen 2n2^n-dimensionalen Vektor, mit Basiszuständen in aufsteigender Binärwert-Reihenfolge:

0000=(1000),0001=1110=(0010),1111=(0001)\vert 0 \dots 000\rangle = \begin{pmatrix}1 \\ 0 \\ 0 \\ \vdots \\ 0\end{pmatrix}, \vert 0 \dots 001 \rangle = \vert 1 \dots 110\rangle = \begin{pmatrix}0 \\ \vdots \\ 0 \\ 1 \\ 0\end{pmatrix}, \vert 1 \dots 111 \rangle = \begin{pmatrix}0 \\ \vdots \\ 0 \\ 0\\ 1\end{pmatrix}

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:

00=(1000),01=(0100),,10=(0010),11=(0001)\vert 00\rangle = \begin{pmatrix}1 \\ 0 \\ 0 \\ 0\end{pmatrix}, \vert 01 \rangle = \begin{pmatrix}0 \\ 1 \\ 0 \\ 0\end{pmatrix}, \dots, \vert 10\rangle = \begin{pmatrix}0 \\ 0 \\ 1 \\ 0\end{pmatrix}, \vert 11 \rangle = \begin{pmatrix}0 \\ 0 \\ 0\\ 1\end{pmatrix}

Gates \rightarrow 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 0|0\rangle und 1|1\rangle 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

XX-Gate: Dies ist das quantenmechanische Äquivalent einer NOT-Operation. Seine Wahrheitstabelle sieht genauso aus wie das klassische NOT-Gate:

EingangAusgang
0\vert 0\rangle1\vert 1\rangle
1\vert 1\rangle0\vert 0\rangle

Und die Matrixdarstellung:

X=(0110)X=\begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}

In Qiskit sieht die Erstellung einer Schaltung mit einem XX-Gate so aus:

from qiskit import QuantumCircuit

qc = QuantumCircuit(1)
qc.x(0)
qc.draw("mpl")

Ausgabe der vorherigen Code-Zelle

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:

EingangAusgang
0\vert 0\rangle12(0+1)\frac{1}{\sqrt{2}}\left(\vert 0\rangle+\vert 1\rangle\right)
1\vert 1\rangle12(01)\frac{1}{\sqrt{2}}\left(\vert 0\rangle-\vert 1\rangle\right)

Matrixdarstellung: H=12(1111)H=\frac{1}{\sqrt{2}}\begin{pmatrix} 1 & 1 \\ 1 & -1 \end{pmatrix}

Eine Schaltung mit einem Hadamard-Gate wird wie folgt erstellt:

from qiskit import QuantumCircuit

qc = QuantumCircuit(1)
qc.h(0)
qc.draw("mpl")

Ausgabe der vorherigen Code-Zelle

ZZ-Gate: Fügt dem 1|1\rangle-Zustand eine Phasenverschiebung von Δϕ=π\Delta \phi = \pi hinzu:

EingangAusgang
0\vert 0\rangle0\vert 0\rangle
1\vert 1\rangle1-\vert 1\rangle

Z=(1001)Z=\begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}

In Qiskit sieht die Erstellung einer Schaltung mit einem ZZ-Gate so aus:

qc = QuantumCircuit(1)
qc.z(0)
qc.draw("mpl")

Ausgabe der vorherigen Code-Zelle

TT-Gate: Fügt dem 1|1\rangle-Zustand eine Phasenverschiebung von Δϕ=π/4\Delta \phi = \pi/4 hinzu:

EingangAusgang
0\vert 0\rangle0\vert 0\rangle
1\vert 1\rangleeiπ/41e^{i\pi/4}\vert 1\rangle

T=(100eiπ/4)T=\begin{pmatrix} 1 & 0 \\ 0 & e^{i\pi/4} \end{pmatrix}

In Qiskit sieht die Erstellung einer Schaltung mit einem TT-Gate so aus:

qc = QuantumCircuit(1)
qc.t(0)
qc.draw("mpl")

Ausgabe der vorherigen Code-Zelle

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 1\vert 1\rangle, wird ein XX-Gate auf das Ziel-Qubit angewendet; ist das Kontroll-Qubit im Zustand 0\vert 0\rangle, bleibt alles unverändert. In der folgenden Notation ist Qubit AA (ganz rechts) das Kontroll-Qubit und Qubit BB (ganz links) das Ziel-Qubit. Es gilt die Schreibweise CNOT(qcontrol,qtarget)BA.CNOT(q_{control},q_{target})\vert BA\rangle.

CNOT(A,B)BAinput=BAoutputCNOT(A,B)\vert BA\rangle_{input} = \vert BA\rangle_{output}

EingangAusgang
00\vert 00\rangle00\vert 00\rangle
01\vert 01\rangle11\vert 11\rangle
10\vert 10\rangle10\vert 10\rangle
11\vert 11\rangle01\vert 01\rangle

Die Matrix, die diese Wirkung darstellt, lautet:

CNOT=(1000000100100100)CNOT=\begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix}

qc = QuantumCircuit(2)
qc.cx(0, 1)
qc.draw("mpl")

Output of the previous code cell

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 q0q_0 das Kontroll-Qubit und q1q_1 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 q0,q1,...\vert q_0,q_1,...\rangle 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 01\vert 01\rangle hat.

Antwort:

CNOT01=(1000000100100100)(0100)=(0001)=11CNOT\vert 01\rangle =\begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix}\begin{pmatrix}0 \\ 1 \\ 0 \\0\end{pmatrix} = \begin{pmatrix}0 \\ 0 \\ 0 \\1\end{pmatrix} = \vert 11\rangle

SWAP-Gate: Dieses Gate tauscht die Zustände zweier Qubits. Wahrheitstabelle:

EingangAusgang
00\vert 00\rangle00\vert 00\rangle
01\vert 01\rangle10\vert 10\rangle
10\vert 10\rangle01\vert 01\rangle
11\vert 11\rangle11\vert 11\rangle

Die Matrix, die diese Wirkung darstellt, lautet:

SWAP=(1000001001000001)SWAP=\begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1\end{pmatrix}

qc = QuantumCircuit(2)
qc.swap(0, 1)
qc.draw("mpl")

Output of the previous code cell

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")

Output of the previous code cell

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:

(1000000100100100)(1000010000010010)(1000000100100100)=(1000001001000001)=SWAP \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix} \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0\end{pmatrix} \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix} = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1\end{pmatrix} = SWAP ~\checkmark

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:

EingangCNOT(A,B)CNOT(B,A)CNOT(A,B)
00\vert 00\rangle00\vert 00\rangle00\vert 00\rangle00\vert 00\rangle \checkmark
01\vert 01\rangle11\vert 11\rangle10\vert 10\rangle10\vert 10\rangle \checkmark
10\vert 10\rangle10\vert 10\rangle11\vert 11\rangle01\vert 01\rangle \checkmark
11\vert 11\rangle01\vert 01\rangle01\vert 01\rangle11\vert 11\rangle \checkmark

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 1\vert 1\rangle sind. Wir behalten die Reihenfolge-Konvention bei, die wir beim CNOT verwendet haben:

CCNOT(ControlA,ControlB,TargetC)CBACCNOT(Control A, Control B, Target C)\vert CBA\rangle

Die Wahrheitstabelle lautet:

EingangAusgang
000\vert 000\rangle000\vert 000\rangle
001\vert 001\rangle001\vert 001\rangle
010\vert 010\rangle010\vert 010\rangle
011\vert 011\rangle111\vert 111\rangle
100\vert 100\rangle100\vert 100\rangle
101\vert 101\rangle101\vert 101\rangle
110\vert 110\rangle110\vert 110\rangle
111\vert 111\rangle011\vert 011\rangle

Und die entsprechende Matrix lautet:

CCNOT=(1000000001000000001000000000000100001000000001000000001000010000)CCNOT=\begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\end{pmatrix}
qc = QuantumCircuit(3)
qc.ccx(0, 1, 2)
qc.draw("mpl")

Output of the previous code cell

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 NN-Qubit-Quantenzustand ψ=i=02N1cii\vert \psi\rangle = \sum_{i=0}^{2^N-1} c_i \vert i\rangle, kollabiert eine Messung den Zustand auf eine der Basisfunktionen i\vert i\rangle mit einer Wahrscheinlichkeit von ci2\vert c_i\vert ^2.

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")

Output of the previous code cell

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:

  1. Abbilden unseres Problems auf Quantencircuits und Operatoren
  2. Optimieren des Circuits für die Zielhardware
  3. Ausführen auf der Zielhardware
  4. 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 0\vert 0\rangle initialisiert werden, um die Summe und den Übertrag zu speichern. Unser vollständiger Quantenzustand besteht also aus den Qubits AA und BB sowie den Summen- und Übertrags-Qubits, die wir SS und CC nennen:

ψ=CSBA\vert \psi\rangle = \vert C S B A\rangle

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 AA und BB und dem Ziel-Qubit SS für beide. Wenn AA und BB verschieden sind, kippt einer der CNOT-Gates SS in den Zustand 1\vert 1\rangle. Wenn AA und BB beide 0\vert 0\rangle sind, bleibt SS unverändert im Zustand 0\vert 0\rangle. Wenn AA und BB beide 1\vert 1\rangle sind, wird SS zweimal umgekehrt und kehrt damit in den Zustand 0\vert 0\rangle 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 1\vert 1\rangle sind. Wenn das Ziel-Qubit mit dem Zustand 0\vert 0\rangle 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")

Output of the previous code cell

Oben ist das Circuit-Diagramm für den Quanten-Halbaddierer-Circuit. Wie bereits erwähnt, stellen die Leitungen die Qubits 00 bis 33 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 00- oder 11-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:

CCNOT(q0,q1,q3)CNOT(q1,q2)CNOT(q0,q2)q3q2q1q0CCNOT(q_0,q_1,q_3)CNOT(q_1, q_2)CNOT(q_0,q_2)\vert q_3 q_2 q_1 q_0\rangle

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")

Output of the previous code cell

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}

Output of the previous code cell

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 AA, BB, SS und CC und überprüfe, ob der Quanten-Addierer-Circuit korrekt funktioniert hat.

Antwort:

Wir müssen überprüfen, dass A+B=S+2×CA+B = S+2 \times C 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.

0+0=0+0×2=0 0 + 0 = 0 + 0 \times 2 = 0 ~\checkmark

Gehe zurück und ändere die Werte von AA und BB auf A=1A=1 und B=1B=1, 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:

1+1=0+1×2=2 1 + 1 = 0 + 1 \times 2 = 2 ~\checkmark

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 AA und BB 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, q0q_0, an der rechtesten Position und das signifikanteste Qubit, qNq_N, 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

  1. Ein einzelnes Bit in einem klassischen Computer kann nur den Wert 0 oder 1 speichern.

  2. Verschränkung bedeutet, dass der Zustand eines Qubits unabhängig vom Zustand eines anderen ist.

  3. Quantengatter sind im Allgemeinen irreversible Operationen.

  4. Die Qiskit-Konvention platziert das am wenigsten signifikante Qubit, q0q_0, an der linksten Position.

  5. Eine Messung eines Quantenzustands liefert bei wiederholter Durchführung immer dasselbe Ergebnis.

  6. Das Hadamard-Gate erzeugt Superposition in einem einzelnen Qubit.

  7. Quantencircuits können Messoperationen enthalten, die den Superpositionszustand in einen der klassisch erlaubten Zustände kollabieren.

  8. Die Anzahl möglicher klassischer Zustände für NN Bits beträgt 2N2N.

  9. Die Wahrscheinlichkeiten für Quantenmessungen werden durch die quadrierten Amplituden der klassisch messbaren Basiszustände angegeben.

Kurzantwort-Fragen

  1. Was sind wesentliche Unterschiede zwischen einem Bit und einem Qubit?

  2. Was passiert mit einem Quantenzustand, wenn er gemessen wird?

  3. Warum verwenden wir in Qiskit die Little-Endian-Notation?

  4. Was sind die vier Schritte des Qiskit-Patterns-Arbeitsablaufs?

Herausforderungsfragen:

  1. Im Modul haben wir den Addierer nur für klassisch erlaubte Zustände von AA und BB verwendet. Aber wir können AA und BB 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.

  2. 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!