Portuguese
Idiomas
English
Bengali
French
German
Japanese
Korean
Portuguese
Spanish
Tamil

Nota

Esta página foi originada de tutorials/circuits/1_getting_started_with_qiskit.ipynb.

Começando com o Qiskit

Aqui, trazemos uma visão geral de como utilizar o Qiskit. O pacote fundamental do Qiskit é o Terra, que fornece os blocos básicos de construção necessários para programar computadores quânticos. A unidade fundamental do Qiskit é o circuito quântico. Um fluxo básico utilizando Qiskit consiste de dois estágios: Construção e Execução. Construção permite que você faça diferentes circuitos quânticos que representam o problema que você está resolvendo, e Execução permite que você rode tais circuitos em diferentes backends. Após rodar os processos, os dados são coletados e pós-processados dependendo da saída desejada.

[1]:
import numpy as np
from qiskit import *

Princípios básicos sobre Circuitos

Construindo o circuito

O elemento básico necessário para seu primeiro programa é o QuantumCircuit. Começamos por criar um QuantumCircuit composto de três qubits.

[2]:
# Create a Quantum Circuit acting on a quantum register of three qubits
circ = QuantumCircuit(3)

After you create the circuit with its registers, you can add gates («operations») to manipulate the registers. As you proceed through the tutorials you will find more gates and circuits; below is an example of a quantum circuit that makes a three-qubit GHZ state

\[|\psi\rangle = \left(|000\rangle+|111\rangle\right)/\sqrt{2}.\]

To create such a state, we start with a three-qubit quantum register. By default, each qubit in the register is initialized to \(|0\rangle\). To make the GHZ state, we apply the following gates: - A Hadamard gate \(H\) on qubit \(q_{0}\), which puts it into the superposition state \(\left(|0\rangle+|1\rangle\right)/\sqrt{2}\). - A controlled-Not operation (\(C_{X}\)) between qubit \(q_{0}\) and qubit \(q_{1}\). - A controlled-Not operation between qubit \(q_{0}\) and qubit \(q_{2}\).

Em um computador quântico ideal, a execução desse circuito produziria 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 $q_{0}$, putting this qubit in superposition.
circ.h(0)
# Add a CX (CNOT) gate on control qubit $q_{0}$ and target qubit $q_{1}$, putting
# the qubits in a Bell state.
circ.cx(0, 1)
# Add a CX (CNOT) gate on control qubit $q_{0}$ and target qubit $q_{2}$, putting
# the qubits in a GHZ state.
circ.cx(0, 2)
[3]:
<qiskit.circuit.instructionset.InstructionSet at 0x7fa0f8fc9310>

Visualizar o Circuito

Você pode visualizar seu circuito usando Qiskit QuantumCircuit.draw(), que desenha o circuito na forma encontrada em muitos livros didáticos.

[4]:
circ.draw('mpl')
[4]:
../../_images/tutorials_circuits_1_getting_started_with_qiskit_7_0.png

In this circuit, the qubits are put in order, with qubit \(q_{0}\) at the top and qubit \(q_{2}\) at the bottom. The circuit is read left to right (meaning that gates that are applied earlier in the circuit show up further to the left).

Ao representar o estado de um sistema de múltiplos qubits, a ordem tensorial utilizada no Qiskit é diferente daquela empregada na maioria dos livros de física. Suponha que existam \(n\) qubits, e o qubit \(j\) é rotulado como \(Q_{j}\). O Qiskit usa uma ordem na qual o qubit \(n^{\mathrm{th}}\) está do lado esquerdo do produto tensorial, de forma que os vetores de base são rotulados como \(Q_{n-1}\otimes \cdots \otimes Q_1\otimes Q_0\).

For example, if qubit \(Q_{0}\) is in state 0, qubit \(Q_{1}\) is in state 0, and qubit \(Q_{2}\) is in state 1, Qiskit would represent this state as \(|100\rangle\), whereas many physics textbooks would represent it as \(|001\rangle\).

This difference in labeling affects the way multi-qubit operations are represented as matrices. For example, Qiskit represents a controlled-X (\(C_{X}\)) operation with qubit \(Q_{0}\) being the control and qubit \(Q_{1}\) being the target as

\[\begin{split}C_X = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\\end{pmatrix}.\end{split}\]

Simulando circuitos usando Qiskit Aer

Qiskit Aer é o nosso pacote para a simulação de circuitos quânticos. Ele provê diferentes backends para a realização de simulações. Há também uma implementação básica, apenas para Python, chamada BasicAer no Terra que pode ser usada como um substituto direto para o Aer, como nos exemplos abaixo.

Backend de Vetor de Estados

O backend mais comum do Qiskit Aer é o statevector_simulator. Ele retorna o estado quântico, que é um vetor complexo de dimensão \(2^n\), na qual \(n\) é o número de qubits (então tenha cuidado ao usá-lo, já que ele rapidamente se tornará grande demais para a execução na sua máquina).

Para executar o circuito acima usando o backend de vetor de estados, primeiro é necessário importar o Aer e então definir o backend como statevector_simulator.

[5]:
# Import Aer
from qiskit import Aer

# Run the quantum circuit on a statevector simulator backend
backend = Aer.get_backend('statevector_simulator')

Now that we have chosen the backend, it’s time to compile and run the quantum circuit. In Qiskit we provide the run method for this. run returns a job object that encapsulates information about the job submitted to the backend.

