Zum Hauptinhalt springen

Quanten-Fourier-Transformation

Für dieses Qiskit-in-Classrooms-Modul benötigen die Studierenden 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

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.

Single sinusoidal signal plotted as a function of time.

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

Frequency spectrum of the audio waveform. One clear sharp peak at 260 Hz.

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:

Displacement versus time graph of multiple sine waves at once, creating a more complicated periodic pattern.

Aber das Frequenzspektrum identifiziert klar drei Peaks:

Frequency spectrum of the above audio waveform. Three peaks at approximately 260 Hz, 330 Hz, and 392 Hz. The last peak is very weak, but visible.

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 NN Datenpunkten transformieren – keine kontinuierliche Funktion. In diesem Fall verwenden wir die diskrete Fourier-Transformation. Die diskrete Fourier-Transformation (DFT) wirkt auf einen Vektor (x0,...,xN1)(x_0, ..., x_{N-1}) und bildet ihn auf den Vektor (y0,...,yN1)(y_0, ..., y_{N-1}) gemäß der Formel ab:

yk=1Nj=0N1xjωNjky_k = \frac{1}{\sqrt{N}}\sum_{j=0}^{N-1}x_j\omega_N^{jk}

wobei wir ωNjk=e2πijkN\omega_N^{jk} = e^{2\pi i \frac{jk}{N}} setzen. (Beachte, dass es andere Konventionen mit einem Minuszeichen im Exponenten gibt, also sei vorsichtig, wenn du die DFT anderswo siehst.) Erinnere dich, dass e2πijkNe^{2\pi i \frac{jk}{N}} eine periodische Funktion mit der Periode Nk\frac{N}{k} ist. Durch die Multiplikation mit dieser Funktion ist die Fourier-Transformation also im Wesentlichen eine Möglichkeit, die (diskrete) Funktion {xj}\{x_{j}\} in eine Linearkombination ihrer periodischen Bestandteilfunktionen zu zerlegen, jede mit der Periode Nk\frac{N}{k}.

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 ψ|\psi\rangle in der Rechenbasis ausgedrückt werden als ψ=c00+c11|\psi\rangle = c_0 |0\rangle + c_1 |1\rangle, mit den Basiszuständen 0|0\rangle und 1|1\rangle, oder in der XX-Basis als ψ=c+++c|\psi\rangle = c_+ |+\rangle + c_- |-\rangle mit den Basiszuständen +=12(0+1)|+\rangle = \frac{1}{\sqrt{2}} (|0\rangle + |1\rangle) und =12(01)|-\rangle = \frac{1}{\sqrt{2}} (|0\rangle - |1\rangle). 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 ϕy|\phi_y\rangle anstelle der üblichen Rechenbasis-Zustände x|x\rangle dargestellt wird. Dazu musst du eine Quanten-Fourier-Transformation (QFT) anwenden:

ϕy=1Nx=0N1ωNyxx | \phi_y \rangle = \frac{1}{\sqrt{N}}\sum_{x=0}^{N-1}\omega_N^{y x} \vert x \rangle

mit ωNyx=e2πiyxN\omega_N^{yx} = e^{\frac{2\pi i y x}{N}} wie oben, und NN ist die Anzahl der Basiszustände in deinem Quantensystem. Beachte, dass wir nun mit Qubits arbeiten: mm Qubits ergeben 2m2^m Basiszustände, also N=2mN=2^m. Hier werden die Basiszustände als einzelne Zahl x|x\rangle geschrieben, wobei xx von 00 bis N1N-1 reicht, aber du siehst die Basiszustände möglicherweise typischerweise als 00...00|00...00\rangle, 00...01|00...01\rangle, 00...11|00...11\rangle, ..., 11...11|11...11\rangle ausgedrückt, wobei jede Binärziffer den Zustand von Qubit 0 bis m1m-1 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 00...00=0|00...00\rangle = |0\rangle, 00...01=1|00...01\rangle = |1\rangle, 00...10=2|00...10\rangle = |2\rangle, 00...11=3|00...11\rangle = |3\rangle, und so weiter, bis hin zu 11...11=2m1=N1|11...11\rangle = |2^m -1\rangle = |N-1\rangle.

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 00 oder 11 ist, und wir ordnen sie vom Zustand, in dem alle Qubits 00 sind, 00...00|00...00\rangle, bis zum Zustand, in dem alle 11 sind, 11...11|11...11\rangle.

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:

ϕ0=12(00+01+10+11)|\phi_0\rangle = \frac{1}{2} (|00\rangle + |01\rangle + |10\rangle + |11\rangle)

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 ϕ0|\phi_0\rangle bleibt die Phase konstant:

Bar graph of the complex amplitude (x-y plane) for each computational basis state (z-axis) for phi_0. They are all real, and so the bars all point to +1 on the x-axis

Der nächste Fourier-Basiszustand ist derjenige, dessen Komponentenphasen genau einmal von 00 bis 2π2\pi umlaufen:

ϕ1=12(00+eiπ/201+eiπ10+e3iπ/211)=12(00+i0110i11)|\phi_1\rangle = \frac{1}{2} (|00\rangle + e^{i\pi/2}|01\rangle + e^{i\pi}|10\rangle + e^{3i\pi/2}|11\rangle) = \frac{1}{2}(|00\rangle + i|01\rangle - |10\rangle - i|11\rangle)

Und wir können dieses Umlaufen im Diagramm der komplexen Amplitude gegenüber dem Rechenbasis-Zustand sehen:

Bar graph of the complex amplitude (x-y plane) for each computational basis state (z-axis) for phi_1. The red line shows how the complex phase accumulates such that it winds around 2\pi once as you step through all of the computational basis states.

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

ϕ2=12(00+eiπ01+e2iπ10+e3iπ11)=12(0001+1011)|\phi_2\rangle = \frac{1}{2} (|00\rangle + e^{i\pi}|01\rangle + e^{2i\pi}|10\rangle + e^{3i\pi}|11\rangle) = \frac{1}{2} (|00\rangle - |01\rangle + |10\rangle - |11\rangle)

Bar graph of the complex amplitude (x-y plane) for each computational basis state (z-axis) for phi_2. The red line shows how the complex phase accumulates such that it winds around 2\pi twice as you step through all of the computational basis states.

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 2π2\pi umlaufen:

ϕ3=12(00+e3iπ/201+e6iπ/210+e9iπ/211)=12(00i0110+i11)|\phi_3\rangle = \frac{1}{2} (|00\rangle + e^{3i\pi/2}|01\rangle + e^{6i\pi/2}|10\rangle + e^{9i\pi/2}|11\rangle) = \frac{1}{2} (|00\rangle - i|01\rangle - |10\rangle + i|11\rangle)

Bar graph of the complex amplitude (x-y plane) for each computational basis state (z-axis) for phi_3. The red line shows how the complex phase accumulates such that it winds around 2\pi three times as you step through all of the computational basis states.

Im Allgemeinen gibt es für einen mm-Qubit-Zustand 2m2^m Fourier-Basiszustände, deren Frequenz in der Phasenvariation von konstant für ϕ0|\phi_0\rangle bis schnell variierend für ϕ2m1|\phi_{2^m-1}\rangle reicht, wobei 2m12^m-1 Umläufe um 2π2\pi ü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")

Output of the previous code cell

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

Output of the previous code cell

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

Output of the previous code cell

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

Output of the previous code cell

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 ΔxΔp/2\Delta x \Delta p \ge \hbar / 2 formuliert. Wenn also die Unsicherheit in xx (Δx\Delta x) klein ist, muss die Unsicherheit im Impuls (Δp\Delta p) groß sein, und umgekehrt. Es stellt sich heraus, dass die Transformation von der Ortsbasis xx zur Impulsbasis pp 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:

