Créer une téléportation avec Q#

Effectué

Dans l’unité précédente, vous avez examiné les étapes du protocole de téléportation quantique. À votre tour d’aider Alice et Bob dans leur expérience de téléportation quantique !

Dans cette unité, vous allez créer un programme de téléportation quantique en Q# qui utilise le protocole de téléportation quantique afin de faire envoyer à Alice l’état d’un qubit à Bob.

Créer un programme de téléportation quantique dans Q#

  1. Ouvrez Visual Studio Code.
  2. Sélectionnez Fichier > Nouveau fichier texte, puis enregistrez celui-ci sous le nom Main.qs.
  3. Sélectionnez Afficher -> Palette de commandes et tapez Q# : Définir le profil QIR target Azure Quantum. Appuyez sur Entrée.
  4. Sélectionnez Q# : Sans restriction.

Importer les bibliothèques nécessaires

Pour commencer, vous devez importer les bibliothèques nécessaires pour utiliser les opérations et les fonctions Q#. Copiez et collez le code suivant dans le fichier Main.qs.

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

Définir l’opération Teleport

Vous devez d’abord définir l’opération Teleport qui implémente le protocole de téléportation quantique. L’opération accepte deux qubits en entrée : le qubit message qui contient l’état quantique à téléporter, et le qubit bob qui va recevoir l’état.

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

Décomposons l’opération Teleport :

  1. L’opération utilise le qubit alice, et crée une intrication entre les qubits alice et bob. Le qubit message est ensuite intriqué avec le qubit alice. Ainsi, les deux qubits sont intriqués avec le qubit bob, et le message est codé.

  2. Vous devez ensuite mesurer les qubits alice et message dans la base de Bell. Comment pouvez-vous exprimer une mesure dans la base de Bell en Q# ? Vous ne le pouvez pas. Ou du moins pas directement. En Q#, vous avez l’opération M, qui effectue une mesure dans la base $Z$ ou base de calcul. Ainsi, pour utiliser correctement l’opération M, vous devez transformer les états de Bell en états de base de calcul. Pour ce faire, appliquez une opération H au qubit message. Le tableau suivant montre la correspondance entre les états de Bell et les états de base de calcul.

    État de Bell État de base de calcul
    $\ket{\phi^+}$ $\ket{00}$
    $\ket{\phi^-}$ $\ket{01}$
    $\ket{\psi^+}$ $\ket{10}$
    $\ket{\psi^-}$ $\ket{11}$

    Conseil

    La vérification de l’équivalence entre les états de Bell et les états de base de calcul après l’application de l’opération Hadamard au premier qubit est un bon exercice. Bonne chance !

  3. Enfin, les instructions if vérifient les résultats des mesures, et appliquent les corrections au qubit de bob de manière appropriée. Si le qubit de message est mesuré dans l’état One, vous appliquez la porte Z au qubit de bob. Si le qubit de alice est également mesuré dans l’état One, vous appliquez la porte X au qubit de bob.

Définir les opérations SetToPlus et SetToMinus

Au cas où vous souhaiteriez téléporter des qubits dans différents états, par exemple |0⟩, |1⟩, |+⟩ et |−⟩, vous devez définir les états initialisés. Vous disposez déjà de l’opération Teleport pour téléporter le qubit, mais vous devez préparer le qubit dans l’état approprié avant de le téléporter.

Vous devez définir deux autres opérations, SetToPlus et SetToMinus, pour définir un qubit dans l’état |0⟩ vers |+⟩ et |−⟩, respectivement.

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

Définir l’opération Main

Chaque programme Q# doit avoir une opération Main qui sert de point d’entrée pour le programme. L’opération Main exécute le protocole de téléportation pour différents états quantiques, $\ket{{0}$, $\ket{1}$, $\ket{+}$ et $\ket{-}$.

Décomposons l’opération Main :

  1. L’opération alloue deux qubits, message et bob.
  2. Elle définit une liste de tuples qui contiennent l’état quantique, l’opération d’initialiseur nécessaire pour initialiser le qubit dans cet état et la base de la téléportation. Les opérations d’initialiseur sont I pour $\ket{0}$, X pour $\ket{1}$, SetToPlus pour $\ket{+}$ et SetToMinus pour $\ket{-}$. Les opérations SetToPlus et SetToMinus sont définies aux étapes précédentes.
  3. L’opération itère sur la liste de tuples et initialise le qubit message dans l’état correspondant et utilise DumpMachine pour afficher l’état. Elle téléporte ensuite l’état du qubit message vers le qubit bob à l’aide de l’opération Teleport définie aux étapes précédentes.
  4. Après avoir téléporté l’état, l’opération mesure le qubit bob dans la base correspondante et réinitialise les qubits pour poursuivre la téléportation de messages supplémentaires.
  5. Enfin, l’opération retourne les résultats de mesure pour chaque téléportation.
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;
}

Exécuter le programme

Votre programme de téléportation quantique est prêt ! Vous pouvez exécuter le programme afin de voir comment fonctionne la téléportation quantique pour différents états quantiques. Le programme initialise le qubit de message dans différents états, et téléporte l’état vers le qubit de bob.

Le code suivant contient l’opération Teleport, les opérations SetToPlus et SetToMinus ainsi que l’opération Main, qui exécute le protocole de téléportation pour différents états quantiques.

  1. Votre fichier Main.qs doit se présenter comme suit :

    /// 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. Pour exécuter votre programme sur le simulateur intégré, cliquez sur Exécuter au-dessus de l’opération Main ou appuyez sur Ctrl+F5. Votre sortie s’affiche dans la console de débogage.

  3. Vérifiez que les états reçus correspondent aux états de téléportation. Par exemple :

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