Esercizio - Usare l'entanglement per il teletrasporto con Q#

Completato

Nell'unità precedente sono stati esaminati i passaggi del protocollo di teletrasporto quantistico. È ora necessario aiutare Alice e Bob con l'esperimento di teletrasporto quantistico.

In questa unità, si creerà un programma di teletrasporto quantistico in Q# che usa il protocollo di teletrasporto quantistico per inviare lo stato di un qubit da Alice a Bob.

Creare un programma di teletrasporto quantistico in Q#

  1. Aprire Visual Studio Code.
  2. Selezionare File > Nuovo file di testo e salvarlo come Main.qs.
  3. Selezionare Visualizza -> Riquadro comandi e digitare Q#: Impostare il profilo target QIR di Azure Quantum. Premere INVIO.
  4. Selezionare Q#: Senza restrizioni.

Importare le librerie necessarie

Prima di tutto, è necessario importare le librerie necessarie per usare le operazioni e le funzioni Q#. Copiare e incollare il codice seguente nel file Main.qs.

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

Definire l'operazione Teleport

È prima di tutto necessario definire l'operazione Teleport che implementa il protocollo di teletrasporto quantistico. L'operazione accetta due qubit come input: il qubit message che contiene lo stato quantistico da teletrasportare e il qubit bob che riceverà lo stato.

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

Di seguito sono riportati i dettagli dell'operazione Teleport:

  1. L'operazione usa il qubit alice e crea un'entanglement tra i qubit alice e bob. Il qubit message viene quindi sottoposto a entanglement con il qubit alice, quindi i due qubit vengono sottoposti a entanglement con il qubit bob e message viene codificato.

  2. È quindi necessario misurare i qubit alice e message nella base Bell. Come è possibile esprimere una misura nella base Bell in Q#? Non puoi. O almeno non direttamente. In Q# è disponibile l'operazione M, che esegue una misurazione nella base $Z$ o computazionale. Pertanto, per usare correttamente l'operazione M, è necessario trasformare gli stati di Bell negli stati di base computazionale. A tale scopo, è possibile applicare un'operazione H al qubit message. Nella tabella seguente viene illustrata la corrispondenza tra gli stati di Bell e gli stati di base computazionale.

    Stato di Bell Stato di base computazionale
    $\ket{\phi^+}$ $\ket{00}$
    $\ket{\phi^-}$ $\ket{01}$
    $\ket{\psi^+}$ $\ket{10}$
    $\ket{\psi^-}$ $\ket{11}$

    Suggerimento

    Un buon esercizio consiste nel verificare l'equivalenza degli stati di Bell e degli stati di base computazionali dopo aver applicato l'operazione Hadamard al primo qubit. Buona fortuna!

  3. Infine, le istruzioni if controllano i risultati della misurazione e applicano le correzioni al qubit bob di conseguenza. Se il qubit message viene misurato in One, si applica il gate Z al qubit bob. Se il qubit alice viene misurato anche in One, si applica il gate X al qubit bob.

Definire le operazioni SetToPlus e SetToMinus

Nel caso in cui si vogliano teletrasportare i qubit in stati diversi, ad esempio |0⟩, |1⟩, |+⟩ e |−⟩, è necessario definire gli stati inizializzati. È già disponibile l'operazione Teleport per teletrasportare il qubit, ma è necessario preparare il qubit nello stato corretto prima di teletrasportarlo.

È necessario definire altre due operazioni, SetToPlus e SetToMinus, per impostare un qubit che si trova nello stato |0⟩ rispettivamente in |+⟩ e |−⟩.

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

Definire l'operazione Main

Ogni programma Q# deve avere un'operazione Main che funge da punto di ingresso per il programma. L'operazione Main esegue il protocollo di teletrasporto per stati quantistici diversi, $\ket{{0}$, $\ket{1}$, $\ket{+}$ e $\ket{-}$.

Di seguito sono riportati i dettagli dell'operazione Main:

  1. L'operazione alloca due qubit, message e bob.
  2. Definisce un elenco di tuple che contengono lo stato quantistico, l'operazione di inizializzazione necessaria per inizializzare il qubit in tale stato e la base per il teletrasporto. Le operazioni di inizializzatore sono I per $\ket{0}$, X per $\ket{1}$, SetToPlus per $\ket{+}$e SetToMinus per $\ket{-}$. Le operazioni SetToPlus e SetToMinus sono definite nei passaggi precedenti.
  3. L'operazione esegue l'iterazione sull'elenco delle tuple e inizializza il qubit message nello stato corrispondente e usa DumpMachine per visualizzare lo stato. Quindi teletrasporta lo stato del qubit message al qubit bob usando l'operazione Teleport definita nei passaggi precedenti.
  4. Dopo aver teletrasportato lo stato, l'operazione misura il qubit bob nella base corrispondente e reimposta i qubit per continuare a teletrasportare altri messaggi.
  5. Infine, l'operazione restituisce i risultati della misurazione per ogni teletrasporto.
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;
}

Eseguire il programma

Il programma di teletrasporto quantistico è pronto. È possibile eseguire il programma per verificare il funzionamento del teletrasporto quantistico per stati quantistici diversi. Il programma inizializza il qubit message in stati diversi e teletrasporta lo stato al qubit bob.

Il codice seguente contiene l'operazione Teleport, le operazioni SetToPlus e SetToMinus e l'operazione Main che esegue il protocollo di teletrasporto per stati quantistici diversi.

  1. Il file Main.qs dovrebbe essere simile al seguente:

    /// 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. Per eseguire il programma nel simulatore predefinito, fare clic su Esegui sopra l'operazione Main o premere CTRL+F5. L'output verrà visualizzato nella console di debug.

  3. Verificare che gli stati ricevuti corrispondano agli stati di teletrasporto. Ad esempio:

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