Exercício - Crie diferentes estados de superposição com Q#

Concluído

Nas unidades anteriores, você aprendeu sobre sobreposição e notação Dirac. Isso é teoria suficiente por enquanto! Vamos explorar a superposição em Q# escrevendo algum código.

Nesta unidade, você criará superposição quântica e mergulhará em probabilidades com Q# usando a DumpMachine função. A DumpMachine função despeja informações sobre o status atual do sistema quântico no ponto em que é chamada.

Criar um novo arquivo Q#

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

Introdução à sobreposição

Vamos começar com um programa simples que gera um bit aleatório usando um qubit em superposição. Você usará a DumpMachine função para ver o estado do qubit em diferentes pontos do programa.

  1. Adicione o seguinte código ao arquivo Main.qs :

    import Microsoft.Quantum.Diagnostics.*;
    
    operation Main() : Result {
        use q = Qubit();
        Message("Initialized qubit:");
        DumpMachine(); // First dump
        Message(" ");
        H(q);
        Message("Qubit after applying H:");
        DumpMachine(); // Second dump
        Message(" ");
        let randomBit = M(q);
        Message("Qubit after the measurement:");
        DumpMachine(); // Third dump
        Message(" ");
        Reset(q);
        Message("Qubit after resetting:");
        DumpMachine(); // Fourth dump
        Message(" ");
        return randomBit;
    }
    

    Aqui, chama DumpMachine quatro vezes:

    • Depois de o qubit ser alocado.
    • Depois de colocar o qubit em superposição.
    • Depois de medir o estado do qubit.
    • Depois de redefinir o qubit.

    A operação MResetZ é dividida em duas operações, M e Reset. Fá-lo porque deseja inspecionar o estado após a medição.

  2. Para executar o programa no simulador integrado, clique em Executar acima da Main operação ou pressione Ctrl+F5. Sua saída aparecerá no console de depuração.

  3. A função DumpMachine cria uma tabela de informações que descrevem o estado do registo de qubit. Especificamente, indica a amplitude de probabilidade, a probabilidade e a fase em radianos para cada estado de base.

  4. No final do programa, obtém um resultado de Zero ou One. Vamos examinar cada passo.

    1. Qubit inicializado: cada qubit alocado com a use instrução começa no estado $|0\rangle$. Assim, DumpMachine produz as informações que correspondem a um registo de qubit único no estado $|0\rangle$.

      Initialized qubit:
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
         |0⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
      
    2. Qubit depois de aplicar H: Depois de aplicar H, preparamos o qubit no estado de superposição $|\psi\rangle=\frac1{\sqrt2} |0\rangle + \frac1{\sqrt2} |1\rangle$.

      Qubit after applying H:
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
         |0⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
         |1⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
      
    3. Qubit após a medição: Depois medimos e armazenamos o resultado, que pode ser um Zero ou One. Por exemplo, se o estado resultante for One, o estado dos registradores colapsa para $|1\rangle$ e não está mais em superposição.

      Qubit after the measurement:
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
         |1⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
      
    4. Qubit após redefinição: A operação Reset redefine o qubit para o estado $|0\rangle$. Lembre-se de que, para qualquer operação Q#, tem sempre de deixar os qubits utilizados no estado $|0\rangle$, para que possam ser utilizados por outras operações.

      Qubit after resetting:
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
         |0⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
      

    Nota

    Suas saídas podem diferir porque o gerador de números aleatórios é probabilístico. As probabilidades dos resultados não são deterministas.

Explore outros tipos de estados de superposição

Agora que você sabe como inspecionar o estado de um registro, você pode ver mais operações que modificam o estado de seus qubits e os colocam em uma superposição.

O gerador de números aleatórios atual produz Zero ou One com uma probabilidade de 50%. Vejamos um segundo exemplo que gera números aleatórios com uma probabilidade diferente.

Gerador de bits aleatórios distorcido

Suponha que você queira criar um gerador de bits aleatório que esteja enviesado, ou seja, a probabilidade de obter Zero é diferente da probabilidade de obter One.

Por exemplo, você quer o resultado Zero com probabilidade $P$ e o resultado One com probabilidade $1-P$. Aqui está um estado de qubit válido que produz um gerador de bits aleatório:

$$|\psi\rangle=\sqrt{P}|0\rangle+\sqrt{1-P}|1\rangle$$

Aqui, $\alpha=\sqrt{P}$ e $\beta=\sqrt{1-P}$ são as amplitudes dos estados base $|0\rangle$ e $|1\rangle$, respectivamente.

Esse estado pode ser obtido aplicando sequencialmente o operador $R_y(2\arccos\sqrt{P})$ a um qubit no estado $|0\rangle.$ Você pode obter esse resultado em Q# usando a operação Ry na biblioteca Standard.

Gorjeta

Para saber mais sobre a matemática por trás das operações de qubit único, confira o tutorial Single-Qubit Gates no Quantum Katas.

  1. Modifique Main.qs como o exemplo a seguir e salve o arquivo. Este exemplo escolhe $\alpha$ para ser cerca de $\frac13$.

    import Microsoft.Quantum.Diagnostics.*;
    import Microsoft.Quantum.Math.*;
    
    operation Main() : Result {
        use q = Qubit();
        let P = 0.333333; // P is 1/3
        Ry(2.0 * ArcCos(Sqrt(P)), q);
        Message("The qubit is in the desired state.");
        Message("");
        DumpMachine(); // Dump the state of the qubit 
        Message("");
        Message("Your skewed random bit is:");
        let skewedrandomBit = M(q);
        Reset(q);
        return skewedrandomBit;
    }
    
  2. Para executar o programa no simulador integrado, clique em Executar acima da Main operação ou pressione Ctrl+F5. Sua saída aparecerá no console de depuração.

  3. Pode ver como DumpMachine mostra o estado esperado depois de aplicar as operações e apresenta as probabilidades associadas. Observe que a probabilidade de obter Zero é de cerca de 33,33% e a probabilidade de obter One é de cerca de 66,67%. Assim, o gerador de bits aleatório é enviesado.

    The qubit is in the desired state.
    
    DumpMachine:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
       |0⟩ |  0.5773+0.0000𝑖 |    33.3333% |   0.0000
       |1⟩ |  0.8165+0.0000𝑖 |    66.6667% |   0.0000
    
    
    Your skewed random bit is:
    Result: "One"
    

    Nota

    Sua saída pode diferir porque o gerador de números aleatórios é probabilístico. As probabilidades dos resultados não são deterministas.

Sobreposição de vários qubits

Agora, vamos explorar as sobreposições de um registo que inclui muitos qubits. Por exemplo se o seu registo consistir em três qubits, tem oito estados de base.

$$|000\rangle,|001\rangle,|010\rangle,|011\rangle,|100\rangle,|101\rangle, |110\rangle,|111\rangle $$

Por isso, pode expressar um estado de três qubits arbitrário como:

$$|\psi\rangle=\alpha_0|000\rangle+\alpha_1|001\rangle+\alpha_2|010\rangle+\alpha_3|011\rangle+\alpha_4|100\rangle+\alpha_5|101\rangle+\alpha_6 |110\rangle+\alpha_7|111\rangle$$

Aqui, $\alpha_i$ são números complexos que satisfazem $\sum|\alpha_i|^2=1$.

Por exemplo, você pode colocar qubits em uma superposição uniforme aplicando H a cada qubit. Pode utilizar esta sobreposição uniforme para criar uma versão diferente do gerador quântico de números aleatórios que gera números de três bits ao medir três qubits na sobreposição em vez de medir um qubit três vezes.

