Pular para o conteúdo principal

Comece a usar o Qiskit em sala de aula

Para este módulo do Qiskit in Classrooms, os alunos precisam ter um ambiente Python funcional com os seguintes pacotes instalados:

  • qiskit v2.1.0 ou mais recente
  • qiskit-ibm-runtime v0.40.1 ou mais recente
  • qiskit-aer v0.17.0 ou mais recente
  • qiskit.visualization
  • numpy
  • pylatexenc

Para configurar e instalar os pacotes acima, consulte o guia Instalar o Qiskit. Para executar jobs em computadores quânticos reais, os alunos precisarão criar uma conta no IBM Quantum® seguindo os passos do guia Configurar sua conta IBM Cloud®.

Este módulo foi testado e utilizou 2 segundos de tempo de QPU em um processador Heron v2. Trata-se apenas de uma estimativa. Seu uso real pode variar.

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-aer qiskit-ibm-runtime
# Uncomment and modify this line as needed to install dependencies
#!pip install 'qiskit>=2.1.0' 'qiskit-ibm-runtime>=0.40.1' 'qiskit-aer>=0.17.0' 'numpy' 'pylatexenc'

Introdução

Nos módulos do Qiskit in the Classroom, você terá a oportunidade de usar um computador quântico para explorar vários conceitos em áreas relacionadas à computação quântica, como mecânica quântica, ciência da computação, química e muito mais. Este módulo serve como pré-requisito para os demais — ele apresenta os fundamentos da computação quântica e como usar o Qiskit para executar circuitos quânticos.

Primeiro, daremos uma breve visão geral de como um computador clássico funciona e, em seguida, mostraremos como esses conceitos são adaptados para o paradigma da computação quântica. Por fim, mostraremos como reunir esses conceitos para construir e executar seu primeiro circuito quântico.

Computadores clássicos

Você provavelmente já está familiarizado com os conceitos básicos de como os computadores clássicos funcionam, mas aqui destacaremos alguns dos recursos principais para que possamos fazer uma comparação com os computadores quânticos.

As unidades básicas de informação: bits

Os computadores clássicos processam informação clássica, e a unidade fundamental de informação clássica é o bit. Um único bit pode armazenar a resposta a uma pergunta de "sim/não". Geralmente representamos os dois estados binários de um bit como "0" e "1".

Revisão de números binários

Combinar bits permite que você armazene mais informações. Por exemplo, se você quiser armazenar um número de 0 a 15, poderia fazer isso com quatro bits da seguinte maneira:

0 = 00004 = 01008 = 100012 = 1100
1 = 00015 = 01019 = 100113 = 1101
2 = 00106 = 011010 = 101014 = 1110
3 = 00117 = 011111 = 101115 = 1111

Em geral, para converter um número binário de NN bits em um número familiar na base 10, você multiplica o bit menos significativo (mais à direita) por 20=12^0 = 1, o próximo bit à esquerda por 21=22^1 = 2, depois o seguinte por 22=42^2 = 4, e assim por diante, até chegar ao bit mais significativo (mais à esquerda), que você multiplica por 2N12^{N-1}.

Portanto, isso significa que NN bits podem estar em um de 2N2^N estados possíveis diferentes.

Verifique seu entendimento

Leia a(s) pergunta(s) abaixo, pense na sua resposta e clique no triângulo para revelar a solução.

Quantos bits você precisaria para representar o número 86? Escreva a cadeia de bits que codifica esse número em binário.

Resposta:

Lembre-se de que NN bits permitem representar os números de 00 a 2N12^N - 1. Com seis bits, chegamos até 261=632^6 - 1 = 63. Isso não é suficiente. Adicionamos mais um bit para chegar até 271=1272^7 - 1 = 127. Agora vamos decompor 86 em potências de 2:

86=64+16+4+2=26×1+25×0+24×1+23×0+22×1+21×1+20×0=1010110\begin{aligned} 86 &= 64 + 16 + 4 + 2 \\ &= 2^6 \times 1 + 2^5 \times 0 + 2^4 \times 1 + 2^3 \times 0 + 2^2 \times 1 + 2^1 \times 1 + 2^0 \times 0 \\ &= 1010110 \end{aligned}

Operações fundamentais: portas lógicas

Agora, um computador precisa ser capaz de fazer algo com os bits para, bem, computar. As portas binárias são as operações que formam os blocos fundamentais de construção de todos os algoritmos e códigos mais complexos.

Porta de um único bit:

NOT

Quando você tem apenas um bit, há apenas uma maneira de transformar seu estado: inverter o estado de 0 para 1 ou de 1 para 0. Chamamos isso de porta "NOT". O efeito dessa porta — e das demais portas que discutiremos abaixo — pode ser representado em uma chamada "tabela verdade", com colunas para os estados de entrada e saída dos qubits. A tabela verdade para a porta NOT é:

EntradaSaída
01
10

Portas de múltiplos bits:

AND

AND é uma porta de dois bits que recebe dois bits de entrada e produz um único bit de saída. Ela produz 1 se ambos os bits de entrada forem 1, e 0 caso contrário:

EntradaSaída
000
010
100
111

OR

OR é outra porta de dois bits com um único bit de saída. Ela produz 1 se qualquer um dos bits for 1:

EntradaSaída
000
011
101
111

