Exercício: Usar o emaranhamento para teletransportar com Q#

Concluído

Na unidade anterior, você revisou as etapas do protocolo de teletransporte quântico. Agora é a sua vez de ajudar Alice e Bob com seu experimento de teletransporte quântico!

Nesta unidade, você criará um programa de teletransporte quântico no Q# que usa o protocolo de teletransporte quântico para enviar o estado de um qubit de Alice para Bob.

Criar um programa de teletransporte quântico no Q#

  1. Abra o Visual Studio Code.
  2. Selecione Arquivo > Novo Arquivo de Texto e salve-o como Main.qs.
  3. Select Exibir -> Paleta de Comandos e digite Q#: Definir o perfil target do QIR do Azure Quantum. Pressione Enter.
  4. Selecione Q#: Sem restrições.

Importar as bibliotecas necessárias

Primeiro, importe as bibliotecas necessárias para usar as operações e as funções Q#. Copie e cole o código a seguir no seu arquivo Main.qs.

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

Definir a operação Teleport

Primeiro, você precisa definir a operação Teleport que implementa o protocolo de teletransporte quântico. A operação usa dois qubits como entrada: o qubit message que contém o estado quântico a ser teleportado e o qubit bob que receberá o estado.

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

Vamos detalhar a operação Teleport:

  1. A operação usa o qubit alice e cria um emaranhamento entre os qubits alice e bob. O qubit message é então emaranhado com o qubit alice, de modo que os dois qubits ficam emaranhados com o qubit bob e o message é codificado.

  2. Em seguida, você precisa medir os qubits alice e message na base de Bell. Como você pode expressar uma medida na base de Bell em Q#? Não é possível. Ou pelo menos não diretamente. Em Q# você tem a operação M, que executa uma medição na base $Z$ ou na base computacional. Portanto, para usar a operação M corretamente, você precisa transformar os estados de Bell nos estados de base computacional. Você pode fazer isso aplicando uma operação H ao qubit message. A tabela a seguir mostra a correspondência entre os estados de Bell e os estados de base computacional.

    Estado de sino Estado de base computacional
    $\ket{\phi^+}$ $\ket{00}$
    $\ket{\phi^-}$ $\ket{01}$
    $\ket{\psi^+}$ $\ket{10}$
    $\ket{\psi^-}$ $\ket{11}$

    Dica

    Um bom exercício é verificar a equivalência dos estados de Bell e os estados de base computacional depois de aplicar a operação Hadamard ao primeiro qubit. Boa sorte!

  3. Por fim, as instruções if verificam os resultados da medição e aplicam correções ao qubit bob adequadamente. Se o qubit message for medido em One, você aplicará o portão Z ao qubit bob. Se o qubit alice também for medido em One, você aplicará o portão X ao qubit bob.

Definir as operações SetToPlus e SetToMinus

Caso você queira teletransportar qubits em estados diferentes, como |0⟩, |1⟩, |+⟩ e |−⟩, você deve definir os estados inicializados. Você já tem a operação Teleport para teletransportar o qubit, mas precisa preparar o qubit no estado correto antes de teletransportá-lo.

Você precisa definir mais duas operações, SetToPlus e SetToMinus, para definir um qubit no estado |0⟩ como |+⟩ e |−⟩, respectivamente.

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

Definir a operação Main

Cada programa Q# deve ter uma operação Main que serve como ponto de entrada para o programa. A operação Main executa o protocolo de teletransporte para diferentes estados quânticos, $\ket{{0}$, $\ket{1}$, $\ket{+}$, e $\ket{-}$.

Vamos detalhar a operação Main:

  1. A operação aloca dois qubits message e bob.
  2. Ele define uma lista de tuplas que contêm o estado quântico, a operação inicializador necessária para inicializar o qubit nesse estado e a base para o teletransporte. As operações de inicializador são I para $\ket{0}$, X para $\ket{1}$, SetToPlus para $\ket{+}$ e SetToMinus para $\ket{-}$. As operações SetToPlus e SetToMinus são definidas nas etapas anteriores.
  3. A operação itera na lista de tuplas e inicializa o qubit message no estado correspondente e usa DumpMachine para exibir o estado. Em seguida, ele teletransporta o estado do qubit message para o bob qubit usando a operação Teleport definida nas etapas anteriores.
  4. Depois de teletransportar o estado, a operação mede o qubit bob na base correspondente e redefine os qubits para continuar teletransportando mais mensagens.
  5. Por fim, a operação retorna os resultados da medida para cada teletransporte.
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;
}

Execute o programa

Seu programa de teletransporte quântico está pronto! Você pode executar o programa para ver como o teletransporte quântico funciona para diferentes estados quânticos. O programa inicializa o qubit message em estados diferentes e teletransporta o estado para o qubit bob.

O código a seguir contém a operação Teleport, as operações SetToPlus e SetToMinus e a operação Main que executa o protocolo de teletransporte para diferentes estados quânticos.

  1. Seu arquivo Main.qs deve ter esta aparência:

    /// 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. Para executar seu programa no simulador interno, clique em Executar acima da operaçãoMain ou pressione Ctrl+F5. A saída será exibida no console de depuração.

  3. Verifique se os estados recebidos correspondem aos estados do teletransporte. Por exemplo:

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