Base Número
$\ket{000}$ 0
$\ket{001}$ 1
$\ket{010}$ 2
$\ket{011}$ 3
$\ket{100}$ 4
$\ket{101}$ 5
$\ket{110}$ 6
$\ket{111}$ 7
  1. Modifique Main.qs como o exemplo a seguir e salve o arquivo.

    import Microsoft.Quantum.Diagnostics.*;
    import Microsoft.Quantum.Math.*;
    import Microsoft.Quantum.Convert.*;
    import Microsoft.Quantum.Arrays.*;
    
    operation Main() : Int {
        use qubits = Qubit[3];
        ApplyToEach(H, qubits);
        Message("The qubit register in a uniform superposition: ");
        DumpMachine();
        let result = ForEach(M, qubits);
        Message("Measuring the qubits collapses the superposition to a basis state.");
        DumpMachine();
        ResetAll(qubits);
        return BoolArrayAsInt(ResultArrayAsBoolArray(result));
    }
    

    Aqui, você vê três conceitos:

    • A variável qubits representa, agora, uma matriz de Qubit com um comprimento de três.
    • As operações ApplyToEach e ForEach são úteis para medir e agir em vários qubits, e eles usam menos código. As bibliotecas de Q# oferecem muitos tipos de operações e funções diferentes que tornam a escrita de programas quânticos mais eficiente.
    • As BoolArrayAsInt funções e ResultArrayAsBoolArray da biblioteca transformam a Microsoft.Quantum.Convert matriz binária Result que é retornada por ForEach(M, qubits) em um inteiro.
  2. Para executar o programa, clique em Executar acima da Main operação ou pressione Ctrl+F5. Sua saída aparecerá no console de depuração.

  3. Ao utilizar DumpMachine, pode ver como o ato de medir os três qubits colapsa o estado do registo para um dos oito estados de base possíveis. Por exemplo, se você obtiver o resultado 3, isso significa que o estado do registro caiu para $|110\rangle$.

    The qubit register in a uniform superposition:
    
    DumpMachine:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
     |000⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |001⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |010⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |011⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |100⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |101⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |110⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |111⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
    
    Measuring the qubits collapses the superposition to a basis state.
    
    DumpMachine:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
     |110⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
    
    Result: "3"
    

    Nota

    Sua saída pode diferir porque o gerador de números aleatórios é probabilístico. As probabilidades dos resultados não são deterministas.

  4. A operação ForEach(M, qubit) mede um qubit de cada vez, colapsando gradualmente o estado. Você também pode despejar os estados intermediários após cada medição. Para fazer isso, modifique Main.qs como o exemplo a seguir e, em seguida, salve o arquivo.

    import Microsoft.Quantum.Diagnostics.*;
    import Microsoft.Quantum.Measurement.*;
    import Microsoft.Quantum.Math.*;
    import Microsoft.Quantum.Convert.*;
    
    operation Main() : Int {
        use qubits = Qubit[3];
        ApplyToEach(H, qubits);
        Message("The qubit register in a uniform superposition: ");
        DumpMachine();
        mutable results = [];
        for q in qubits {
            Message(" ");
            set results += [M(q)];
            DumpMachine();
        }
        Message(" ");
        Message("Your random number is: ");
        ResetAll(qubits);
        return BoolArrayAsInt(ResultArrayAsBoolArray(results));
    }
    
  5. Aqui, utiliza um ciclo for para atuar em cada qubit sequencialmente. O Q# tem recursos clássicos de controle de fluxo, como for loops e if instruções, que você pode usar para controlar o fluxo do seu programa.

  6. Para executar o programa, clique em Executar na lista de comandos acima da Main operação ou pressione Ctrl+F5.

  7. Pode ver como cada medição consecutiva altera o estado quântico e, como tal, as probabilidades de obter cada resultado. Por exemplo, se o resultado for o número cinco, você obterá a seguinte saída. Vamos examinar brevemente cada passo:

    1. Preparação do Estado: Depois de aplicar H a cada qubit do registo, obtém-se uma sobreposição uniforme.

      The qubit register in a uniform superposition: 
      
      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
       |000⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |001⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |010⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |011⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |100⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |101⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |110⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
       |111⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
      
    2. Primeira medição: Na primeira medição, o resultado foi One. Portanto, todas as amplitudes dos estados cujo qubit mais à direita é Zero já não estão presentes. As amplitudes são $|0\rangle=|000\rangle, |2\rangle=|010\rangle, |4\rangle=|100\rangle$ e $|6\rangle= |110\rangle$. O resto das amplitudes aumenta para atender à condição de normalização.

      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
       |001⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
       |011⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
       |101⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
       |111⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
      
    3. Segunda medição: Na segunda medição, o resultado foi Zero. Portanto, todas as amplitudes dos estados cujo segundo qubit mais à direita (meio) é One desaparecem. As amplitudes são $|3\rangle=|011\rangle$ e $|7\rangle=|111\rangle$. O resto das amplitudes aumenta para atender à condição de normalização.

      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
       |001⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
       |101⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
      
    4. Terceira medição: Na terceira medição, o resultado foi One. Portanto, todas as amplitudes dos estados cujo qubit mais à esquerda está Zero claro. O único estado compatível é $|5\rangle=|101\rangle$. Este estado obtém uma probabilidade de amplitude de $1$.

      DumpMachine:
      
       Basis | Amplitude      | Probability | Phase
       -----------------------------------------------
       |101⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
      
      
      Your random number is: 
      Result: "5"
      

    Nota

    Sua saída pode diferir porque o gerador de números aleatórios é probabilístico. As probabilidades dos resultados não são deterministas.