Tutorial: Erkunden der Quantenverschränkung mit Q#
In diesem Lernprogramm schreiben Sie ein Q# Programm, das Qubits bearbeitet und misst und die Auswirkungen von Überlagerung und Verschränkung veranschaulicht. Sie bereiten zwei Qubits in einem bestimmten Quantenzustand vor, lernen, wie Sie mit Qubits arbeiten, um Q# ihren Zustand zu ändern, und zeigen die Auswirkungen von Superposition und Veranglement. Sie erstellen Ihr Q# Programm Stück für Stück, um Qubit-Zustände, Vorgänge und Messungen einzuführen.
Im Folgenden sind einige wichtige Konzepte aufgeführt, die Sie verstehen sollten, bevor Sie beginnen:
- Klassische Bits enthalten einen einzelnen binären Wert (0 oder 1). Der Zustand eines Qubits kann dagegen eine Superposition von zwei Quantenzuständen sein (also 0 und 1). Jeder mögliche Quantenzustand besitzt eine zugeordnete Wahrscheinlichkeitsamplitude.
- Der Akt der Messung eines Qubits erzeugt ein binäres Ergebnis mit einer bestimmten Wahrscheinlichkeit und ändert den Zustand des Qubits außerhalb der Superposition.
- Mehrere Qubits können verangt werden, sodass sie nicht unabhängig voneinander beschrieben werden können. Das bedeutet Folgendes: Was auch immer mit einem Qubit in einem verschränkten Paar geschieht, geschieht auch mit dem anderen Qubit.
In diesem Tutorial lernen Sie Folgendes:
- Erstellen Sie Q# Vorgänge zum Initialisieren eines Qubits in einen gewünschten Zustand.
- Setzen eines Qubits in Superposition
- Verschränken eines Qubit-Paars
- Messen Sie ein Qubit, und beobachten Sie die Ergebnisse.
Tipp
Wenn Sie Ihre Quantum Computing-Reise beschleunigen möchten, schauen Sie sich Code mit Azure Quantum an, einem einzigartigen Feature der Azure Quantum-Website. Hier können Sie integrierte Q# Beispiele oder Eigene Q# Programme ausführen, neuen Q# Code aus Ihren Eingabeaufforderungen generieren, Ihren Code in VS Code für das Web mit nur einem Klick öffnen und ausführen und Copilot fragen.
Voraussetzungen
Um das Codebeispiel im Copilot für Azure Quantum auszuführen, benötigen Sie Folgendes:
- Ein Microsoft-E-Mail-Konto (MSA).
Weitere Informationen zum Copilot finden Sie unter Explore Azure Quantum.
Initialisieren eines Qubits in einen bekannten Zustand
Der erste Schritt besteht darin, einen Q#-Vorgang zu definieren, der ein Qubit in einem bekannten Zustand initialisiert. Dieser Vorgang kann aufgerufen werden, um ein Qubit auf einen klassischen Zustand festzulegen, d. h., dass er bei Gemessen entweder 100 % der Zeit zurückgibt Zero
oder 100 % der Zeit zurückgibt One
. Das Messen eines Qubits gibt einen Q# Typ Result
zurück, der nur einen Wert oder One
Zero
einen Wert aufweisen kann.
Öffnen Sie den Copilot für Azure Quantum , und kopieren Sie den folgenden Code in das Code-Editor-Fenster. Klicken Sie noch nicht auf "Ausführen" . Sie führen den Code weiter unten im Lernprogramm aus.
import Microsoft.Quantum.Intrinsic.*;
import Microsoft.Quantum.Canon.*;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
Im Codebeispiel werden die beiden Standardvorgänge M
und X
eingeführt, die den Zustand eines Qubits transformieren.
Der SetQubitState
-Vorgang:
- Verwendet zwei Parameter: einen Typ
Result
, benanntdesired
, der den gewünschten Zustand für das Qubit in (Zero
oderOne
) und einen TypQubit
darstellt. - Führt einen Messvorgang
M
aus, der den Zustand des Qubits misst (Zero
oderOne
) und das Ergebnis mit dem indesired
angegebenen Wert vergleicht. - Wenn die Messung nicht mit dem verglichenen Wert übereinstimmt, führt sie einen Vorgang
X
aus, der den Zustand des Qubits so umdreht, dass die Wahrscheinlichkeiten einerZero
undOne
zurückgebenden Messung umgekehrt werden. Auf diese Weise versetztSetQubitState
das Zielqubit immer in den gewünschten Zustand.
Schreiben eines Testvorgangs zum Testen des Bell-Zustands
Erstellen Sie als Nächstes einen weiteren Vorgang mit dem Namen Main
, um die Auswirkungen des SetQubitState
-Vorgangs zu veranschaulichen. Dieser Vorgang weist zwei Qubits zu, ruft SetQubitState
auf, um den ersten Qubit auf einen bekannten Zustand festzulegen, und misst dann die Qubits, um die Ergebnisse anzuzeigen.
Kopieren Sie den folgenden Code in das Code-Editor-Fenster unter dem SetQubitState
Vorgang.
operation Main() : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
let count = 1000;
let initial = One;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones' returned:
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Display the times that |0> is returned, and times that |1> is returned
Message($"Q1 - Zeros: {count - numOnesQ1}");
Message($"Q1 - Ones: {numOnesQ1}");
Message($"Q2 - Zeros: {count - numOnesQ2}");
Message($"Q2 - Ones: {numOnesQ2}");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
Im Code werden die Variablen bzw. die count
Variablen festgelegt 1000
One
.initial
So wird das erste Qubit auf One
initialisiert und jedes Qubit 1000-mal gemessen.
Beim Main
-Vorgang geschieht Folgendes:
- Legt Variablen für den Zähler und den anfänglichen Qubit-Zustand fest.
- Ruft die
use
-Anweisung auf, um zwei Qubits zu initialisieren. - Führt Schleifendurchläufe für
count
Iterationen aus. Für jede Schleife wirdSetQubitState
aufgerufen, um einen angegebeneninitial
-Wert für das erste Qubit festzulegen.SetQubitState
erneut aufgerufen, um das zweite Qubit in einenZero
-Zustand zu setzen.- der
M
-Vorgang verwendet, um jedes Qubit zu messen. - die Anzahl der Messungen für jedes Qubit gespeichert, das
One
zurückgibt.
- Nach dem Schleifendurchlauf wird
SetQubitState
erneut aufgerufen, um die Qubits in einen bekannten Zustand (Zero
) zurückzusetzen, damit andere Benutzer die Qubits in einem bekannten Zustand zuordnen können. Das Zurücksetzen ist von deruse
Anweisung erforderlich. - Schließlich wird die
Message
Funktion verwendet, um Ergebnisse in die Copilot-Ausgabefenster zu drucken, bevor die Ergebnisse zurückgegeben werden.
Ausführen des Codes im Copilot für Azure Quantum
Bevor Sie mit den Verfahren für Die Überlagerung und Verschränkung fortfahren, können Sie den Code bis zu diesem Punkt testen, um die Initialisierung und Messung der Qubits zu sehen.
Um den Code als eigenständiges Programm auszuführen, muss der Q# Compiler im Copilot wissen , wo das Programm gestartet werden soll. Da kein Namespace angegeben ist, erkennt der Compiler den Standardeinstiegspunkt als Main
Vorgang. Weitere Informationen finden Sie unter Projekte und implizite Namespaces.
Ihr Q# Programm bis zu diesem Punkt sollte nun wie folgt aussehen:
import Microsoft.Quantum.Intrinsic.*;
import Microsoft.Quantum.Canon.*;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
operation Main() : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
let count = 1000;
let initial = One;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones' returned:
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Display the times that |0> is returned, and times that |1> is returned
Message($"Q1 - Zeros: {count - numOnesQ1}");
Message($"Q1 - Ones: {numOnesQ1}");
Message($"Q2 - Zeros: {count - numOnesQ2}");
Message($"Q2 - Ones: {numOnesQ2}");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
Kopieren Sie das vollständige Codebeispiel, und fügen Sie es in das Codefenster "Copilot für Azure Quantum " ein, legen Sie die Folie für die Anzahl der Aufnahmen auf "1" fest, und klicken Sie auf "Ausführen". Die Ergebnisse werden im Histogramm und in den Feldern "Ergebnisse " angezeigt.
Q1 - Zeros: 0
Q1 - Ones: 1000
Q2 - Zeros: 1000
Q2 - Ones: 0
Da die Qubits noch nicht bearbeitet wurden, haben sie ihre Anfangswerte beibehalten: Das erste Qubit gibt jedes Mal One
zurück, und das zweite Qubit gibt Zero
zurück.
Wenn Sie den Wert von initial
"in Zero
" ändern und das Programm erneut ausführen, sollten Sie beachten, dass auch das erste Qubit jedes Mal zurückgegeben wird Zero
.
Q1 - Zeros: 1000
Q1 - Ones: 0
Q2 - Zeros: 1000
Q2 - Ones: 0
Tipp
Wählen Sie STRG-Z oder "Rückgängig bearbeiten>" aus, und speichern Sie die Datei immer dann, wenn Sie eine Teständerung an den Code vorführen, bevor Sie sie erneut ausführen.
Setzen eines Qubits in Superposition
Derzeit befinden sich alle Qubits im Programm in einem klassischen Zustand, d. h. entweder 1 oder 0. Sie wissen dies, da das Programm die Qubits in einem bekannten Zustand initialisiert und Sie keine Prozesse hinzugefügt haben, um sie zu bearbeiten. Bevor Sie die Qubits verkoppeln, setzen Sie den ersten Qubit in einen Superpositionszustand, in dem eine Messung des Qubits ~50% der Zeit und One
~50% der Zeit zurückgibt Zero
. Konzeptionell kann das Qubit als gleiche Wahrscheinlichkeit für die Messung einer oder One
mehrerer Zero
Qubits betrachtet werden.
Um ein Qubit in die Superposition zu versetzen, stellt Q# den H
-Vorgang (Hadamard) bereit. Rufen Sie den X
Vorgang von der Initialisierung eines Qubits in eine bekannte Zustandsprozedur früher zurück, die ein Qubit von 0 auf 1 gekippt hat (oder umgekehrt). Der H
Vorgang kippt das Qubit halbway in einen Zustand gleicher Wahrscheinlichkeiten von Zero
oder One
. Bei der Messung sollte ein Qubit in Superposition ungefähr die gleiche Anzahl von Zero
- und One
-Ergebnissen zurückgeben.
Ändern Sie den Code im Main
Vorgang, indem Sie den Anfangswert One
zurücksetzen und eine Zeile für den H
Vorgang einfügen:
for test in 1..count {
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
H(q1); // Add the H operation after initialization and before measurement
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
...
Wenn Sie nun das Programm ausführen, können Sie die Ergebnisse des ersten Qubits in Der Superposition sehen.
Q1 - Zeros: 523 // results vary
Q1 - Ones: 477
Q2 - Zeros: 1000
Q2 - Ones: 0
Jedes Mal, wenn Sie das Programm ausführen, variieren die Ergebnisse für das erste Qubit geringfügig, sind jedoch nahe 50 % One
und 50 % Zero
, während die Ergebnisse für das zweite Qubit immer verbleiben Zero
.
Q1 - Zeros: 510
Q1 - Ones: 490
Q2 - Zeros: 1000
Q2 - Ones: 0
Das Initialisieren des ersten Qubits auf Zero
gibt ähnliche Ergebnisse zurück.
Q1 - Zeros: 504
Q1 - Ones: 496
Q2 - Zeros: 1000
Q2 - Ones: 0
Hinweis
Indem Sie den Schieberegler im Copilot für Azure Quantum bewegen und die Anzahl der Aufnahmen erhöhen, können Sie sehen, wie die Superpositionsergebnisse geringfügig über die Verteilung der Aufnahmen variieren.
Verschränken zweier Qubits
Wie bereits erwähnt, sind verschränkte Qubits so verbunden, dass sie nicht unabhängig voneinander beschrieben werden können. Das bedeutet Folgendes: Jeder Vorgang, der für ein Qubit ausgeführt wird, wird auch für das verschränkte Qubit ausgeführt. Dies ermöglicht es Ihnen, den resultierenden Zustand eines Qubits ohne Messung zu ermitteln, indem Sie nur den Zustand des anderen Qubits messen. (In diesem Beispiel werden zwei Qubits verwendet. Es ist jedoch auch möglich, drei oder mehr Qubits zu verschränken.)
Um die Verschränkung zu ermöglichen, wird von Q# der CNOT
-Vorgang bereitgestellt, der für Controlled-NOT steht. Das Ergebnis des Ausführens dieses Vorgangs für zwei Qubits ist, dass das zweite Qubit umgekehrt wird, wenn das erste Qubit One
ist.
Fügen Sie den CNOT
-Vorgang Ihrem Programm unmittelbar nach dem H
-Vorgang hinzu. Ihr vollständiges Programm sollte wie folgt aussehen:
import Microsoft.Quantum.Intrinsic.*;
import Microsoft.Quantum.Canon.*;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
operation Main() : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
let count = 1000;
let initial = Zero;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
H(q1);
CNOT(q1, q2); // Add the CNOT operation after the H operation
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones' returned:
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Display the times that |0> is returned, and times that |1> is returned
Message($"Q1 - Zeros: {count - numOnesQ1}");
Message($"Q1 - Ones: {numOnesQ1}");
Message($"Q2 - Zeros: {count - numOnesQ2}");
Message($"Q2 - Ones: {numOnesQ2}");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
Wenn Sie nun das Programm ausführen, sollte folgendes angezeigt werden:
Q1 - Zeros: 502 // results will vary
Q1 - Ones: 498
Q2 - Zeros: 502
Q2 - Ones: 498
Beachten Sie, dass sich die Statistiken für den ersten Qubit nicht geändert haben (es gibt immer noch eine ~50/50 Chance einer Zero
oder einer One
nach der Messung), aber die Messergebnisse für das zweite Qubit sind immer identisch mit der Messung des ersten Qubits, unabhängig davon, wie oft Sie das Programm ausführen. Der CNOT
-Vorgang hat die zwei Qubits verschränkt, sodass was immer mit dem einen von ihnen geschieht, auch mit dem anderen geschieht.
Voraussetzungen
So entwickeln und führen Sie das Codebeispiel in Ihrer lokalen Entwicklungsumgebung aus:
- Die neueste Version von Visual Studio Code oder öffnen Sie VS Code im Web.
- Die neueste Version der Azure Quantum Development Kit-Erweiterung. Installationsdetails finden Sie unter Installieren des QDK unter VS Code.
Erstellen einer neuen Q# Datei
- Öffnen Sie Visual Studio Code und wählen Sie Datei > Neue Textdatei aus, um eine neue Datei zu erstellen.
- Speichern Sie die Datei unter dem Namen
CreateBellStates.qs
. Diese Datei enthält den Q# Code für Ihr Programm.
Initialisieren eines Qubits in einen bekannten Zustand
Der erste Schritt besteht darin, einen Q#-Vorgang zu definieren, der ein Qubit in einem bekannten Zustand initialisiert. Dieser Vorgang kann aufgerufen werden, um ein Qubit auf einen klassischen Zustand festzulegen, was bedeutet, dass er entweder 100 % der Zeit zurückgibt Zero
oder 100 % der Zeit zurückgibt One
. Zero
und One
sind Q#-Werte, die die beiden einzigen möglichen Ergebnisse der Messung eines Qubits darstellen.
Öffnen CreateBellStates.qs
Sie den folgenden Code, und kopieren Sie den folgenden Code:
import Microsoft.Quantum.Intrinsic.*;
import Microsoft.Quantum.Canon.*;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
Im Codebeispiel werden die beiden Standardvorgänge M
und X
eingeführt, die den Zustand eines Qubits transformieren.
Der SetQubitState
-Vorgang:
- Verwendet zwei Parameter: einen Typ
Result
, benanntdesired
, der den gewünschten Zustand für das Qubit in (Zero
oderOne
) und einen TypQubit
darstellt. - Führt einen Messvorgang
M
aus, der den Zustand des Qubits misst (Zero
oderOne
) und das Ergebnis mit dem indesired
angegebenen Wert vergleicht. - Wenn die Messung nicht mit dem verglichenen Wert übereinstimmt, führt sie einen Vorgang
X
aus, der den Zustand des Qubits so umdreht, dass die Wahrscheinlichkeiten einerZero
undOne
zurückgebenden Messung umgekehrt werden. Auf diese Weise versetztSetQubitState
das Zielqubit immer in den gewünschten Zustand.
Schreiben eines Testvorgangs zum Testen des Bell-Zustands
Erstellen Sie als Nächstes einen weiteren Vorgang mit dem Namen Main
, um die Auswirkungen des SetQubitState
-Vorgangs zu veranschaulichen. Dieser Vorgang weist zwei Qubits zu, ruft SetQubitState
auf, um den ersten Qubit auf einen bekannten Zustand festzulegen, und misst dann die Qubits, um die Ergebnisse anzuzeigen.
Fügen Sie der Datei CreateBellStates.qs
nach dem Vorgang SetQubitState
den folgenden Vorgang hinzu:
operation Main() : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
let count = 1000;
let initial = One;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones' returned:
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Display the times that |0> is returned, and times that |1> is returned
Message($"Q1 - Zeros: {count - numOnesQ1}");
Message($"Q1 - Ones: {numOnesQ1}");
Message($"Q2 - Zeros: {count - numOnesQ2}");
Message($"Q2 - Ones: {numOnesQ2}");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
Im Code werden die Variablen bzw. die count
Variablen festgelegt 1000
One
.initial
In diesem Schritt wird der erste Qubit initialisiert One
und jeder Qubit 1000 mal misst.
Beim Main
-Vorgang geschieht Folgendes:
- Verwendet zwei Parameter:
count
, die Anzahl der Ausführungen einer Messung, undinitial
, den gewünschten Zustand zum Initialisieren des Qubits. - Ruft die
use
-Anweisung auf, um zwei Qubits zu initialisieren. - Führt Schleifendurchläufe für
count
Iterationen aus. Für jede Schleife wirdSetQubitState
aufgerufen, um einen angegebeneninitial
-Wert für das erste Qubit festzulegen.SetQubitState
erneut aufgerufen, um das zweite Qubit in einenZero
-Zustand zu setzen.- der
M
-Vorgang verwendet, um jedes Qubit zu messen. - die Anzahl der Messungen für jedes Qubit gespeichert, das
One
zurückgibt.
- Nach dem Schleifendurchlauf wird
SetQubitState
erneut aufgerufen, um die Qubits in einen bekannten Zustand (Zero
) zurückzusetzen, damit andere Benutzer die Qubits in einem bekannten Zustand zuordnen können. Das Zurücksetzen des Qubits ist von deruse
Anweisung erforderlich. - Schließlich wird die
Message
-Funktion verwendet, um eine Meldung in der Konsole auszugeben, bevor die Ergebnisse zurückgegeben werden.
Ausführen des Codes
Bevor Sie mit den Prozeduren für Superposition und Verschränkung fortfahren, testen Sie den Code bis zu diesem Punkt, um die Initialisierung und Messung der Qubits zu sehen.
Um den Code als eigenständiges Programm auszuführen, muss der Q# Compiler wissen , wo das Programm gestartet werden soll. Da kein Namespace angegeben ist, erkennt der Compiler den Standardeinstiegspunkt als Main
Vorgang. Weitere Informationen finden Sie unter Projekte und implizite Namespaces.
Ihre
CreateBellStates.qs
Datei bis zu diesem Punkt sollte nun wie folgt aussehen:import Microsoft.Quantum.Intrinsic.*; import Microsoft.Quantum.Canon.*; operation SetQubitState(desired : Result, target : Qubit) : Unit { if desired != M(target) { X(target); } } operation Main() : (Int, Int, Int, Int) { mutable numOnesQ1 = 0; mutable numOnesQ2 = 0; let count = 1000; let initial = One; // allocate the qubits use (q1, q2) = (Qubit(), Qubit()); for test in 1..count { SetQubitState(initial, q1); SetQubitState(Zero, q2); // measure each qubit let resultQ1 = M(q1); let resultQ2 = M(q2); // Count the number of 'Ones' returned: if resultQ1 == One { set numOnesQ1 += 1; } if resultQ2 == One { set numOnesQ2 += 1; } } // reset the qubits SetQubitState(Zero, q1); SetQubitState(Zero, q2); // Display the times that |0> is returned, and times that |1> is returned Message($"Q1 - Zeros: {count - numOnesQ1}"); Message($"Q1 - Ones: {numOnesQ1}"); Message($"Q2 - Zeros: {count - numOnesQ2}"); Message($"Q2 - Ones: {numOnesQ2}"); return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 ); }
Stellen Sie vor dem Ausführen des Programms sicher, dass das Zielprofil auf "Uneingeschränkt" festgelegt ist. Wählen Sie "Ansicht - Befehlspalette", suchen Sie nach QIR, wählen Sie : Q#Legen Sie das Azure Quantum QIR-Zielprofil fest, und wählen Sie dann : uneingeschränkt ausQ#.>
Hinweis
Wenn das Zielprofil nicht auf "Uneingeschränkt" festgelegt ist, wird beim Ausführen des Programms eine Fehlermeldung angezeigt.
Um das Programm auszuführen, wählen Sie in der Dropdownliste "Wiedergabesymbol" oben rechts "Datei ausführenQ#" aus, wählen Sie "Ausführen" aus der Liste der Befehle vor dem
Main
Vorgang aus, oder drücken Sie STRG+F5. Das Programm führt denMain
Vorgang im Standardsimulator aus.Die Ausgabe wird in der Debugkonsole angezeigt.
Q1 - Zeros: 0 Q1 - Ones: 1000 Q2 - Zeros: 1000 Q2 - Ones: 0
Da die Qubits noch nicht bearbeitet wurden, haben sie ihre Anfangswerte beibehalten: Das erste Qubit gibt jedes Mal
One
zurück, und das zweite Qubit gibtZero
zurück.Wenn Sie den Wert von
initial
"inZero
" ändern und das Programm erneut ausführen, sollten Sie beachten, dass auch das erste Qubit jedes Mal zurückgegeben wirdZero
.Q1 - Zeros: 1000 Q1 - Ones: 0 Q2 - Zeros: 1000 Q2 - Ones: 0
Tipp
Wählen Sie STRG-Z oder "Rückgängig bearbeiten>" aus, und speichern Sie die Datei immer dann, wenn Sie eine Teständerung an den Code vorführen, bevor Sie sie erneut ausführen.
Setzen eines Qubits in Superposition
Derzeit befinden sich alle Qubits im Programm in einem klassischen Zustand, d. h. entweder 1 oder 0. Sie wissen dies, da das Programm die Qubits in einem bekannten Zustand initialisiert und Sie keine Prozesse hinzugefügt haben, um sie zu bearbeiten. Bevor Sie die Qubits verkoppeln, setzen Sie den ersten Qubit in einen Superpositionszustand, in dem eine Messung des Qubits 50 % der Zeit und One
50 % der Zeit zurückgibtZero
. Konzeptuell können Sie sich das Qubit als Kombination von Zero
und One
vorstellen.
Um ein Qubit in die Superposition zu versetzen, stellt Q# den H
-Vorgang (Hadamard) bereit. Rufen Sie den X
Vorgang von der Initialisierung eines Qubits in eine bekannte Zustandsprozedur früher zurück, die einen Qubit von Zero
( One
oder umgekehrt) gekippt hat; der H
Vorgang kippt den Qubit halb in einen Zustand gleicher Wahrscheinlichkeit oder Zero
One
. Bei der Messung sollte ein Qubit in Superposition ungefähr die gleiche Anzahl von Zero
- und One
-Ergebnissen zurückgeben.
Ändern Sie den Code im
Main
-Vorgang so, dass er denH
-Vorgang einschließt:for test in 1..count { use (q1, q2) = (Qubit(), Qubit()); for test in 1..count { SetQubitState(initial, q1); SetQubitState(Zero, q2); H(q1); // Add the H operation after initialization and before measurement // measure each qubit let resultQ1 = M(q1); let resultQ2 = M(q2); ...
Wenn Sie nun das Programm ausführen, sehen Sie die Ergebnisse des ersten Qubits in Superposition:
Q1 - Zeros: 523 // results will vary Q1 - Ones: 477 Q2 - Zeros: 1000 Q2 - Ones: 0
Jedes Mal, wenn Sie das Programm ausführen, variieren die Ergebnisse für das erste Qubit geringfügig, sind jedoch nahe 50 %
One
und 50 %Zero
, während die Ergebnisse für das zweite Qubit immer verbleibenZero
.Q1 - Zeros: 510 Q1 - Ones: 490 Q2 - Zeros: 1000 Q2 - Ones: 0
Das Initialisieren des ersten Qubits auf
Zero
gibt ähnliche Ergebnisse zurück.Q1 - Zeros: 504 Q1 - Ones: 496 Q2 - Zeros: 1000 Q2 - Ones: 0
Verschränken zweier Qubits
Wie bereits erwähnt, sind verschränkte Qubits so verbunden, dass sie nicht unabhängig voneinander beschrieben werden können. Das bedeutet Folgendes: Jeder Vorgang, der für ein Qubit ausgeführt wird, wird auch für das verschränkte Qubit ausgeführt. Dies ermöglicht es Ihnen, den resultierenden Zustand eines Qubits ohne Messung zu ermitteln, indem Sie nur den Zustand des anderen Qubits messen. (In diesem Beispiel werden zwei Qubits verwendet. Es ist jedoch auch möglich, drei oder mehr Qubits zu verschränken.)
Um die Verschränkung zu ermöglichen, wird von Q# der CNOT
-Vorgang bereitgestellt, der für Controlled-NOT steht. Das Ergebnis des Ausführens dieses Vorgangs für zwei Qubits ist, dass das zweite Qubit umgekehrt wird, wenn das erste Qubit One
ist.
Fügen Sie den
CNOT
-Vorgang Ihrem Programm unmittelbar nach demH
-Vorgang hinzu. Ihr vollständiges Programm sollte wie folgt aussehen:import Microsoft.Quantum.Intrinsic.*; import Microsoft.Quantum.Canon.*; operation SetQubitState(desired : Result, target : Qubit) : Unit { if desired != M(target) { X(target); } } operation Main() : (Int, Int, Int, Int) { mutable numOnesQ1 = 0; mutable numOnesQ2 = 0; let count = 1000; let initial = Zero; // allocate the qubits use (q1, q2) = (Qubit(), Qubit()); for test in 1..count { SetQubitState(initial, q1); SetQubitState(Zero, q2); H(q1); CNOT(q1, q2); // Add the CNOT operation after the H operation // measure each qubit let resultQ1 = M(q1); let resultQ2 = M(q2); // Count the number of 'Ones' returned: if resultQ1 == One { set numOnesQ1 += 1; } if resultQ2 == One { set numOnesQ2 += 1; } } // reset the qubits SetQubitState(Zero, q1); SetQubitState(Zero, q2); // Display the times that |0> is returned, and times that |1> is returned Message($"Q1 - Zeros: {count - numOnesQ1}"); Message($"Q1 - Ones: {numOnesQ1}"); Message($"Q2 - Zeros: {count - numOnesQ2}"); Message($"Q2 - Ones: {numOnesQ2}"); return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 ); }
Q1 - Zeros: 502 Q1 - Ones: 498 // results will vary Q2 - Zeros: 502 Q2 - Ones: 498 Result: "(502, 498, 502, 498)"
Die Statistiken für das erste Qubit haben sich nicht geändert (eine Wahrscheinlichkeit von 50/50 für Zero
oder One
nach der Messung). Die Messergebnisse für das zweite Qubit sind jedoch immer identisch mit der Messung des ersten Qubits. Der CNOT
Vorgang hat die beiden Qubits verangt, sodass alles, was mit einem von ihnen passiert, mit dem anderen passiert.
Zeichnen des Häufigkeits histogramms
Lassen Sie uns die Verteilung der Ergebnisse visualisieren, die aus der Ausführung des Quantenprogramms mehrmals erzielt werden. Das Häufigkeits histogramm hilft dabei, die Wahrscheinlichkeitsverteilung dieser Ergebnisse zu visualisieren.
Wählen Sie "Ansicht"> aus, oder drücken Sie STRG+UMSCHALT+P, und geben Sie "Histogramm" ein, das die Q#Option "Datei ausführen" und "Histogramm" anzeigen soll. Sie können auch Histogramm aus der Liste der vorherigen
Main
Befehle auswählen. Wählen Sie diese Option aus, um das Q# Histogrammfenster zu öffnen.Geben Sie eine Reihe von Aufnahmen ein, um das Programm auszuführen, z. B. 100 Aufnahmen, und drücken Sie die EINGABETASTE. Das Histogramm wird im Q# Histogrammfenster angezeigt.
Jeder Balken im Histogramm entspricht einem möglichen Ergebnis, und seine Höhe stellt die Anzahl der Beobachteten dar. In diesem Fall gibt es 50 verschiedene eindeutige Ergebnisse. Beachten Sie, dass für jedes Ergebnis die Messergebnisse für das erste und das zweite Qubit immer gleich sind.
Tipp
Sie können das Histogramm mithilfe des Mausrads oder einer Trackpadgeste zoomen. Beim Vergrößern können Sie das Diagramm verschieben, indem Sie beim Scrollen ALT drücken.
Wählen Sie einen Balken aus, um den Prozentsatz dieses Ergebnisses anzuzeigen.
Wählen Sie das Symbol für die oberen linken Einstellungen aus, um Optionen anzuzeigen. Sie können top 10 Ergebnisse, top 25 Ergebnisse oder alle Ergebnisse anzeigen. Sie können die Ergebnisse auch von hoch bis niedrig oder niedrig bis hoch sortieren.
Zugehöriger Inhalt
Sehen Sie sich weitere Q#-Tutorials an:
- Der Suchalgorithmus von Grover zeigt, wie ein Q# Programm geschrieben wird, das den Suchalgorithmus von Grover verwendet.
- Quantum Fourier Transform untersucht, wie ein Q# Programm geschrieben wird, das direkt bestimmte Qubits adressiert.
- Die Quantum Katas sind selbstgesteuerte Lernprogramme und Programmierübungen, die darauf abzielen, die Elemente von Quantencomputing und Q# Programmierung gleichzeitig zu unterrichten.