Primeiro Passo na Computação Quântica
- Dificuldade: Iniciante
- Tempo de uso de QPU: 11s
Bem-vindos, hackers! Estamos animados em ter vocês no workshop. O principal objetivo desta introdução prática é prepará-los para sua jornada quântica, 1) orientando você sobre como instalar o qiskit, 2) como criar uma conta IBM Cloud e preparar api_key e crn para usar um computador quântico real, 3) criar seu primeiro circuito quântico, 4) resolver um quiz de estado quântico e 5) executar seus circuitos no computador quântico real e plotar o resultado.
1. Primeiro o mais importante: Qiskit
O que é o Qiskit
O Qiskit SDK é uma stack de software de alto desempenho construída para ajudar desenvolvedores e pesquisadores a aproveitarem todo o poder dos computadores quânticos em escala de utilidade e além. Em seu núcleo está o Qiskit SDK, um kit de desenvolvimento de software de código aberto para trabalhar com computadores quânticos no nível de circuitos quânticos estendidos. Operadores e primitivas. O Qiskit SDK permite que qualquer pessoa obtenha desempenho ideal de computadores quânticos reais usando seu ambiente de computação preferido.
Além do SDK, o Qiskit também inclui um conjunto de ferramentas e serviços de alto desempenho como o Qiskit Runtime Service, que permite computações otimizadas em computadores quânticos da IBM através da nuvem usando primitivas que gerenciam mitigação de erros. O serviço Qiskit Transpiler, que fornece métodos heurísticos e baseados em IA de última geração que aumentam o desempenho para tarefas comuns de otimização de circuitos quânticos.
Qiskit functions, um catálogo de serviços da IBM e de terceiros que facilita a otimização de cargas de trabalho e o uso do Qiskit para casos de uso na indústria. Quer você seja um desenvolvedor de software quântico, um experimentalista quântico, um cientista computacional ou apenas alguém querendo começar, a estrutura modular e flexível do Qiskit permite que você trabalhe no nível de abstração que melhor se adapta às suas necessidades.
O Qiskit foi projetado para extensibilidade e personalização, para que você possa extrair desempenho líder na indústria e enfrentar novos tipos de problemas. Uma base de código de alto desempenho significa que o Qiskit SDK funciona mais rápido, usa menos memória e fornece melhores resultados do que nunca. E o Qiskit também apresenta a você uma vasta comunidade de usuários e desenvolvedores que estão ansiosos para recebê-lo e ajudar a responder suas perguntas. Lançado pela primeira vez em 2019, o programa Qiskit advocate é uma iniciativa global, centrada na comunidade, que recruta profissionais e entusiastas de computação quântica de todo o mundo. Ao longo dos anos, advocates se tornaram líderes reconhecidos na comunidade quântica. Quer ser o próximo líder quântico? Não hesite em se inscrever - aqui
Instalar o Qiskit
Primeiro, verifique se a versão do Python que você está usando em seu ambiente é python>=3.10, para garantir que seja compatível com a versão mais recente do Qiskit que usaremos
from platform import python_version
print(python_version())
Se este não for o caso, você pode atualizá-la usando sua ferramenta preferida. Se não tiver certeza de como fazer isso, algumas opções recomendadas são:
- MacOS: Homebrew
- Linux:
sudo apt-get update
Um guia detalhado sobre como atualizar o Python dependendo do seu SO é detalhado aqui: How to update Python
Para mais informações, dê uma olhada na wiki da QGSS (Qiskit Global Summer School) 2025: https://github.com/qiskit-community/qgss-2025/wiki/Jupyter-Notebook-Environment-(Local-and-Online)
Você pode verificar sua instalação executando a célula abaixo. Se você instalou corretamente, ela retornará a versão do qiskit.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
%pip install 'qiskit[visualization]'
%pip install qiskit-ibm-runtime
%pip install qiskit-aer
import qiskit
print(f"Qiskit version: {qiskit.__version__}")
Solução de problemas
Se a célula anterior gerou um erro, você pode optar por instalar o Qiskit em um ambiente virtual (dois métodos sugeridos a seguir). Se você não tiver erros, pode ignorar esta célula e prosseguir para a próxima.
Aqui propomos dois métodos diferentes para configurar um ambiente virtual para instalar o Qiskit.
- Usando venv, conforme explicado no guia de instalação do Qiskit.
- Usando conda, conforme explicado neste vídeo do Coding with Qiskit.
2. Configure sua conta IBM Cloud
Para usar um computador quântico real, você precisa de uma api key - um ingresso de entrada principal para a nuvem e de uma crn - token que trará seus recursos para você ao configurar sua conta.
Configure sua conta da seguinte forma:
- Acesse a IBM Quantum® Platform.
- Vá ao canto superior direito (como mostrado na imagem acima), crie seu token de API e copie-o para um local seguro.
- Na próxima célula, substitua
deleteThisAndPasteYourAPIKeyHerepor sua chave de API. - Vá ao canto inferior esquerdo (como mostrado na imagem acima) e crie sua instância. Certifique-se de escolher o plano aberto.
- Após a instância ser criada, copie o código CRN associado a ela. Pode ser necessário atualizar a página para ver a instância.
- Na célula abaixo, substitua
deleteThisAndPasteYourCRNHerepelo seu código CRN.
Veja este guia para mais detalhes sobre como configurar sua conta IBM Cloud®.
⚠️ Nota: Trate sua chave de API como você trataria uma senha segura. Veja o guia Cloud setup para mais informações sobre o uso de sua chave de API em ambientes seguros e não confiáveis.
Adicionalmente, se você é membro da rede de parceiros universitários da IBM, por favor, use o endereço de e-mail da sua instituição para seu IBM ID para receber o benefício de parceiro.
from qiskit_ibm_runtime import QiskitRuntimeService
# Save your API key and crn and have access to the quantum computers
your_api_key = "deleteThisAndPasteYourAPIKeyHere"
your_crn = "deleteThisAndPasteYourCRNHere"
QiskitRuntimeService.save_account(
channel="ibm_cloud",
token=your_api_key,
instance=your_crn,
overwrite=True
)
# Check that the account has been saved properly
service = QiskitRuntimeService()
service.saved_accounts()
# See backends you can use
service.backends()
3. Seu primeiro Circuito Quântico
Circuitos quânticos
A unidade fundamental do Qiskit é o circuito quântico, que é uma série de instruções que um computador quântico pode usar para trabalhar com bits quânticos de informação, também conhecidos como qubits. Esses qubits têm propriedades especiais que permitem que os computadores quânticos abordem problemas de maneira diferente de como seu laptop ou iPhone podem fazer. O Qiskit está avançando rapidamente como tecnologia -- embora você ainda possa projetar manualmente seus circuitos quânticos e decidir como deseja executá-los (e há muitas boas razões para fazê-lo), a IBM Quantum também fornece ferramentas que simplificam o processo. Para fins de aprendizado, vamos projetar um circuito muito simples e executá-lo em um simulador.
Estamos passando rapidamente por esta visão geral porque, honestamente, poderíamos passar horas apenas explicando os fundamentos da informação e computação quânticas. Na verdade, a IBM Quantum já fez isso, produzindo um curso escrito e uma série de palestras em vídeo dedicadas ao tópico. Se precisar de uma revisão, confira-os!
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
from qiskit.visualization import plot_state_qsphere
from qiskit_aer import AerSimulator
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.visualization import array_to_latex
from qiskit.visualization import plot_distribution
import numpy as np
from numpy import sqrt
Operações Básicas em Qubits e Medições
Escrevendo estados de qubit único
Vamos começar olhando para um único qubit. A principal diferença em relação a um bit clássico, que pode assumir apenas os valores 0 e 1, é que um bit quântico, ou qubit, pode estar nos estados , , bem como em uma combinação linear desses dois estados. Esta característica é conhecida como superposição e nos permite escrever o estado mais geral de um qubit como:
Se medíssemos o estado deste qubit, encontraríamos o resultado com probabilidade , e o resultado com probabilidade . Como você pode ver, a probabilidade total é , o que significa que de fato mediremos ou , e nenhum outro resultado existe.
Além de , você pode ter notado outro parâmetro acima. A variável indica a fase quântica relativa entre os dois estados e . Como descobriremos depois, esta fase relativa é bastante importante. Por enquanto, basta notar que a fase quântica é o que permite a interferência entre estados quânticos, resultando em nossa capacidade de escrever algoritmos quânticos para resolver tarefas específicas.
Visualizando estados quânticos
Visualizamos estados quânticos ao longo deste exercício usando o que é conhecido como qsphere. Veja como a qsphere aparece para os estados e , respectivamente. Note que a parte mais alta da esfera representa o estado , enquanto a parte inferior representa .
#visualize |0>
sv=Statevector([1, 0])
plot_state_qsphere(sv)
Você pode criar exatamente a mesma QSphere usando um circuito quântico. O statevector que usamos aqui é do estado . No Qiskit, o qubit é inicializado no estado . Tente executar o circuito abaixo e veja se consegue obter a mesma QSphere.
qc1 = QuantumCircuit(1)
sv=Statevector(qc1)
plot_state_qsphere(sv)
Agora vamos visualizar o estado .
Não deve ser surpresa que o estado de superposição com fase quântica e probabilidade (significando uma probabilidade igual de medir tanto 0 quanto 1) é mostrado na qsphere com dois pontos. No entanto, note também que o tamanho dos círculos nos dois pontos é menor do que quando tínhamos simplesmente e acima. Isto ocorre porque o tamanho dos círculos é proporcional à probabilidade de medir cada um, que agora é reduzida pela metade.
#visualize 1/sqrt(2)|0> + 1/sqrt(2)|1>
sv=Statevector([1/sqrt(2), 1/sqrt(2)])
plot_state_qsphere(sv)
No caso de estados de superposição, onde a fase quântica é diferente de zero, a qsphere nos permite visualizar essa fase alterando a cor da bolha respectiva. Por exemplo, o estado com (graus) e probabilidade é mostrado na qsphere abaixo.
sv=Statevector([1/sqrt(2), 1/sqrt(2)*1j])
plot_state_qsphere(sv)
Manipulando qubits
Os qubits são manipulados aplicando portas quânticas. Vamos passar por uma visão geral das diferentes portas que consideraremos nos exercícios a seguir.
Primeiro, vamos descrever como podemos alterar o valor de para nosso estado quântico geral. Para fazer isso, usaremos duas portas:
-
porta : Esta porta inverte os dois estados e . Esta operação é a mesma que a porta NOT clássica. Como resultado, a porta é às vezes chamada de bit flip ou porta NOT. Matematicamente, a porta muda para , então em particular de 0 para 1, e vice-versa.
-
porta : Esta porta nos permite ir do estado para o estado . Este estado também é conhecido como . Matematicamente, isso significa ir de para . Como o estado final do qubit é uma superposição de e , a porta Hadamard representa uma verdadeira operação quântica.
Note que ambas as portas alteraram o valor de , mas não de . Felizmente para nós, é bastante fácil visualizar a ação dessas portas olhando para a figura abaixo.
Uma vez que temos o estado , podemos então alterar a fase quântica aplicando várias outras portas. Por exemplo, uma porta adiciona uma fase de graus a , enquanto a porta adiciona uma fase de graus a . Para subtrair uma fase de graus, podemos aplicar a porta , que é lida como S-dagger e comumente escrita como sdg. Finalmente, há uma porta que aplica uma sequência de portas e .
Você pode experimentar com as portas , , , , e para se familiarizar com as diferentes operações e como elas afetam o estado de um qubit. Para fazer isso, você pode visitar o Circuit Composer e iniciar nosso widget de circuito. Depois de visitar o circuit composer, escolha uma porta para aplicar a um qubit e, em seguida, escolha o qubit (nos primeiros exemplos, o único qubit a escolher é o qubit 0). Observe como o estado correspondente muda com cada porta, bem como a descrição desse estado. Ele também fornecerá o código que cria o circuito quântico correspondente no Qiskit.
Se quiser aprender mais sobre a descrição de estados quânticos, operadores de Pauli e outras portas de qubit único, consulte Quantum Information do Sistema Único do curso Basics of Quantum Information por John Watrous.
Práticas: Circuitos Quânticos Usando Portas de Qubit Único
Aqui estão quatro pequenas práticas para alcançar diferentes estados na qsphere. Você pode resolvê-las com o circuit composer e copiar e colar o código que ele fornece nas células respectivas para criar os circuitos quânticos, ou pode inserir diretamente uma combinação das seguintes linhas de código no programa para aplicar as diferentes portas:
qc.x(0) # bit flip qc.y(0) # bit and phase flip qc.z(0) # phase flip qc.h(0) # superpostion qc.s(0) # quantum phase rotation by pi/2 (90 degrees) qc.sdg(0) # quantum phase rotation by -pi/2 (90 degrees)
O '(0)' indica que aplicamos esta porta ao qubit 'q0', que é o primeiro (e neste caso único) qubit.
Tente alcançar o estado dado na qsphere em cada um dos exercícios a seguir.
i) Vamos começar realizando um bit flip. O objetivo é alcançar o estado partindo do estado .
def create_circuit():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc
# check solution
qc2 = create_circuit()
state = Statevector(qc2)
plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)
ii) Em seguida, vamos criar uma superposição. O objetivo é alcançar o estado .
def create_circuit2():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc
qc3 = create_circuit2()
state = Statevector(qc3)
plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)
iii) Vamos combinar essas duas. O objetivo é alcançar o estado .
Você consegue combinar as duas tarefas acima para chegar à solução?
def create_circuit3():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc
qc4 = create_circuit3()
state = Statevector(qc4)
plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)
iv) Por fim, passamos para os números complexos. O objetivo é alcançar o estado
def create_circuit4():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc
qc5 = create_circuit4()
state = Statevector(qc5)
plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)
4. Quiz Quântico com Portas de Múltiplos Qubits
Ótimo trabalho! Agora que você entendeu as portas de qubit único, vamos olhar para portas que operam em múltiplos qubits. Aqui você será solicitado a resolver 4 quizzes de estado quântico combinando portas de qubit único e portas de múltiplos qubits. As portas básicas em dois qubits são dadas por
qc.cx(c,t) # controlled-X (= CNOT) gate with control qubit c and target qubit t qc.cz(c,t) # controlled-Z gate with control qubit c and target qubit t qc.swap(a,b) # SWAP gate that swaps the states of qubit a and qubit b
Se quiser ler mais sobre as diferentes portas de múltiplos qubits e suas relações, visite Quantum Information de múltiplos sistemas, do curso Basics of Quantum Information de John.
Note que para dois qubits um estado geral é da forma , onde , , e são números complexos cujos valores absolutos ao quadrado dão a probabilidade de medir o respectivo estado; por exemplo, seria a probabilidade de terminar no estado '0' em ambos os qubits. Isto significa que agora podemos ter até quatro pontos na qsphere.
Começamos com a porta canônica de dois qubits, a porta controlled-NOT (também CNOT ou CX). Aqui, como em todas as portas de dois qubits controladas, um qubit é rotulado como o "controle", enquanto o outro é chamado de "alvo". Se o qubit de controle estiver no estado , ele aplica a porta de identidade ao alvo, ou seja, nenhuma operação é realizada. Em vez disso, se o qubit de controle estiver no estado , uma porta X é executada no qubit alvo. Portanto, com ambos os qubits em um dos dois estados clássicos, ou , a porta CNOT é limitada a operações clássicas.
Esta situação muda dramaticamente quando primeiro aplicamos uma porta Hadamard ao qubit de controle, levando-o ao estado de superposição . A ação de uma porta CNOT sobre essa entrada não-clássica pode produzir estados altamente emaranhados entre os qubits de controle e alvo. Se o qubit alvo está inicialmente no estado , o estado resultante é denotado por , e é um dos chamados estados de Bell.
i) Construa o estado de Bell .
Para este estado teríamos probabilidade de medir "00" e probabilidade de medir "11". Assim, os resultados de ambos os qubits estão perfeitamente correlacionados.
def create_circuit5():
qc = QuantumCircuit(2)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc
qc6 = create_circuit5()
state = Statevector(qc6) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc6.draw(output='mpl') # we draw the circuit
Em seguida, tente criar o estado de qubits perfeitamente anti-correlacionados. Note o sinal negativo aqui, que indica a fase relativa entre os dois estados.
ii) Construa o estado de Bell .
def create_circuit6():
qc = QuantumCircuit(2)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc
qc7 = create_circuit6()
state = Statevector(qc7) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc7.draw(output='mpl') # we draw the circuit
iii) Você recebe o circuito quântico descrito na função abaixo. Troque os estados do primeiro e do segundo qubit para obter esta QSphere.
def create_circuit7():
qc = QuantumCircuit(2)
qc.rx(np.pi/3,0)
qc.x(1)
return qc
qc8 = create_circuit7()
#
#
# FILL YOUR CODE IN HERE
#
#
state = Statevector(qc8) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc8.draw(output='mpl') # we draw the circuit
iv) Escreva um programa do zero que cria o estado GHZ (em três qubits),
def create_circuit8():
#
#
# FILL YOUR CODE IN HERE
#
#
#
return qc
qc9 = create_circuit8()
pub4 = (qc9)
state = Statevector(qc9) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc9.draw(output='mpl') # we draw the circuit
5. Execute seu circuito e veja o resultado medido com um computador quântico real
Agora que sabemos como construir um circuito quântico para manipular um statevector de qubits. E é hora da parte mais empolgante: executá-lo e ver a saída! Aqui aprenderemos a maneira moderna e eficaz de executar nossos circuitos usando o Qiskit.
Um padrão Qiskit é uma estrutura geral para decompor problemas específicos de domínio e contextualizar as capacidades necessárias em estágios. Isto permite a composição perfeita de novas capacidades desenvolvidas por pesquisadores da IBM Quantum (e outros) e possibilita um futuro em que as tarefas de computação quântica são realizadas por uma poderosa infraestrutura de computação heterogênea (CPU/GPU/QPU).
As quatro etapas de um padrão Qiskit são as seguintes:
- Mapear o problema para circuitos e operadores quânticos
- Otimizar para o hardware alvo
- Executar no hardware alvo
- Pós-processar os resultados
Acabamos de terminar a Etapa 1: Mapeamento, construindo circuitos quânticos para gerar o estado quântico desejado. Agora, vamos percorrer as etapas restantes para ver os resultados.
Otimizar
Aqui vamos definir o backend para executar os circuitos - você pode selecionar a least busy qpu entre seus grupos de qpu acessíveis, ou pode simplesmente escolher um simulador se não tiver tempo de GPU restante suficiente. Uma vez selecionado um backend, o pass_manager irá transpile seus circuitos para os conjuntos de portas nativas do backend que você escolheu e otimizá-lo para você obter um melhor resultado. Você pode declarar facilmente o pass_manager usando generate_preset_pass_manager e definindo o optimization_level, sendo um número maior indicativo de mais etapas de otimização.
A próxima etapa é empolgante - vamos executar o circuito quântico usando o Qiskit Runtime!
Faremos isso usando as duas primitivas Qiskit:
- Sampler amostra o registro de saída da execução de um ou mais circuitos quânticos. Sua saída são contagens em medições por shot.
- Estimator calcula o valor esperado de um ou mais observáveis em relação aos estados gerados pelo circuito quântico. Sua saída consiste nos valores esperados juntamente com seus erros padrão.
Aqui, usaremos o Sampler para executar nossos circuitos. A célula de código abaixo mostra que você primeiro define um backend e um pass manager para ele. Em seguida, ele adicionará measurement a todos os circuitos e criará um array de circuitos quânticos (pub) para passar ao Sampler.
backend=service.least_busy()
#backend=AerSimulator()
pm = generate_preset_pass_manager(optimization_level=3, backend=backend)
sampler = Sampler(mode=backend)
pub = []
for qc in circ:
qc.measure_all()
pub.append(pm.run(qc))
Executar
Vamos executar nossos circuitos. Caso haja muitas filas de espera na nuvem, imprima e salve job_id para uso posterior e verifique o job_status. Depois de ver o status do trabalho mudar para Done, recupere o resultado do trabalho.
job = sampler.run(pub)
job_id = job.job_id()
print(job_id)
job.status()
job_retrived = service.job(job_id)
result = job.result()
Pós-processar
A etapa final é interpretar a visualização para entender os estados quânticos que criamos. Antes de plotar vários gráficos, vamos trazer todas as contagens de todos os circuitos. Em seguida, faremos 4 plotagens categorizando os circuitos.
result = job.result()
counts_all = [result[k].data.meas.get_counts() for k in range(9)]
Os Estados de Qubit Único
plot_distribution([counts_all[0], counts_all[1]], legend =['qc1', 'qc2'])
Os Estados de Um Qubit em Superposição
plot_distribution([counts_all[2], counts_all[3], counts_all[4]], legend =['qc3', 'qc4', 'qc5'])
Estados de Dois Qubits
plot_distribution([counts_all[5], counts_all[6], counts_all[7]],legend =['qc6', 'qc7', 'qc8'] )
Estados de Três Qubits
plot_distribution(counts_all[8], legend=['qc9'])
Desafio adicional
Você encontrou algum ruído nos resultados experimentais reais do backend? Remover o ruído de qubit é uma das áreas de pesquisa ativa. Experimente as várias opções de mitigação e supressão de erros do Qiskit Runtime para ver como o ruído nos resultados de execução muda! (Observação) Estas opções permitem mais tempo de QPU.
Informações Adicionais
import qiskit, qiskit_ibm_runtime
print("Qiskit version:", qiskit.version.get_version_info())
print("Qiskit Runtime version:", qiskit_ibm_runtime.__version__)
Qiskit version: 2.1.1
Qiskit Runtime version: 0.40.1
Criado por: Sophy Shin
Revisado por: Nate Earnest-Noble
© IBM Corp., 2025
Isto é licenciado sob a Apache License, Version 2.0. Você pode obter uma cópia desta licença no arquivo LICENSE no diretório raiz desta árvore de código-fonte ou em http://www.apache.org/licenses/LICENSE-2.0.
Quaisquer modificações ou trabalhos derivados deste devem manter este aviso de direitos autorais, e os arquivos modificados precisam carregar um aviso indicando que foram alterados em relação aos originais.