Simulação exata e ruidosa com primitivas Qiskit Aer
O código desta página foi desenvolvido usando os seguintes requisitos. Recomendamos o uso dessas versões ou de versões mais recentes.
qiskit[all]~=2.5.0 qiskit-aer~=0.17
A simulação exata com Qiskit primitives demonstra como usar as primitivas de referência incluídas no Qiskit para realizar a simulação exata de circuitos quânticos. Os processadores quânticos existentes atualmente sofrem com erros ou ruídos, portanto, os resultados de uma simulação exata não refletem necessariamente os resultados que você esperaria ao executar circuitos em um hardware real. Embora as primitivas de referência no Qiskit não ofereçam suporte à modelagem de ruído, o Qiskit Aer inclui implementações das primitivas que oferecem suporte à modelagem de ruído. O Qiskit Aer é um simulador de circuito quântico de alto desempenho que você pode usar no lugar das primitivas de referência para obter melhor desempenho e mais recursos. Ele faz parte do ecossistema Qiskit. Neste artigo, demonstramos o uso das primitivas do Qiskit Aer para simulação exata e com ruído.
qiskit-aerv0.14 ou posterior é necessário.- Embora as primitivas do Qiskit Aer implementem as interfaces primitivas, elas não oferecem 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 site AerSimulator para obter detalhes sobre as opções de método de simulação suportadas pelo Aer.
Para explorar a simulação exata e com ruído, crie um circuito de exemplo com oito qubits:
from qiskit.circuit.library import efficient_su2
n_qubits = 8
circuit = efficient_su2(n_qubits)
circuit.draw("mpl")Output:
Esse circuito contém parâmetros para representar os ângulos de rotação das 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 exato da expectativa 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_valueOutput:
0.8870140234256602
Agora, vamos inicializar um modelo de ruído que inclua um erro de despolarização de 2% em cada porta CX. Na prática, os erros decorrentes das portas de dois qubits — que, neste caso, são portas CX — constituem a principal fonte de erros durante a execução de um circuito. Consulte “Criação de modelos de ruído” para obter uma visão geral sobre como construir modelos de ruído no Qiskit Aer.
Na próxima célula, construímos um Estimador 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_valueOutput:
0.7247404214143528
Como você pode ver, o valor esperado na presença do ruído está muito longe do valor correto. Na prática, você pode empregar várias técnicas de atenuação de erros para combater os efeitos do ruído, mas uma discussão sobre essas técnicas está fora do escopo deste artigo.
Para ter uma noção 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 em uma matriz de densidade :
em que é o número de qubits, neste caso, 2. Ou seja, com probabilidade , o estado é substituído pelo estado completamente misto, e o estado é preservado com probabilidade . Após aplicações do canal despolarizante, a probabilidade de o estado ser preservado seria . Portanto, esperamos que a probabilidade de manter o estado correto no 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_countOutput:
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 fazer a amostragem do circuito com ruído. Precisamos adicionar medições ao circuito antes de executá-lo com o primitivo 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()Output:
{'00000011': 2,
'00000000': 68,
'00001100': 2,
'00000101': 2,
'01010000': 1,
'00000010': 2,
'01101010': 1,
'10100000': 1,
'00110000': 1,
'11100000': 1,
'00011110': 1,
'10000000': 8,
'00000001': 1,
'11000000': 1,
'01000011': 1,
'00001010': 2,
'00010000': 1,
'01000000': 1,
'00000110': 1,
'11001010': 1,
'00000111': 1}
Próximas etapas
- Para simular circuitos pequenos e simples, consulte Simulação exata com Qiskit primitives.
- Examine a documentação do Qiskit Aer.