Simulation efficace des circuits stabilisateurs avec les primitives Qiskit Aer
Versions des packages
Le code de cette page a été développé avec les dépendances suivantes. Nous recommandons d'utiliser ces versions ou des versions plus récentes.
qiskit[all]~=2.3.0
qiskit-aer~=0.17
Cette page montre comment utiliser les primitives Qiskit Aer pour simuler efficacement des circuits stabilisateurs, y compris ceux soumis à du bruit de Pauli.
Les circuits stabilisateurs, aussi appelés circuits de Clifford, constituent une classe restreinte importante de circuits quantiques qui peuvent être simulés efficacement de manière classique. Il existe plusieurs façons équivalentes de définir les circuits stabilisateurs. Selon une définition, un circuit stabilisateur est un circuit quantique composé uniquement des portes suivantes :
Note qu'en utilisant Hadamard et S, on peut construire n'importe quelle porte de rotation de Pauli (, , et ) dont l'angle appartient à l'ensemble (à une phase globale près), donc ces portes peuvent également être incluses dans la définition.
Les circuits stabilisateurs sont importants pour l'étude de la correction d'erreurs quantiques. Leur simulabilité classique les rend aussi utiles pour vérifier la sortie des ordinateurs quantiques. Par exemple, suppose que tu veuilles exécuter un circuit quantique de 100 qubits sur un ordinateur quantique. Comment savoir que l'ordinateur quantique fonctionne correctement ? Un circuit quantique à 100 qubits est hors de portée d'une simulation classique par force brute. En modifiant ton circuit pour en faire un circuit stabilisateur, tu peux exécuter sur l'ordinateur quantique des circuits ayant une structure similaire à ton circuit souhaité, mais que tu peux simuler sur un ordinateur classique. En vérifiant la sortie de l'ordinateur quantique sur les circuits stabilisateurs, tu peux acquérir la certitude qu'il se comporte correctement sur les circuits non-stabilisateurs aussi. Voir Evidence for the utility of quantum computing before fault tolerance pour un exemple concret de cette idée.
Simulation exacte et bruitée avec les primitives Qiskit Aer montre comment utiliser Qiskit Aer pour effectuer des simulations exactes et bruitées de circuits quantiques génériques. Considérons l'exemple de circuit utilisé dans cet article, un circuit à 8 qubits construit avec 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")
Avec Qiskit Aer, nous avons pu simuler ce circuit facilement. Cependant, suppose qu'on fixe le nombre de qubits à 500 :
n_qubits = 500
circuit = efficient_su2(n_qubits)
# don't try to draw the circuit because it's too large
Le coût de la simulation des circuits quantiques croissant de façon exponentielle avec le nombre de qubits, un tel circuit dépasse généralement les capacités même d'un simulateur haute performance comme Qiskit Aer. La simulation classique de circuits quantiques génériques devient infaisable lorsque le nombre de qubits dépasse environ 50 à 100 qubits. Cependant, note que le circuit efficient_su2 est paramétré par des angles sur les portes et . Si tous ces angles appartiennent à l'ensemble , alors le circuit est un circuit stabilisateur et peut être simulé efficacement !
Dans la cellule suivante, on exécute le circuit avec la primitive Sampler appuyée par le simulateur de circuits stabilisateurs, en utilisant des paramètres choisis aléatoirement de façon à garantir que le circuit est bien un circuit stabilisateur.
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()
Le simulateur de circuits stabilisateurs prend également en charge la simulation bruitée, mais uniquement pour une classe restreinte de modèles de bruit. Plus précisément, tout bruit quantique doit être caractérisé par un canal d'erreur de Pauli. L'erreur de dépolarisation entre dans cette catégorie et peut donc également être simulée. Les canaux de bruit classiques comme l'erreur de lecture peuvent aussi être simulés.
La cellule de code suivante exécute la même simulation qu'avant, mais en spécifiant cette fois un modèle de bruit qui ajoute une erreur de dépolarisation de 2 % à chaque porte CX, ainsi qu'une erreur de lecture qui inverse chaque bit mesuré avec une probabilité de 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()
Maintenant, utilisons la primitive Estimator appuyée par le simulateur stabilisateur pour calculer la valeur d'espérance de l'observable . En raison de la structure particulière des circuits stabilisateurs, le résultat est très probablement 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
Prochaines étapes
- Pour simuler des circuits avec Qiskit Aer, voir Simulation exacte et bruitée avec les primitives Qiskit Aer.
- Consulte la documentation de Qiskit Aer.