انتقل إلى المحتوى الرئيسي

المحاكاة الدقيقة والمحاكاة بالضوضاء باستخدام Qiskit Aer primitives

إصدارات الحزم

تم تطوير الكود في هذه الصفحة باستخدام المتطلبات التالية. ننصح باستخدام هذه الإصدارات أو ما هو أحدث منها.

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

يوضح المحاكاة الدقيقة باستخدام Qiskit primitives كيفية استخدام الـ primitives المرجعية المضمّنة في Qiskit لإجراء محاكاة دقيقة للدوائر الكمومية. تعاني المعالجات الكمومية الحالية من أخطاء أو ضوضاء، لذا فإن نتائج المحاكاة الدقيقة لا تعكس بالضرورة النتائج التي ستحصل عليها عند تشغيل الدوائر على أجهزة حقيقية. في حين أن الـ primitives المرجعية في Qiskit لا تدعم نمذجة الضوضاء، يتضمن Qiskit Aer تطبيقات للـ primitives تدعم نمذجة الضوضاء. Qiskit Aer هو محاكي دوائر كمومية عالي الأداء يمكنك استخدامه بدلاً من الـ primitives المرجعية للحصول على أداء أفضل وميزات إضافية. وهو جزء من Qiskit Ecosystem. في هذا المقال، نستعرض استخدام Qiskit Aer primitives للمحاكاة الدقيقة والمحاكاة بالضوضاء.

ملاحظات
  • يُشترط استخدام الإصدار qiskit-aer v0.14 أو أحدث.
  • رغم أن Qiskit Aer primitives تُطبّق واجهات الـ primitives، إلا أنها لا توفر نفس الخيارات المتاحة في Qiskit Runtime primitives. فمستوى المرونة (Resilience level)، على سبيل المثال، غير متاح في Qiskit Aer primitives.
  • راجع توثيق AerSimulator للاطلاع على تفاصيل خيارات أساليب المحاكاة التي يدعمها Aer.

لاستكشاف المحاكاة الدقيقة والمحاكاة بالضوضاء، أنشئ دائرة مثال على ثمانية Qubits:

# 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")

Output of the previous code cell

تحتوي هذه الدائرة على معاملات تمثّل زوايا الدوران لبوابات RyR_y و RzR_z. عند محاكاة هذه الدائرة، نحتاج إلى تحديد قيم صريحة لهذه المعاملات. في الخلية التالية، نحدد بعض القيم لهذه المعاملات ونستخدم الـ Estimator primitive من Qiskit Aer لحساب القيمة المتوقعة الدقيقة للمؤثر ZZZZZ \cdots Z.

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

الآن، لنقم بتهيئة نموذج ضوضاء يتضمن خطأ depolarizing بنسبة 2% على كل بوابة CX. في الواقع العملي، الأخطاء الناشئة عن بوابات الـ Qubitين، وهي بوابات CX هنا، هي المصدر الرئيسي للخطأ عند تشغيل الدائرة. راجع بناء نماذج الضوضاء للاطلاع على نظرة عامة حول إنشاء نماذج الضوضاء في Qiskit Aer.

في الخلية التالية، نبني Estimator يدمج نموذج الضوضاء هذا ونستخدمه لحساب القيمة المتوقعة للمؤثر.

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

كما ترى، القيمة المتوقعة في ظل وجود الضوضاء بعيدة جداً عن القيمة الصحيحة. في الواقع العملي، يمكنك توظيف مجموعة من تقنيات تخفيف الأخطاء لمواجهة تأثيرات الضوضاء، لكن الحديث عن هذه التقنيات يخرج عن نطاق هذا المقال.

للحصول على فكرة تقريبية عن كيفية تأثير الضوضاء على النتيجة النهائية، تأمّل نموذج الضوضاء لدينا، الذي يضيف خطأ depolarizing بنسبة 2% إلى كل بوابة CX. يُعرَّف خطأ Depolarizing بالاحتمال pp على أنه قناة كمومية EE لها التأثير التالي على مصفوفة الكثافة ρ\rho:

E(ρ)=(1p)ρ+pI2nE(\rho) = (1 - p) \rho + p\frac{I}{2^n}

حيث nn هو عدد الـ Qubits، وهو 2 في هذه الحالة. أي أنه باحتمال pp، تُستبدل الحالة بالحالة المختلطة تماماً، وتُحفظ الحالة باحتمال 1p1 - p. بعد mm تطبيقاً لقناة depolarizing، سيكون احتمال الحفاظ على الحالة هو (1p)m(1 - p)^m. لذا، نتوقع أن يتراجع احتمال الحفاظ على الحالة الصحيحة في نهاية المحاكاة بشكل أسّي مع زيادة عدد بوابات CX في دائرتنا.

لنحسب عدد بوابات CX في دائرتنا ونحسب (1p)m(1 - p)^m. نستدعي count_ops للحصول على قاموس يربط أسماء البوابات بعدد مرات ظهورها، ثم نسترجع القيمة المقابلة لبوابة CX.

cx_count = circuit.count_ops()["cx"]
(1 - cx_depolarizing_prob) ** cx_count
0.6542558123199923

هذه القيمة، 65%، تعطي تقديراً تقريبياً لاحتمال صحة حالتنا النهائية. وهي تقدير متحفظ لأنها لا تأخذ بعين الاعتبار الحالة الابتدائية للمحاكاة.

تُظهر خلية الكود التالية كيفية استخدام الـ Sampler primitive من Qiskit Aer للأخذ بالعينات من الدائرة ذات الضوضاء. نحتاج إلى إضافة قياسات إلى الدائرة قبل تشغيلها مع الـ Sampler primitive.

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}

الخطوات التالية

توصيات