Simulation précise et bruyante avec les primitives Qiskit Aer
Le code de cette page a été développé en tenant compte des exigences suivantes. Nous recommandons d'utiliser ces versions ou des versions plus récentes.
qiskit[all]~=2.5.1 qiskit-aer~=0.17
La simulation exacte à l'aide des primitives « Qiskit SDK » montre comment utiliser les primitives de référence fournies avec Qiskit pour réaliser une simulation exacte de circuits quantiques. Les processeurs quantiques actuels sont sujets à des erreurs, ou au bruit, de sorte que les résultats d'une simulation exacte ne reflètent pas nécessairement ceux auxquels on pourrait s'attendre en exécutant des circuits sur du matériel réel. Bien que les primitives de référence de Qiskit ne prennent pas en charge la modélisation du bruit, Qiskit Aer propose des implémentations de ces primitives qui, elles, prennent en charge la modélisation du bruit. Qiskit Aer est un simulateur de circuits quantiques hautement performant que vous pouvez utiliser à la place des primitives de référence pour bénéficier de meilleures performances et de fonctionnalités supplémentaires. Il fait partie de l' écosystème Qiskit. Dans cet article, nous présentons l'utilisation des primitives de Qiskit Aer pour la simulation exacte et la simulation avec bruit.
qiskit-aerv0.14 ou une version ultérieure est nécessaire.- Bien que les primitives de Qiskit Aer implémentent les interfaces de primitives, elles n'offrent pas les mêmes options que les primitives d' IBM Quantum. Le niveau de résilience, par exemple, n'est pas disponible avec les primitives de Qiskit Aer.
- Voir la documentation de AerSimulator pour plus de détails sur les options de méthodes de simulation prises en charge par Aer.
Pour explorer la simulation exacte et bruyante, créez un circuit d'exemple sur huit qubits :
from qiskit.circuit.library import efficient_su2
n_qubits = 8
circuit = efficient_su2(n_qubits)
circuit.draw("mpl")Output:
Ce circuit contient des paramètres représentant les angles de rotation des portes et . Lors de la simulation de ce circuit, nous devons spécifier des valeurs explicites pour ces paramètres. Dans la cellule suivante, nous spécifions quelques valeurs pour ces paramètres et utilisons la primitive Estimator de Qiskit Aer pour calculer la valeur exacte de l'espérance de l'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
Initialisons maintenant un modèle de bruit qui inclut une erreur de dépolarisation de 2 % sur chaque porte CX. Dans la pratique, les erreurs liées aux portes à deux qubits, en l'occurrence les portes CX, constituent la principale source d'erreurs lors de l'exécution d'un circuit. Consultez la section « Créer des modèles de bruit » pour obtenir un aperçu de la création de modèles de bruit dans Qiskit Aer.
Dans la cellule suivante, nous construisons un estimateur qui incorpore ce modèle de bruit et l'utilisons pour calculer la valeur d'espérance de l'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
Comme vous pouvez le constater, la valeur attendue en présence de bruit est assez éloignée de la valeur correcte. Dans la pratique, il est possible de recourir à diverses techniques d'atténuation des erreurs pour contrer les effets du bruit, mais l'examen de ces techniques sort du cadre de cet article.
Pour avoir une idée très approximative de la façon dont le bruit affecte le résultat final, considérons notre modèle de bruit, qui ajoute une erreur de dépolarisation de 2 % à chaque porte CX. L'erreur de dépolarisation avec la probabilité est définie comme un canal quantique qui a l'action suivante sur une matrice de densité :
où est le nombre de qubits, dans ce cas, 2. C'est-à-dire qu'avec la probabilité , l'état est remplacé par l'état complètement mélangé, et l'état est préservé avec la probabilité . Après applications du canal dépolarisant, la probabilité que l'état soit préservé serait de . Par conséquent, nous nous attendons à ce que la probabilité de conserver l'état correct à la fin de la simulation diminue de manière exponentielle avec le nombre de portes CX dans notre circuit.
Comptons le nombre de portes CX dans notre circuit et calculons . Nous appelons count_ops pour obtenir un dictionnaire qui associe les noms de portes aux nombres, et nous récupérons l'entrée correspondant à la porte CX.
cx_count = circuit.count_ops()["cx"]
(1 - cx_depolarizing_prob) ** cx_countOutput:
0.6542558123199923
Cette valeur, 65%, donne une estimation approximative de la probabilité que notre état final soit correct. Il s'agit d'une estimation prudente car elle ne tient pas compte de l'état initial de la simulation.
La cellule de code suivante montre comment utiliser la primitive Sampler de Qiskit Aer pour échantillonner le circuit bruyant. Nous devons ajouter des mesures au circuit avant de l'exécuter avec la primitive 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:
{'00000000': 60,
'00001111': 1,
'11000000': 3,
'10100000': 3,
'10001111': 1,
'00010000': 1,
'00001010': 1,
'00111100': 1,
'01000000': 6,
'10000000': 5,
'00110000': 1,
'00011000': 2,
'01100000': 2,
'00000110': 2,
'11000100': 1,
'10000110': 1,
'01010000': 2,
'00011110': 1,
'00010100': 2,
'01011010': 1,
'00000010': 1,
'00001100': 1,
'11100000': 1}
Etapes suivantes
- Pour simuler des circuits simples et de petite taille, consultez la section « Simulation exacte à l'aide des primitives d' Qiskit SDK ».
- Consultez la documentation de Qiskit Aer.