Nota
Esta página foi gerada a partir do tutorials/circuits/1_getting_started_with_qiskit.ipynb.
Execute interativamente no IBM Quantum lab.
Primeiros passos com Qiskit¶
Aqui, apresentamos uma visão do trabalho com o Qiskit. O pacote fundamental do Qiskit é o Terra que fornece os blocos básicos de desenvolvimento, necessários para programar computadores quânticos. A unidade fundamental do Qiskit é o circuito quantum. Um fluxo de trabalho básico usando Qiskit consiste em dois estágios: Construir e Executar. Construir permite que você crie circuitos quânticos diferentes que representam o problema que você está resolvendo, e Execute permite que você os execute em diferentes backends. Após a execução dos trabalhos, os dados são coletados e processados dependendo da saída desejada.
[1]:
import numpy as np
from qiskit import *
%matplotlib inline
Circuitos básicos¶
Construindo o circuito¶
O elemento básico necessário para o seu primeiro programa é o QuantumCircuit. Vamos criar um QuantumCircuit
composto por três qubits.
[2]:
# Create a Quantum Circuit acting on a quantum register of three qubits
circ = QuantumCircuit(3)
Depois de criar o circuito com os registros, você pode adicionar portas (“operações”) para manipular os registros. Conforme avançar nos tutoriais, você encontrará mais portas e circuitos; abaixo está um exemplo de um circuito quântico que cria um estado de 3-qubit GHZ
Para criar tal estado, começamos com um registo quântico de três qubit. Por padrão, cada qubit no registro é inicializado para o \(|0\rangle\). Para tornar o estado de GHZ, aplicamos os seguintes gates: - Um Hadamard gate \(H\) no qubit 0, que o coloca no estado de superposição \(\left(|0\rangle+|1\rangle\right)/\sqrt{2}\). - Uma operação controlada Not (\(C_{X}\)) entre o qubit 0 e o qubit 1. - Uma operação controlada Not entre o qubit 0 e o qubit 2.
Em um computador quântico ideal, o estado produzido após rodar este circuito seria o estado GHZ acima.
No Qiskit, as operações podem ser adicionadas ao circuito uma a uma, como mostrado abaixo.
[3]:
# Add a H gate on qubit 0, putting this qubit in superposition.
circ.h(0)
# Add a CX (CNOT) gate on control qubit 0 and target qubit 1, putting
# the qubits in a Bell state.
circ.cx(0, 1)
# Add a CX (CNOT) gate on control qubit 0 and target qubit 2, putting
# the qubits in a GHZ state.
circ.cx(0, 2)
[3]:
<qiskit.circuit.instructionset.InstructionSet at 0x2452282f708>
Visualizar Circuito¶
Você pode visualizar seu circuito usando Qiskit QuantumCircuit.draw()
, que plota o circuito na forma encontrada em muitos livros didáticos.
[28]:
circ.draw('mpl')
[28]:

Neste circuito, os qubits são ordenados com qubit zero na parte superior e qubit dois na parte inferior. O circuito é lido da esquerda para a direita (significando que portões que são aplicados no circuito mais cedo aparecem mais para a esquerda).
Ao representar o estado de um sistema multi-qubit, a ordem de tensor utilizada no Qiskit é diferente daquela utilizada na maioria dos livros sobre física. Suponhamos que existam \(n\) qubits, e o qubit \(j\) é rotulado como \(Q_{j}\). O Qiskit usa uma ordenação na qual o \(n^{\mathrm{th}}\) qubit está do lado esquerdo do produto tensorial, de modo que os vetores de base são rotulados como \(Q_{n-1}\otimes \cdots \otimes Q_1\otimes Q_0\).
Por exemplo, se o qubit zero estiver no estado 0, o qubit 1 no estado 0 e o qubit 2 no estado 1, o Qiskit representaria este estado como \(|100\rangle\), enquanto que muitos livros sobre física o representariam como \(|001\rangle\).
Essa diferença de rotulagem afeta a forma como as operações multi-qubit são representadas como matrizes. Por exemplo, o Qiskit representa uma operação X-controlada (\(C_{X}\)) com o qubit 0 sendo o controle e o qubit 1 sendo o alvo como
Simulando circuitos usando Qiskit Aer¶
O Qiskit Aer é o nosso pacote para simular circuitos quânticos. Ele fornece muitos backends diferentes para fazer uma simulação. Há também uma implementação básica, em Python, chamada BasicAer
no Qiskit Terra que pode ser usado como um substituto drop-in para o Aer
nos exemplos abaixo.
Backend de statevector¶
O backend mais comum no Qiskit Aer é o statevector_simulator
. Este simulador retorna o estado quântico, o qual é um vetor complexo de dimensões \(2^n\), onde \(n\) é o número de qubits (portanto, tenha cuidado ao usá-lo já que ele ficará rapidamente muito grande para rodar em sua máquina).
Para executar o circuito acima usando o simulador statevector, primeiro você precisa importar o Aer e, em seguida, configurar o backend para statevector_simulator
.
[5]:
# Import Aer
from qiskit import Aer
# Run the quantum circuit on a statevector simulator backend
backend = Aer.get_backend('statevector_simulator')
Agora que escolhemos o backend, é hora de compilar e executar o circuito quântico. No Qiskit fornecemos a função execute
para isso. execute
retorna um objeto job
que encapsula informações sobre o trabalho submetido ao backend.
Dica: Você pode obter os parâmetros acima no Jupyter. Basta colocar o cursor de texto em uma função e pressionar Shift+Tab.
[6]:
# Create a Quantum Program for execution
job = execute(circ, backend)
Quando você executa um programa, um objeto é criado com os dois métodos úteis a seguir: job.status()
e job.result()
, que retornam, respectivamente, o status e o objeto resultante do job.
Nota: As tarefas são executadas assincronamente, mas quando o método de resultado é chamado, alterna para a execução síncrona e aguarda o término antes de passar para outra tarefa.
[7]:
result = job.result()
Os objetos resultantes contém os dados e o Qiskit provê o método result.get_statevector(circ)
para retornar o estado do vetor para o circuito quântico.
[8]:
outputstate = result.get_statevector(circ, decimals=3)
print(outputstate)
[0.707+0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j
0.707+0.j]
O Qiskit também fornece uma caixa de ferramentas de visualização para permitir que você visualize esses resultados.
Below, we use the visualization function to plot the real and imaginary components of the state density matrix \(\rho\).
[9]:
from qiskit.visualization import plot_state_city
plot_state_city(outputstate)
[9]:

Backend unitário¶
O Qiskit Aer também inclui um unitary_simulator
que funciona desde que todos os elementos no circuito sejam operações unitárias. Este backend calcula a matriz \(2^n \times 2^n\) que representa os gates no circuito quântico.
[10]:
# Run the quantum circuit on a unitary simulator backend
backend = Aer.get_backend('unitary_simulator')
job = execute(circ, backend)
result = job.result()
# Show the results
print(result.get_unitary(circ, decimals=3))
[[ 0.707+0.j 0.707-0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j
0. +0.j 0. +0.j]
[ 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j
0.707+0.j -0.707+0.j]
[ 0. +0.j 0. +0.j 0.707+0.j 0.707-0.j 0. +0.j 0. +0.j
0. +0.j 0. +0.j]
[ 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0.707+0.j -0.707+0.j
0. +0.j 0. +0.j]
[ 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0.707+0.j 0.707-0.j
0. +0.j 0. +0.j]
[ 0. +0.j 0. +0.j 0.707+0.j -0.707+0.j 0. +0.j 0. +0.j
0. +0.j 0. +0.j]
[ 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j
0.707+0.j 0.707-0.j]
[ 0.707+0.j -0.707+0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j
0. +0.j 0. +0.j]]
Backend OpenQASM¶
Os simuladores acima são úteis porque fornecem informações sobre a saída do estado pelo circuito ideal e a representação da matriz do circuito. No entanto, um experimento real termina por medir cada qubit (normalmente na base computacional \(|0\rangle, |1\rangle\)). Sem a medição, não podemos obter informações sobre o estado. As medidas fazem com que o sistema quântico seja desmembrado em bits clássicos.
Por exemplo, suponha que façamos medições independentes em cada qubit do estado GHZ de três qubits
e deixe \(xyz\) denotar o bitstring que resultou. Lembre que, sob o rótulo de qubit usado pelo Qiskit, \(x\) corresponderia ao resultado no qubit 2, \(y\) para o resultado no qubit 1 e \(z\) para o resultado no qubit 0.
Nota: Esta representação do bitstring coloca o bit mais significativo (sigla em inglês, MSB) à esquerda, e o bit menos significativo (sigla em inglês, LSB) à direita. Esta é a ordem padronizada para bitstrings binários. Ordena-se os qubits da mesma maneira (qubit representando o MSB tem índice “0”), razão para o Qiskit usar uma ordem diversa para o tensor.
Lembre-se que a probabilidade de obter resultado \(xyz\) é dada por
e como tal, a probabilidade de estado GHZ de obter 000 ou 111 são ambos de 1/2.
Para simular um circuito que inclui medição, precisamos adicionar medições ao circuito original acima e usar um backend Aer diferente.
[11]:
# Create a Quantum Circuit
meas = QuantumCircuit(3, 3)
meas.barrier(range(3))
# map the quantum measurement to the classical bits
meas.measure(range(3), range(3))
# The Qiskit circuit object supports composition using
# the addition operator.
qc = circ + meas
#drawing the circuit
qc.draw()
[11]:
┌───┐ ░ ┌─┐ q_0: |0>┤ H ├──■────■───░─┤M├────── └───┘┌─┴─┐ │ ░ └╥┘┌─┐ q_1: |0>─────┤ X ├──┼───░──╫─┤M├─── └───┘┌─┴─┐ ░ ║ └╥┘┌─┐ q_2: |0>──────────┤ X ├─░──╫──╫─┤M├ └───┘ ░ ║ ║ └╥┘ c_0: 0 ═══════════════════╩══╬══╬═ ║ ║ c_1: 0 ══════════════════════╩══╬═ ║ c_2: 0 ═════════════════════════╩═
Este circuito adiciona um registro clássico e três medições que são usadas para mapear o resultado dos qubits para os bits clássicos.
Para simular este circuito, nós usamos o qasm_simulator
no Qiskit Aer. Cada execução deste circuito irá gerar a bitstring 000 ou 111. Para construir estatísticas sobre a distribuição dos bitstrings (por exemplo, para estimar \(\mathrm{Pr}(000)\)), precisamos repetir o circuito várias vezes. O número de vezes que o circuito será repetido pode ser especificado na função execute
, através da palavra-chave shots
.
[12]:
# Use Aer's qasm_simulator
backend_sim = Aer.get_backend('qasm_simulator')
# Execute the circuit on the qasm simulator.
# We've set the number of repeats of the circuit
# to be 1024, which is the default.
job_sim = execute(qc, backend_sim, shots=1024)
# Grab the results from the job.
result_sim = job_sim.result()
Uma vez que você possua um objeto de resultado, você pode acessar as contagens através da função get_counts(circuit)
. Isso gera os resultados binários agregados do circuito que você submeteu.
[13]:
counts = result_sim.get_counts(qc)
print(counts)
{'000': 510, '111': 514}
Aproximadamente 50% do tempo, a bitstring de saída é 000. O Qiskit também fornece uma função plot_histogram
, que permite você ver os resultados.
[14]:
from qiskit.visualization import plot_histogram
plot_histogram(counts)
[14]:

As probabilidades estimadas do resultado \(\mathrm{Pr}(000)\) e \(\mathrm{Pr}(111)\) são calculadas pegando as contagens agregadas e dividindo pelo número de shots (vezes que o circuito foi repetido). Tente alterar a palavra-chave shots
na função execute
e veja como as probabilidades se alteram.
[32]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
Qiskit | 0.14.0 |
Terra | 0.11.0 |
Aer | 0.3.4 |
Ignis | 0.2.0 |
Aqua | 0.6.1 |
IBM Q Provider | 0.4.4 |
System information | |
Python | 3.7.4 (default, Aug 9 2019, 18:34:13) [MSC v.1915 64 bit (AMD64)] |
OS | Windows |
CPUs | 2 |
Memory (Gb) | 7.9987335205078125 |
Tue Dec 10 15:25:10 2019 Eastern Standard Time |
This code is a part of Qiskit
© Copyright IBM 2017, 2019.
This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.