ψ=12(0+N/2)=12(000...0+100...0)|\psi\rangle = \frac{1}{\sqrt{2}} (|0\rangle + |N/2\rangle) = \frac{1}{\sqrt{2}} (|000...0\rangle + |100...0\rangle)

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

Output of the previous code cell

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

Output of the previous code cell

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

Output of the previous code cell

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

Output of the previous code cell

Das hier könnte etwas überraschender sein. Es sieht so aus, als wäre die QFT des Zustands ψ=12(0+N/2)|\psi\rangle = \frac{1}{\sqrt{2}} (|0\rangle + |N/2\rangle) eine Überlagerung aller geraden Basiszustände. Aber wenn wir an unsere Visualisierung jedes Basiszustands ϕy|\phi_y\rangle zurückdenken und daran, wie die Phase jeder Komponente yy Mal um 2π2\pi 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 ψ=12(0+N/2)|\psi\rangle = \frac{1}{\sqrt{2}} (|0\rangle + |N/2\rangle) erhalten haben, zu erwarten ist.

Antwort:

Der ursprüngliche Zustand hat eine relative Phase von 0 (oder einem ganzzahligen Vielfachen von 2π2\pi) 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 ϕy|\phi_y\rangle besteht aus Termen, deren Phase mit einer Rate von 2πy/N2\pi y/N akkumuliert, was bedeutet, dass in der üblichen Reihenfolge jeder Term in der Überlagerung eine Phase von 2πy/N2\pi y/N mehr hat als der vorherige Term. Am Halbierungspunkt N/2N/2 soll also die Phase 2πy/NN/22\pi y/N * N/2 ein ganzzahliges Vielfaches von 2π2\pi sein. Das passiert, wenn yy 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 ψ=0N/2\psi = |0\rangle - |N/2\rangle 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. QFT2_2 transformiert die Rechenbasis-Zustände 0|0\rangle und 1|1\rangle in die Fourier-Basiszustände ϕ0\phi_0 und ϕ1\phi_1:

ϕ0=12(0+1)|\phi_0\rangle = \frac{1}{\sqrt{2}}(|0\rangle + |1\rangle)

ϕ1=12(01)|\phi_1\rangle = \frac{1}{\sqrt{2}}(|0\rangle - |1\rangle)

Ü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:

ϕy=1Nx=0N1ωNyxx | \phi_y \rangle = \frac{1}{\sqrt{N}}\sum_{x=0}^{N-1}\omega_N^{y x} \vert x \rangle

Für ein einzelnes Qubit (n=1n=1) ist N=2n=2N=2^n=2 und ωNxy=e2πiyx2\omega_N^{xy} = e^{2\pi i \frac {y x}{2}}. Wir erhalten also

ϕ0=12(e2πi0×020+e2πi0×121)=12(0+1) | \phi_0 \rangle = \frac{1}{\sqrt{2}}(e^{2\pi i \frac {0 \times 0}{2}}|0\rangle + e^{2\pi i \frac {0 \times 1}{2}}|1\rangle) = \frac{1}{\sqrt{2}}(|0\rangle + |1\rangle)

ϕ1=12(e2πi1×020+e2πi1×121)=12(01) | \phi_1 \rangle = \frac{1}{\sqrt{2}}(e^{2\pi i \frac {1 \times 0}{2}}|0\rangle + e^{2\pi i \frac {1 \times 1}{2}}|1\rangle) = \frac{1}{\sqrt{2}}(|0\rangle - |1\rangle)

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 0|0\rangle und 1|1\rangle in die jeweiligen Fourier-Basiszustände ϕ0|\phi_0\rangle und ϕ1|\phi_1\rangle transformiert. Es ist ein Hadamard-Gate! Das wird noch deutlicher, wenn wir eine Matrixdarstellung der QFTN_N-Operation einführen:

QFTN=1Nx=0N1y=0N1ωNxyxy \text{QFT}_N = \frac{1}{\sqrt{N}} \sum_{x=0}^{N-1} \sum_{y=0}^{N-1} \omega_N^{xy} \vert x \rangle \langle y \vert

