Simulación eficiente de circuitos estabilizadores con las primitivas de Qiskit Aer
Versiones de paquetes
El código de esta página fue desarrollado usando los siguientes requisitos. Se recomienda usar estas versiones o versiones más recientes.
qiskit[all]~=2.3.0
qiskit-aer~=0.17
Esta página muestra cómo usar las primitivas de Qiskit Aer para simular eficientemente circuitos estabilizadores, incluidos aquellos sujetos a ruido de Pauli.
Los circuitos estabilizadores, también conocidos como circuitos de Clifford, son una clase restringida importante de circuitos cuánticos que pueden simularse de manera eficiente de forma clásica. Existen varias formas equivalentes de definir los circuitos estabilizadores. Una definición es que un circuito estabilizador es un circuito cuántico compuesto únicamente por las siguientes compuertas:
Ten en cuenta que usando Hadamard y S podemos construir cualquier compuerta de rotación de Pauli (, y ) cuyo ángulo esté contenido en el conjunto (salvo fase global), por lo que también podemos incluir estas compuertas en la definición.
Los circuitos estabilizadores son importantes para el estudio de la corrección de errores cuánticos. Su simulabilidad clásica también los hace útiles para verificar la salida de computadoras cuánticas. Por ejemplo, supón que quieres ejecutar en una computadora cuántica un circuito cuántico de 100 qubits. ¿Cómo sabes que la computadora cuántica se está comportando correctamente? Un circuito cuántico de 100 qubits está fuera del alcance de la simulación clásica por fuerza bruta. Al modificar tu circuito para que se convierta en un circuito estabilizador, puedes ejecutar circuitos en la computadora cuántica que tengan una estructura similar a tu circuito deseado, pero que puedas simular en una computadora clásica. Al verificar la salida de la computadora cuántica en los circuitos estabilizadores, puedes ganar confianza en que se está comportando correctamente también en los circuitos no estabilizadores. Consulta Evidence for the utility of quantum computing before fault tolerance para ver un ejemplo de esta idea en la práctica.
Simulación exacta y con ruido con las primitivas de Qiskit Aer muestra cómo usar Qiskit Aer para realizar simulaciones exactas y con ruido de circuitos cuánticos genéricos. Considera el circuito de ejemplo usado en ese artículo, un circuito de 8 qubits construido con efficient_su2:
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-aer
from qiskit.circuit.library import efficient_su2
n_qubits = 8
circuit = efficient_su2(n_qubits)
circuit.draw("mpl")
Usando Qiskit Aer, pudimos simular este circuito fácilmente. Sin embargo, supón que establecemos el número de qubits en 500:
n_qubits = 500
circuit = efficient_su2(n_qubits)
# don't try to draw the circuit because it's too large
Dado que el costo de simular circuitos cuánticos escala exponencialmente con el número de qubits, un circuito tan grande generalmente superaría las capacidades incluso de un simulador de alto rendimiento como Qiskit Aer. La simulación clásica de circuitos cuánticos genéricos se vuelve inviable cuando el número de qubits supera aproximadamente los 50 a 100 qubits. Sin embargo, ten en cuenta que el circuito efficient_su2 está parametrizado por ángulos en las compuertas y . Si todos esos ángulos están contenidos en el conjunto , entonces el circuito es un circuito estabilizador y puede simularse eficientemente.
En la siguiente celda, ejecutamos el circuito con la primitiva Sampler respaldada por el simulador de circuitos estabilizadores, usando parámetros elegidos aleatoriamente de modo que el circuito sea garantizadamente un circuito estabilizador.
import numpy as np
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_aer import AerSimulator
from qiskit_aer.primitives import SamplerV2 as Sampler
measured_circuit = circuit.copy()
measured_circuit.measure_all()
rng = np.random.default_rng(1234)
params = rng.choice(
[0, np.pi / 2, np.pi, 3 * np.pi / 2],
size=circuit.num_parameters,
)
# Initialize a Sampler backed by the stabilizer circuit simulator
exact_sampler = Sampler(
options=dict(backend_options=dict(method="stabilizer"))
)
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(
1, AerSimulator(method="stabilizer")
)
isa_circuit = pass_manager.run(measured_circuit)
pub = (isa_circuit, params)
job = exact_sampler.run([pub])
result = job.result()
pub_result = result[0]
counts = pub_result.data.meas.get_counts()
El simulador de circuitos estabilizadores también admite simulación con ruido, pero solo para una clase restringida de modelos de ruido. En concreto, cualquier ruido cuántico debe caracterizarse por un canal de error de Pauli. El error de despolarización entra en esta categoría, por lo que también puede simularse. Los canales de ruido clásico como el error de lectura también pueden simularse.
La siguiente celda de código ejecuta la misma simulación que antes, pero esta vez especificando un modelo de ruido que añade un error de despolarización del 2 % a cada compuerta CX, así como un error de lectura que invierte cada bit medido con una probabilidad del 5 %.
from qiskit_aer.noise import NoiseModel, depolarizing_error, ReadoutError
noise_model = NoiseModel()
cx_depolarizing_prob = 0.02
bit_flip_prob = 0.05
noise_model.add_all_qubit_quantum_error(
depolarizing_error(cx_depolarizing_prob, 2), ["cx"]
)
noise_model.add_all_qubit_readout_error(
ReadoutError(
[
[1 - bit_flip_prob, bit_flip_prob],
[bit_flip_prob, 1 - bit_flip_prob],
]
)
)
noisy_sampler = Sampler(
options=dict(
backend_options=dict(method="stabilizer", noise_model=noise_model)
)
)
job = noisy_sampler.run([pub])
result = job.result()
pub_result = result[0]
counts = pub_result.data.meas.get_counts()
Ahora usemos la primitiva Estimator respaldada por el simulador de estabilizadores para calcular el valor esperado del observable . Debido a la estructura especial de los circuitos estabilizadores, es muy probable que el resultado sea 0.
from qiskit.quantum_info import SparsePauliOp
from qiskit_aer.primitives import EstimatorV2 as Estimator
observable = SparsePauliOp("Z" * n_qubits)
exact_estimator = Estimator(
options=dict(backend_options=dict(method="stabilizer")),
)
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.0
Próximos pasos
- Para simular circuitos con Qiskit Aer, consulta Simulación exacta y con ruido con las primitivas de Qiskit Aer.
- Revisa la documentación de Qiskit Aer.