Simulare eficientă a circuitelor stabilizator cu primitivele Qiskit Aer
Versiunile pachetelor
Codul de pe această pagină a fost dezvoltat folosind următoarele cerințe. Îți recomandăm să folosești aceste versiuni sau unele mai noi.
qiskit[all]~=2.6.1
qiskit-aer~=0.18
Această pagină arată cum să folosești primitivele Qiskit Aer pentru a simula eficient circuitele stabilizator, inclusiv pe cele supuse zgomotului Pauli.
Circuitele stabilizator, cunoscute și sub denumirea de circuite Clifford, reprezintă o clasă restricționată importantă de circuite cuantice care pot fi simulate eficient în mod clasic. Există mai multe moduri echivalente de a defini circuitele stabilizator. O definiție este că un circuit stabilizator este un circuit cuantic format exclusiv din următoarele porți:
Reține că, folosind Hadamard și S, putem construi orice poartă de rotație Pauli (, și ) cu un unghi din mulțimea (până la o fază globală), așa că putem include și aceste porți în definiție.
Circuitele stabilizator sunt importante pentru studiul corecției erorilor cuantice. Posibilitatea de a le simula clasic le face utile și pentru verificarea ieșirii calculatoarelor cuantice. De exemplu, să presupunem că vrei să execuți un circuit cuantic cu 100 de Qubiți pe un calculator cuantic. Cum știi că acesta se comportă corect? Un circuit cuantic cu 100 de Qubiți depășește capacitățile simulării clasice prin forță brută. Modificând circuitul tău astfel încât să devină un circuit stabilizator, poți rula circuite pe calculatorul cuantic cu o structură similară cu circuitul dorit, dar pe care le poți simula pe un calculator clasic. Verificând ieșirea calculatorului cuantic pe circuitele stabilizator, poți căpăta încredere că acesta se comportă corect și pe circuitele non-stabilizator. Consultă Evidence for the utility of quantum computing before fault tolerance pentru un exemplu practic al acestei idei.
Simulare exactă și cu zgomot cu primitivele Qiskit Aer arată cum să folosești Qiskit Aer pentru a efectua simulări exacte și cu zgomot ale circuitelor cuantice generice. Consideră circuitul exemplu folosit în acel articol, un circuit cu 8 Qubiți construit cu efficient_su2:
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit", "qiskit_aer": "qiskit-aer"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
from qiskit.circuit.library import efficient_su2
n_qubits = 8
circuit = efficient_su2(n_qubits)
circuit.draw("mpl")
Folosind Qiskit Aer, am putut simula acest circuit cu ușurință. Cu toate acestea, să presupunem că setăm numărul de Qubiți la 500:
n_qubits = 500
circuit = efficient_su2(n_qubits)
# don't try to draw the circuit because it's too large
Deoarece costul simulării circuitelor cuantice crește exponențial cu numărul de Qubiți, un circuit atât de mare ar depăși în general capacitățile chiar și ale unui simulator performant precum Qiskit Aer. Simularea clasică a circuitelor cuantice generice devine neviabilă când numărul de Qubiți depășește aproximativ 50 până la 100. Totuși, reține că circuitul efficient_su2 este parametrizat prin unghiuri pe porțile și . Dacă toate aceste unghiuri sunt din mulțimea , atunci circuitul este un circuit stabilizator și poate fi simulat eficient!
În celula de mai jos, rulăm circuitul cu primitiva Sampler susținută de simulatorul de circuite stabilizator, folosind parametri aleși aleatoriu astfel încât să avem garanția că circuitul este unul stabilizator.
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()
Simulatorul de circuite stabilizator suportă și simularea cu zgomot, dar numai pentru o clasă restricționată de modele de zgomot. Mai precis, orice zgomot cuantic trebuie caracterizat printr-un canal de eroare Pauli. Eroarea de depolarizare se încadrează în această categorie, deci poate fi simulată. Canalele de zgomot clasic, precum eroarea de citire, pot fi de asemenea simulate.
Celula de cod de mai jos rulează aceeași simulare ca anterior, dar de data aceasta specificând un model de zgomot care adaugă o eroare de depolarizare de 2% fiecărui Gate CX, precum și o eroare de citire care inversează fiecare bit măsurat cu o probabilitate 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()
Acum, să folosim primitiva Estimator susținută de simulatorul stabilizator pentru a calcula valoarea așteptată a observabilului . Datorită structurii speciale a circuitelor stabilizator, rezultatul va fi, foarte probabil, 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
Pași următori
- Pentru a simula circuite cu Qiskit Aer, consultă Simulare exactă și cu zgomot cu primitivele Qiskit Aer.
- Consultă documentația Qiskit Aer.