Übung – Verwenden einer Verschränkung zum Teleportieren mit Q#

Abgeschlossen

In der vorherigen Lerneinheit haben Sie die Schritte für das Quantenteleportationsprotokoll überprüft. Jetzt sind Sie an der Reihe, Alice und Bob bei ihrem Quantenteleportationsexperiment zu helfen!

In dieser Lerneinheit erstellen Sie ein Quantenteleportationsprogramm in Q#, welches das Quantenteleportationsprotokoll verwendet, um den Zustand eines Qubits von Alice an Bob zu senden.

Erstellen eines Quantenteleportierungsprogramms in Q#

  1. Öffnen Sie Visual Studio Code.
  2. Wählen Sie Datei > Neue Textdatei aus, und speichern Sie diese als Main.qs.
  3. Wählen Sie Ansicht -> Befehlspalette und Typ Q# aus: Legen Sie das Azure Quantum QIRtarget Profil fest. Drücken Sie die EINGABETASTE.
  4. Wählen Sie Q#: Nicht eingeschränkt.

Importieren der erforderlichen Bibliotheken

Sie müssen zuerst die erforderlichen Bibliotheken importieren, um die Q#-Vorgänge und -Funktionen verwenden zu können. Kopieren Sie den folgenden Code, und fügen Sie ihn in Ihre Datei Main.qs ein.

import Microsoft.Quantum.Diagnostics.*; // Aka Std.Diagnostics.*;
import Microsoft.Quantum.Intrinsic.*; // Aka Std.Intrinsic.*;
import Microsoft.Quantum.Measurement.*; // Aka Std.Measurement.*;

Definieren des Teleport Vorgangs

Zunächst müssen Sie den Teleport Vorgang definieren, der das Quantenteleportationsprotokoll implementiert. Der Vorgang verwendet zwei Qubits als Eingabe: das message Qubit, das den Quantenzustand enthält, um teleportiert zu werden, und das bob Qubit, der den Zustand empfängt.

operation Teleport(message : Qubit, bob : Qubit) : Unit {
        // Allocate an alice qubit.
        use alice = Qubit();

        // Create some entanglement that we can use to send our message.
        H(alice);
        CNOT(alice, bob);

        // Encode the message into the entangled pair.
        CNOT(message, alice);
        H(message);

        // Measure the qubits to extract the classical data we need to decode
        // the message by applying the corrections on the bob qubit
        // accordingly.
        if M(message) == One {
            Z(bob);
        }
        if M(alice) == One {
            X(bob);
        }

        // Reset alice qubit before releasing.
        Reset(alice);
    }

Lassen Sie uns den Teleport Vorgang aufschlüsseln:

  1. Der Vorgang verwendet den alice Qubit und erstellt eine Verschränkung zwischen alice und bob Qubits. Der message Qubit wird dann mit dem alice Qubit verschränkt, sodass die beiden Qubits mit dem bob Qubit verschränkt werden und die message codiert sind.

  2. Dann müssen Sie die alice und message Qubits in der Ball-Basis messen. Wie können Sie eine Messung in der Bell-Basis in Q# ausdrücken? Sie können das nicht. Oder zumindest nicht direkt. Bei Q# gibt es den M Vorgang, der eine Messung auf der $Z-Basis$ oder rechenbasierten Basis durchführt. Um den M Vorgang also richtig zu verwenden, müssen Sie die Bell-Zustände in die Berechnungsbasiszustände umwandeln. Dazu können Sie einen H Vorgang auf das message Qubit anwenden. Die folgende Tabelle zeigt die Korrespondenz zwischen den Bell-Zuständen und den Rechenbasiszuständen.

    Bell-Zustand Computerbasiszustand
    $\ket{\phi^+}$ $\ket{00}$
    $\ket{\phi^-}$ $\ket{01}$
    $\ket{\psi^+}$ $\ket{10}$
    $\ket{\psi^-}$ $\ket{11}$

    Tipp

    Eine gute Übung besteht darin, die Äquivalenz der Bell-Zustände und die Rechenbasiszustände nach der Anwendung des Hadamard-Vorgangs auf den ersten Qubit zu überprüfen. Viel Glück!

  3. Schließlich überprüfen die if Aussagen die Messergebnisse und wenden entsprechend Korrekturen auf das bob Qubit an. Wenn der message Qubit in One gemessen wird, wenden Sie das Z-Gate auf das bob Qubit an. Wenn das alice Qubit auch in One gemessen wird, wenden Sie das X-Gate auf das bob Qubit an.

Definieren von SetToPlus und SetToMinus Vorgängen

Wenn Sie Qubits in verschiedenen Zuständen teleportieren möchten, z. B. |0⟩, |1⟩, |+⟩ und |−⟩, müssen Sie die initialisierten Zustände definieren. Sie haben bereits den Teleport Vorgang zum Teleportieren des Qubits, aber Sie müssen das Qubit im richtigen Zustand vorbereiten, bevor Sie es teleportieren.

Sie müssen zwei weitere Vorgänge definieren, SetToPlus und SetToMinus, um ein Qubit auf |0⟩ und auf |+⟩ bzw |−⟩ festzulegen.

    /// Sets a qubit in state |0⟩ to |+⟩.
    operation SetToPlus(q : Qubit) : Unit is Adj + Ctl {
        H(q);
    }

    /// Sets a qubit in state |0⟩ to |−⟩.
    operation SetToMinus(q : Qubit) : Unit is Adj + Ctl {
        X(q);
        H(q);
    }

Definieren des Main Vorgangs

Jedes Q#-Programm muss über einen Vorgang Main verfügen, der als Eintrittspunkt für das Programm dient. Der Vorgang Main führt das Teleportationsprotokoll für verschiedene Quantenzustände aus, $\ket{{0}$, $\ket{1}$, $\ket{+}$ und $\ket{-}$.

Lassen Sie uns den Main Vorgang aufschlüsseln:

  1. Der Vorgang weist zwei Qubits zu, message und bob.
  2. Er definiert eine Liste von Tupeln, die den Quantenzustand, den benötigten Initialisierungsvorgang für die Initialisierung des Qubits in diesem Zustand und die Basis für die Teleportation enthalten. Die Initialisierungsvorgänge sind I für $\ket{0}$, X für $\ket{1}$, SetToPlus für $\ket{+}$ und SetToMinus für $\ket{-}$. Die Vorgänge SetToPlus und SetToMinus wurden im vorherigen Schritt definiert.
  3. Der Vorgang iteriert über die Liste der Tupel und initialisiert das Qubit message im entsprechenden Zustand und verwendet DumpMachine, um den Zustand anzuzeigen. Er teleportiert den Zustand des Qubits message dann zum Qubit bob mithilfe des Vorgangs Teleport, der im vorherigen Schritt definiert wurde.
  4. Nach dem Teleportieren des Zustands misst der Vorgang das Qubit bob in der entsprechenden Basis und setzt die Qubits zurück, um das Teleportieren weiterer Nachrichten fortzusetzen.
  5. Schlussendlich gibt der Vorgang die Messergebnisse für jede Teleportation zurück.
operation Main() : Result[] {
    // Allocate the message and bob qubits.
    use (message, bob) = (Qubit(), Qubit());

    // Use the `Teleport` operation to send different quantum states.
    let stateInitializerBasisTuples = [
        ("|0〉", I, PauliZ),
        ("|1〉", X, PauliZ),
        ("|+〉", SetToPlus, PauliX),
        ("|-〉", SetToMinus, PauliX)
    ];

    mutable results = [];
    for (state, initializer, basis) in stateInitializerBasisTuples {
        // Initialize the message and show its state using the `DumpMachine`
        // function.
        initializer(message);
        Message($"Teleporting state {state}");
        DumpMachine();

        // Teleport the message and show the quantum state after
        // teleportation.
        Teleport(message, bob);
        Message($"Received state {state}");
        DumpMachine();

        // Measure bob in the corresponding basis and reset the qubits to
        // continue teleporting more messages.
        let result = Measure([basis], [bob]);
        set results += [result];
        ResetAll([message, bob]);
    }

    return results;
}

