Exercice - Utiliser l’enchevêtrement pour la téléportation avec Q#

Terminé

Dans l’unité précédente, vous avez appris les étapes du protocole de téléportation quantique. Maintenant, c’est votre tour pour aider Alice et Bob à implémenter leur expérience de téléportation quantique !

Dans cette unité, vous créez un programme en Q# qui utilise le protocole de téléportation quantique pour envoyer l’état d’un qubit de message d’Alice à Bob. Le programme contient quatre opérations qui fonctionnent ensemble pour effectuer la téléportation.

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

Pour commencer à utiliser votre programme de téléportation, procédez comme suit :

  1. Ouvrez Visual Studio Code (VS Code).
  2. Ouvrez le menu Fichier , puis choisissez Nouveau fichier texte pour créer un fichier.
  3. Enregistrez le fichier en tant que Main.qs.

Importer les bibliothèques nécessaires

Pour importer les bibliothèques qui contiennent les Q# opérations et les fonctions dont vous avez besoin pour écrire votre programme, copiez le code suivant dans votre 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

Créez une opération appelée Teleport qui implémente le protocole de téléportation quantique. L’opération prend deux qubits comme entrée : le message qubit qui contient l’état de téléportation et le bob qubit qui reçoit l’état téléporté.

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

Nous allons décomposer les étapes de notre Teleport opération :

  1. Créez un alice qubit. Nous avons maintenant les trois qubits qu'il nous faut pour effectuer la téléportation quantique : alice, bob et message.

  2. Enchevêtrez les qubits alice et bob. Nous faisons cela de la manière habituelle : appliquez une porte Hadamard pour placer le alice qubit dans un état de superposition.

  3. Encoder le message qubit dans la paire enchevêtrée de qubits alice et bob. Pour ce faire, nous appliquons une porte CNOT avec message comme qubit de contrôle et alice comme qubit target. Les états des qubits alice et message sont maintenant dans la base de Bell.

  4. Transformez les états Bell en états de calcul. Nous faisons cela parce que, dans Q#, nous ne pouvons pas effectuer des mesures directement sur les états Bell. Appliquez une porte Hadamard au message qubit pour transformer les états en base de calcul. Le tableau suivant associe les états Bell à leurs états de calcul correspondants :

    État de Bell État de base de calcul
    $\ket{\phi^+}$ $\ket{00}$
    $\ket{\phi^-}$ $\ket{01}$
    $\ket{\psi^+}$ $\ket{10}$
    $\ket{\psi^-}$ $\ket{11}$
  5. Mesurez les qubits alice et message, et appliquez les portes appropriées au qubit bob en fonction des résultats de mesure. Tout d’abord, utilisez l’opération M pour mesurer message. Si le résultat est 1, appliquez la $porte Z$ à bob. Ensuite, mesurez alice avec l’opération M . Si le résultat est 1, appliquez la $porte X$ à bob.

Ce protocole téléporte l’état initial du message qubit sur le bob qubit.

Définir les opérations SetToPlus et SetToMinus

Dans un protocole de téléportation réelle, le qubit de message peut être dans n’importe quel état de superposition. Ni Alice ni Bob ne connaissent l’état du qubit de message. L’état est téléporté du qubit de message vers le qubit de Bob, même si l’état n’est pas connu. Mais dans Q#, nous devons définir l’état du qubit de message avant le protocole de téléportation.

Pour tester notre protocole de téléportation avec le qubit de message dans différents états initiaux, tels que |0⟩, |1⟩, |+⟩ et |−⟩, nous créons les opérations SetToPlus et SetToMinus. Ces opérations placent le qubit de message dans l’état initial souhaité avant de le téléporter.

Copiez le code suivant pour les opérations SetToPlus et SetToMinus dans votre fichier 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);
}

Définir l’opération Main

Chaque Q# programme doit avoir une opération de point d’entrée, qui est l’opération Main par défaut. Ici, notre Main opération exécute le protocole de téléportation pour différents états initiaux du qubit de message, $\ket{{0}$, +$\ket{1}$$\ket{}$ et .$\ket{-}$ Si le protocole réussit, le qubit de Bob se retrouve dans le même état que l'état initial du qubit de message.

Voici l’opération Main du programme de téléportation quantique :

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

Nous allons décomposer les composants de l’opération Main :

  1. Allouez deux qubits, message et bob.
  2. Créez une liste de tuples qui contiennent l’état quantique, l’opération qui initialise le message qubit dans l’état souhaité et la base de la mesure. Les opérations d’initialisation sont I pour $\ket{0}$, X pour $\ket{1}$, SetToPlus pour $\ket{+}$ et SetToMinus pour $\ket{-}$.
  3. Itérer sur la liste des tuples pour initialiser le qubit message et afficher cet état initial. Ensuite, appelez l’opération Teleport pour téléporter l’état du message qubit sur le bob qubit.
  4. Mesurez le bob qubit dans la base correspondante et réinitialisez les qubits afin de pouvoir les réutiliser pour la téléportation.
  5. Retourne les résultats de mesure pour chaque téléportation.

Si le protocole fonctionne correctement, vos résultats de mesure correspondent bob aux états initialisés pour message.

Exécuter le programme

Votre programme de téléportation quantique est prêt ! Exécutez le programme pour voir comment fonctionne la téléportation quantique pour différents états initiaux du qubit de message.

Le programme complet contient l’opération Teleport, l’opération SetToPlus, l’opération SetToMinus et l’opération Main. Pour exécuter votre code et analyser les résultats, procédez comme suit :

  1. Remplacez le contenu de votre fichier Main.qs par le code suivant Q# :

    /// 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. Pour exécuter votre programme sur le simulateur intégré, choisissez le code lens 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 téléportés. Par exemple :

    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
    

Félicitations! Vous avez correctement téléporté l’état du qubit d’Alice sur le qubit de Bob via le protocole de téléportation quantique. Merci à l’enchevêtrement quantique !