XOR

XOR significa "OR exclusivo" e é como a porta OR, mas produz 1 se apenas um dos bits de entrada for 1. Produz 0 se ambos forem 1 ou ambos forem 0:

EntradaSaída
000
011
101
110

Medições:

Normalmente, ao aprender sobre computação clássica, não se dá muita atenção ao processo de leitura do estado dos bits. Isso porque não é muito complexo do ponto de vista conceitual. Você pode medir os bits a qualquer momento — antes, durante ou depois de um cálculo — e isso não afeta o resultado. Não é o caso na computação quântica, como discutiremos a seguir.

Circuitos:

Combinando as portas lógicas acima, você pode realizar qualquer tipo de operação em um computador. Vejamos um exemplo simples: usando as portas AND e XOR, você pode construir o circuito meio-somador, que calcula a soma de dois bits. Isso é representado em um diagrama de circuito lógico, onde os fios representam os bits e as portas que operam sobre eles são mostradas como símbolos nos fios correspondentes:

Diagrama de circuito clássico para o circuito meio-somador. Uma porta XOR gera o bit de saída Soma e uma porta AND gera o bit de saída Carry.

Assim, os dois bits são copiados e alimentados tanto em uma porta AND quanto em uma porta XOR. O resultado da porta XOR é o "bit de soma" (S), que permanece na posição das unidades do número binário, e o resultado da porta AND é o "bit de carry" (C), que é o valor do próximo dígito mais significativo no número binário. Aqui está a tabela verdade:

AABBSoma (ABA \oplus B)Carry (ABA \wedge B)
0000
0110
1010
1101

Verifique seu entendimento

Leia a(s) pergunta(s) abaixo, pense na sua resposta e clique no triângulo para revelar a solução.

Verifique que a tabela verdade acima fornece a solução correta para um circuito somador. Ou seja, para cada uma das quatro opções de A e B, verifique que A+B=S+2×CA+B=S+2 \times C.

Resposta:

0+0=0+0=0 0+1=1+0=1 1+0=1+0=1 1+1=0+2=2 \begin{aligned} 0+0 &= 0+0 = 0 ~\checkmark \\ 0+1 &= 1+0 = 1 ~\checkmark \\ 1+0 &= 1+0 = 1 ~\checkmark \\ 1+1 &= 0+2 = 2 ~\checkmark \\ \end{aligned}

Computadores quânticos

Bits \rightarrow qubits

Assim como os bits são as unidades fundamentais de informação clássica, os bits quânticos, ou "qubits", são as unidades fundamentais de informação quântica. Como o bit clássico, o estado de um qubit pode ser 0 ou 1, o que normalmente denotamos como 0\vert 0\rangle e 1\vert 1\rangle. Mas, diferentemente do bit clássico, um bit quântico também pode estar em uma superposição dos estados 0\vert 0\rangle e 1\vert 1\rangle ao mesmo tempo. Em geral, um qubit pode estar em qualquer estado ψ\vert \psi\rangle da forma:

ψ=c00+c11\vert \psi\rangle = c_0 \vert 0\rangle + c_1 \vert 1\rangle

onde c0c_0 e c1c_1 são amplitudes complexas com c02+c12=1\vert c_0 \vert ^2+\vert c_1\vert ^2=1.

A fase quântica

Como c0c_0 e c1c_1 são complexos, cada um pode ser escrito como ci=cieiϕic_i = \vert c_i\vert e^{i\phi_i}, onde ϕi\phi_i é chamado de fase. Se multiplicarmos todo o estado pelo mesmo fator de fase global, nada muda fisicamente — isso é chamado de fase global e não tem consequências observáveis.

Por esse motivo, é convencional "fatorar" eiϕ0e^{i\phi_0}, resultando em:

ψ=c00+c1eiϕ1\vert \psi\rangle = \vert c_0\vert \vert 0\rangle + \vert c_1\vert e^{i\phi}\vert 1\rangle

onde ϕ=ϕ1ϕ0\phi = \phi_1-\phi_0 é a fase relativa do estado quântico, que possui consequências observáveis.

Essa fase desempenha um papel muito importante na computação quântica, e você explorará suas diversas consequências nos módulos subsequentes do Qiskit in the Classroom.

Múltiplos qubits

Enquanto o estado de múltiplos bits pode ser expresso simplesmente como uma cadeia de 0s e 1s, o estado de múltiplos qubits fica um pouco mais complicado por causa dos princípios de superposição e emaranhamento.

Lembre-se de que NN bits poderiam estar em um de 2N2^N estados possíveis, variando dos números binários 000...000 a 111...111. Mas agora, por causa do princípio da superposição, NN qubits podem estar em uma superposição de todos esses estados ao mesmo tempo!

Isso pode ser expresso como

ψN=i=02N1cii\psi_N = \sum_{i=0}^{2^N-1} c_i \vert i\rangle

onde, como no caso clássico, o estado i\vert i\rangle corresponde ao estado em que cada qubit está na combinação correta de 0s e 1s para produzir o número binário ii. Esses são conhecidos como os "estados da base computacional" do sistema quântico. Por exemplo, um estado de três qubits pode ser escrito como uma superposição de seus oito estados da base computacional:

ψ3=c0000+c1001+c2010+c3011+c4100+c5101+c6110+c7111\psi_3 = c_0 \vert 000\rangle + c_1 \vert 001\rangle + c_2 \vert 010\rangle + c_3 \vert 011\rangle + c_4 \vert 100\rangle + c_5 \vert 101\rangle + c_6 \vert 110\rangle + c_7 \vert 111\rangle

Cada qubit no sistema é identificado com um índice de 00 a N1N-1. A convenção é ler os estados dos qubits da direita para a esquerda, de modo que o estado do qubit 00 é o estado mais à direita e o estado do qubit N1N-1 é o mais à esquerda. Isso é conhecido como notação "little-endian" e pode parecer contraintuitivo no início, pois estamos acostumados a ler da esquerda para a direita.

Verifique seu entendimento

Leia a(s) pergunta(s) abaixo, pense na sua resposta e clique no triângulo para revelar a solução.

À primeira vista, pode parecer contraintuitivo ordenar os qubits da direita para a esquerda, como na notação little-endian, mas na verdade é algo muito lógico de se fazer! Explique por quê. (Lembre-se da nossa discussão acima sobre a conversão de binário para base 10.)

Resposta:

Se ordenarmos os qubits da direita para a esquerda, de modo que o qubit 0 seja o mais à direita e o qubit N-1 seja o mais à esquerda, é lógico associar o qubit 00 ao bit menos significativo, que é multiplicado por 202^0, e o qubit N1N-1 ao bit mais significativo, que é multiplicado por 2N12^{N-1}.

Emaranhamento

Como mencionamos anteriormente, outra característica fundamental dos qubits é que eles podem ser emaranhados uns com os outros. Vejamos um exemplo de um estado de dois qubits, onde c0=c3=12c_0 = c_3 = \frac{1}{\sqrt{2}} e c1=c2=0c_1 = c_2 = 0:

ψ=12(00+11)\vert \psi\rangle = \frac{1}{\sqrt{2}}(\vert 00\rangle + \vert 11\rangle)

Assim, o estado do qubit 0 pode ser 0\vert 0\rangle ou 1\vert 1\rangle com probabilidade igual, assim como o estado do qubit 1. Mas essas probabilidades não são mais independentes entre si. Se encontrarmos o estado do qubit 0 como 0\vert 0\rangle, então sabemos que o qubit 1 também estará em 0\vert 0\rangle. Isso é verdade independentemente da distância entre eles, razão pela qual o ato de medir um estado emaranhado às vezes é chamado de "ação fantasmagórica à distância".

O emaranhamento também pode assumir outras formas. Por exemplo, o estado

ψ=12(01+10)\vert \psi\rangle = \frac{1}{\sqrt{2}}(\vert 01\rangle + \vert 10\rangle)

produz resultados opostos sempre: se um qubit for medido como 0\vert 0\rangle, o outro será garantidamente encontrado no estado 1\vert 1\rangle.

Verifique seu entendimento

Leia a(s) pergunta(s) abaixo, pense na sua resposta e clique no triângulo para revelar a solução.

O estado ψ=11\vert \psi\rangle = \vert 11\rangle está emaranhado? Por quê ou por que não?

Resposta:

Não está emaranhado. Embora os resultados sejam sempre iguais quando você mede ambos os qubits, isso ocorre apenas porque cada qubit está sempre fixo no estado 1\vert 1\rangle. O resultado da medição de um qubit não depende de fato do outro — ambos são simplesmente sempre 1\vert 1\rangle.

Em geral, se você puder descrever o estado de cada qubit separadamente e depois multiplicá-los desta forma:

ψ=ψ1ψ0\vert \psi\rangle = \vert \psi_1\rangle \vert \psi_0\rangle

Então isso é conhecido como "estado produto" e não está emaranhado.

Notação vetorial

Frequentemente é útil usar vetores e matrizes para ver como o estado quântico se transforma sob diferentes operações. Nesta representação, nossos estados quânticos serão vetores, e nossas portas quânticas (discutidas na próxima seção) serão matrizes que transformam esses vetores.

Para um único qubit, as formas vetoriais dos estados são definidas como: 0=(10)\vert 0\rangle = \begin{pmatrix}1 \\ 0\end{pmatrix} 1=(01)\vert 1\rangle = \begin{pmatrix}0 \\ 1\end{pmatrix} Desta forma, um estado arbitrário ψ=a0+b1\vert \psi\rangle = a\vert 0\rangle+b\vert 1\rangle pode ser escrito como ψ=(ab)\vert \psi\rangle =\begin{pmatrix}a \\ b\end{pmatrix}

Para um estado geral de nn qubits, precisaremos de um vetor de dimensão 2n2^n, com os estados da base ordenados como se poderia esperar, em ordem binária crescente:

0000=(1000),0001=1110=(0010),1111=(0001)\vert 0 \dots 000\rangle = \begin{pmatrix}1 \\ 0 \\ 0 \\ \vdots \\ 0\end{pmatrix}, \vert 0 \dots 001 \rangle = \vert 1 \dots 110\rangle = \begin{pmatrix}0 \\ \vdots \\ 0 \\ 1 \\ 0\end{pmatrix}, \vert 1 \dots 111 \rangle = \begin{pmatrix}0 \\ \vdots \\ 0 \\ 0\\ 1\end{pmatrix}

Com essa escolha de notação vetorial em mente, podemos introduzir as portas quânticas necessárias, seus efeitos sobre os estados quânticos e suas formas matriciais.

Verifique seu entendimento

Leia a(s) pergunta(s) abaixo, pense na sua resposta e clique no triângulo para revelar a solução.

Há quatro estados da base computacional para um sistema de dois qubits. Escreva cada um deles nas notações ket e vetorial.

Resposta:

00=(1000),01=(0100),,10=(0010),11=(0001)\vert 00\rangle = \begin{pmatrix}1 \\ 0 \\ 0 \\ 0\end{pmatrix}, \vert 01 \rangle = \begin{pmatrix}0 \\ 1 \\ 0 \\ 0\end{pmatrix}, \dots, \vert 10\rangle = \begin{pmatrix}0 \\ 0 \\ 1 \\ 0\end{pmatrix}, \vert 11 \rangle = \begin{pmatrix}0 \\ 0 \\ 0\\ 1\end{pmatrix}

Gates \rightarrow portas quânticas

Assim como as portas clássicas NOT, AND, OR e XOR podem ser combinadas para construir circuitos clássicos arbitrários, as portas quânticas desempenham o mesmo papel na computação quântica. Como os qubits possuem características quânticas adicionais, as portas quânticas são correspondentemente mais ricas. Embora ainda seja possível descrever sua ação nos estados de base 0|0\rangle e 1|1\rangle com uma tabela verdade, isso não captura o quadro completo. Para portas quânticas, é frequentemente mais natural usar uma representação matricial, já que elas também atuam em superposições dos estados de base.

A seguir, apresentaremos as portas quânticas mais comuns e como elas transformam os qubits com os quais interagem. Quando aplicável, vamos conectá-las de volta às portas clássicas familiares.

Portas de um único qubit

Porta XX: É o equivalente quântico de uma operação NOT. Sua tabela verdade se parece exatamente com a da porta NOT clássica:

EntradaSaída
0\vert 0\rangle1\vert 1\rangle
1\vert 1\rangle0\vert 0\rangle

E a representação matricial:

X=(0110)X=\begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}

No Qiskit, criar um circuito com uma porta XX é assim:

from qiskit import QuantumCircuit

qc = QuantumCircuit(1)
qc.x(0)
qc.draw("mpl")

Output of the previous code cell

Neste diagrama de circuito muito simples, o qubit é representado por um fio — a linha horizontal preta — e a porta aparece como uma caixa nesse fio.

Porta Hadamard: Cria um estado de superposição. Tabela verdade:

EntradaSaída
0\vert 0\rangle12(0+1)\frac{1}{\sqrt{2}}\left(\vert 0\rangle+\vert 1\rangle\right)
1\vert 1\rangle12(01)\frac{1}{\sqrt{2}}\left(\vert 0\rangle-\vert 1\rangle\right)

Representação matricial: H=12(1111)H=\frac{1}{\sqrt{2}}\begin{pmatrix} 1 & 1 \\ 1 & -1 \end{pmatrix}

Um circuito com uma porta Hadamard é criado da seguinte forma:

from qiskit import QuantumCircuit

qc = QuantumCircuit(1)
qc.h(0)
qc.draw("mpl")

Output of the previous code cell

Porta ZZ: Adiciona um deslocamento de fase Δϕ=π\Delta \phi = \pi ao estado 1|1\rangle:

EntradaSaída
0\vert 0\rangle0\vert 0\rangle
1\vert 1\rangle1-\vert 1\rangle

Z=(1001)Z=\begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}

No Qiskit, criar um circuito com uma porta ZZ é assim:

qc = QuantumCircuit(1)
qc.z(0)
qc.draw("mpl")

Output of the previous code cell

Porta TT: Adiciona um deslocamento de fase Δϕ=π/4\Delta \phi = \pi/4 ao estado 1|1\rangle:

EntradaSaída
0\vert 0\rangle0\vert 0\rangle
1\vert 1\rangleeiπ/41e^{i\pi/4}\vert 1\rangle

T=(100eiπ/4)T=\begin{pmatrix} 1 & 0 \\ 0 & e^{i\pi/4} \end{pmatrix}

No Qiskit, criar um circuito com uma porta TT é assim:

qc = QuantumCircuit(1)
qc.t(0)
qc.draw("mpl")

Output of the previous code cell

Portas de múltiplos qubits

As portas de dois qubits podem lembrar as portas clássicas de dois bits, mas com uma ressalva importante: todas as portas quânticas devem ser reversíveis. Em termos de álgebra linear, isso significa que são representadas por matrizes unitárias. Portanto, dois qubits de entrada sempre se mapeiam para dois qubits de saída, e a operação pode, em princípio, ser desfeita. Isso contrasta com as portas clássicas que vimos acima, como AND ou OR, que perdem informação e são irreversíveis — dado um resultado, não é possível determinar a entrada de forma unívoca.

Porta CNOT (NOT controlada): Os dois qubits de entrada são chamados de qubit "controle" e qubit "alvo". O qubit de controle permanece inalterado, mas seu estado dita o que acontece com o qubit alvo. Se o qubit de controle estiver no estado 1\vert 1\rangle, uma porta XX é aplicada ao alvo; se o estado do qubit de controle for 0\vert 0\rangle, nenhuma mudança é feita. Na notação abaixo, assume-se que o qubit AA (qubit mais à direita) é o controle, e o qubit BB (o mais à esquerda) é o alvo. A notação usada é CNOT(qcontrol,qtarget)BA.CNOT(q_{control},q_{target})\vert BA\rangle.