Ausführen des Programms

Ihr Quantenteleportationsprogramm ist bereit! Sie können das Programm ausführen, um zu sehen, wie die Quantenteleportation für verschiedene Quantenzustände funktioniert. Das Programm initialisiert den message Qubit in verschiedenen Zuständen und teleportiert den Zustand in den bob Qubit.

Der folgende Code enthält den Teleport Vorgang, die Vorgänge SetToPlus und SetToMinus, sowie den Main Vorgang, der das Teleportierungsprotokoll für verschiedene Quantenzustände ausführt.

  1. Ihre Datei Main.qs sollte wie folgt aussehen:

    /// This Q# program implements quantum teleportation.
    import Microsoft.Quantum.Diagnostics.*;
    import Microsoft.Quantum.Intrinsic.*;
    import Microsoft.Quantum.Measurement.*;
    
    operation Main() : Result[] {
        // Allocate the message and bob qubits.
        use (message, bob) = (Qubit(), Qubit());
    
        // Use the `Teleport` operation to send different quantum states.
        let stateInitializerBasisTuples = [
            ("|0〉", I, PauliZ),
            ("|1〉", X, PauliZ),
            ("|+〉", SetToPlus, PauliX),
            ("|-〉", SetToMinus, PauliX)
        ];
    
        mutable results = [];
        for (state, initializer, basis) in stateInitializerBasisTuples {
            // Initialize the message and show its state using the `DumpMachine`
            // function.
            initializer(message);
            Message($"Teleporting state {state}");
            DumpMachine();
    
            // Teleport the message and show the quantum state after
            // teleportation.
            Teleport(message, bob);
            Message($"Received state {state}");
            DumpMachine();
    
            // Measure bob in the corresponding basis and reset the qubits to
            // continue teleporting more messages.
            let result = Measure([basis], [bob]);
            set results += [result];
            ResetAll([message, bob]);
        }
    
        return results;
    }
    
    /// # Summary
    /// Sends the state of one qubit to a bob qubit by using teleportation.
    ///
    /// Notice that after calling Teleport, the state of `message` is collapsed.
    ///
    /// # Input
    /// ## message
    /// A qubit whose state we wish to send.
    /// ## bob
    /// A qubit initially in the |0〉 state that we want to send
    /// the state of message to.
    operation Teleport(message : Qubit, bob : Qubit) : Unit {
        // Allocate an alice qubit.
        use alice = Qubit();
    
        // Create some entanglement that we can use to send our message.
        H(alice);
        CNOT(alice, bob);
    
        // Encode the message into the entangled pair.
        CNOT(message, alice);
        H(message);
    
        // Measure the qubits to extract the classical data we need to decode
        // the message by applying the corrections on the bob qubit
        // accordingly.
        if M(message) == One {
            Z(bob);
        }
        if M(alice) == One {
            X(bob);
        }
    
        // Reset alice qubit before releasing.
        Reset(alice);
    }
    
    /// # Summary
    /// Sets a qubit in state |0⟩ to |+⟩.
    operation SetToPlus(q : Qubit) : Unit is Adj + Ctl {
        H(q);
    }
    
    /// # Summary
    /// Sets a qubit in state |0⟩ to |−⟩.
    operation SetToMinus(q : Qubit) : Unit is Adj + Ctl {
        X(q);
        H(q);
    }
    
  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. Überprüfen Sie, ob die empfangenen Zustände mit den Teleportierungszuständen übereinstimmen. Zum Beispiel:

    Teleporting state |0〉
    
    DumpMachine:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
      |00⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
    
    Received state |0〉