Übung – Erstellen unterschiedlicher Superpositionszustände mit Q#

Abgeschlossen

In den vorherigen Lektionen haben Sie über Superposition und Dirac-Notation erfahren. Das ist jetzt genug Theorie! Sehen wir uns die Überlagerung in Q# an, indem wir Code schreiben.

In dieser Lerneinheit erstellen Sie mithilfe der DumpMachine-Funktion Quantenüberlagerung in Q# und tauchen in Wahrscheinlichkeiten ein. Die DumpMachine-Funktion erfasst Informationen zum aktuellen Status des Quantensystems an dem Punkt, an dem sie aufgerufen wird.

Erstellen einer neuen Q#-Datei

  1. Öffnen Sie Visual Studio Code.
  2. Wählen Sie in Visual Studio Code Datei > Neue Textdatei aus, und speichern Sie die Datei unter dem Namen Main.qs.
  3. Wählen Sie Ansicht -> Befehlspalette aus, und geben Sie Q#: Azure Quantum QIR-Zielprofil festlegen ein. Drücken Sie die EINGABETASTE.
  4. Wählen Sie Q#: Nicht eingeschränkt.

Erste Schritte mit Überlagerung

Beginnen wir mit einem einfachen Programm, das ein zufälliges Bit unter Verwendung eines Qubits in Überlagerung generiert. Verwenden Sie die DumpMachine-Funktion, um den Zustand des Qubits an verschiedenen Stellen im Programm anzuzeigen.

  1. Fügen Sie der Datein Main.qs den folgenden Code hinzu:

    import Microsoft.Quantum.Diagnostics.*;
    
    operation Main() : Result {
        use q = Qubit();
        Message("Initialized qubit:");
        DumpMachine(); // First dump
        Message(" ");
        H(q);
        Message("Qubit after applying H:");
        DumpMachine(); // Second dump
        Message(" ");
        let randomBit = M(q);
        Message("Qubit after the measurement:");
        DumpMachine(); // Third dump
        Message(" ");
        Reset(q);
        Message("Qubit after resetting:");
        DumpMachine(); // Fourth dump
        Message(" ");
        return randomBit;
    }
    

    Hier rufen Sie DumpMachine viermal auf:

    • Nach dem Zuordnen des Qubits
    • Nach dem Platzieren des Qubits in der Überlagerung
    • Nach dem Messen des Qubitzustands
    • Nach dem Zurücksetzen des Qubits

    Sie teilen den Vorgang MResetZ in zwei Vorgänge auf: M und Reset. So können Sie den Zustand nach jeder Messung untersuchen.

  2. Um Ihr Programm auf dem integrierten Simulator auszuführen, klicken Sie über dem Vorgang Main auf Ausführen, oder drücken Sie STRG+F5. Die Ausgabe wird in der Debugkonsole angezeigt.

  3. Die Funktion DumpMachine erstellt eine Tabelle mit den Informationen, die den Zustand des Qubitregisters beschreiben. Insbesondere wird Folgendes ausgegeben: die Wahrscheinlichkeitsamplitude, die Wahrscheinlichkeit und die Phase (in Radiant) für jeden Basiszustand.

  4. Nach Ausführung des Programms erhalten Sie das Ergebnis Zero oder One. Sehen wir uns die einzelnen Schritte an.

    1. Initialisiertes Qubit: Jedes der Anweisung use zugeordnete Qubit startet im Zustand $|0\rangle$. Daher gibt DumpMachine die Informationen aus, die einem einzelnen Qubitregister im Zustand $|0\rangle$ entsprechen.

      Initialized qubit:
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
         |0⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
      
    2. Qubit nach der Anwendung von H: Nach der Anwendung von H wird das Qubit in den Superpositionszustand versetzt: $|\psi\rangle=\frac1{\sqrt2} |0\rangle + \frac1{\sqrt2} |1\rangle$.

      Qubit after applying H:
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
         |0⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
         |1⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
      
    3. Qubit nach der Messung: Nachdem wir das Ergebnis messen und speichern, das Zero oder One sein kann. Wenn der resultierende Zustand beispielsweise One lautet, wird der Zustand der Register auf $|1\rangle$ reduziert und befindet sich nicht mehr in der Überlagerung.

      Qubit after the measurement:
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
         |1⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
      
    4. Qubit nach dem Zurücksetzen: Der Vorgang Reset setzt das Qubit auf den Zustand „$|0\rangle$“ zurück. Denken Sie daran: Bei jedem Q#-Vorgang müssen Sie die verwendeten Qubits wieder in den Zustand $|0\rangle$ versetzen, damit sie von anderen Vorgängen verwendet werden können.

      Qubit after resetting:
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
         |0⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
      

    Hinweis

    Sie können andere Ausgaben erhalten, da der Zufallszahlengenerator probabilistisch ist. Die Wahrscheinlichkeiten der Ergebnisse sind nicht deterministisch.

