Exercício: Criar diferentes estados de superposição com Q#
Nas unidades anteriores, você aprendeu sobre a superposição e a notação Dirac. Chega de teoria por enquanto! Vamos explorar a superposição em Q# escrevendo algum código.
Nesta unidade, você criará uma superposição quântica e a se aprofundar nas probabilidades com Q# utilizando a função DumpMachine
. A função DumpMachine
exibe informações sobre o estado atual do sistema quântico no ponto em que é chamado.
Crie um novo arquivo em Q#
- Abra o Visual Studio Code.
- No Visual Studio Code, selecione Arquivo > Novo Arquivo de Texto e salve o arquivo como Main.q.
- Selecione Exibir -> Paleta de Comandos e digite Q#: Defina o perfil de destino do QIR do Azure Quantum. Pressione Enter.
- Selecione Q#: Sem restrições.
Introdução à superposição
Vamos começar com um programa simples que gera um bit aleatório usando um qubit na superposição. Você usará a função DumpMachine
para ver o estado do qubit em diferentes pontos do programa.
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, você chama
DumpMachine
quatro vezes:- Depois que o qubit é alocado.
- Depois de colocar o qubit em superposição.
- Depois de medir o estado do qubit.
- Depois de redefinir o qubit.
Você divide a operação
MResetZ
em duas operações:M
eReset
. Você faz isso para inspecionar o estado após a medição.Para executar seu programa no simulador interno, selecione Executar acima da operação
Main
ou pressione Ctrl+F5. A saída será exibida no console de depuração.A função
DumpMachine
cria uma tabela de informações que descreve o estado do registro de qubit. Ela fornece especificamente a amplitude de probabilidade, a probabilidade e a fase em radianos para cada estado de base.No final do programa, você deve obter o resultado
Zero
ouOne
. Vamos examinar cada etapa.Qubit inicializado: Cada qubit que é alocado com a instrução
use
começa no estado $|0\rangle$. Portanto,DumpMachine
produz as informações que correspondem a um registro de qubit único no estado $|0\rangle$.Initialized qubit: DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |0⟩ | 1.0000+0.0000𝑖 | 100.0000% | 0.0000
Qubit após aplicar H: Depois da aplicação de
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
Qubit após a medida: Depois de medirmos e armazenarmos o resultado, que pode ser um
Zero
ouOne
. Por exemplo, se o estado resultante forOne
, o estado dos registros será recolhido para $|1\rangle$ e não ficará mais em superposição.Qubit after the measurement: DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |1⟩ | 1.0000+0.0000𝑖 | 100.0000% | 0.0000
Qubit após a redefinição: A operação
Reset
redefine o qubit para o estado $|0\rangle$. Lembre-se de que, em qualquer operação Q#, você sempre precisará deixar os qubits usados no estado $|0\rangle$ para que outras operações possam usá-lo.Qubit after resetting: DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |0⟩ | 1.0000+0.0000𝑖 | 100.0000% | 0.0000
Observação
Suas saídas podem ser diferentes porque o gerador de número aleatório é probabilístico. As probabilidades dos resultados não são determinísticas.
Explorar outros tipos de estados de superposição
Agora que você sabe como inspecionar o estado de um registro, pode visualizar mais operações que modificam o estado dos qubits e colocá-las em uma superposição.
O gerador de número aleatório atual produz Zero
ou One
com 50% de probabilidade. Vejamos um segundo exemplo que gera números aleatórios com uma probabilidade diferente.
Gerador de bit aleatório distorcido
Suponha que você queira criar um gerador de bits aleatório que seja distorcido, ou seja, a probabilidade de obter Zero
é diferente da probabilidade de obter One
.
Por exemplo, você deseja 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 de base $|0\rangle$ e $|1\rangle$, respectivamente.
É possível obter esse estado por meio da aplicação sequencial do operador $R_y(2\arccos\sqrt{P})$ a um qubit no estado $|0\rangle.$. Você pode conseguir esse resultado no Q# usando a operação Ry da Biblioteca padrão.
Dica
Para saber mais sobre a matemática por trás de operações de qubit único, confira o tutorial sobre portas de Qubit Único no Quantum Katas.
Modifique Main.qs como no seguinte exemplo 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; }
Para executar seu programa no simulador interno, selecione Executar acima da operação
Main
ou pressione Ctrl+F5. A saída será exibida no console de depuração.Você pode ver como
DumpMachine
exibe o estado esperado depois de aplicar as operações e mostra as probabilidades associadas. Observe que a probabilidade de obterZero
é de cerca de 33,33%, e a probabilidade de obterOne
é de cerca de 66,67%. Assim, o gerador de bits aleatório é distorcido.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"
Observação
Sua saída pode ser diferente porque o gerador de número aleatório é probabilístico. As probabilidades dos resultados não são determinísticas.
Superposição de vários qubits
Agora, vamos explorar as superposições de um registro que inclui vários qubits. Por exemplo, se o seu registro consistir em três qubits, você terá oito estados de base:
$$|000\rangle,|001\rangle,|010\rangle,|011\rangle,|100\rangle,|101\rangle, |110\rangle,|111\rangle $$
Portanto, você pode expressar um estado arbitrário de três qubits 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 atendem a $\sum|\alpha_i|^2=1$.
Por exemplo, você pode colocar qubits em uma superposição uniforme aplicando H
a cada um deles. Você pode usar essa superposição uniforme para criar uma versão diferente do gerador de número quântico aleatório que gera números de três bits medindo três qubits na superposiçã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 |
Modifique Main.qs como no seguinte exemplo 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ê verá três conceitos:
- A variável
qubits
agora representa uma matriz deQubit
que tem um comprimento igual a três. - As operações
ApplyToEach
eForEach
são úteis para medir e agir em vários qubits e usam menos códigos. As bibliotecas do Q# oferecem muitos tipos de operações e funções que tornam mais eficiente escrever programas quânticos. - As funções
BoolArrayAsInt
eResultArrayAsBoolArray
da bibliotecaMicrosoft.Quantum.Convert
transformam a matriz bináriaResult
que é retornada porForEach(M, qubits)
em um número inteiro.
- A variável
Para executar o programa, selecione Executar acima da operação
Main
ou pressione Ctrl+F5. A saída será exibida no console de depuração.Ao usar
DumpMachine
, você verá como o ato de medir os três qubits recolhe o estado do registro para um dos oito estados de base possíveis. Por exemplo, se você receber o resultado3
, 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"
Observação
Sua saída pode ser diferente porque o gerador de número aleatório é probabilístico. As probabilidades dos resultados não são determinísticas.
A operação
ForEach(M, qubit)
mede um qubit por vez, recolhendo gradualmente o estado. Você também pode despejar os estados intermediários após cada medição. Para isso, modifique Main.qs como no seguinte exemplo e 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)); }
Aqui, você usa um loop
for
para agir sequencialmente em cada qubit. O Q# tem recursos de controle de fluxo clássico, como loops defor
e instruçõesif
, que você pode usar para controlar o fluxo do programa.Para executar o programa, selecione Executarna lista de comandos acima da operação
Main
ou pressione Ctrl+F5.Você pode ver como cada medição consecutiva altera o estado quântico e, portanto, as probabilidades de obter cada resultado. Por exemplo, se o resultado for o número cinco, você obterá a saída a seguir. Vamos examinar rapidamente cada etapa:
Preparação do estado: depois de aplicar
H
a cada qubit do registro, obtemos uma superposiçã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
Primeira medição: nela, o resultado foi
One
. Portanto, todas as amplitudes dos estados cujo qubit mais à direita éZero
não estão mais presentes. As amplitudes são $|0\rangle=|000\rangle, |2\rangle=|010\rangle, |4\rangle=|100\rangle$ e $|6\rangle=|110\rangle$. As outras amplitudes aumentam 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
Segunda medição: nela, 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$. As outras amplitudes aumentam 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
Terceira medição: nela, o resultado foi
One
. Portanto, todas as amplitudes dos estados cujo qubit mais à esquerda éZero
são limpas. O único estado compatível é $|5\rangle=|101\rangle$. Esse 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"
Observação
Sua saída pode ser diferente porque o gerador de número aleatório é probabilístico. As probabilidades dos resultados não são determinísticas.