Tutorial: Implementieren der Quanten fourier-Transformation in Q#

Hinweis

Microsoft Quantum Development Kit (classic QDK) wird nach dem 30. Juni 2024 nicht mehr unterstützt. Wenn Sie ein vorhandener QDK-Entwickler sind, empfehlen wir Ihnen, auf das neue Azure Quantum Development Kit (Modern QDK) umzusteigen, um die Entwicklung von Quantenlösungen fortzusetzen. Weitere Informationen finden Sie unter Migrieren ihres Q# Codes zum modernen QDK.

In diesem Tutorial erfahren Sie, wie Sie ein einfaches Quantenprogramm schreiben und simulieren, das mit einzelnen Qubits arbeitet.

Q# wurde zwar in erster Linie als Programmiersprache auf hoher Ebene für umfangreiche Quantenprogramme entwickelt, eignet sich aber genauso gut zur Erkundung der unteren Ebene von Quantenprogrammen: die direkte Adressierung bestimmter Qubits. In diesem Tutorial wird insbesondere die Quanten fourier-Transformation (QFT) genauer betrachtet, eine Unterroutine, die für viele größere Quantenalgorithmen von wesentlicher Bedeutung ist.

In diesem Tutorial lernen Sie Folgendes:

  • Definieren Sie Quantenvorgänge in Q#.
  • Schreiben der Quantum Fourier Transform-Leitung
  • Simulieren Sie einen Quantenvorgang von der Qubitzuordnung zur Messausgabe.
  • Beobachten Sie, wie sich die simulierte Wellenfunktion des Quantensystems während des Vorgangs entwickelt.

Hinweis

Diese Betrachtung der Verarbeitung von Quanteninformationen auf niedrigerer Ebene wird häufig in Form von Quantenschaltungen beschrieben, die die sequenzielle Anwendung von Gates (oder Vorgängen) auf bestimmte Qubits eines Systems darstellen. Daher können die sequenziell angewendeten Einzel- und Multi-Qubit-Vorgänge problemlos in Schaltungsdiagrammen dargestellt werden. Die in diesem Tutorial verwendete vollständige Drei-Qubit-Quanten fourier-Transformation weist beispielsweise die folgende Darstellung als Schaltung auf: Diagramm einer Quanten fourier-Transformationsschaltung.

Tipp

Wenn Sie Ihren Weg zum Quantencomputing beschleunigen möchten, lesen Sie Code mit Azure Quantum, ein einzigartiges Feature der Azure Quantum-Website. Hier können Sie integrierte Q# Beispiele oder Ihre eigenen Q# Programme ausführen, neuen Q# Code aus Ihren Eingabeaufforderungen generieren, Ihren Code in VS Code für das Web mit einem Klick öffnen und ausführen und Copilot Fragen zum Quantencomputing stellen.

Voraussetzungen

Create einer neuen Q# Datei

  1. Wählen Sie in VS Code Die Option Datei > Neue Textdatei aus.
  2. Speichern Sie die Datei als QFTcircuit.qs. Diese Datei enthält den Q# Code für Ihr Programm.
  3. Öffnen Sie QFTcircuit.qs.

Schreiben einer QFT-Verbindung in Q#

Der erste Teil dieses Tutorials besteht aus der Definition des Q#Vorgangs Perform3qubitQFT, der die Fourier-Quantentransformation für drei Qubits ausführt. Die DumpMachine-Funktion wird verwendet, um zu beobachten, wie sich die simulierte Wellenfunktion des Drei-Qubit-Systems im Laufe des Vorgangs entwickelt. Im zweiten Teil des Tutorials werden Messfunktionen hinzugefügt und die Zustände vor und nach der Messung der Qubits miteinander verglichen.

Der Vorgang wird Schritt für Schritt aufgebaut. Kopieren Sie den Code in den folgenden Abschnitten, und fügen Sie ihn in die Datei QFTcircuit.qs ein.

Sie können den vollständigen Q# Code für diesen Abschnitt als Referenz anzeigen.

Namespaces für den Zugriff auf andere Q# Vorgänge