Erkunden anderer Arten von Überlagerungszuständen

Sie wissen jetzt, wie Sie den Zustand eines Registers untersuchen. Als Nächstes können Sie weitere Vorgänge anzeigen, die den Zustand Ihrer Qubits ändern und diese in eine Superposition versetzen.

Der derzeitige Zufallszahlengenerator erzeugt mit einer Wahrscheinlichkeit von 50 % entweder Zero oder One. Sehen wir uns jetzt ein zweites Beispiel an, das Zufallszahlen mit einer anderen Wahrscheinlichkeit generiert.

Zufallsbitgenerator mit Versatz

Angenommen, Sie möchten einen Zufallsbitgenerator erstellen, der schief ist, d. h., die Wahrscheinlichkeit, Zero zu erhalten, unterscheidet sich von der Wahrscheinlichkeit, One zu erhalten.

Beispielsweise möchten Sie mit der Wahrscheinlichkeit $P$ das Ergebnis Zero und mit der Wahrscheinlichkeit $1-P$ das Ergebnis One erzielen. Folgendes ist ein gültiger Qubitzustand, der einen solchen Zufallsbitgenerator erzeugt:

$$|\psi\rangle=\sqrt{P}|0\rangle+\sqrt{1-P}|1\rangle$$

Hier sind $\alpha=\sqrt{P}$ und $\beta=\sqrt{1-P}$ die Amplituden der Basiszustände $|0\rangle$ bzw. $|1\rangle$.

Dieser Zustand lässt sich erreichen, indem der Operator $R_y(2\arccos \sqrt{P})$ sequenziell auf ein Qubit im Zustand $|0\rangle.$ angewendet wird. Um dieses Ergebnis zu erzielen, verwenden Sie in Q# den Vorgang Ry der Standardbibliothek.

Tipp

Wenn Sie mehr über die mathematischen Operationen hinter einzelnen Qubitvorgängen erfahren möchten, arbeiten Sie das Tutorial „Single-Qubit Gates“ unter Quantum Katas durch.

  1. Ändern Sie Main.qs wie im folgenden Beispiel gezeigt, und speichern Sie die Datei. In diesem Beispiel wird $\alpha$ auf etwa $\frac13$ festgelegt.

    import Microsoft.Quantum.Diagnostics.*;
    import Microsoft.Quantum.Math.*;
    
    operation Main() : Result {
        use q = Qubit();
        let P = 0.333333; // P is 1/3
        Ry(2.0 * ArcCos(Sqrt(P)), q);
        Message("The qubit is in the desired state.");
        Message("");
        DumpMachine(); // Dump the state of the qubit 
        Message("");
        Message("Your skewed random bit is:");
        let skewedrandomBit = M(q);
        Reset(q);
        return skewedrandomBit;
    }
    
  2. Um Ihr Programm auf dem integrierten Simulator auszuführen, klicken Sie über dem Vorgang Main auf Ausführen, oder drücken Sie STRG+F5. Die Ausgabe wird in der Debugkonsole angezeigt.

  3. Wie Sie sehen, zeigt DumpMachine den erwarteten Zustand nach Anwendung der Vorgänge sowie die zugehörigen Wahrscheinlichkeiten an. Beachten Sie, dass die Wahrscheinlichkeit, Zero zu erhalten, etwa 33,33 % beträgt, und die Wahrscheinlichkeit, One zu erhalten, etwa 66,67 % beträgt. Daher ist der Zufallsbitgenerator schief.

    The qubit is in the desired state.
    
    DumpMachine:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
       |0⟩ |  0.5773+0.0000𝑖 |    33.3333% |   0.0000
       |1⟩ |  0.8165+0.0000𝑖 |    66.6667% |   0.0000
    
    
    Your skewed random bit is:
    Result: "One"
    

    Hinweis

    Sie können eine andere Ausgabe erhalten, da der Zufallszahlengenerator probabilistisch ist. Die Wahrscheinlichkeiten der Ergebnisse sind nicht deterministisch.