Falls du mit dieser Notation zur Darstellung eines Quantenoperators nicht vertraut bist, ist das kein Problem! Es ist eine Möglichkeit, eine N×NN \times N-Matrix darzustellen, wobei xx und yy die Spalten und Zeilen der Matrix indexieren, von 00 bis N1N-1, und ωNxy\omega_N^{xy} der Wert des jeweiligen Eintrags ist. Der Eintrag in der 0-ten Spalte und 2-ten Zeile wäre beispielsweise einfach ωN0,2=e2πi0×2N=1\omega_N^{0,2} = e^{2 \pi i \frac{0 \times 2}{N}} = 1.

In dieser Darstellung wird jeder der Rechenbasis-Zustände einem der Basisvektoren zugeordnet:

(100),1=(010),N1=(001).\begin{pmatrix} 1 \\ 0 \\ \vdots \\ 0 \end{pmatrix}, |1\rangle = \begin{pmatrix} 0 \\ 1 \\ \vdots \\ 0 \end{pmatrix}, |N-1\rangle = \begin{pmatrix} 0 \\ 0 \\ \vdots \\ 1 \end{pmatrix}.

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 QFT4_4 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 α\alpha auf den Zustand des Ziel-Qubits anwendet, solange das Kontroll-Qubit im Zustand 1|1\rangle 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 11|11\rangle 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 QFT2m_{2^m}-Circuits auf mm Qubits ist iterativ – du wendest zuerst QFT2m1_{2^{m-1}} auf die Qubits 11 bis m1m-1 an und fügst dann einige Gates zwischen Qubit 00 und den anderen m1m-1 Qubits hinzu. Aber um QFT2m1_{2^{m-1}} anzuwenden, musst du zuerst QFT2m2_{2^{m-2}} auf die Qubits 2 bis m1m-1 anwenden und dann einige Gates zwischen Qubit 1 und den verbleibenden Qubits 22 bis m1m-1 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 QFT2_2 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:

  1. Wende zuerst QFT2m1_{2^{m-1}} auf die untersten m1m-1 Qubits an. Das ist deine „kleinere Puppe" des russischen Matroschka-Sets, die du bald in die nächstgrößere Puppe setzen wirst.
  2. Verwende das nächsthöhere Qubit als Kontrolle und wende kontrollierte Phasen-Gates auf jedes der unteren m1m-1 Qubits an, mit Phasen auf die Standardbasiszustände jedes der verbleibenden m1m-1 Qubits.
  3. Führe ein Hadamard auf demselben obersten Qubit durch, das als Kontrolle in den Phasen-Gates verwendet wurde.
  4. 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")

Output of the previous code cell

qc = QuantumCircuit(2)
qc.compose(QFTGate(2), inplace=True)
qc.decompose().draw("mpl")

Output of the previous code cell

qc = QuantumCircuit(3)
qc.compose(QFTGate(3), inplace=True)
qc.decompose().draw("mpl")

Output of the previous code cell

qc = QuantumCircuit(4)
qc.compose(QFTGate(4), inplace=True)
qc.decompose().draw("mpl")

Output of the previous code cell

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 λ\lambda eines unitären Operators einen Betrag λ=1|\lambda| = 1. Wir können also jeden Eigenwert als komplexe Zahl mit Betrag eins schreiben:

λ=e2πiθ\lambda = e^{2\pi i \theta}

wobei θ\theta 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 λ\lambda periodisch in θ\theta 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 θ=0\theta = 0 und θ=1/2\theta = 1/2 unterscheiden, aber nicht besser. Hier ist das Schaltkreisdiagramm:

Circuit diagram of the QPE algorithm for a single data qubit. A Hadamard is applied to the data qubit. Next, the algorithm uses another helper qubit, on which a controlled-U gate is applied, with the data qubit as the control. After another Hadamard on qubit 0, the qubits are measured.

