Simulación exacta y ruidosa con primitivas Qiskit Aer
El código de esta página se ha desarrollado teniendo en cuenta los siguientes requisitos. Recomendamos utilizar estas versiones o versiones más recientes.
qiskit[all]~=2.5.0 qiskit-aer~=0.17
Simulación exacta con Qiskit primitives demuestra cómo utilizar las primitivas de referencia incluidas con Qiskit para realizar la simulación exacta de circuitos cuánticos. Los procesadores cuánticos actuales adolecen de errores, o ruido, por lo que los resultados de una simulación exacta no reflejan necesariamente los resultados que cabría esperar al ejecutar los circuitos en hardware real. Aunque las primitivas de referencia de Qiskit no admiten ruido de modelado, Qiskit Aer incluye implementaciones de las primitivas que sí admiten ruido de modelado. Qiskit Aer es un simulador de circuitos cuánticos de alto rendimiento que puedes utilizar en lugar de las primitivas de referencia para obtener un mayor rendimiento y más funciones. Forma parte del ecosistema Qiskit. En este artículo, demostramos el uso de las primitivas Qiskit Aer para la simulación exacta y ruidosa.
qiskit-aerv0.14 o posterior.- Aunque las primitivas Qiskit Aer implementan las interfaces de las primitivas, no proporcionan las mismas opciones que las primitivas Qiskit Runtime. El nivel de resistencia, por ejemplo, no está disponible con las primitivas Qiskit Aer.
- Consulte la documentación de AerSimulator para obtener más información sobre las opciones de métodos de simulación que admite Aer.
Para explorar la simulación exacta y ruidosa, crea un circuito de ejemplo con ocho qubits:
from qiskit.circuit.library import efficient_su2
n_qubits = 8
circuit = efficient_su2(n_qubits)
circuit.draw("mpl")Output:
Este circuito contiene parámetros para representar los ángulos de rotación de las compuertas y . Al simular este circuito, necesitamos especificar valores explícitos para estos parámetros. En la siguiente celda, especificamos algunos valores para estos parámetros y utilizamos la primitiva Estimator de Qiskit Aer para calcular el valor exacto de la expectativa del observable .
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
Ahora, inicialicemos un modelo de ruido que incluya un error de despolarización del 2 % en cada puerta CX. En la práctica, los errores derivados de las puertas de dos qubits —en este caso, las puertas CX— son la principal fuente de error al ejecutar un circuito. Consulte «Creación de modelos de ruido» para obtener una descripción general sobre cómo construir modelos de ruido en Qiskit Aer.
En la siguiente celda, construimos un Estimador que incorpora este modelo de ruido y lo utilizamos para calcular el valor de la expectativa del observable.
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 se puede ver, el valor de la expectativa en presencia del ruido está bastante lejos del valor correcto. En la práctica, se pueden emplear diversas técnicas de mitigación de errores para contrarrestar los efectos del ruido, pero un análisis de estas técnicas queda fuera del alcance de este artículo.
Para hacernos una idea muy aproximada de cómo afecta el ruido al resultado final, consideremos nuestro modelo de ruido, que añade un error de despolarización del 2% a cada puerta CX. El error despolarizante con probabilidad se define como un canal cuántico que tiene la siguiente acción sobre una matriz de densidad :
donde es el número de qubits, en este caso, 2. Es decir, con probabilidad , el estado se sustituye por el estado completamente mezclado, y el estado se conserva con probabilidad . Después de aplicaciones del canal despolarizante, la probabilidad de que el estado se conserve sería . Por lo tanto, esperamos que la probabilidad de conservar el estado correcto al final de la simulación disminuya exponencialmente con el número de puertas CX de nuestro circuito.
Contemos el número de puertas CX en nuestro circuito y calculemos . Llamamos a count_ops para obtener un diccionario que relaciona los nombres de las puertas con los recuentos, y recuperamos la entrada de la puerta CX.
cx_count = circuit.count_ops()["cx"]
(1 - cx_depolarizing_prob) ** cx_countOutput:
0.6542558123199923
Este valor, 65%, da una estimación aproximada de la probabilidad de que nuestro estado final sea correcto. Es una estimación conservadora porque no tiene en cuenta el estado inicial de la simulación.
La siguiente celda de código muestra cómo utilizar la primitiva Sampler de Qiskit Aer para muestrear desde el circuito ruidoso. Tenemos que añadir medidas al circuito antes de ejecutarlo con la 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()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óximos pasos
- Para simular circuitos pequeños y sencillos, consulte Simulación exacta con Qiskit primitives.
- Revise la documentación de Qiskit Aer.