Definieren Sie in Ihrer Q#-Datei den Namespace NamespaceQFT. Auf diesen wird durch den Compiler zugegriffen. Öffnen Sie die relevanten Namespaces vom Typ Microsoft.Quantum.*, damit dieser Vorgang bereits vorhandene Q#-Vorgänge verwendet.

namespace NamespaceQFT {
    open Microsoft.Quantum.Intrinsic;
    open Microsoft.Quantum.Diagnostics;
    open Microsoft.Quantum.Math;
    open Microsoft.Quantum.Arrays;

    // operations go here
}

Definieren von Vorgängen mit Argumenten und Rückgaben

Definieren Sie als Nächstes den Vorgang Perform3qubitQFT:

operation Perform3qubitQFT() : Unit {
    // do stuff
}

Der Vorgang verwendet vorerst noch keine Argumente und gibt ein Unit-Objekt zurück – analog zur Rückgabe von void in C# oder zur Rückgabe eines leeren Tupels (Tuple[()]) in Python. Später wird der Vorgang geändert, um ein Array von Messergebnissen zurückzugeben.

Zuordnen von Qubits

Ordnen Sie innerhalb des Vorgangs Q# dem Schlüsselwort (keyword) ein Register von use drei Qubits zu. Bei use werden die Qubits automatisch im $\ket {0} $-Zustand zugeordnet.

use qs = Qubit[3]; // allocate three qubits

Message("Initial state |000>:");
DumpMachine();

Genau wie bei echten Quantenberechnungen kann mit Q# nicht direkt auf Qubitzustände zugegriffen werden. Der DumpMachine Vorgang gibt jedoch den aktuellen Zustand des target Computers aus, sodass er wertvolle Einblicke für das Debuggen und Lernen bieten kann, wenn er in Verbindung mit dem vollständigen Zustandssimulator verwendet wird.

Anwenden von Einzel qubit- und kontrollierten Vorgängen

Als Nächstes wenden Sie die Vorgänge an, aus denen sich der Perform3qubitQFT Vorgang selbst zusammensetzt. Diese und viele weitere grundlegende Quantenvorgänge sind in Q# bereits im Namespace Microsoft.Quantum.Intrinsic enthalten.

Als Erstes wird der H-Vorgang (Hadamard) auf das erste Qubit angewendet:

Diagramm: Leitung für drei Qubit-QFT bis zum ersten Hadamard

Verwenden Sie die Standardindexnotation, um einen Vorgang auf ein bestimmtes Qubit aus einem Register anzuwenden – etwa ein einzelnes Qubit aus einem Array (Qubit[]). Wenn Sie also den H-Vorgang auf das erste Qubit des Registers qs anwenden, sieht das wie folgt aus:

H(qs[0]);

Neben der Anwendung des H-Vorgangs auf einzelne Qubits besteht die QFT-Schaltung in erster Linie aus gesteuerten R1-Rotationen. Bei einem R1(θ, <qubit>) Vorgang bleibt die $\ket{0}$-Komponente des Qubits im Allgemeinen unverändert, während eine Drehung von $e^{i\theta}$ auf die $\ket{1}$-Komponente angewendet wird.

Mit Q# ist es einfach, die Ausführung eines Vorgangs auf einzelne oder mehrere Steuerqubits zu konditionieren. Im Allgemeinen wird dem Aufruf Controlled vorangestellt, und die Vorgangsargumente ändern sich wie folgt:

Op(<normal args>) $\to$ Controlled Op([<control qubits>], (<normal args>))

Beachten Sie, dass es sich bei den Steuerqubits um ein Array handeln muss. Das gilt auch im Falle eines einzelnen Qubits.

Die kontrollierten Vorgänge im QFT sind die Vorgänge, die R1 auf das erste Qubit reagieren (und von den zweiten und dritten Qubits gesteuert werden):

Diagramm, das eine Schaltung für drei Qubit-Quanten fourier-Transformation durch das erste Qubit zeigt.

Rufen Sie diese Vorgänge in Ihrer Q#-Datei mit den folgenden Anweisungen auf:

Controlled R1([qs[1]], (PI()/2.0, qs[0]));
Controlled R1([qs[2]], (PI()/4.0, qs[0]));