Die Qubits werden im Zustand π0=ψ0|\pi_0\rangle = |\psi\rangle|0\rangle präpariert, wobei Qubit 00 im Zustand 0|0\rangle ist und die verbleibenden Qubits im Zustand ψ|\psi\rangle, der ein Eigenzustand von UU ist. Nach dem ersten Hadamard wird der Qubit-Zustand zu:

π1=12ψ(0+1)|\pi_1\rangle = \frac{1}{\sqrt{2}}|\psi\rangle (|0\rangle + |1\rangle)

Das nächste Gate ist ein „kontrolliertes-UU"-Gate. Dieses wendet die unitäre Operation UU auf die unteren Qubits an, die sich im Zustand ψ|\psi\rangle befinden, wenn Qubit 0 im Zustand 1|1\rangle ist, tut aber nichts mit ψ|\psi\rangle, wenn Qubit 0 im Zustand 0|0\rangle ist. Dies transformiert die Qubits in den Zustand:

π2=12(ψ0+e2πiθψ1)|\pi_2\rangle = \frac{1}{\sqrt{2}}( |\psi\rangle|0\rangle + e^{2\pi i \theta}|\psi\rangle|1\rangle) =12ψ(0+e2πiθ1)= \frac{1}{\sqrt{2}}|\psi\rangle (|0\rangle + e^{2\pi i \theta}|1\rangle)

Etwas Seltsames ist gerade passiert: Das kontrollierte-UU-Gate verwendet Qubit 00 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 00 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 00 an, was zum Zustand führt:

π3=ψ(1+e2πiθ20+1e2πiθ21)=ψ(cos(πθ)0isin(πθ)1)|\pi_3\rangle = |\psi\rangle ( \frac{1+e^{2\pi i \theta}}{2} |0\rangle + \frac{1 - e^{2\pi i \theta}}{2}|1\rangle) = |\psi\rangle ( \cos(\pi\theta) |0\rangle - i \sin(\pi\theta)|1\rangle)

Wenn wir also Qubit 00 am Ende messen, werden wir 0|0\rangle mit 100%iger Sicherheit messen, wenn θ=0\theta = 0, und wir werden 1|1\rangle mit 100%iger Sicherheit messen, wenn θ=12\theta = \frac{1}{2} (und wenn unser Quantencomputer perfekt ist, ohne Rauschen). Wenn θ\theta 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 00 zum Messen der Phase mm Qubits 00 bis m1m-1 verwenden, können wir die Phase mit mm Bit Präzision schätzen. Schauen wir, wie das funktioniert:

Circuit diagram of the QPE algorithm for a multiple qubits. Hadamards are applied to the data qubits 0 through m-1. Then a series of controlled-U gates are applied to the m helper qubits. Finally, an inverse QFT is applied to the qubits and they are measured.

Dieser präzisere QPE-Circuit beginnt genauso wie die Ein-Bit-Version: Hadamards werden auf die ersten mm Qubits angewendet, und die verbleibenden Qubits werden im Zustand ψ|\psi\rangle präpariert, was den Zustand erzeugt:

π1=12m/2ψ(0+1)(0+1)...(0+1)|\pi_1\rangle = \frac{1}{2^{m/2}}|\psi\rangle(|0\rangle+|1\rangle)(|0\rangle+|1\rangle)...(|0\rangle+|1\rangle)

Nun werden die kontrollierten Unitären angewendet. Qubit 00 ist die Kontrolle für dasselbe Unitäre UU wie zuvor. Aber jetzt ist Qubit 11 die Kontrolle für das Unitäre U2U^2, was einfach UU zweimal angewendet ist. Der Eigenwert von U2U^2 ist also e22πiθe^{2*2\pi i \theta}. Im Allgemeinen ist jedes Qubit kk von 0 bis m1m-1 die Kontrolle für das Unitäre U2kU^{2^k}. Das bedeutet, jedes dieser Qubits erfährt einen Phase-Kickback von e2k2πiθe^{2^k*2\pi i \theta}. Das ergibt den Zustand:

π2=ψ12m/2(0+e2m12πiθ1)(0+e2m22πiθ1)...(0+e2πiθ1)|\pi_2\rangle = |\psi\rangle \otimes \frac{1}{2^{m/2}} (|0\rangle+e^{2^{m-1}2\pi i \theta}|1\rangle)(|0\rangle+e^{2^{m-2}2\pi i \theta}|1\rangle)...(|0\rangle+e^{2\pi i \theta}|1\rangle)

Das kann als Summe über die Rechenbasis-Zustände umgeschrieben werden:

π2=ψ12m/2k=02m1e2πikθk|\pi_2\rangle = |\psi\rangle \otimes \frac{1}{2^{m/2}} \sum_{k=0}^{2^{m}-1} e^{2\pi i k \theta} |k\rangle

Kommt dir die Summe bekannt vor? Es ist eine QFT! Erinnere dich an die Gleichung für eine Quanten-Fourier-Transformation:

QFT2my=12mx=02m1ω2myxx \text{QFT}_{2^m}| y \rangle = \frac{1}{\sqrt{2^m}}\sum_{x=0}^{2^m-1}\omega_{2^m}^{y x} \vert x \rangle

Wenn also die Phase θ=y/2m\theta = y/2^m für eine ganze Zahl yy zwischen 00 und 2m12^m-1 ist, dann ergibt die inverse QFT dieses Zustands den Zustand:

π3=ψy|\pi_3\rangle = |\psi\rangle \otimes |y\rangle

und aus y|y\rangle können wir θ\theta ableiten.

Wenn θ/2m\theta/2^m kein ganzzahliges Vielfaches ist, dann wird die inverse QFT θ\theta nur approximieren. Wie gut sie θ\theta approximiert, ist probabilistisch, was bedeutet, dass wir nicht immer die beste Approximation erhalten, aber sie wird ziemlich nahe sein, und je mehr Qubits mm du verwendest, desto besser wird die Approximation. Um zu erfahren, wie man diese Approximation von θ\theta 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

  1. W/F Die Quanten-Fourier-Transformation ist das Quantenanalogon der klassischen diskreten Fourier-Transformation (DFT).
  2. W/F Die QFT kann nur mit Hadamard- und CNOT-Gates implementiert werden.
  3. W/F Die QFT ist eine Schlüsselkomponente von Shors Algorithmus.
  4. W/F Die Ausgabe der Quanten-Phasenschätzung ist ein Quantenzustand, der den Eigenvektor des Operators darstellt.
  5. W/F QPE erfordert die Verwendung der inversen Quanten-Fourier-Transformation (QFT^\dag).
  6. W/F In der QPE liefert der Algorithmus bei exakt mit nn Bits darstellbarer Phase ϕ\phi das korrekte Ergebnis mit Wahrscheinlichkeit 1.

Kurzantworten

  1. Wie viele Qubits werden benötigt, um eine QFT an einem System mit 2n2^n Datenpunkten durchzuführen?
  2. Kann die QFT auf einen Zustand angewendet werden, der kein Rechenbasis-Zustand ist? Wenn ja, was passiert?
  3. Wie beeinflusst die Anzahl der Kontroll-Qubits in der QPE die Auflösung der resultierenden Phasenschätzung?

Aufgaben

  1. Verwende Matrixmultiplikation, um zu verifizieren, dass die Schritte im QFT-Algorithmus tatsächlich die QFT4\text{QFT}_4-Matrix ergeben:
QFT4=12(11111i1i11111i1i)\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}

(Du musst das nicht von Hand machen!)

Bonusaufgaben

  1. Erstelle einen Vier-Qubit-Zustand, der eine gleichmäßige Überlagerung aller ungeraden Rechenbasen ist: ψ=0001+0011+0101+0111+1001+1011+1101+1111|\psi\rangle = |0001\rangle + |0011\rangle + |0101\rangle + |0111\rangle +|1001\rangle +|1011\rangle +|1101\rangle +|1111\rangle. 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.