Simulare exactă și zgomotoasă cu primitivele Qiskit Aer
Versiuni de pachete
Codul de pe această pagină a fost dezvoltat folosind următoarele cerințe. Recomandăm utilizarea acestor versiuni sau a unora mai noi.
qiskit[all]~=2.3.0
qiskit-aer~=0.17
Simularea exactă cu primitivele Qiskit demonstrează cum să folosești primitivele de referință incluse în Qiskit pentru a efectua simularea exactă a circuitelor cuantice. Procesoarele cuantice existente în prezent sunt afectate de erori, sau zgomot, astfel că rezultatele unei simulări exacte nu reflectă neapărat rezultatele pe care le-ai obține când rulezi circuite pe hardware real. Deși primitivele de referință din Qiskit nu suportă modelarea zgomotului, Qiskit Aer include implementări ale primitivelor care suportă modelarea zgomotului. Qiskit Aer este un simulator de circuite cuantice de înaltă performanță pe care îl poți folosi în locul primitivelor de referință pentru performanță mai bună și mai multe funcționalități. Face parte din Ecosistemul Qiskit. În acest articol, demonstrăm utilizarea primitivelor Qiskit Aer pentru simulare exactă și zgomotoasă.
- Este necesară versiunea
qiskit-aerv0.14 sau mai recentă. - Deși primitivele Qiskit Aer implementează interfețele primitive, ele nu oferă aceleași opțiuni ca primitivele Qiskit Runtime. Nivelul de reziliență, de exemplu, nu este disponibil cu primitivele Qiskit Aer.
- Consultă documentația AerSimulator pentru detalii despre opțiunile metodei de simulare pe care Aer le suportă.
Pentru a explora simularea exactă și zgomotoasă, creează un circuit exemplu pe opt qubiți:
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-aer
from qiskit.circuit.library import efficient_su2
n_qubits = 8
circuit = efficient_su2(n_qubits)
circuit.draw("mpl")
Acest Circuit conține parametri pentru a reprezenta unghiurile de rotație pentru Gate-urile și . La simularea acestui Circuit, trebuie să specificăm valori explicite pentru acești parametri. În celula următoare, specificăm câteva valori pentru acești parametri și folosim primitiva Estimator din Qiskit Aer pentru a calcula valoarea exactă a valorii așteptate a observabilului .
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_value
0.8870140234256602
Acum, să inițializăm un model de zgomot care include eroare de depolarizare de 2% pe fiecare Gate CX. În practică, eroarea care provine din Gate-urile cu doi qubiți, care sunt Gate-urile CX în acest caz, reprezintă sursa dominantă de eroare la rularea unui Circuit. Consultă Construiește modele de zgomot pentru o prezentare generală a construirii modelelor de zgomot în Qiskit Aer.
În celula următoare, construim un Estimator care încorporează acest model de zgomot și îl folosim pentru a calcula valoarea așteptată a observabilului.
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_value
0.7247404214143528
După cum poți vedea, valoarea așteptată în prezența zgomotului este destul de departe de valoarea corectă. În practică, poți folosi o varietate de tehnici de atenuare a erorilor pentru a contracara efectele zgomotului, dar o discuție despre aceste tehnici depășește scopul acestui articol.
Pentru a obține o idee aproximativă despre cum afectează zgomotul rezultatul final, ia în considerare modelul nostru de zgomot, care adaugă o eroare de depolarizare de 2% la fiecare Gate CX. Eroarea de depolarizare cu probabilitatea este definită ca un canal cuantic care are următoarea acțiune asupra unei matrice densitate :
unde este numărul de qubiți, în acest caz, 2. Adică, cu probabilitatea , starea este înlocuită cu starea complet mixtă, iar starea este păstrată cu probabilitatea . După aplicări ale canalului de depolarizare, probabilitatea ca starea să fie păstrată ar fi . Prin urmare, ne așteptăm ca probabilitatea de a păstra starea corectă la sfârșitul simulării să scadă exponențial cu numărul de Gate-uri CX din Circuit.
Să numărăm Gate-urile CX din Circuit și să calculăm . Apelăm count_ops pentru a obține un dicționar care mapează numele Gate-urilor la numărători și recuperăm intrarea pentru Gate-ul CX.
cx_count = circuit.count_ops()["cx"]
(1 - cx_depolarizing_prob) ** cx_count
0.6542558123199923
Această valoare, 65%, oferă o estimare aproximativă a probabilității ca starea noastră finală să fie corectă. Este o estimare conservatoare deoarece nu ține cont de starea inițială a simulării.
Următoarea celulă de cod arată cum să folosești primitiva Sampler din Qiskit Aer pentru a eșantiona din Circuitul zgomotos. Trebuie să adăugăm măsurători la Circuit înainte de a-l rula cu 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()
{'00100000': 1,
'00000000': 65,
'10101000': 1,
'10000000': 5,
'00001000': 1,
'00000110': 2,
'11110010': 1,
'00000011': 3,
'01010000': 3,
'11000000': 3,
'01111000': 1,
'01000000': 2,
'00000010': 1,
'01100000': 1,
'00011000': 1,
'00111100': 1,
'00010100': 1,
'00001111': 1,
'00110000': 1,
'01100101': 1,
'00000100': 1,
'10100000': 1,
'00000001': 1,
'11010000': 1}
Pași următori
- Pentru a simula circuite mici și simple, consultă Simulare exactă cu primitivele Qiskit.
- Consultă documentația Qiskit Aer.