Die Funktion PI() dient zum Definieren der Rotationen im Hinblick auf Pi Radiant.

Swap-Vorgang anwenden

Nachdem die relevanten H Vorgänge und kontrollierten Drehungen auf das zweite und dritte Qubit angewendet wurden, sieht die Schaltung wie folgt aus:

//second qubit:
H(qs[1]);
Controlled R1([qs[2]], (PI()/2.0, qs[1]));

//third qubit:
H(qs[2]);

Schließlich wenden Sie einen SWAP Vorgang auf das erste und dritte Qubit an, um die Verbindung abzuschließen. Dies ist notwendig, weil die Natur der Quanten-Fourier-Transformation die Qubits in umgekehrter Reihenfolge ausgibt, so dass die Vertauschungen eine nahtlose Integration der Subroutine in größere Algorithmen ermöglichen.

SWAP(qs[2], qs[0]);

Die Vorgänge auf Qubit-Ebene der Quantum-Fourier-Transformation in Ihrem Q#-Vorgang sind damit fertig geschrieben:

Diagramm, das eine Schaltung für drei Qubit-Quanten fourier-Transformation zeigt.

Qubits freigeben

Der letzte Schritt besteht darin, erneut DumpMachine() aufzurufen, um den Zustand nach dem Vorgang anzuzeigen und die Zuordnung der Qubits aufzuheben. Die Qubits befanden sich bei der Zuordnung im Zustand $\ket{0}$ und müssen mithilfe des ResetAll-Vorgangs wieder in ihren ursprünglichen Zustand zurückversetzt werden.

Die Anforderung, dass alle Qubits explizit auf $\ket{0}$ zurückgesetzt werden, ist ein grundlegendes Feature von Q#, da es anderen Vorgängen ermöglicht, ihren Zustand genau zu kennen, wenn sie mit der Verwendung derselben Qubits beginnen (eine knappe Ressource). Darüber hinaus wird dadurch sichergestellt, dass sie nicht mit anderen Qubits im System verschränkt sind. Wenn das Zurücksetzen nicht am Ende eines use-Zuordnungsblocks durchgeführt wird, kann ein Laufzeitfehler ausgelöst werden.

Fügen Sie Ihrer Q#-Datei folgende Zeilen hinzu:

Message("After:");
DumpMachine();

ResetAll(qs); // deallocate qubits

Der vollständige QFT-Vorgang

Das Q# Programm ist abgeschlossen. Ihre QFTcircuit.qs-Datei sollte jetzt wie folgt aussehen:

namespace NamespaceQFT {
    open Microsoft.Quantum.Intrinsic;
    open Microsoft.Quantum.Diagnostics;
    open Microsoft.Quantum.Math;
    open Microsoft.Quantum.Arrays;

    operation Perform3qubitQFT() : Unit {

        use qs = Qubit[3]; // allocate three qubits

        Message("Initial state |000>:");
        DumpMachine();

        //QFT:
        //first qubit:
        H(qs[0]);
        Controlled R1([qs[1]], (PI()/2.0, qs[0]));
        Controlled R1([qs[2]], (PI()/4.0, qs[0]));

        //second qubit:
        H(qs[1]);
        Controlled R1([qs[2]], (PI()/2.0, qs[1]));

        //third qubit:
        H(qs[2]);

        SWAP(qs[2], qs[0]);

        Message("After:");
        DumpMachine();

        ResetAll(qs); // deallocate qubits

    }
}

Ausführen der QFT-Verbindung

