Simulação exata e com ruído com primitivas do Qiskit Aer
Versões dos pacotes
O código nesta página foi desenvolvido com os seguintes requisitos. Recomendamos usar essas versões ou mais recentes.
qiskit[all]~=2.3.0
qiskit-aer~=0.17
A simulação exata com primitivas do Qiskit demonstra como usar as primitivas de referência incluídas no Qiskit para realizar simulação exata de circuitos quânticos. Os processadores quânticos existentes atualmente sofrem de erros, ou ruído, portanto os resultados de uma simulação exata não refletem necessariamente os resultados que você esperaria ao executar circuitos em hardware real. Enquanto as primitivas de referência no Qiskit não suportam modelagem de ruído, o Qiskit Aer inclui implementações das primitivas que suportam modelagem de ruído. O Qiskit Aer é um simulador de circuitos quânticos de alto desempenho que você pode usar no lugar das primitivas de referência para melhor desempenho e mais recursos. Ele faz parte do Qiskit Ecosystem. Neste artigo, demonstramos o uso das primitivas do Qiskit Aer para simulação exata e com ruído.
- É necessário
qiskit-aerv0.14 ou posterior. - Embora as primitivas do Qiskit Aer implementem as interfaces de primitivas, elas não fornecem as mesmas opções que as primitivas do Qiskit Runtime. O nível de resiliência, por exemplo, não está disponível com as primitivas do Qiskit Aer.
- Consulte a documentação do AerSimulator para obter detalhes sobre as opções de método de simulação que o Aer suporta.
Para explorar a simulação exata e com ruído, crie um circuito de exemplo com oito qubits:
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-aer
from qiskit.circuit.library import efficient_su2
n_qubits = 8
circuit = efficient_su2(n_qubits)
circuit.draw("mpl")
Este circuito contém parâmetros que representam os ângulos de rotação para as portas e . Ao simular esse circuito, precisamos especificar valores explícitos para esses parâmetros. Na próxima célula, especificamos alguns valores para esses parâmetros e usamos a primitiva Estimator do Qiskit Aer para calcular o valor esperado exato do observável .
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_aer import AerSimulator
from qiskit_aer.primitives import EstimatorV2 as Estimator
observable = SparsePauliOp("Z" * n_qubits)
params = [0.1] * circuit.num_parameters
exact_estimator = Estimator()
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(3, AerSimulator())
isa_circuit = pass_manager.run(circuit)
pub = (isa_circuit, observable, params)
job = exact_estimator.run([pub])
result = job.result()
pub_result = result[0]
exact_value = float(pub_result.data.evs)
exact_value
0.8870140234256602
Agora, vamos inicializar um modelo de ruído que inclui erro de despolarização de 2% em cada porta CX. Na prática, os erros provenientes das portas de dois qubits, que aqui são portas CX, são a principal fonte de erro ao executar um circuito. Consulte Construir modelos de ruído para uma visão geral da construção de modelos de ruído no Qiskit Aer.
Na próxima célula, construímos um Estimator que incorpora esse modelo de ruído e o usamos para calcular o valor esperado do observável.
from qiskit_aer.noise import NoiseModel, depolarizing_error
noise_model = NoiseModel()
cx_depolarizing_prob = 0.02
noise_model.add_all_qubit_quantum_error(
depolarizing_error(cx_depolarizing_prob, 2), ["cx"]
)
noisy_estimator = Estimator(
options=dict(backend_options=dict(noise_model=noise_model))
)
job = noisy_estimator.run([pub])
result = job.result()
pub_result = result[0]
noisy_value = float(pub_result.data.evs)
noisy_value
0.7247404214143528
Como você pode ver, o valor esperado na presença do ruído está bem distante do valor correto. Na prática, você pode empregar uma variedade de técnicas de mitigação de erros para neutralizar os efeitos do ruído, mas a discussão dessas técnicas está fora do escopo deste artigo.
Para ter uma noção bem aproximada de como o ruído afeta o resultado final, considere nosso modelo de ruído, que adiciona um erro de despolarização de 2% a cada porta CX. O erro de despolarização com probabilidade é definido como um canal quântico que tem a seguinte ação sobre uma matriz de densidade :
onde é o número de qubits, neste caso, 2. Ou seja, com probabilidade , o estado é substituído pelo estado completamente misturado, e o estado é preservado com probabilidade . Após aplicações do canal de despolarização, a probabilidade de o estado ser preservado seria . Portanto, esperamos que a probabilidade de reter o estado correto ao final da simulação diminua exponencialmente com o número de portas CX em nosso circuito.
Vamos contar o número de portas CX em nosso circuito e calcular . Chamamos count_ops para obter um dicionário que mapeia nomes de portas para contagens, e recuperamos a entrada para a porta CX.
cx_count = circuit.count_ops()["cx"]
(1 - cx_depolarizing_prob) ** cx_count
0.6542558123199923
Esse valor, 65%, fornece uma estimativa aproximada da probabilidade de que nosso estado final esteja correto. É uma estimativa conservadora porque não leva em conta o estado inicial da simulação.
A célula de código a seguir mostra como usar a primitiva Sampler do Qiskit Aer para amostrar do circuito com ruído. Precisamos adicionar medições ao circuito antes de executá-lo com a primitiva Sampler.
from qiskit_aer.primitives import SamplerV2 as Sampler
measured_circuit = circuit.copy()
measured_circuit.measure_all()
noisy_sampler = Sampler(
options=dict(backend_options=dict(noise_model=noise_model))
)
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(3, AerSimulator())
isa_circuit = pass_manager.run(measured_circuit)
pub = (isa_circuit, params, 100)
job = noisy_sampler.run([pub])
result = job.result()
pub_result = result[0]
pub_result.data.meas.get_counts()
{'00100000': 1,
'00000000': 65,
'10101000': 1,
'10000000': 5,
'00001000': 1,
'00000110': 2,
'11110010': 1,
'00000011': 3,
'01010000': 3,
'11000000': 3,
'01111000': 1,
'01000000': 2,
'00000010': 1,
'01100000': 1,
'00011000': 1,
'00111100': 1,
'00010100': 1,
'00001111': 1,
'00110000': 1,
'01100101': 1,
'00000100': 1,
'10100000': 1,
'00000001': 1,
'11010000': 1}
Próximos passos
- Para simular circuitos pequenos e simples, consulte Simulação exata com primitivas do Qiskit.
- Revise a documentação do Qiskit Aer.