CNOT(A,B)BAentrada=BAsaıˊdaCNOT(A,B)\vert BA\rangle_{entrada} = \vert BA\rangle_{saída}

EntradaSaída
00\vert 00\rangle00\vert 00\rangle
01\vert 01\rangle11\vert 11\rangle
10\vert 10\rangle10\vert 10\rangle
11\vert 11\rangle01\vert 01\rangle

Assim, a matriz que representa essa ação é:

CNOT=(1000000100100100)CNOT=\begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix}

qc = QuantumCircuit(2)
qc.cx(0, 1)
qc.draw("mpl")

Output of the previous code cell

Este é o primeiro diagrama de circuito que vemos com dois qubits, representados pelos dois fios. A porta CNOT é implementada entre os dois qubits, com q0q_0 como controle e q1q_1 como alvo.

Verifique seu entendimento

Leia a(s) pergunta(s) abaixo, pense em sua resposta e clique no triângulo para revelar a solução.

A maioria das portas tem a mesma forma matricial no Qiskit e em qualquer outro lugar. Mas a porta CNOT atua em dois qubits, e por isso as convenções de ordenação dos qubits se tornam um problema. Textos que ordenam os qubits como q0,q1,...\vert q_0,q_1,...\rangle mostrarão uma forma matricial diferente para suas portas CNOT. Verifique por multiplicação matricial explícita que a matriz CNOT acima tem a ação correta sobre o estado 01.\vert 01\rangle.

Resposta:

CNOT01=(1000000100100100)(0100)=(0001)=11CNOT\vert 01\rangle =\begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix}\begin{pmatrix}0 \\ 1 \\ 0 \\0\end{pmatrix} = \begin{pmatrix}0 \\ 0 \\ 0 \\1\end{pmatrix} = \vert 11\rangle

Porta SWAP: Essa porta troca os estados de dois qubits. Tabela verdade:

EntradaSaída
00\vert 00\rangle00\vert 00\rangle
01\vert 01\rangle10\vert 10\rangle
10\vert 10\rangle01\vert 01\rangle
11\vert 11\rangle11\vert 11\rangle

Assim, a matriz que representa essa ação é:

SWAP=(1000001001000001)SWAP=\begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1\end{pmatrix}

qc = QuantumCircuit(2)
qc.swap(0, 1)
qc.draw("mpl")

Output of the previous code cell

A porta SWAP pode, na verdade, ser construída a partir de três CNOTs. Para ver como, podemos usar decompose() na porta com o Qiskit:

qc = QuantumCircuit(2)
qc.swap(0, 1)
qc.decompose().draw("mpl")

Output of the previous code cell

Aqui vemos pela primeira vez como múltiplas portas são exibidas em um diagrama de circuito. Lemos da esquerda para a direita, então a porta mais à esquerda é aplicada primeiro.

Verifique seu entendimento

Leia a(s) pergunta(s) abaixo, pense em sua resposta e clique no triângulo para revelar a solução.

Verifique que a combinação de CNOTs acima resulta em uma porta SWAP. Você pode fazer isso com multiplicação matricial ou qualquer outro método.

Resposta:

Com multiplicação matricial:

(1000000100100100)(1000010000010010)(1000000100100100)=(1000001001000001)=SWAP \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix} \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0\end{pmatrix} \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix} = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1\end{pmatrix} = SWAP ~\checkmark

Usando uma tabela verdade para ver como os estados mudam a cada CNOT. Na última coluna, os estados devem ser equivalentes à coluna "saída" da tabela verdade do SWAP:

EntradaCNOT(A,B)CNOT(B,A)CNOT(A,B)
00\vert 00\rangle00\vert 00\rangle00\vert 00\rangle00\vert 00\rangle \checkmark
01\vert 01\rangle11\vert 11\rangle10\vert 10\rangle10\vert 10\rangle \checkmark
10\vert 10\rangle10\vert 10\rangle11\vert 11\rangle01\vert 01\rangle \checkmark
11\vert 11\rangle01\vert 01\rangle01\vert 01\rangle11\vert 11\rangle \checkmark

Porta Toffoli (ou "NOT controlado-controlado" (CCNOT)): Esta é uma porta de três qubits. O nome "NOT controlado-controlado" já sugere como ela funciona: há dois qubits de controle e um qubit alvo, e o estado do qubit alvo é invertido somente se ambos os qubits de controle estiverem no estado 1\vert 1\rangle. Mantemos a convenção de ordenação que usamos com o CNOT:

CCNOT(ControleA,ControleB,AlvoC)CBACCNOT(Controle A, Controle B, Alvo C)\vert CBA\rangle

Portanto, a tabela verdade é:

EntradaSaída
000\vert 000\rangle000\vert 000\rangle
001\vert 001\rangle001\vert 001\rangle
010\vert 010\rangle010\vert 010\rangle
011\vert 011\rangle111\vert 111\rangle
100\vert 100\rangle100\vert 100\rangle
101\vert 101\rangle101\vert 101\rangle
110\vert 110\rangle110\vert 110\rangle
111\vert 111\rangle011\vert 011\rangle

E a matriz que representa essa ação é:

CCNOT=(1000000001000000001000000000000100001000000001000000001000010000)CCNOT=\begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\end{pmatrix}
qc = QuantumCircuit(3)
qc.ccx(0, 1, 2)
qc.draw("mpl")

Output of the previous code cell

A porta Toffoli também pode ser decomposta em CNOTs, junto com algumas outras portas. No entanto, ela é significativamente mais complexa do que a decomposição da porta SWAP, portanto ficará como exercício opcional ao final do módulo explorar e verificar essa decomposição.

Medições

As medições desempenham um papel especial na computação quântica — um papel que não tem análogo na computação clássica. Enquanto na computação clássica você pode verificar seus bits em qualquer momento de sua escolha durante um algoritmo, na computação quântica você deve ser muito criterioso sobre quando observar seus qubits, pois a medição colapsa seu estado e destrói a superposição que confere aos qubits sua complexidade computacional.

Em particular, dado um estado quântico de NN bits ψ=i=02N1cii\vert \psi\rangle = \sum_{i=0}^{2^N-1} c_i \vert i\rangle, uma medição colapsa o estado para uma das funções de base i\vert i\rangle com probabilidade igual a ci2\vert c_i\vert ^2.

Mas esse efeito destrutivo de uma medição nem sempre é um obstáculo. Na verdade, é um recurso fundamental em certos algoritmos e protocolos, como o teletransporte quântico e a distribuição quântica de chaves.

No Qiskit, quando uma medição é feita, ela é enviada para um registrador clássico, onde é armazenada como um bit clássico. Criar um circuito com uma medição é assim:

qc = QuantumCircuit(
1, 1
) # the second number is the number of classical bits in the circuit
qc.measure(0, 0)
qc.draw("mpl")

Output of the previous code cell

Circuitos

Agora que sabemos como qubits, portas e medições funcionam, vamos criar e executar nosso próprio circuito quântico! Para isso, precisamos apresentar um fluxo de trabalho útil chamado Qiskit patterns.

Framework Qiskit patterns

O framework Qiskit patterns é um procedimento geral para abordar e resolver problemas com um computador quântico. Ele consiste em quatro etapas:

  1. Mapear nosso problema para circuitos e operadores quânticos
  2. Otimizar o circuito para o hardware alvo
  3. Executar no hardware alvo
  4. Pós-processar nossos resultados

Para ilustrar essas etapas, implementaremos uma versão quântica do circuito meio-somador discutido acima.

1. Mapeamento

O circuito somador clássico usa uma porta XOR e uma porta AND para calcular os bits de soma e carry, respectivamente. Podemos adaptar essas portas ao contexto quântico para criar o meio-somador quântico. Primeiro, lembrando que as portas quânticas são reversíveis, não podemos simplesmente sobrescrever as entradas. Em vez disso, introduzimos dois qubits auxiliares inicializados em 0\vert 0\rangle para armazenar as saídas de soma e carry. Portanto, nosso estado quântico completo consistirá nos qubits AA e BB, além dos qubits de soma e carry, que chamaremos de SS e CC:

ψ=CSBA\vert \psi\rangle = \vert C S B A\rangle

Agora, precisamos de portas quânticas que realizem o que as portas XOR e AND faziam no circuito clássico.

Soma:

Para o XOR, aplicamos dois CNOTs, cada um com qubits de controle AA e BB e qubit alvo SS para ambos. Se AA e BB forem diferentes, uma das portas CNOT irá inverter SS para o estado 1\vert 1\rangle. Se AA e BB forem ambos 0\vert 0\rangle, nada acontece com SS e ele permanece no estado 0\vert 0\rangle. Se AA e BB forem ambos 1\vert 1\rangle, o estado de SS será invertido duas vezes, retornando ao estado 0\vert 0\rangle.

Carry:

Para o bit de carry, precisamos de algo que funcione como a porta AND clássica.

Verifique seu entendimento

Leia a(s) pergunta(s) abaixo, pense em sua resposta e clique no triângulo para revelar a solução.

Reveja as portas que discutimos para ver se você consegue adivinhar qual porta quântica usaremos no lugar da porta AND clássica:

Resposta:

É a porta Toffoli! Lembre-se: a porta Toffoli, ou NOT controlado-controlado, inverte o estado alvo se e somente se o qubit de controle 0 E o qubit de controle 1 estiverem ambos em 1\vert 1\rangle. Portanto, se o qubit alvo começa no estado 0\vert 0\rangle, ela tem a mesma ação que a porta AND.

Portanto, agora temos todos os ingredientes necessários para construir o circuito quântico:

# qubits: a, b, sum, carry
qc = QuantumCircuit(4)

# Choose values for A and B:
a = 0
b = 0

# Prepare A and B qubits according to selected values:
if a:
qc.x(0)
if b:
qc.x(1)

# XOR (sum) into qubit 2
qc.cx(0, 2)
qc.cx(1, 2)

# AND (carry) into qubit 3
qc.ccx(0, 1, 3) # a AND b

# measure
qc.measure_all()

qc.draw("mpl")

Output of the previous code cell

Acima está o diagrama de circuito para o circuito meio-somador quântico. Como mencionado anteriormente, os fios representam os qubits de 00 a 33, ordenados de cima para baixo, e o registrador de bits clássicos é o fio duplo na parte inferior. Em seguida, lendo da esquerda para a direita, vemos como as portas são aplicadas a cada qubit observando onde as caixas aparecem nos fios correspondentes. Por fim, as medições são mostradas no final. As medições colapsam os estados dos qubits em valores definidos de 00 ou 11, e os resultados são enviados para um registrador clássico.

Uma sutileza: embora o diagrama de circuito seja desenhado da esquerda para a direita, ao escrever a expressão matricial correspondente, devemos lê-la da direita para a esquerda. Isso ocorre porque na multiplicação matricial, o operador mais próximo do vetor de estado (que está mais à direita) age primeiro. Assim, por exemplo, o circuito acima (ignorando as medições) seria escrito como:

CCNOT(q0,q1,q3)CNOT(q1,q2)CNOT(q0,q2)q3q2q1q0CCNOT(q_0,q_1,q_3)CNOT(q_1, q_2)CNOT(q_0,q_2)\vert q_3 q_2 q_1 q_0\rangle

2. Otimizando:

Em seguida, precisamos otimizar o circuito para ser executado no hardware quântico. Essa otimização é realizada pelo transpilador, que traduz o circuito abstrato mostrado acima em instruções que o computador quântico irá entender. Ele atribui os qubits lógicos acima a qubits físicos reais no processador e reescreve as portas em termos do conjunto nativo de portas do computador, que foram otimizadas para execução nele. Por fim, o transpilador também implementa algo chamado de "supressão e mitigação de erros" para tentar minimizar o efeito dos erros no resultado. Isso não é tão importante para o nosso circuito muito simples, mas se você continuar sua jornada em computação quântica e executar circuitos mais complexos, logo verá o valor da supressão e mitigação de erros. Se quiser saber mais sobre isso, veja o curso de Olivia Lane, Computação Quântica na Prática.

Primeiro, carregamos os pacotes necessários para nos comunicar com os computadores quânticos da IBM® e selecionamos um backend para executar. Podemos escolher o backend menos ocupado ou selecionar um backend específico cujas propriedades conhecemos.

Há código abaixo para salvar suas credenciais no primeiro uso. Certifique-se de excluir essas informações do notebook após salvá-las em seu ambiente, para que suas credenciais não sejam compartilhadas acidentalmente ao compartilhar o notebook. Consulte Configurar sua conta IBM Cloud e Inicializar o serviço em um ambiente não confiável para mais orientações.

# Load the Qiskit Runtime service
from qiskit_ibm_runtime import QiskitRuntimeService

# Load the Qiskit Runtime service

# Syntax for first saving your token. Delete these lines after saving your credentials.
# QiskitRuntimeService.save_account(channel='ibm_quantum_platform', instance = '<YOUR_IBM_INSTANCE_CRN>', token='<YOUR-API_KEY>', overwrite=True, set_as_default=True)
# service = QiskitRuntimeService(channel='ibm_quantum_platform')

# Load saved credentials
service = QiskitRuntimeService()

# Use the least busy backend, or uncomment the loading of a specific backend like "ibm_brisbane".
backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)
# backend = service.backend("ibm_brisbane")
print(backend.name)
ibm_fez

Agora, usamos o transpilador para otimizar o circuito. Podemos escolher o nível de otimização de 0 (sem otimização) a 3 (otimização máxima). Para ver o que cada nível implica, visite o guia Definir nível de otimização do transpilador. O circuito resultante será significativamente diferente do circuito lógico que criamos na etapa de mapeamento.

# Transpile the circuit and optimize for running on the quantum computer selected
# Step 2: Transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)

qc_isa.draw("mpl")

Output of the previous code cell

Um "Sampler" é uma primitiva projetada para amostrar possíveis estados resultantes de um circuito quântico e coletar estatísticas sobre quais estados podem ser medidos e com qual probabilidade. Importamos o Sampler do Qiskit Runtime aqui:

# Load the Runtime primitive and session
from qiskit_ibm_runtime import SamplerV2 as Sampler

sampler = Sampler(mode=backend)

Se você esgotou seu tempo alocado em computadores quânticos reais ou se estiver sem conexão à internet, pode preferir usar um simulador. Para isso, execute a célula abaixo e remova o comentário da linha associada na etapa "Executar".

# Load the backend sampler
from qiskit.primitives import BackendSamplerV2

# Load the Aer simulator and generate a noise model based on the currently-selected backend.
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel

noise_model = NoiseModel.from_backend(backend)

# Define a simulator using Aer, and use it in Sampler.
backend_sim = AerSimulator(noise_model=noise_model)
sampler_sim = BackendSamplerV2(backend=backend_sim)

# Alternatively, load a fake backend with generic properties and define a simulator.
# backend_gen = GenericBackendV2(num_qubits=18)
# sampler_gen = BackendSamplerV2(backend=backend_gen)

3. Executando

Após preparar o circuito, agora podemos executá-lo no computador quântico!

job = sampler.run([qc_isa], shots=100)
# job = sampler_sim.run([qc_isa]) # uncomment if you want to run on a simulator
res = job.result()
counts = res[0].data.meas.get_counts()

