Ćwiczenie — użyj splątania do teleportacji za pomocą Q#

Ukończone

W poprzedniej lekcji przedstawiono kroki protokołu teleportacji kwantowej. Teraz to twoja kolej, aby pomóc Alice i Bob zaimplementować swój eksperyment teleportacji kwantowej!

W tej jednostce utworzysz program w Q#, który będzie używał protokołu teleportacji kwantowej do wysłania stanu kubitu wiadomości od Alice do Boba. Program zawiera cztery operacje, które współpracują ze sobą w celu przeprowadzenia teleportacji.

Tworzenie programu teleportacji kwantowej w programie Q#

Aby rozpocząć pracę z programem teleportacji, wykonaj następujące kroki:

  1. Otwórz program Visual Studio Code (VS Code).
  2. Otwórz menu Plik , a następnie wybierz pozycję Nowy plik tekstowy , aby utworzyć nowy plik.
  3. Zapisz plik jako Main.qs.

Importowanie wymaganych bibliotek

Aby zaimportować biblioteki zawierające Q# operacje i funkcje potrzebne do zapisania programu, skopiuj następujący kod do pliku Main.qs :

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

Definiowanie Teleport operacji

Utwórz operację o nazwie Teleport , która implementuje protokół teleportacji kwantowej. Operacja przyjmuje dwa kubity jako dane wejściowe: message kubit zawierający stan teleportowany i bob kubit odbierający stan teleportowany.

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

    // Transform the Bell states into computational states for measurement
    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);
}

Przeanalizujmy kroki wykonywane w naszej Teleport operacji:

  1. alice Utwórz kubit. Mamy teraz trzy kubity, które są potrzebne do wykonania teleportacji kwantowej: alice, bob, i message.

  2. Splątaj kubity alice i bob. Robimy to w zwykły sposób: należy zastosować bramę Hadamarda, aby umieścić alice kubit w stanie superpozycji.

  3. Zamień kubit message na splątaną parę kubitów alice i bob. W tym celu stosujemy bramkę CNOT z message jako kubitem kontrolnym i alice jako kubitem target. Stany alice i message kubitu znajdują się teraz w bazie Bell.

  4. Przekształć stany Bell w stany obliczeniowe. Robimy to, ponieważ w systemie Q# nie możemy wykonywać pomiarów bezpośrednio na stanach Bell. Zastosuj bramę hadamarda do kubitu message , aby przekształcić stany w podstawę obliczeniową. W poniższej tabeli przedstawiono relacje stanów Bell z odpowiednimi stanami obliczeniowymi:

    Stan dzwonka Stan podstawy obliczeniowej
    $\ket{\phi^+}$ $\ket{00}$
    $\ket{\phi^-}$ $\ket{01}$
    $\ket{\psi^+}$ $\ket{10}$
    $\ket{\psi^-}$ $\ket{11}$
  5. Zmierz kubity alice i message, a następnie zastosuj odpowiednie bramki do kubitu bob na podstawie wyników pomiaru. Najpierw użyj operacji M, aby zmierzyć message. Jeśli wynik wynosi 1, zastosuj bramę $Z$ do bob. Następnie zmierz alice przy użyciu operacji M. Jeśli wynik wynosi 1, zastosuj bramę $X$ do bob.

Ten protokół teleportuje początkowy stan kubitu message na bob kubit.

Definiowanie operacji SetToPlus i SetToMinus

W rzeczywistym protokole teleportacji kubit komunikatu może być w dowolnym stanie superpozycji. Ani Alice, ani Bob nie znają stanu kubitu wiadomości. Stan jest teleportowany z kubitu wiadomości do kubitu Boba, mimo że stan nie jest znany. Jednak w systemie Q# musimy ustawić stan kubitu wiadomości przed protokołem teleportacji.

Aby przetestować nasz protokół teleportacji przy użyciu kubitu komunikatu w różnych stanach początkowych, takich jak |0⟩, |1⟩, |+⟩ i |−⟩, tworzymy operacje SetToPlus i SetToMinus. Te operacje umieszczają kubit komunikatu w żądanym stanie początkowym przed jego teleportem.

Skopiuj następujący kod operacji SetToPlus i SetToMinus do pliku Main.qs :

/// 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);
}

Definiowanie Main operacji

Każdy Q# program musi mieć operację punktu wejścia, która jest operacją Main domyślnie. W tym miejscu nasza Main operacja uruchamia protokół teleportacji dla różnych początkowych stanów kubitu wiadomości: $\ket{, {0}$, $\ket{1}$, $\ket{+}$ i $\ket{-}$. Jeśli protokół zakończy się pomyślnie, kubit Boba znajduje się w tym samym stanie, do którego początkowo ustawiliśmy kubit wiadomości.

Main Oto operacja programu teleportacji kwantowej:

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;
}

Przeanalizujmy składniki Main operacji:

  1. Przydziel dwa kubity message i bob.
  2. Utwórz listę krotek, które zawierają stan kwantowy, operację inicjującą message kubit w żądany stan oraz podstawę pomiaru. Operacje inicjowania są I dla $\ket{0}$, X dla $\ket{1}$, SetToPlus dla $\ket{+}$ i SetToMinus dla $\ket{-}$.
  3. Iteruj po liście krotek, aby zainicjować message qubit i wyświetlić stan początkowy. Następnie wywołaj operację Teleport, aby teleportować stan kubitu message na kubit bob.
  4. bob Zmierz kubit w odpowiedniej bazie i zresetuj kubity, aby umożliwić ich ponowne użycie w celu teleportacji.
  5. Zwróć wyniki pomiaru dla każdej teleportacji.

Jeśli protokół działa poprawnie, wyniki pomiaru dla bob zgadzają się ze stanami zainicjowanymi dla message.

Uruchamianie programu

Twój program teleportacji kwantowej jest gotowy! Uruchom program, aby zobaczyć, jak działa teleportacja kwantowa dla różnych początkowych stanów kubitu komunikatu.

Kompletny program zawiera operację Teleport, operację SetToPlus, SetToMinus oraz operację Main. Aby uruchomić kod i przeanalizować wyniki, wykonaj następujące kroki:

  1. Zastąp zawartość pliku Main.qs następującym Q# kodem:

    /// 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 a message qubit to a bob qubit by 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. Aby uruchomić program w wbudowanym symulatorze, wybierz opcję Uruchom w CodeLens nad operacją Main. Lub naciśnij Ctrl + F5. Dane wyjściowe są wyświetlane w konsoli debugowania.

  3. Sprawdź, czy odebrane stany są zgodne ze stanami teleportowanych. Na przykład:

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

Gratulacje! Z powodzeniem teleportowałeś stan kubitu Alicji do kubitu Boba za pomocą protokołu teleportacji kwantowej. Wszystko dzięki splątaniu kwantowemu!