Derzeit gibt der Perform3qubitQFT Vorgang keinen Wert zurück, der Vorgang gibt einen Wert zurück Unit . Später ändern Sie den Vorgang, um ein Array von Messergebnissen (Result[]) zurückzugeben.

  1. Wenn Sie ein Q# Programm ausführen, müssen Sie der Q# Datei ein EntryPoint hinzufügen. Dieses Attribut teilt dem Compiler mit, dass dieser Vorgang der Einstiegspunkt in das Programm ist. Fügen Sie die folgende Zeile am Anfang der Q# Datei vor dem Perform3qubitQFT Vorgang hinzu:

    @EntryPoint()
    operation Perform3qubitQFT() : Unit {
    
  2. Bevor Sie das Programm ausführen, müssen Sie das target Profil auf Uneingeschränkt festlegen. Wählen Sie Ansicht –> Befehlspalette aus, suchen Sie nach QIR, wählen SieQ# : Legen Sie das Azure Quantum QIR-Profil target fest, und wählen Sie dann : uneingeschränkt ausQ#.

  3. Wählen Sie zum Ausführen des Programms in der Dropdownliste des Wiedergabesymbols oben rechts die Option Datei ausführen Q# aus, oder drücken Sie STRG+F5. Das Programm führt den Vorgang oder die Funktion aus, die mit dem @EntryPoint() -Attribut im Standardsimulator gekennzeichnet ist.

  4. Die Message Ausgaben und DumpMachine werden in der Debugkonsole angezeigt.

Hinweis

Wenn das target Profil nicht auf Uneingeschränkt festgelegt ist, wird beim Ausführen des Programms eine Fehlermeldung angezeigt.

Grundlegendes zur Ausgabe der QFT-Leitung

Beim Aufruf des Vollzustandssimulators liefert DumpMachine() diese mehrfachen Darstellungen der Wellenfunktion des Quantenzustands. Die möglichen Zustände eines $n$-Qubit-Systems lassen sich durch $2^n$ rechnerische Basiszustände darstellen, jeweils mit einem entsprechenden komplexen Koeffizienten (eine Amplitude und eine Phase). Die rechnerischen Basiszustände entsprechen allen möglichen binären Zeichenfolgen der Länge $n$ – also allen möglichen Kombinationen der Qubitzustände $\ket{0}$ und $\ket{1}$, wobei jede Binärstelle einem einzelnen Qubit entspricht.

Die erste Zeile enthält einen Kommentar mit den IDs der entsprechenden Qubits in ihrer signifikanten Reihenfolge. Dass das Qubit 2 das signifikanteste ist, bedeutet, dass in der binären Darstellung des Basiszustandsvektors $\ket{i}$ der Zustand des Qubits 2 der äußerst linken Ziffer entspricht. Beispielsweise umfasst $\ket {6} = \ket {110} $ Qubits und beide in 2 $\ket1$ und {1} Qubit in 0 $\ket{0}$.

Die restlichen Zeilen beschreiben die Wahrscheinlichkeitsamplitude der Messung des Basiszustandsvektors $\ket{i}$ im kartesischen und polaren Format. Im Anschluss wird die erste Zeile für den Eingabezustand $\ket{000}$ untersucht:

  • |0>: Diese Zeile entspricht dem rechnerischen Basiszustand 0. (Da der Ausgangszustand nach der Zuweisung $\ket{000}$ war, ist zu erwarten, dass dies der einzige Zustand mit einer Wahrscheinlichkeitsamplitude an diesem Punkt ist.)
  • 1.000000 + 0.000000 i: Die Wahrscheinlichkeitsamplitude im kartesischen Format.
  • == : Das Zeichen equal trennt die beiden gleichwertigen Darstellungen.
  • ********************: Eine grafische Darstellung der Größenordnung. Die Anzahl von * ist proportional zur Wahrscheinlichkeit der Messung dieses Zustandsvektors.
  • [ 1.000000 ]: Der numerische Wert der Größenordnung.
  • --- : Eine grafische Darstellung der Amplitudenphase.
  • [ 0.0000 rad ]: Der numerische Wert der Phase (im Bogenmaß).

Sowohl der Betrag als auch die Phase werden in einer grafischen Darstellung angezeigt. Die Größenordnung wird einfach durch einen Balken mit *-Zeichen dargestellt. Je höher die Wahrscheinlichkeit, desto länger der Balken.

Die angezeigte Ausgabe veranschaulicht, dass der Zustand durch die programmierten Vorgänge transformiert wurde: von

$$ \ket{\psi}_{initial} = \ket{000} $$

in

$$ \begin{align} \ket{\psi}_{final} &= \frac{1}{\sqrt{8}} \left( \ket{000} + \ket{001} + \ket{010} + \ket + \ket + \ket + \kett{101}{100}{110}{011} + \ket{111} \right) \\ &= \frac{1}{\sqrt{2^n}}\sum_{j=0}^{2^n-1} \ket{j}, \end{align} $$

Das entspricht exakt dem Verhalten der Fourier-Transformation mit drei Qubits.

Wenn Sie sich für die Auswirkungen auf andere Eingangszustände interessieren, können Sie gerne mit der Anwendung anderer Qubit-Vorgänge vor der Transformation experimentieren.

Hinzufügen von Messungen zur QFT-Leitung

Die Anzeige der DumpMachine-Funktion enthielt zwar die Ergebnisse des Vorgangs, leider besagt jedoch ein Eckpunkt der Quantenmechanik, dass ein echtes Quantensystem keine solche DumpMachine-Funktion haben kann. Stattdessen werden die Informationen durch Messungen extrahiert, was im Allgemeinen keine Informationen zum vollständigen Quantenzustand liefert und auch das System selbst drastisch verändern kann.

Es gibt viele Arten von Quantenmessungen. Im vorliegenden Beispiel wird jedoch die grundlegendste Option verwendet: projektive Messungen für einzelne Qubits. Nach der Messung in einer bestimmten Basis (z  B. der Rechenbasis { \ket{0}, \ket{1} } $) wird der Qubit-Zustand auf den gemessenen Basiszustand projiziert und damit jegliche Superposition zwischen den beiden zerstört.

Ändern des QFT-Vorgangs

Verwenden Sie den M-Vorgang, der einen Result-Typ zurückgibt, um Messungen innerhalb eines Q#-Programms zu implementieren.

Ändern Sie zunächst den Vorgang Perform3QubitQFT so, dass anstelle von Unit ein Array von Messergebnissen (Result[]) zurückgegeben wird.

operation Perform3QubitQFT() : Result[] {

Definieren und Initialisieren einer Result[] Array

Deklarieren und binden Sie vor der Zuweisung von Qubits ein Array mit drei Elementen (eines Result für jedes Qubit):

mutable resultArray = [Zero, size = 3];

Das Schlüsselwort mutable vor resultArray sorgt dafür, dass die Variable später im Code geändert werden kann – etwa beim Hinzufügen der Messergebnisse.

Messungen in einer for-Schleife durchführen und Ergebnisse zum Array hinzufügen

Fügen Sie nach den QFT-Transformationsvorgängen den folgenden Code ein:

for i in IndexRange(qs) {
    set resultArray w/= i <- M(qs[i]);
}

Wenn die IndexRange-Funktion für ein Array (z. B. für das Qubit-Array qs) aufgerufen wird, wird ein Bereich über die Indizes des Arrays zurückgegeben. Hier wird die Schleife for verwendet, um die einzelnen Qubits nacheinander mithilfe der Anweisung M(qs[i]) zu messen. Jeder gemessene Result-Typ (entweder Zero oder One ) wird dann resultArray mit einer Update-and-Reassign-Anweisung an der entsprechenden Indexposition in hinzugefügt.

Hinweis

Die Syntax dieser Anweisung ist einzigartig in Q#, entspricht aber der ähnlichen Variablenneuzuweisung resultArray[i] <- M(qs[i]) in anderen Sprachen wie F# und R.

Das Schlüsselwort wird immer verwendet, um Variablen neu zu set zuweisen, die mithilfe von gebunden mutable sind.

resultArray zurückgeben

Nachdem alle drei Qubits gemessen und die Ergebnisse zu resultArray hinzugefügt wurden, können die Qubits wie zuvor zurückgesetzt und freigegeben werden. Um die Messungen zurückzugeben, geben Sie Folgendes ein:

return resultArray;

Ausführen der QFT-Leitung mit den Messungen

Ändern Sie nun die Platzierung der DumpMachine-Funktionen, um den Zustand vor und nach den Messungen auszugeben. Der fertige Q#-Code sollte wie folgt aussehen:

namespace NamespaceQFT {
    open Microsoft.Quantum.Intrinsic;
    open Microsoft.Quantum.Diagnostics;
    open Microsoft.Quantum.Math;
    open Microsoft.Quantum.Arrays;

    operation Perform3QubitQFT() : Result[] {

        mutable resultArray = [Zero, size = 3];

        use qs = Qubit[3];

        //QFT:
        //first qubit:
        H(qs[0]);
        Controlled R1([qs[1]], (PI()/2.0, qs[0]));
        Controlled R1([qs[2]], (PI()/4.0, qs[0]));

        //second qubit:
        H(qs[1]);
        Controlled R1([qs[2]], (PI()/2.0, qs[1]));

        //third qubit:
        H(qs[2]);

        SWAP(qs[2], qs[0]);

        Message("Before measurement: ");
        DumpMachine();

        for i in IndexRange(qs) {
            set resultArray w/= i <- M(qs[i]);
        }

        Message("After measurement: ");
        DumpMachine();

        ResetAll(qs);
        Message("Post-QFT measurement results [qubit0, qubit1, qubit2]: ");
        return resultArray;

    }
}

Tipp

Denken Sie daran, ihre Datei jedes Mal zu speichern, wenn Sie eine Änderung am Code einführen, bevor Sie sie erneut ausführen.

  1. Fügen Sie vor dem Perform3qubitQFT Vorgang eine hinzuEntryPoint:

    @EntryPoint()
    operation Perform3qubitQFT() : Unit {
    
  2. Legen Sie das target Profil auf Uneingeschränkt fest. Klicken Sie unten im VS Code-Fenster auf die Schaltfläche QIR: Basis , und wählen Sie im Dropdownmenü Uneingeschränkt aus. Wenn das target Profil nicht auf Uneingeschränkt festgelegt ist, wird beim Ausführen des Programms eine Fehlermeldung angezeigt.

  3. Wählen Sie zum Ausführen des Programms in der Dropdownliste Wiedergabesymbol oben rechts die Option Datei ausführen Q# aus, oder drücken Sie STRG+5. Das Programm führt den Vorgang oder die Funktion aus, die im Standardsimulator mit dem @EntryPoint() Attribut gekennzeichnet ist.

  4. Die Message Ausgaben und DumpMachine werden in der Debugkonsole angezeigt.

Die Ausgabe sollte ähnlich wie die Ausgabe aussehen:

Before measurement: 
# wave function for qubits with ids (least to most significant): 0;1;2
|0>:     0.353553 +  0.000000 i  ==     ***                  [ 0.125000 ]     --- [  0.00000 rad ]
|1>:     0.353553 +  0.000000 i  ==     ***                  [ 0.125000 ]     --- [  0.00000 rad ]
|2>:     0.353553 +  0.000000 i  ==     ***                  [ 0.125000 ]     --- [  0.00000 rad ]
|3>:     0.353553 +  0.000000 i  ==     ***                  [ 0.125000 ]     --- [  0.00000 rad ]
|4>:     0.353553 +  0.000000 i  ==     ***                  [ 0.125000 ]     --- [  0.00000 rad ]
|5>:     0.353553 +  0.000000 i  ==     ***                  [ 0.125000 ]     --- [  0.00000 rad ]
|6>:     0.353553 +  0.000000 i  ==     ***                  [ 0.125000 ]     --- [  0.00000 rad ]
|7>:     0.353553 +  0.000000 i  ==     ***                  [ 0.125000 ]     --- [  0.00000 rad ]
After measurement:
# wave function for qubits with ids (least to most significant): 0;1;2
|0>:     0.000000 +  0.000000 i  ==                          [ 0.000000 ]
|1>:     0.000000 +  0.000000 i  ==                          [ 0.000000 ]
|2>:     0.000000 +  0.000000 i  ==                          [ 0.000000 ]
|3>:     1.000000 +  0.000000 i  ==     ******************** [ 1.000000 ]     --- [  0.00000 rad ]
|4>:     0.000000 +  0.000000 i  ==                          [ 0.000000 ]
|5>:     0.000000 +  0.000000 i  ==                          [ 0.000000 ]
|6>:     0.000000 +  0.000000 i  ==                          [ 0.000000 ]
|7>:     0.000000 +  0.000000 i  ==                          [ 0.000000 ]

Post-QFT measurement results [qubit0, qubit1, qubit2]: 
[One,One,Zero]

Diese Ausgabe veranschaulicht einige verschiedene Dinge:

  1. Vergleicht man das zurückgegebene Ergebnis mit der VormessungDumpMachine, so zeigt es eindeutig nicht die Post-QFT-Überlagerung über Basiszustände. Eine Messung liefert nur einen einzigen Basiszustand mit einer Wahrscheinlichkeit, die durch die Amplitude dieses Zustands in der Wellenfunktion des Systems bestimmt wird.
  2. Die Nachmessung DumpMachine zeigt, dass die Messung den Zustand verändert, indem sie ihn von der anfänglichen Superposition über Basiszustände auf den einzigen Basiszustand projiziert, der dem gemessenen Wert entspricht.

Wenn Sie diesen Vorgang viele Male wiederholen, bildet die Ergebnisstatistik die gleichgewichtige Superposition des Post-QFT-Zustands ab, die bei jedem Shot ein zufälliges Ergebnis liefert. Dies wäre jedochnicht nur ineffizient und immer noch unvollkommen, sondern würde auch nur die relativen Amplituden der Basiszustände wiedergeben, nicht aber die relativen Phasen zwischen ihnen. Letzteres ist in diesem Beispiel kein Problem, aber Sie würden sehen, dass relative Phasen auftreten, wenn die QFT eine komplexere Eingabe erhält als $\ket{000}$.

Verwenden sie die Q# Vorgänge, um die QFT-Leitung zu vereinfachen

Wie in der Einführung erwähnt, liegt einer der großen Vorteile von Q# darin, dass sich damit die Probleme im Zusammenhang mit der Verwendung einzelner Qubits abstrahieren lassen. In der Tat, wenn Sie vollwertige, anwendbare Quantenprogramme entwickeln wollen, würde die Sorge darüber, ob ein H-Vorgang vor oder nach einer bestimmten Rotation stattfindet, Sie nur ausbremsen.

Der Q# Namespace Microsoft.Quantum.Canon enthält den Vorgang, den ApplyQFT Sie für eine beliebige Anzahl von Qubits verwenden und anwenden können.

  1. Um auf den ApplyQFT Vorgang zuzugreifen, fügen Sie open am Anfang der Datei eine Microsoft.Quantum.Canon Anweisung für den Q# Namespace hinzu:

    open Microsoft.Quantum.Canon;
    
  2. Ersetzen Sie alles von der ersten H bis zur SWAP ersetzten durch:

    ApplyQFT(qs);
    
  3. Führen Sie das Q# Programm erneut aus, und beachten Sie, dass die Ausgabe die gleiche ist wie zuvor.

  4. Um den tatsächlichen Nutzen der Verwendung Q# von Vorgängen zu sehen, ändern Sie die Anzahl der Qubits in etwas anderes als 3:

mutable resultArray = [Zero, size = 4];

use qs = Qubit[4];
//...

Sie können also die richtige QFT für eine beliebige Anzahl von Qubits anwenden, ohne sich um das Durcheinander von neuen H-Vorgänge und Rotationen auf jedem Qubit kümmern zu müssen.

Nächste Schritte

Sehen Sie sich weitere Q#-Tutorials an:

  • Der Quanten-Zufallszahlengenerator zeigt, wie ein Q# Programm geschrieben wird, das Zufallszahlen aus Qubits in Der Überlagerung generiert.
  • Der Suchalgorithmus von Grover zeigt, wie ein Q# Programm geschrieben wird, das den Suchalgorithmus von Grover verwendet.
  • Die Quantenverschränkung zeigt, wie ein Q# Programm geschrieben wird, das Qubits bearbeitet und misst und die Auswirkungen von Überlagerung und Verschränkung veranschaulicht.
  • Die Quantum Katas sind selbstgesteuerte Tutorials und Programmierübungen, die darauf abzielen, die Elemente des Quantencomputings und Q# der Programmierung gleichzeitig zu vermitteln.