Superposition mehrerer Qubits

Sehen wir uns jetzt die Superpositionen eines Registers aus mehreren Qubits an. Wenn Ihr Register beispielsweise aus drei Qubits besteht, liegen acht Basiszustände vor:

$$|000\rangle,|001\rangle,|010\rangle,|011\rangle,|100\rangle,|101\rangle, |110\rangle,|111\rangle $$

So können Sie einen beliebigen Zustand mit drei Qubits folgendermaßen ausdrücken:

$$|\psi\rangle=\alpha_0|000\rangle+\alpha_1|001\rangle+\alpha_2|010\rangle+\alpha_3|011\rangle+\alpha_4|100\rangle+\alpha_5|101\rangle+\alpha_6 |110\rangle+\alpha_7|111\rangle$$

Hierbei sind $\alpha_i$ komplexe Zahlen, die die Gleichung $\sum|\alpha_i|^2=1$ erfüllen.

Sie können z. B. Qubits in einer einheitlichen Überlagerung platzieren, indem Sie H auf jedes Qubit anwenden. Mit dieser einheitlichen Superposition können Sie verschiedene Versionen des Quanten-Zufallszahlengenerators erstellen, der 3-Bit-Zahlen erzeugt, indem er nicht dreimal ein Qubit, sondern drei Qubits in einer Superposition misst.

