דלג לתוכן הראשי

סימולציה יעילה של מעגלי stabilizer עם Qiskit Aer primitives

גרסאות חבילות

הקוד בדף זה פותח באמצעות הדרישות הבאות. אנו ממליצים להשתמש בגרסאות אלו או בגרסאות חדשות יותר.

qiskit[all]~=2.3.0
qiskit-aer~=0.17

דף זה מציג כיצד להשתמש ב-Qiskit Aer primitives לסימולציה יעילה של מעגלי stabilizer, כולל אלו הכפופים לרעש Pauli.

מעגלי stabilizer, הידועים גם כמעגלי Clifford, הם מחלקה מוגבלת חשובה של מעגלים קוונטיים שניתן לסמלץ אותם בצורה יעילה קלאסית. ישנן מספר דרכים שקולות להגדיר מעגלי stabilizer. הגדרה אחת היא שמעגל stabilizer הוא מעגל קוונטי המורכב אך ורק מ-Gateים הבאים:

שים לב שבאמצעות Hadamard ו-S, נוכל לבנות כל Gate סיבוב Pauli (RxR_x, RyR_y ו-RzR_z) שיש לו זווית הכלולה בקבוצה {0,π2,π,3π2}\{0, \frac{\pi}{2}, \pi, \frac{3\pi}{2}\} (עד פאזה גלובלית), ולכן נוכל לכלול Gateים אלו גם בהגדרה.

מעגלי stabilizer חשובים לחקר תיקון שגיאות קוונטיות. יכולת הסימולציה הקלאסית שלהם גם הופכת אותם לשימושיים לאימות הפלט של מחשבים קוונטיים. לדוגמה, נניח שאתה רוצה להריץ מעגל קוונטי המשתמש ב-100 Qubit על מחשב קוונטי. איך אתה יודע שהמחשב הקוונטי מתנהג כראוי? מעגל קוונטי על 100 Qubit הוא מעבר ליכולות הסימולציה הקלאסית הגסה. על ידי שינוי המעגל שלך כך שיהפוך למעגל stabilizer, תוכל להריץ מעגלים על המחשב הקוונטי שיש להם מבנה דומה למעגל הרצוי שלך, אך שניתן לסמלץ על מחשב קלאסי. על ידי בדיקת הפלט של המחשב הקוונטי על מעגלי stabilizer, תוכל לצבור ביטחון שהוא מתנהג כראוי גם על מעגלים שאינם stabilizer. ראה Evidence for the utility of quantum computing before fault tolerance לדוגמה של רעיון זה בפועל.

סימולציה מדויקת ורועשת עם Qiskit Aer primitives מציג כיצד להשתמש ב-Qiskit Aer לביצוע סימולציות מדויקות ורועשות של מעגלים קוונטיים גנריים. שקול את מעגל הדוגמה המשמש במאמר זה, מעגל של 8 Qubit שנבנה באמצעות 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")

Output of the previous code cell

באמצעות Qiskit Aer, הצלחנו לסמלץ את המעגל הזה בקלות. אולם, נניח שנגדיר את מספר ה-Qubit ל-500:

n_qubits = 500
circuit = efficient_su2(n_qubits)
# don't try to draw the circuit because it's too large

מכיוון שעלות הסימולציה של מעגלים קוונטיים גדלה באופן מעריכי עם מספר ה-Qubit, מעגל גדול כזה בדרך כלל יחרוג מיכולות אפילו סימולטור בעל ביצועים גבוהים כמו Qiskit Aer. הסימולציה הקלאסית של מעגלים קוונטיים גנריים הופכת לבלתי אפשרית כאשר מספר ה-Qubit עולה על בערך 50 עד 100 Qubit. עם זאת, שים לב שמעגל efficient_su2 הוא מפרמטר על ידי זוויות על Gate RyR_y ו-RzR_z. אם כל הזוויות הללו כלולות בקבוצה {0,π2,π,3π2}\{0, \frac{\pi}{2}, \pi, \frac{3\pi}{2}\}, אז המעגל הוא מעגל stabilizer, וניתן לסמלץ אותו בצורה יעילה!

בתא הבא, נריץ את המעגל עם ה-Sampler primitive הנשען על סימולטור מעגלי stabilizer, באמצעות פרמטרים שנבחרו אקראית כך שהמעגל מובטח להיות מעגל stabilizer.

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()

סימולטור מעגלי stabilizer תומך גם בסימולציה רועשת, אך רק עבור מחלקה מוגבלת של מודלי רעש. ספציפית, כל רעש קוונטי חייב להיות מאופיין על ידי ערוץ שגיאת Pauli. שגיאת depolarizing נכללת בקטגוריה זו, ולכן ניתן לסמלץ אותה גם כן. ניתן גם לסמלץ ערוצי רעש קלאסיים כמו שגיאת readout.

תא הקוד הבא מריץ את אותה סימולציה כמו קודם, אך הפעם מציין מודל רעש המוסיף שגיאת depolarizing של 2% לכל Gate CX, כמו גם שגיאת readout שהופכת כל סיביה שנמדדת עם הסתברות של 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()

כעת, נשתמש ב-Estimator primitive הנשען על סימולטור stabilizer כדי לחשב את ערך הציפייה של האובייקטבל ZZZZZ \cdots Z. בשל המבנה המיוחד של מעגלי stabilizer, סביר מאוד שהתוצאה תהיה 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

צעדים הבאים

המלצות