Dica: Você pode obter os parâmetros acima no Jupyter. Simplesmente coloque o cursor sobre uma função e aperte Shift+Tab.

[6]:
# Create a Quantum Program for execution
job = backend.run(circ)

Ao rodar um programa, um objeto job é criado que tem 2 métodos úteis: job.status() e job.result(), que retornam o estados da tarefa e um objeto result, respectivamente.

Obs.: Tarefas rodam assincronamente, mas quando o método result é chamado, isso muda para um modo síncrono e espera que termine antes de prosseguir para outra task.

[7]:
result = job.result()

O objeto results contém os dados e o Qiskit provê o método result.get_statevector(circ) para retornar o vetor de estados 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 toolbox de visualização a fim de permitir que você observe esses resultados.

Abaixo, utilizaremos a função de visualização para desenhar as componentes reais e imaginárias da matriz de densidade de estados \(\rho\).

[9]:
from qiskit.visualization import plot_state_city
plot_state_city(outputstate)
[9]:
../../_images/tutorials_circuits_1_getting_started_with_qiskit_20_0.png

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. Esse backend calcula a matrix \(2^n \times 2^n\) que representa as portas no circuito quântico.

[10]:
# Run the quantum circuit on a unitary simulator backend
backend = Aer.get_backend('unitary_simulator')
job = backend.run(circ)
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 o estado final do circuito ideal e a representação matricial do circuito. No entanto, um experimento real termina medindo cada qubit (geralmente na base computacional \(|0\rangle, |1\rangle\) ). Sem medições, não podemos obter informações sobre o estado. Medições fazem o sistema quântico colapsar para bits clássicos.

Por exemplo, suponha que façamos medições independentes em cada qubit do estado GHZ de três qubits

\[|\psi\rangle = (|000\rangle +|111\rangle)/\sqrt{2},\]

and let \(xyz\) denote the bitstring that results. Recall that, under the qubit labeling used by Qiskit, \(x\) would correspond to the outcome on qubit \(q_{2}\), \(y\) to the outcome on qubit \(q_{1}\), and \(z\) to the outcome on qubit \(q_{0}\).

Obs.: Esta representação da bitstring coloca o bit mais significativo (MSB) à esquerda, e o bit menos significativo (LSB) à direita. Esta é a ordenação padrão de bitstrings binárias. Ordenamos os qubits da mesma forma (qubit representando o MSB tem índice 0), razão pela qual o Qiskit usa uma ordem de produto tensorial fora do padrão.

Lembre-se que a probabilidade de obter resultado \(xyz\) é dada por

\[\mathrm{Pr}(xyz) = |\langle xyz | \psi \rangle |^{2}\]

e como tal, as probabilidades de se obter 000 ou 111 no estado GHZ são ambas de 1/2.

Para simular um circuito que inclua medições, nós precisamos adicionar elas ao circuito original acima e usar um backend Aer diferente.

[13]:
# 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 compose method.
circ.add_register(meas.cregs[0])
qc = circ.compose(meas)

#drawing the circuit
qc.draw()
[13]:
     ┌───┐           ░ ┌─┐
q_0: ┤ H ├──■────■───░─┤M├──────
     └───┘┌─┴─┐  │   ░ └╥┘┌─┐
q_1: ─────┤ X ├──┼───░──╫─┤M├───
          └───┘┌─┴─┐ ░  ║ └╥┘┌─┐
q_2: ──────────┤ X ├─░──╫──╫─┤M├
               └───┘ ░  ║  ║ └╥┘
c: 3/═══════════════════╩══╩══╩═
                        0  1  2 

Este circuito adiciona um registrador clássico e três medições que são usadas para mapear o resultado dos qubits nos bits clássicos.

To simulate this circuit, we use the qasm_simulator in Qiskit Aer. Each run of this circuit will yield either the bitstring 000 or 111. To build up statistics about the distribution of the bitstrings (to, e.g., estimate \(\mathrm{Pr}(000)\)), we need to repeat the circuit many times. The number of times the circuit is repeated can be specified in the run method, via the shots keyword.

[17]:
# 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 = backend_sim.run(transpile(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 lhe fornece os resultados binários agregados do circuito que você submeteu.

[18]:
counts = result_sim.get_counts(qc)
print(counts)
{'111': 514, '000': 510}

Aproximadamente 50% das vezes, a string de bits da saída é 000. Qiskit também provê a função plot_histogram, que permite que você veja os resultados.

[19]:
from qiskit.visualization import plot_histogram
plot_histogram(counts)
[19]:
../../_images/tutorials_circuits_1_getting_started_with_qiskit_32_0.png

The estimated outcome probabilities \(\mathrm{Pr}(000)\) and \(\mathrm{Pr}(111)\) are computed by taking the aggregate counts and dividing by the number of shots (times the circuit was repeated). Try changing the shots keyword in the run method and see how the estimated probabilities change.

[20]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
qiskit-terra0.19.0.dev0+be0ed5f
qiskit-aer0.8.2
qiskit-ignis0.6.0
qiskit-ibmq-provider0.16.0.dev0+4e20edc
System information
Python3.7.7 (default, May 6 2020, 04:59:01) [Clang 4.0.1 (tags/RELEASE_401/final)]
OSDarwin
CPUs6
Memory (Gb)32.0
Sat Jul 31 01:06:28 2021 EDT

This code is a part of Qiskit

© Copyright IBM 2017, 2021.

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.

[ ]: