Quanten-Fourier-Transformation
Für dieses Qiskit-in-Classrooms-Modul benötigen die Studierenden 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
Zur Einrichtung und Installation der oben genannten Pakete siehe die Anleitung Qiskit installieren. Um Jobs auf echten Quantencomputern auszuführen, müssen die Studierenden ein Konto bei IBM Quantum® einrichten, indem sie den Schritten in der Anleitung IBM Cloud-Konto einrichten folgen.
Dieses Modul wurde getestet und benötigte 13 Sekunden QPU-Zeit. Dies ist eine Schätzung nach bestem Wissen; dein tatsächlicher Verbrauch kann abweichen.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy 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
Eine Fourier-Transformation ist ein allgegenwärtiges Werkzeug mit Anwendungen in Mathematik, Physik, Signalverarbeitung, Datenkompression und unzähligen anderen Bereichen. Eine Quanten-Version der Fourier-Transformation, treffend als Quanten-Fourier-Transformation bezeichnet, bildet die Grundlage für einige der wichtigsten Quantenalgorithmen.
Heute werden wir nach einer Wiederholung der klassischen Fourier-Transformation besprechen, wie wir die Quanten-Fourier-Transformation auf einem Quantencomputer implementieren. Anschließend werden wir eine der Anwendungen der Quanten-Fourier-Transformation in einem Algorithmus namens Phasenschätzungsalgorithmus diskutieren. Die Quanten-Phasenschätzung ist eine Subroutine in Shors berühmtem Faktorisierungsalgorithmus, der manchmal als das „Kronjuwel" des Quantencomputings bezeichnet wird. Dieses Modul baut auf ein weiteres Modul über Shors Algorithmus auf, ist aber auch als eigenständiges Modul gedacht. Die Quanten-Fourier-Transformation ist für sich genommen ein faszinierender und nützlicher Algorithmus!
Die klassische Fourier-Transformation
Bevor wir in die Quanten-Fourier-Transformation einsteigen, erinnern wir uns zunächst an die klassische Version. Die Fourier-Transformation ist eine Methode zur Transformation von einer sogenannten „Basis" in eine andere. Du kannst dir zwei Basen als verschiedene Perspektiven desselben Problems vorstellen – beide sind gültige Wege, eine Funktion auszudrücken, aber je nach Problem kann die eine oder die andere aufschlussreicher sein. Einige Beispiele für Paare von Basen, die durch die Fourier-Transformation verbunden sind, sind Ort und Impuls sowie Zeit und Frequenz.
Schauen wir uns ein Beispiel an, wie uns die Fourier-Transformation helfen kann herauszufinden, welche Note ein Instrument spielt, basierend auf seiner Audio-Wellenform. Typischerweise sehen wir die Wellenformen in der Zeitbasis dargestellt – das heißt, die Amplitude der Welle wird als Funktion der Zeit ausgedrückt.

Wir können diese Wellenform fouriertransformieren, um von der Zeitbasis in die Frequenzbasis zu wechseln:

In der Frequenzbasis können wir deutlich einen Peak bei etwa 260 Hz erkennen. Das ist ein mittleres C!
Nun, du hättest vielleicht auch ohne Fourier-Transformation bestimmen können, dass ein mittleres C gespielt wurde, aber was ist, wenn mehrere Noten gleichzeitig gespielt werden? Dann wird die Wellenform komplizierter, wenn wir sie in der Zeitbasis darstellen:

Aber das Frequenzspektrum identifiziert klar drei Peaks:

Das war ein C-Dur-Akkord, der die Noten C, E und G spielt.
Diese Art der Fourier-Analyse kann uns helfen, die Frequenzkomponenten jedes beliebigen komplizierten Signals zu extrahieren.
Diskrete Fourier-Transformation
Die Fourier-Transformation ist für eine Vielzahl von Signalverarbeitungsanwendungen nützlich. Aber in den meisten dieser realen Anwendungen (einschließlich des Musikbeispiels, das wir oben verwendet haben) möchten wir einen diskreten Satz von Datenpunkten transformieren – keine kontinuierliche Funktion. In diesem Fall verwenden wir die diskrete Fourier-Transformation. Die diskrete Fourier-Transformation (DFT) wirkt auf einen Vektor und bildet ihn auf den Vektor gemäß der Formel ab:
wobei wir setzen. (Beachte, dass es andere Konventionen mit einem Minuszeichen im Exponenten gibt, also sei vorsichtig, wenn du die DFT anderswo siehst.) Erinnere dich, dass eine periodische Funktion mit der Periode ist. Durch die Multiplikation mit dieser Funktion ist die Fourier-Transformation also im Wesentlichen eine Möglichkeit, die (diskrete) Funktion in eine Linearkombination ihrer periodischen Bestandteilfunktionen zu zerlegen, jede mit der Periode .
Die Quanten-Fourier-Transformation
Nun haben wir also gesehen, wie die Fourier-Transformation verwendet wird, um eine Funktion als Linearkombination eines neuen Satzes sogenannter „Basisfunktionen" darzustellen. Basistransformationen werden regelmäßig auch an Qubit-Zuständen durchgeführt. Zum Beispiel kann der Zustand eines einzelnen Qubits in der Rechenbasis ausgedrückt werden als , mit den Basiszuständen und , oder in der -Basis als mit den Basiszuständen und . Beide sind gleichermaßen gültig, aber je nach Art des Problems, das du lösen möchtest, kann eine natürlicher sein als die andere.
Qubit-Zustände können auch in der Fourier-Basis ausgedrückt werden, wobei ein Zustand als Linearkombination der Fourier-Basiszustände anstelle der üblichen Rechenbasis-Zustände dargestellt wird. Dazu musst du eine Quanten-Fourier-Transformation (QFT) anwenden:
mit wie oben, und ist die Anzahl der Basiszustände in deinem Quantensystem. Beachte, dass wir nun mit Qubits arbeiten: Qubits ergeben Basiszustände, also . Hier werden die Basiszustände als einzelne Zahl geschrieben, wobei von bis reicht, aber du siehst die Basiszustände möglicherweise typischerweise als , , , ..., ausgedrückt, wobei jede Binärziffer den Zustand von Qubit 0 bis darstellt, von rechts nach links. Es gibt eine einfache Möglichkeit, diese Binärzustände in eine einzelne Zahl umzuwandeln: behandle sie einfach wie Binärzahlen! Also ist , , , , und so weiter, bis hin zu .
Intuition für die Fourier-Basiszustände aufbauen
Wir haben also gerade besprochen, was die Rechenbasis-Zustände sind und wie sie geordnet werden: Sie sind die Menge der Zustände, bei denen jedes Qubit entweder in oder ist, und wir ordnen sie vom Zustand, in dem alle Qubits sind, , bis zum Zustand, in dem alle sind, .
Aber wie können wir die Fourier-Basiszustände verstehen? Alle Fourier-Basiszustände sind gleichmäßige Überlagerungen aller Rechenbasis-Zustände, aber jeder Zustand unterscheidet sich von den anderen in der Periodizität der Phase der Komponenten. Um dies konkreter zu verstehen, schauen wir uns die vier Fourier-Basiszustände eines Zwei-Qubit-Systems an. Der niedrigste Fourier-Zustand ist einer, dessen Phase überhaupt nicht variiert:
Wir können diesen Zustand visualisieren, indem wir die komplexe Amplitude jedes Terms auftragen. Die rote Linie führt das Auge und zeigt dir, wie die Phase dieser Amplitude in der komplexen Ebene als Funktion des Rechenbasis-Zustands umläuft. Für bleibt die Phase konstant:

Der nächste Fourier-Basiszustand ist derjenige, dessen Komponentenphasen genau einmal von bis umlaufen:
Und wir können dieses Umlaufen im Diagramm der komplexen Amplitude gegenüber dem Rechenbasis-Zustand sehen:

Jeder Zustand hat also eine Phase, die Radiant höher ist als der vorherige Zustand, wenn sie in der Standardreihenfolge angeordnet werden, da wir in diesem Beispiel vier Basiszustände haben (). Der nächste Basiszustand läuft zweimal von 0 bis 2 um:

Schließlich ist die höchste Fourier-Komponente diejenige mit der am schnellsten variierenden Phase. Für unser Beispiel mit zwei Qubits ist es diejenige, deren Phasen dreimal von 0 bis umlaufen:

Im Allgemeinen gibt es für einen -Qubit-Zustand Fourier-Basiszustände, deren Frequenz in der Phasenvariation von konstant für bis schnell variierend für reicht, wobei Umläufe um über die Superposition der Zustände vollendet werden. Wenn wir also eine QFT eines Quantenzustands durchführen, machen wir im Wesentlichen die gleiche grundlegende Analyse, die wir für die musikalische Wellenform in der Einführung gemacht haben. Wir bestimmen die Fourier-Frequenzkomponenten, die zur Erzeugung des betrachteten Quantenzustands beitragen.
Einige Beispiel-QFTs ausprobieren
Versuchen wir, unsere Intuition für die Quanten-Fourier-Transformation weiter aufzubauen, indem wir einen Zustand in der Rechenbasis erstellen und dann schauen, was passiert, wenn wir die QFT darauf anwenden. Vorerst werden wir die QFT einfach als Black Box behandeln, die wir mit dem QFTGate aus der Qiskit Circuit Library anwenden. Später werden wir unter die Haube schauen, um zu sehen, wie sie implementiert ist.
Wir beginnen mit dem Laden der notwendigen Pakete und der Auswahl eines Geräts, auf dem wir unseren Circuit ausführen:
import numpy as np
from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
from qiskit.circuit.library import QFTGate
# Load the Qiskit Runtime service
from qiskit_ibm_runtime import QiskitRuntimeService
# Load the Runtime primitive and session
from qiskit_ibm_runtime import SamplerV2 as Sampler
service = QiskitRuntimeService()
# Use the least busy backend
# backend = service.least_busy(operational=True, simulator=False, min_num_qubits = 127)
backend = service.backend("ibm_pinguino2")
print(backend.name)
ibm_pinguino2
Wenn du keine verfügbare Zeit auf deinem Konto hast oder aus irgendeinem Grund einen Simulator verwenden möchtest, kannst du die folgende Zelle ausführen, um einen Simulator einzurichten, der das oben ausgewählte Quantengerät nachahmt:
# 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.
from qiskit.providers.fake_provider import GenericBackendV2
backend_gen = GenericBackendV2(num_qubits=18)
sampler_gen = BackendSamplerV2(backend=backend_gen)
Einzelner Rechenbasis-Zustand
Zuerst versuchen wir, einen einzelnen Rechenbasis-Zustand zu transformieren. Wir beginnen mit der Erstellung eines zufälligen Rechenbasis-Zustands:
# Step 1: Map
qubits = 4
N = 2**qubits
qc = QuantumCircuit(qubits)
# flip state of random qubits to put in a random single computational basis state
for i in range(1, qubits):
if np.random.randint(0, 2):
qc.x(i)
# make a copy of the above circuit. (to be used when we apply the QFT in next part)
qc_qft = qc.copy()
qc.measure_all()
qc.draw("mpl")
# 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)
# Step 3: Run the job on a real quantum computer OR try fake backend
sampler = Sampler(mode=backend)
pubs = [qc_isa]
# Run the job on real quantum device
job = sampler.run(pubs, shots=1000)
res = job.result()
counts = res[0].data.meas.get_counts()
# OR Run the job on the Aer simulator with noise model from real backend
# job = sampler_sim.run([qc_isa])
# res = job.result()
# counts = res[0].data.meas.get_counts()
# Step 4: Post-Process
plot_histogram(counts)
Jetzt transformieren wir diesen Zustand mit QFTGate mittels Fourier-Transformation:
# Step 1: Map
qc_qft.compose(QFTGate(qubits), inplace=True)
qc_qft.measure_all()
qc_qft.draw("mpl")
# 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_qft)
# Step 3: Run the job on a real quantum computer - try fake backend
sampler = Sampler(mode=backend)
pubs = [qc_isa]
# Run the job on real quantum device
job = sampler.run(pubs, shots=1000)
res = job.result()
counts = res[0].data.meas.get_counts()
# OR Run the job on the Aer simulator with noise model from real backend
# job = sampler_sim.run([qc_isa])
# res = job.result()
# counts = res[0].data.meas.get_counts()
# Step 4: Post-Process
plot_histogram(counts)
Wie du sehen kannst, messen wir die Besetzungen jedes Zustands als mehr oder weniger gleich, mit kleinen Abweichungen durch experimentelles und statistisches Rauschen. Wenn du also die QFT eines einzelnen Rechenbasis-Zustands nimmst, ist das Ergebnis eine gleichmäßige Überlagerung aller Zustände. Wenn du mit Fourier-Transformationen vertraut bist, überrascht dich das wahrscheinlich nicht. Ein grundlegendes Prinzip, das uns helfen kann, eine intuitive Verbindung zwischen einer Funktion und ihrer Fourier-Transformation herzustellen, ist, dass die Breite einer Funktion umgekehrt proportional zur Breite ihrer Fourier-Transformation ist. Etwas, das in der Zeit sehr lokalisiert ist, wie zum Beispiel ein sehr kurzer Puls, benötigt also einen breiten Bereich von Frequenzen, um diesen Puls zu erzeugen. Dieses Signal wird im Fourier-Raum sehr breit sein.
Diese Tatsache hängt tatsächlich mit der Quantenunsicherheit zusammen! Heisenbergs Unschärferelation wird typischerweise als formuliert. Wenn also die Unsicherheit in () klein ist, muss die Unsicherheit im Impuls () groß sein, und umgekehrt. Es stellt sich heraus, dass die Transformation von der Ortsbasis zur Impulsbasis durch eine Fourier-Transformation bewerkstelligt wird.
Hinweis: Bedenke, dass wir Besetzungen in jedem der Basiszustände messen, sodass wir Informationen über die relativen Phasen zwischen den verschiedenen Teilen der Überlagerung verlieren. Während also die QFT jedes einzelnen Rechenbasis-Zustands die gleiche gleichmäßige Verteilung der Besetzung über alle Basiszustände ergibt, werden die Phasen nicht notwendigerweise gleich sein.
Zwei Rechenbasis-Zustände
Nun schauen wir, was passiert, wenn wir eine Überlagerung von Rechenbasis-Zuständen präparieren. Was denkst du, wie die Fourier-Transformation in diesem Fall aussehen wird?
Wählen wir die Überlagerung:
# Step 1: Map
qubits = 4
N = 2**qubits
qc = QuantumCircuit(qubits)
# To make this state, we just need to apply a Hadamard to the last qubit
qc.h(qubits - 1)
qc_qft = qc.copy()
qc.measure_all()
qc.draw("mpl")
# First, let's go through steps 2-4 for the first circuit, qc
# 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)
# Step 3: Run the job on a real quantum computer - try fake backend
sampler = Sampler(mode=backend)
pubs = [qc_isa]
# Run the job on real quantum device
job = sampler.run(pubs, shots=1000)
res = job.result()
counts = res[0].data.meas.get_counts()
# OR run the job on the Aer simulator with noise model from real backend
# job = sampler_sim.run([qc_isa])
# res = job.result()
# counts = res[0].data.meas.get_counts()
# Step 4: Post-process
plot_histogram(counts)
Jetzt transformieren wir diesen Zustand mit QFTGate mittels Fourier-Transformation:
# Step 1: Map
qc_qft.compose(QFTGate(qubits), inplace=True)
qc_qft.measure_all()
qc_qft.draw("mpl")
# 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_qft)
# Step 3: Run the job on a real quantum computer OR try fake backend
sampler = Sampler(mode=backend)
pubs = [qc_isa]
# Run the job on real quantum device
job = sampler.run(pubs, shots=1000)
res = job.result()
counts = res[0].data.meas.get_counts()
# OR run the job on the Aer simulator with noise model from real backend
# job = sampler_sim.run([qc_isa])
# res = job.result()
# counts = res[0].data.meas.get_counts()
# Step 4: Post-process
plot_histogram(counts)
Das hier könnte etwas überraschender sein. Es sieht so aus, als wäre die QFT des Zustands eine Überlagerung aller geraden Basiszustände. Aber wenn wir an unsere Visualisierung jedes Basiszustands zurückdenken und daran, wie die Phase jeder Komponente Mal um umläuft, dann könnte der Grund für dieses Ergebnis klar werden.
Überprüfe dein Verständnis
Lies die Frage(n) unten, denke über deine Antwort nach und klicke dann auf das Dreieck, um die Lösung anzuzeigen.
Erkläre anhand des obigen Hinweises, warum das Ergebnis, das wir für die QFT von erhalten haben, zu erwarten ist.
Antwort:
Der ursprüngliche Zustand hat eine relative Phase von 0 (oder einem ganzzahligen Vielfachen von ) zwischen den beiden Teilen der Überlagerung. Wir wissen also, dass dieser Zustand Fourier-Komponenten hat, deren Phasen ebenfalls auf diese Weise übereinstimmen: diejenigen, die eine Phasenverschiebung von 0 zwischen dem |0000>-Term und dem |1000>-Term aufweisen. Jeder Fourier-Basiszustand besteht aus Termen, deren Phase mit einer Rate von akkumuliert, was bedeutet, dass in der üblichen Reihenfolge jeder Term in der Überlagerung eine Phase von mehr hat als der vorherige Term. Am Halbierungspunkt soll also die Phase ein ganzzahliges Vielfaches von sein. Das passiert, wenn gerade ist.
Welche Rechenbasis-Zustandsüberlagerung würde einer QFT mit Peaks auf jeder ungeraden Binärzahl entsprechen?
Antwort:
Wenn du die QFT des Zustands nehmen würdest, dann würdest du Peaks auf jedem ungeraden binärnummerierten Zustand sehen.
Den QFT-Algorithmus aufschlüsseln
Nachdem wir nun mehr Intuition für die Beziehung zwischen Qubit-Zuständen in der Rechenbasis und der Fourier-Basis gewonnen haben, schauen wir uns den QFT-Algorithmus selbst an. Mit anderen Worten: Welche Gates implementieren wir tatsächlich auf dem Quantencomputer, um diese Transformation zu erreichen?
Fangen wir klein an, mit einem einzelnen Qubit. Das bedeutet, wir haben zwei Basiszustände. QFT transformiert die Rechenbasis-Zustände und in die Fourier-Basiszustände und :
Überprüfe dein Verständnis
Lies die Frage(n) unten, denke über deine Antwort nach und klicke dann auf das Dreieck, um die Lösung anzuzeigen.
Verwende die Gleichung für die QFT aus dem vorherigen Abschnitt, um die beiden obigen Fourier-Basiszustände zu verifizieren.
Antwort:
Die allgemeine QFT-Formel lautet:
Für ein einzelnes Qubit () ist und . Wir erhalten also
Schau dir diese beiden Gleichungen an. Du kennst vielleicht schon ein Quantengatter, das zur Implementierung dieser Transformation verwendet werden kann. Es gibt nämlich ein Gate, das die Rechenbasis-Zustände und in die jeweiligen Fourier-Basiszustände und transformiert. Es ist ein Hadamard-Gate! Das wird noch deutlicher, wenn wir eine Matrixdarstellung der QFT-Operation einführen:
Falls du mit dieser Notation zur Darstellung eines Quantenoperators nicht vertraut bist, ist das kein Problem! Es ist eine Möglichkeit, eine -Matrix darzustellen, wobei und die Spalten und Zeilen der Matrix indexieren, von bis , und der Wert des jeweiligen Eintrags ist. Der Eintrag in der 0-ten Spalte und 2-ten Zeile wäre beispielsweise einfach .
In dieser Darstellung wird jeder der Rechenbasis-Zustände einem der Basisvektoren zugeordnet:
Wenn du mehr über diese Darstellung erfahren möchtest, siehe John Watrous' Lektion über mehrere Systeme im Kurs Grundlagen der Quanteninformation.
Versuchen wir, die Matrix für QFT zu konstruieren. Mit der obigen Formel finden wir, dass
\text\{QFT\}_4 = \frac\{1\}\{2\} \begin\{pmatrix\} 1 & 1 & 1 & 1 \\ 1 & i & -1 & -i \\ 1 & -1 & 1 & -1 \\ 1 & -i & -1 & i \\ \end\{pmatrix\}
Um diese Matrix auf einem Quantencomputer zu implementieren, müssen wir herausfinden, welche Kombination von Gates, angewendet auf welche Qubits, uns eine unitäre Transformation ergibt, die der obigen Matrix entspricht. Wir wissen bereits, dass eines der benötigten Gates das Hadamard ist. Ein weiteres Gate, das wir brauchen, ist das kontrollierte Phasen-Gate, das eine relative Phase auf den Zustand des Ziel-Qubits anwendet, solange das Kontroll-Qubit im Zustand ist. In Matrixform sieht das so aus:
\text\{CP\}_\alpha = \begin\{pmatrix\} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & e^\{i\alpha\} \\ \end\{pmatrix\}
Da nur der Zustand verändert wird, spielt es eigentlich keine Rolle, welches Qubit als „Kontroll-" und welches als „Ziel-"Qubit betrachtet wird. Das Ergebnis ist in beiden Fällen dasselbe.
Schließlich brauchen wir auch einige SWAP-Gates. Ein SWAP-Gate tauscht die Zustände zweier Qubits. Es sieht so aus:
\text\{SWAP\}_\alpha = \begin\{pmatrix\} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ \end\{pmatrix\}
Das Verfahren zur Konstruktion eines QFT-Circuits auf Qubits ist iterativ – du wendest zuerst QFT auf die Qubits bis an und fügst dann einige Gates zwischen Qubit und den anderen Qubits hinzu. Aber um QFT anzuwenden, musst du zuerst QFT auf die Qubits 2 bis anwenden und dann einige Gates zwischen Qubit 1 und den verbleibenden Qubits bis hinzufügen. Es ist wie eine russische Matroschka-Puppe: Jede Puppe fügt einen Faktor zwei in der Dimension des QFT-Circuits hinzu, wobei die kleinste Puppe ganz im Zentrum QFT oder das Hadamard-Gate ist.
Um eine Puppe in die nächstgrößere Puppe zu setzen und damit die Dimension der QFT um den Faktor zwei zu erhöhen, folgst du immer demselben Verfahren:
- Wende zuerst QFT auf die untersten Qubits an. Das ist deine „kleinere Puppe" des russischen Matroschka-Sets, die du bald in die nächstgrößere Puppe setzen wirst.
- Verwende das nächsthöhere Qubit als Kontrolle und wende kontrollierte Phasen-Gates auf jedes der unteren Qubits an, mit Phasen auf die Standardbasiszustände jedes der verbleibenden Qubits.
- Führe ein Hadamard auf demselben obersten Qubit durch, das als Kontrolle in den Phasen-Gates verwendet wurde.
- Verwende SWAP-Gates, um die Reihenfolge der Qubits zu permutieren, sodass das niedrigstwertige (obere) Bit zum höchstwertigen (unteren) Bit wird und alle anderen um eins nach oben rücken.
Wir haben bereits die QFTGate-Funktion aus der Qiskit Circuit Library verwendet, aber jetzt schauen wir in einige dieser QFT-Gates hinein, um das obige Verfahren zu verifizieren. Das können wir mit decompose() tun.
qc = QuantumCircuit(1)
qc.compose(QFTGate(1), inplace=True)
qc.decompose().draw("mpl")
qc = QuantumCircuit(2)
qc.compose(QFTGate(2), inplace=True)
qc.decompose().draw("mpl")
qc = QuantumCircuit(3)
qc.compose(QFTGate(3), inplace=True)
qc.decompose().draw("mpl")
qc = QuantumCircuit(4)
qc.compose(QFTGate(4), inplace=True)
qc.decompose().draw("mpl")
Hoffentlich kannst du anhand der ersten vier QFTs erkennen, wie jede in die nächstgrößere geschachtelt ist. Dir ist vielleicht aufgefallen, dass einige der Phasen-Gates nicht genau dem oben beschriebenen Verfahren entsprechen und die SWAPs nicht nach jeder Subroutine erscheinen, sondern nur ganz am Ende der vollständigen QFT. Das spart uns unnötige Gates, die den Circuit länger und fehleranfälliger machen würden. Anstatt den SWAP nach jeder geschachtelten Puppe zu implementieren, verfolgt der Circuit, wo sich jeder Qubit-Zustand befinden sollte, und passt die Qubits, auf die er die Phasen-Gates anwendet, entsprechend an. Dann bringt ein abschließender Satz von SWAPs am Ende alles an seinen richtigen Platz.
Die QFT anwenden: Phasenschätzung
Schauen wir, wie die QFT zur Lösung eines nützlichen Problems im Quantencomputing eingesetzt werden kann. Die Berechnung der inversen Quanten-Fourier-Transformation ist ein notwendiger Schritt in einem Algorithmus namens Quanten-Phasenschätzung (QPE), die selbst eine Subroutine in vielen anderen Algorithmen ist, einschließlich des „Kronjuwels" der Quantenalgorithmen, Shors Faktorisierungsalgorithmus.
Das Ziel der QPE ist die Schätzung der Eigenwerte eines unitären Operators. Unitäre Operatoren sind allgegenwärtig im Quantencomputing, und oft ist das Finden der Eigenwerte ihrer zugehörigen Eigenvektoren ein notwendiger Schritt in einem größeren Algorithmus. Je nach Problem kann ein Eigenwert eine Energie eines Hamiltonians in einem Simulationsproblem darstellen, kann uns helfen, Primfaktoren einer Zahl in Shors Algorithmus zu finden, oder kann andere wesentliche Informationen enthalten. QPE ist eine der wichtigsten und am weitesten verbreiteten Subroutinen im Quantencomputing.
Was hat das nun mit einer Quanten-Fourier-Transformation zu tun? Nun, wie du dich vielleicht erinnerst, hat jeder Eigenwert eines unitären Operators einen Betrag . Wir können also jeden Eigenwert als komplexe Zahl mit Betrag eins schreiben:
wobei eine reelle Zahl zwischen 0 und 1 ist. Wenn du mehr Informationen über unitäre Matrizen möchtest, siehe John Watrous' Lektion zu diesem Thema in Grundlagen der Quanteninformation.
Beachte, dass periodisch in ist. Das könnte dir bereits nahelegen, dass eine QFT beteiligt sein könnte, da wir gesehen haben, wie nützlich QFTs für die Analyse periodischer Funktionen sind. Im Folgenden werden wir den Algorithmus durchgehen und genau sehen, wie die QFT ins Spiel kommt.
Wie QPE funktioniert
Zunächst beginnen wir mit dem einfachsten QPE-Algorithmus, der die Phase grob auf eine einzige Binärziffer Genauigkeit schätzt. Mit anderen Worten, dieser Algorithmus kann zwischen und unterscheiden, aber nicht besser. Hier ist das Schaltkreisdiagramm:

Die Qubits werden im Zustand präpariert, wobei Qubit im Zustand ist und die verbleibenden Qubits im Zustand , der ein Eigenzustand von ist. Nach dem ersten Hadamard wird der Qubit-Zustand zu:
Das nächste Gate ist ein „kontrolliertes-"-Gate. Dieses wendet die unitäre Operation auf die unteren Qubits an, die sich im Zustand befinden, wenn Qubit 0 im Zustand ist, tut aber nichts mit , wenn Qubit 0 im Zustand ist. Dies transformiert die Qubits in den Zustand:
Etwas Seltsames ist gerade passiert: Das kontrollierte--Gate verwendet Qubit nur als Kontroll-Qubit, sodass man denken könnte, dass dieses Gate den Zustand von Qubit 0 überhaupt nicht ändern würde. Aber irgendwie tut es das! Obwohl die Operation auf die unteren Qubits angewendet wurde, besteht die Gesamtwirkung des Gates darin, die Phase von Qubit zu ändern. Dies ist als „Phase-Kickback-Mechanismus" bekannt und wird in vielen Quantenalgorithmen verwendet, einschließlich Deutsch-Jozsa und Grovers Algorithmen. Wenn du mehr über den Phase-Kickback-Mechanismus erfahren möchtest, siehe John Watrous' Lektion über Quanten-Abfragealgorithmen in Grundlagen der Quantenalgorithmen.
Nach dem Phase-Kickback wenden wir noch ein Hadamard auf Qubit an, was zum Zustand führt:
Wenn wir also Qubit am Ende messen, werden wir mit 100%iger Sicherheit messen, wenn , und wir werden mit 100%iger Sicherheit messen, wenn (und wenn unser Quantencomputer perfekt ist, ohne Rauschen). Wenn etwas anderes ist, ist die abschließende Messung nur probabilistisch und sagt uns nur begrenzt etwas aus.
QPE mit mehr Präzision: mehr Qubits
Wir können dieses einfache Konzept zu einem komplizierteren Algorithmus mit beliebiger Präzision erweitern. Wenn wir statt nur Qubit zum Messen der Phase Qubits bis verwenden, können wir die Phase mit Bit Präzision schätzen. Schauen wir, wie das funktioniert:
Dieser präzisere QPE-Circuit beginnt genauso wie die Ein-Bit-Version: Hadamards werden auf die ersten Qubits angewendet, und die verbleibenden Qubits werden im Zustand präpariert, was den Zustand erzeugt:
Nun werden die kontrollierten Unitären angewendet. Qubit ist die Kontrolle für dasselbe Unitäre wie zuvor. Aber jetzt ist Qubit die Kontrolle für das Unitäre , was einfach zweimal angewendet ist. Der Eigenwert von ist also . Im Allgemeinen ist jedes Qubit von 0 bis die Kontrolle für das Unitäre . Das bedeutet, jedes dieser Qubits erfährt einen Phase-Kickback von . Das ergibt den Zustand:
Das kann als Summe über die Rechenbasis-Zustände umgeschrieben werden:
Kommt dir die Summe bekannt vor? Es ist eine QFT! Erinnere dich an die Gleichung für eine Quanten-Fourier-Transformation:
Wenn also die Phase für eine ganze Zahl zwischen und ist, dann ergibt die inverse QFT dieses Zustands den Zustand:
und aus können wir ableiten.
Wenn kein ganzzahliges Vielfaches ist, dann wird die inverse QFT nur approximieren. Wie gut sie approximiert, ist probabilistisch, was bedeutet, dass wir nicht immer die beste Approximation erhalten, aber sie wird ziemlich nahe sein, und je mehr Qubits du verwendest, desto besser wird die Approximation. Um zu erfahren, wie man diese Approximation von quantifizieren kann, schaue dir John Watrous' Lektion über Phasenschätzung und Faktorisierung in Grundlagen der Quantenalgorithmen an.
Fazit
Dieses Modul gab einen Überblick darüber, was eine QFT ist, wie sie auf einem Quantencomputer implementiert wird und wie nützlich sie bei der Lösung von Problemen sein kann. Wir haben dir einen Vorgeschmack auf ihre Nützlichkeit gegeben, als wir gesehen haben, wie sie in der Quanten-Phasenschätzung verwendet werden kann, um etwas über die Eigenwerte einer unitären Matrix zu erfahren.
Zentrale Konzepte
- Die Quanten-Fourier-Transformation ist das Quantenanalogon zur diskreten Fourier-Transformation.
- Die QFT ist ein Beispiel für eine Basistransformation.
- Das Verfahren der Quanten-Phasenschätzung beruht auf dem Phase-Kickback-Mechanismus der kontrollierten unitären Operationen sowie einer inversen QFT.
- QFT und QPE sind beide weit verbreitete Subroutinen in zahlreichen Quantenalgorithmen.
Fragen
Wahr/Falsch
- W/F Die Quanten-Fourier-Transformation ist das Quantenanalogon der klassischen diskreten Fourier-Transformation (DFT).
- W/F Die QFT kann nur mit Hadamard- und CNOT-Gates implementiert werden.
- W/F Die QFT ist eine Schlüsselkomponente von Shors Algorithmus.
- W/F Die Ausgabe der Quanten-Phasenschätzung ist ein Quantenzustand, der den Eigenvektor des Operators darstellt.
- W/F QPE erfordert die Verwendung der inversen Quanten-Fourier-Transformation (QFT).
- W/F In der QPE liefert der Algorithmus bei exakt mit Bits darstellbarer Phase das korrekte Ergebnis mit Wahrscheinlichkeit 1.
Kurzantworten
- Wie viele Qubits werden benötigt, um eine QFT an einem System mit Datenpunkten durchzuführen?
- Kann die QFT auf einen Zustand angewendet werden, der kein Rechenbasis-Zustand ist? Wenn ja, was passiert?
- Wie beeinflusst die Anzahl der Kontroll-Qubits in der QPE die Auflösung der resultierenden Phasenschätzung?
Aufgaben
- Verwende Matrixmultiplikation, um zu verifizieren, dass die Schritte im QFT-Algorithmus tatsächlich die -Matrix ergeben:
(Du musst das nicht von Hand machen!)
Bonusaufgaben
- Erstelle einen Vier-Qubit-Zustand, der eine gleichmäßige Überlagerung aller ungeraden Rechenbasen ist: . Führe dann eine QFT auf dem Zustand durch. Was ist der resultierende Zustand? Erkläre, warum dein Ergebnis sinnvoll ist, unter Verwendung deines Wissens über Fourier-Transformationen.