4. Pós-processamento

Agora estamos prontos para visualizar nossos resultados! Exibiremos um histograma das 100 amostras do circuito.

from qiskit.visualization import plot_histogram

print("counts = ", counts)
plot_histogram(counts)
counts =  {'0000': 90, '0100': 4, '1100': 3, '0010': 3}

Output of the previous code cell

O histograma acima mostra os resultados de medição dos quatro qubits ao final do circuito. Um computador quântico ideal com zero ruído teria medido os qubits com os mesmos valores sempre, mas na realidade o ruído fará com que algumas execuções produzam erros.

Verifique seu entendimento

Leia a(s) pergunta(s) abaixo, pense em sua resposta e clique no triângulo para revelar a solução.

Usando a sequência de bits com mais contagens como seus valores para AA, BB, SS e CC, verifique que o circuito somador quântico funcionou.

Resposta:

Precisamos verificar que A+B=S+2×CA+B = S+2 \times C. Lembre-se de que a ordem da sequência de bits segue a notação little-endian, portanto é lida como CSBA.

A partir do histograma acima, vemos que a sequência de bits 0000 é a dominante.

0+0=0+0×2=0 0 + 0 = 0 + 0 \times 2 = 0 ~\checkmark

Volte e altere os valores de AA e BB para A=1A=1 e B=1B=1 e percorra novamente as etapas do Qiskit patterns para reexecutar o circuito. Verifique que o circuito somador funcionou novamente.

Resposta:

Você deve obter um histograma com a sequência de bits dominante sendo 1011:

1+1=0+1×2=2 1 + 1 = 0 + 1 \times 2 = 2 ~\checkmark

Uma das características adicionais do meio-somador quântico em relação ao meio-somador clássico é que ele pode ser executado com entradas quânticas. Ou seja, ele pode "somar" os qubits AA e BB mesmo que estejam em estados de superposição. Na seção de Perguntas Desafio abaixo, você será solicitado a preparar os qubits em superposições e ver o que acontece!

Conclusão

Este módulo foi projetado para oferecer a você uma compreensão básica sólida dos princípios fundamentais por trás da computação quântica, comparando-a com a computação clássica. Analisamos o circuito meio-somador clássico e mostramos como adaptar o circuito para ser executado com qubits em um computador quântico. Agora você está pronto para explorar os outros módulos do Qiskit in the Classroom!

Conceitos fundamentais:

  • Em contraste com os bits clássicos, que só podem assumir os valores 0 e 1, os qubits também podem estar em estados de superposição de 0 e 1.
  • Múltiplos qubits podem estar em uma superposição sobre as sequências de bits classicamente permitidas, chamadas de estados de base computacional.
  • Múltiplos qubits podem estar emaranhados, de modo que o estado de um depende do estado do outro.
  • A convenção do Qiskit é usar a notação little-endian, que coloca o qubit menos significativo, q0q_0, na posição mais à direita e o qubit mais significativo, qNq_N, mais à esquerda.
  • Portas quânticas são operações reversíveis representadas por matrizes unitárias que atuam nos vetores de estado quântico. Nessa notação, a matriz mais próxima do vetor (que está mais à direita) age primeiro.
  • Medições colapsam um estado quântico de superposição em um dos seus estados classicamente permitidos, com probabilidade igual ao quadrado da amplitude do estado de base computacional correspondente na superposição.
  • Circuitos quânticos são frequentemente representados usando diagramas de circuito quântico, onde qubits são representados como fios horizontais, e portas quânticas aparecem ao longo desses fios da esquerda para a direita.
  • Para executar um circuito quântico, usamos as quatro etapas do fluxo de trabalho Qiskit patterns: Mapear, Otimizar, Executar, Pós-processar.

Perguntas

Perguntas Verdadeiro/Falso

  1. Um único bit em um computador clássico só pode armazenar o valor 0 ou 1.

  2. Emaranhamento significa que o estado de um qubit é independente do estado de outro.

  3. Portas quânticas são geralmente operações irreversíveis.

  4. A convenção do Qiskit coloca o qubit menos significativo, q0q_0, na posição mais à esquerda.

  5. Medir um estado quântico sempre fornece o mesmo resultado exato se repetido muitas vezes.

  6. A porta Hadamard cria superposição em um único qubit.

  7. Circuitos quânticos podem incluir operações de medição que colapsam o estado de superposição em um dos estados classicamente permitidos.

  8. O número de estados clássicos possíveis para NN bits é 2N2N.

  9. As probabilidades de resultado para medições quânticas são dadas pelas amplitudes ao quadrado dos estados de base classicamente mensuráveis.

Perguntas de Resposta Curta

  1. Quais são algumas das principais diferenças entre um bit e um qubit?

  2. O que acontece com um estado quântico quando ele é medido?

  3. Por que usamos a notação little-endian no Qiskit?

  4. Quais são as quatro etapas do fluxo de trabalho Qiskit patterns?

Perguntas Desafio:

  1. No módulo, usamos o somador apenas para somar estados classicamente permitidos para AA e BB. Mas também podemos preparar AA e BB em superposições! Altere o código para preparar cada qubit em uma superposição igual de 0 e 1, depois execute o novo circuito e obtenha um novo histograma. O que você vê? Explique o que está acontecendo.