Basis Anzahl
$\ket{000}$ 0
$\ket{001}$ 1
$\ket{010}$ 2
$\ket{011}$ 3
$\ket{100}$ 4
$\ket{101}$ 5
$\ket{110}$ 6
$\ket{111}$ 7
  1. Ändern Sie Main.qs wie im folgenden Beispiel gezeigt, und speichern Sie die Datei.

    import Microsoft.Quantum.Diagnostics.*;
    import Microsoft.Quantum.Math.*;
    import Microsoft.Quantum.Convert.*;
    import Microsoft.Quantum.Arrays.*;
    
    operation Main() : Int {
        use qubits = Qubit[3];
        ApplyToEach(H, qubits);
        Message("The qubit register in a uniform superposition: ");
        DumpMachine();
        let result = ForEach(M, qubits);
        Message("Measuring the qubits collapses the superposition to a basis state.");
        DumpMachine();
        ResetAll(qubits);
        return BoolArrayAsInt(ResultArrayAsBoolArray(result));
    }
    

    Hier sehen Sie drei Konzepte:

    • Die Variable qubits repräsentiert jetzt ein Qubit-Array mit der Länge 3.
    • Die Vorgänge ApplyToEach und ForEach sind nützlich, um mehrere Qubits zu messen und zu verarbeiten, und sie erfordern weniger Code. Q#-Bibliotheken bieten viele Arten von Vorgängen und Funktionen, mit denen sich Quantenprogramme effizienter schreiben lassen.
    • Die Funktionen BoolArrayAsInt und ResultArrayAsBoolArray aus der Bibliothek Microsoft.Quantum.Convert wandeln das von ForEach(M, qubits) zurückgegebene Binärarray Result in einen ganzzahligen Wert um.
  2. Klicken Sie zum Ausführen des Programms auf Ausführen über dem Main Vorgang, oder drücken Sie STRG+F5. Die Ausgabe wird in der Debugkonsole angezeigt.

  3. Mit DumpMachine können Sie sehen, wie durch die Messung der drei Qubits der Zustand des Registers auf einen der acht möglichen Basiszustände reduziert wird. Wenn Sie beispielsweise das Ergebnis 3 erhalten, bedeutet dies, dass der Zustand des Registers auf $|110\rangle$ reduziert ist.

    The qubit register in a uniform superposition:
    
    DumpMachine:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
     |000⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |001⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |010⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |011⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |100⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |101⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |110⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |111⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
    
    Measuring the qubits collapses the superposition to a basis state.
    
    DumpMachine:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
     |110⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
    
    Result: "3"
    

    Hinweis

    Sie können eine andere Ausgabe erhalten, da der Zufallszahlengenerator probabilistisch ist. Die Wahrscheinlichkeiten der Ergebnisse sind nicht deterministisch.

  4. Der Vorgang ForEach(M, qubit) misst nacheinander jedes Qubit, wobei der Zustand allmählich reduziert wird. Sie können die Zwischenzustände nach jeder Messung löschen. Ändern Sie dafür Main.qs wie im folgenden Beispiel gezeigt, und speichern Sie die Datei.

    import Microsoft.Quantum.Diagnostics.*;
    import Microsoft.Quantum.Measurement.*;
    import Microsoft.Quantum.Math.*;
    import Microsoft.Quantum.Convert.*;
    
    operation Main() : Int {
        use qubits = Qubit[3];
        ApplyToEach(H, qubits);
        Message("The qubit register in a uniform superposition: ");
        DumpMachine();
        mutable results = [];
        for q in qubits {
            Message(" ");
            set results += [M(q)];
            DumpMachine();
        }
        Message(" ");
        Message("Your random number is: ");
        ResetAll(qubits);
        return BoolArrayAsInt(ResultArrayAsBoolArray(results));
    }
    
  5. Hier verwenden Sie eine for-Schleife, um jedes Qubit einzeln zu verarbeiten. Q# verfügt über klassische Flusssteuerungsfunktionen wie for-Schleifen und if-Anweisungen, mit denen Sie den Fluss Ihres Programms steuern können.

  6. Um das Programm auszuführen, klicken Sie in der Liste der Befehle über dem Vorgang Main auf Ausführen, oder drücken Sie STRG+F5.

  7. Sie sehen, wie jede der aufeinander folgenden Messungen den Quantenzustand und damit auch die Wahrscheinlichkeiten für jedes Ergebnis ändert. Wenn Ihr Ergebnis beispielsweise die Nummer 5 ist, erhalten Sie die folgende Ausgabe. Sehen wir uns die einzelnen Schritte kurz an:

    1. Vorbereitung des Zustands: Nach dem Anwenden von H auf jedes Qubit des Registers erhalten wir eine einheitliche Superposition.

      The qubit register in a uniform superposition: 
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
       |000⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |001⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |010⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |011⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |100⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |101⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |110⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |111⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
      
    2. Erste Messung: In der ersten Messung lautete das Ergebnis One. Daher sind sämtliche Amplituden der Zustände, deren am weitesten rechts gelegenes Qubit Zero lautet, nicht mehr vorhanden. Die Amplituden sind $|0\rangle=|000\rangle, |2\rangle=|010\rangle, |4\rangle=|100\rangle$ und $|6\rangle= |110\rangle$. Der Rest der Amplituden wird erhöht, um die Normalisierungsbedingung zu erfüllen.

      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
       |001⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
       |011⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
       |101⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
       |111⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
      
    3. Zweite Messung: In der zweiten Messung lautete das Ergebnis Zero. Damit verschwinden alle Amplituden der Zustände, deren an zweiter Position von rechts gelegenes Qubit One lautet. Die Amplituden sind $|3\rangle=|011\rangle$ und $|7\rangle=|111\rangle$. Der Rest der Amplituden wird erhöht, um die Normalisierungsbedingung zu erfüllen.

      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
       |001⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
       |101⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
      
    4. Dritte Messung: In der dritten Messung lautete das Ergebnis One. Daher werden sämtliche Amplituden der Zustände, deren am weitesten links gelegenes Qubit Zero lautet, entfernt. Der einzige kompatible Zustand ist $|5\rangle=|101\rangle$. Dieser Zustand erhält eine Amplitudenwahrscheinlichkeit von $1$.

      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
       |101⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
      
      
      Your random number is: 
      Result: "5"
      

    Hinweis

    Sie können eine andere Ausgabe erhalten, da der Zufallszahlengenerator probabilistisch ist. Die Wahrscheinlichkeiten der Ergebnisse sind nicht deterministisch.