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

الخطوة الأولى نحو الحوسبة الكمومية

  • مستوى الصعوبة: مبتدئ
  • وقت استخدام وحدة المعالجة الكمومية: 11 ثانية

أهلاً بكم أيها المبدعون! يسعدنا انضمامكم إلى ورشة العمل. الهدف الرئيسي من هذه الجلسة التطبيقية التمهيدية هو تهيئتكم لرحلتكم الكمومية من خلال: 1) إرشادكم إلى كيفية تثبيت Qiskit، 2) كيفية إنشاء حساب IBM Cloud وإعداد api_key وcrn لاستخدام حاسوب كمومي حقيقي، 3) إنشاء أول Circuit كمومي لكم، 4) حل اختبار الحالة الكمومية، و5) تشغيل دوائركم على الحاسوب الكمومي الحقيقي ورسم النتائج.

1. البداية الصحيحة: Qiskit

ما هو Qiskit

Qiskit SDK هو حزمة برمجيات عالية الأداء مصممة لمساعدة المطورين والباحثين على تسخير القدرة الكاملة لأجهزة الحاسوب الكمومية على نطاق الأداة المساعدة وما يتخطاها. في صميمه يوجد Qiskit SDK، وهو مجموعة أدوات تطوير برمجيات مفتوحة المصدر للتعامل مع أجهزة الحاسوب الكمومية على مستوى الدوائر الكمومية الموسّعة، والمشغّلات والبدائيات. يتيح Qiskit SDK للجميع الحصول على أفضل أداء ممكن من أجهزة الحاسوب الكمومية الحقيقية باستخدام بيئة الحوسبة المفضلة لديهم.

بالإضافة إلى SDK، يتضمن Qiskit أيضاً مجموعة من الأدوات والخدمات عالية الأداء كـQiskit Runtime Service، التي تتيح إجراء حسابات محسّنة على أجهزة الحاسوب الكمومية من IBM عبر السحابة باستخدام بدائيات تدير التخفيف من الأخطاء. وخدمة Qiskit Transpiler التي توفر أساليب ابتكارية مدعومة بالذكاء الاصطناعي تعزز الأداء في مهام تحسين Circuit الكمومي الشائعة.

وظائف Qiskit، كتالوج من خدمات IBM والجهات الخارجية يسهّل تحسين أعباء العمل والاستفادة من Qiskit في حالات الاستخدام الصناعي. سواء كنت مطور برمجيات كمومية، أو باحثاً تجريبياً في مجال الكم، أو عالم حوسبة، أو مجرد مبتدئ، فإن إطار عمل Qiskit المرن والمعياري يتيح لك العمل على مستوى التجريد الذي يناسب احتياجاتك.

صُمّم Qiskit للتوسعة والتخصيص، مما يمكّنك من استخراج أداء رائد في المجال ومعالجة أنواع جديدة من المشكلات. تعني قاعدة الكود عالية الأداء أن Qiskit SDK يعمل بشكل أسرع، ويستهلك ذاكرة أقل، ويحقق نتائج أفضل من أي وقت مضى. كما يُعرّفك Qiskit بمجتمع واسع من المستخدمين والمطورين المتحمسين لترحيبك والمساعدة في الإجابة على أسئلتك. منذ إطلاقه عام 2019، يعدّ برنامج Qiskit advocate مبادرة عالمية تتمحور حول المجتمع تستقطب المهنيين والمتحمسين للحوسبة الكمومية من جميع أنحاء العالم. على مرّ السنين، أصبح كثير من هؤلاء المناصرين قادة معترفاً بهم في مجتمع الكم. هل تريد أن تكون القائد الكمومي القادم؟ لا تتردد في التقديم - هنا

تثبيت Qiskit

أولاً، تحقق من أن إصدار Python المستخدم في بيئتك هو python>=3.10 للتأكد من توافقه مع أحدث إصدار من Qiskit الذي سنستخدمه

from platform import python_version

print(python_version())

إذا لم يكن الأمر كذلك، يمكنك ترقيته باستخدام أداتك المفضلة. إذا لم تكن متأكداً من كيفية القيام بذلك، فإليك بعض الخيارات الموصى بها:

  • نظام MacOS: Homebrew
  • نظام Linux: sudo apt-get update

دليل مفصّل حول كيفية ترقية Python بحسب نظام التشغيل لديك متاح هنا: كيفية تحديث Python

لمزيد من المعلومات، اطّلع على ويكي QGSS (مدرسة Qiskit الصيفية العالمية) 2025: https://github.com/qiskit-community/qgss-2025/wiki/Jupyter-Notebook-Environment-(Local-and-Online)

يمكنك التحقق من تثبيتك بتشغيل الخلية أدناه. إذا كان التثبيت صحيحاً، ستحصل على إصدار Qiskit.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
%pip install 'qiskit[visualization]'
%pip install qiskit-ibm-runtime
%pip install qiskit-aer
import qiskit

print(f"Qiskit version: {qiskit.__version__}")

استكشاف الأخطاء وإصلاحها

إذا أثارت الخلية السابقة خطأً، يمكنك تثبيت Qiskit في بيئة افتراضية (هناك طريقتان مقترحتان في ما يلي). إذا لم تواجه أي أخطاء، يمكنك تجاهل هذه الخلية والمتابعة إلى الخلية التالية.

نقترح هنا طريقتين مختلفتين لإعداد بيئة افتراضية لتثبيت Qiskit.

  1. استخدام venv، كما هو موضح في دليل تثبيت Qiskit.
  2. استخدام conda، كما هو موضح في هذا الفيديو من Coding with Qiskit.

2. إعداد حساب IBM Cloud الخاص بك

لاستخدام حاسوب كمومي حقيقي، تحتاج إلى api key - تذكرة الدخول الرئيسية إلى السحابة، وcrn - الرمز المميز الذي يجلب مواردك إليك عند إعداد حسابك.

أعدّ حسابك على النحو التالي:

  1. انتقل إلى IBM Quantum® Platform.
  2. اذهب إلى الزاوية اليمنى العلوية (كما هو موضح في الصورة أعلاه)، أنشئ رمز API الخاص بك وانسخه إلى موقع آمن.
  3. في الخلية التالية، استبدل deleteThisAndPasteYourAPIKeyHere بمفتاح API الخاص بك.
  4. اذهب إلى الزاوية اليسرى السفلية (كما هو موضح في الصورة أعلاه) وأنشئ نسختك. تأكد من اختيار الخطة المفتوحة.
  5. بعد إنشاء النسخة، انسخ رمز CRN المرتبط بها. قد تحتاج إلى تحديث الصفحة لرؤية النسخة.
  6. في الخلية أدناه، استبدل deleteThisAndPasteYourCRNHere برمز CRN الخاص بك.

راجع هذا الدليل لمزيد من التفاصيل حول كيفية إعداد حساب IBM Cloud® الخاص بك.

⚠️ ملاحظة: تعامل مع مفتاح API الخاص بك كما تتعامل مع كلمة مرور آمنة. راجع دليل إعداد السحابة لمزيد من المعلومات حول استخدام مفتاح API في البيئات الآمنة وغير الموثوقة.

بالإضافة إلى ذلك، إذا كنت عضواً في شبكة شركاء IBM الجامعية، يرجى استخدام عنوان البريد الإلكتروني لمؤسستك لمعرّف IBM الخاص بك للحصول على مزايا الشراكة.

from qiskit_ibm_runtime import QiskitRuntimeService

# Save your API key and crn and have access to the quantum computers
your_api_key = "deleteThisAndPasteYourAPIKeyHere"
your_crn = "deleteThisAndPasteYourCRNHere"

QiskitRuntimeService.save_account(
channel="ibm_cloud",
token=your_api_key,
instance=your_crn,
overwrite=True
)
# Check that the account has been saved properly
service = QiskitRuntimeService()
service.saved_accounts()
# See backends you can use
service.backends()

3. أول Circuit كمومي لك

الدوائر الكمومية

الوحدة الأساسية في Qiskit هي Circuit الكمومي، وهو سلسلة من التعليمات التي يمكن للحاسوب الكمومي استخدامها للتعامل مع وحدات المعلومات الكمومية، المعروفة أيضاً بـQubits. تمتلك هذه الـQubits خصائص خاصة تمكّن أجهزة الحاسوب الكمومي من معالجة المشكلات بطريقة مختلفة عن الحاسوب المحمول أو الهاتف الذكي. يتقدم Qiskit بسرعة كتقنية - فبينما لا يزال بإمكانك تصميم دوائرك الكمومية يدوياً وتحديد طريقة تشغيلها (وهناك أسباب وجيهة كثيرة للقيام بذلك)، توفر IBM Quantum أيضاً أدوات تبسّط هذه العملية. لأغراض التعلم، سنصمم Circuit بسيطاً جداً وننفذه على محاكٍ.

نستعرض هذه النظرة العامة بسرعة لأنه، بصراحة، يمكننا قضاء ساعات في شرح أساسيات المعلومات والحوسبة الكمومية فحسب. في الواقع، قامت IBM Quantum بذلك بالفعل، إذ أنتجت دورة مكتوبة وسلسلة من محاضرات فيديو مخصصة لهذا الموضوع. إذا كنت بحاجة إلى مراجعة، فاطّلع عليها!

from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
from qiskit.visualization import plot_state_qsphere
from qiskit_aer import AerSimulator
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.visualization import array_to_latex
from qiskit.visualization import plot_distribution

import numpy as np
from numpy import sqrt

العمليات الأساسية على الـQubits والقياسات

تدوين حالات Qubit الفردي

لنبدأ بالنظر في Qubit واحد. الفارق الرئيسي بين البت الكلاسيكي الذي يمكنه أخذ القيمتين 0 و1 فقط، هو أن البت الكمومي، أو Qubit، يمكن أن يكون في الحالتين 0\vert0\rangle و1\vert1\rangle، فضلاً عن أي تركيب خطي لهاتين الحالتين. تُعرف هذه الخاصية بالتراكب، وتتيح لنا كتابة أعمّ حالة للـQubit على النحو التالي:

ψ=1p0+eiϕp1\vert\psi\rangle = \sqrt{1-p}\vert0\rangle + e^{i \phi} \sqrt{p} \vert1\rangle

إذا قسنا حالة هذا الـQubit، سنجد النتيجة 11 باحتمالية pp، والنتيجة 00 باحتمالية 1p1-p. كما ترى، مجموع الاحتماليات يساوي 11، مما يعني أننا سنقيس بالتأكيد إما 00 أو 11، ولا توجد نتائج أخرى.

بالإضافة إلى pp، ربما لاحظت معاملاً آخر أعلاه. المتغير ϕ\phi يشير إلى الطور الكمومي النسبي بين الحالتين 0\vert0\rangle و1\vert1\rangle. كما سنكتشف لاحقاً، هذا الطور النسبي بالغ الأهمية. في الوقت الراهن، يكفي الإشارة إلى أن الطور الكمومي هو ما يتيح التداخل بين الحالات الكمومية، مما يمكّننا من كتابة خوارزميات كمومية لحل مهام بعينها.

تصور الحالات الكمومية

نتصور الحالات الكمومية طوال هذا التمرين باستخدام ما يُعرف بـqsphere. إليك كيف يبدو qsphere للحالتين 0\vert0\rangle و1\vert1\rangle على التوالي. لاحظ أن الجزء العلوي من الكرة يمثل الحالة 0\vert0\rangle، بينما يمثل الجزء السفلي الحالة 1\vert1\rangle.

#visualize |0>
sv=Statevector([1, 0])
plot_state_qsphere(sv)

يمكنك إنشاء نفس QSphere بالضبط باستخدام Circuit كمومي. متجه الحالة المستخدم هنا هو من الحالة 0|0\rangle. في Qiskit، يُهيَّأ الـQubit في الحالة 0|0\rangle. حاول تشغيل الدائرة أدناه وانظر إذا كنت تحصل على نفس QSphere.

qc1 = QuantumCircuit(1)
sv=Statevector(qc1)
plot_state_qsphere(sv)

الآن لنتصور حالة 1|1\rangle. لا ينبغي أن يكون مفاجئاً أن حالة التراكب ذات الطور الكمومي ϕ=0\phi = 0 والاحتمالية p=1/2p = 1/2 (أي احتمالية متساوية لقياس كلٍّ من 0 و1) تظهر على qsphere بنقطتين. لاحظ أيضاً أن حجم الدوائر عند النقطتين أصغر مما كان عليه عندما كانت لدينا الحالتان 0\vert0\rangle و1\vert1\rangle فحسب. وذلك لأن حجم الدوائر يتناسب مع احتمالية قياس كل منهما، التي انخفضت الآن إلى النصف.

#visualize 1/sqrt(2)|0> + 1/sqrt(2)|1>

sv=Statevector([1/sqrt(2), 1/sqrt(2)])
plot_state_qsphere(sv)

في حالة حالات التراكب التي يكون فيها الطور الكمومي غير صفري، يتيح لنا الـqsphere تصور هذا الطور عن طريق تغيير لون الكتلة المقابلة. على سبيل المثال، الحالة ذات ϕ=90\phi = 90^\circ (درجة) والاحتمالية p=1/2p = 1/2 معروضة في qsphere أدناه.

sv=Statevector([1/sqrt(2), 1/sqrt(2)*1j])
plot_state_qsphere(sv)

التعامل مع الكيوبتات

يُعدَّل على Qubits عن طريق تطبيق بوابات كمومية. دعنا نستعرض نظرة عامة على البوابات المختلفة التي سنتناولها في التمارين التالية.

أولاً، لنصف كيف يمكننا تغيير قيمة pp لحالتنا الكمومية العامة. للقيام بذلك، سنستخدم بوابتين:

  1. بوابة XX: تقلب هذه البوابة بين الحالتين 0\vert0\rangle و1\vert1\rangle. هذه العملية مماثلة لبوابة NOT الكلاسيكية. ونتيجةً لذلك، تُشار إلى بوابة XX أحياناً بوصفها بوابة قلب البت أو بوابة NOT. رياضياً، تغير بوابة XX قيمة pp إلى 1p1-p، أي من 0 إلى 1 والعكس بالعكس.

  2. بوابة HH: تتيح لنا هذه البوابة الانتقال من الحالة 0\vert0\rangle إلى الحالة 12(0+1)\frac{1}{\sqrt{2}}\left(\vert0\rangle + \vert1\rangle\right). تُعرف هذه الحالة أيضاً بـ+\vert+\rangle. رياضياً، يعني ذلك الانتقال من p=0,ϕ=0p=0, \phi=0 إلى p=1/2,ϕ=0p=1/2, \phi=0. وبما أن الحالة النهائية للـQubit هي تراكب فوقي بين 0\vert0\rangle و1\vert1\rangle، فإن بوابة هادامار تمثل عملية كمومية حقيقية.

لاحظ أن كلتا البوابتين غيّرتا قيمة pp، لكن ليس ϕ\phi. ولحسن الحظ، يسهل علينا تصوّر أثر هذه البوابات بالنظر إلى الشكل أدناه.

بمجرد الحصول على الحالة +\vert+\rangle، يمكننا تغيير الطور الكمومي بتطبيق عدة بوابات أخرى. فعلى سبيل المثال، تضيف بوابة SS طوراً مقداره 9090 درجة إلى ϕ\phi، بينما تضيف بوابة ZZ طوراً مقداره 180180 درجة إلى ϕ\phi. ولطرح طور مقداره 9090 درجة، يمكن تطبيق بوابة SS^\dagger، التي تُقرأ S-dagger وتُكتب عادةً sdg. وأخيراً، توجد بوابة YY التي تطبّق تسلسلاً من بوابتي ZZ وXX.

يمكنك التجريب مع البوابات XX وYY وZZ وHH وSS وSS^\dagger للتعرف على العمليات المختلفة وكيفية تأثيرها على حالة الـQubit. للقيام بذلك، يمكنك زيارة Circuit Composer وتشغيل أداة الدائرة الخاصة بنا. بعد زيارة محرر الدائرة، اختر بوابة لتطبيقها على Qubit، ثم اختر الـQubit (في الأمثلة الأولى، الـQubit الوحيد المتاح هو qubit 0). راقب كيف تتغير الحالة المقابلة مع كل بوابة، فضلاً عن وصف تلك الحالة. كما سيوفر لك الكود الذي يُنشئ الدائرة الكمومية المقابلة في Qiskit.

إذا أردت معرفة المزيد عن وصف الحالات الكمومية ومؤثرات باولي وبوابات الـQubit المفرد الأخرى، راجع Quantum Information من قسم النظام المفرد في دورة Basics of Quantum Information لجون واتروس.

التمارين: الدوائر الكمومية باستخدام بوابات الـQubit المفرد

فيما يلي أربعة تمارين صغيرة للوصول إلى حالات مختلفة على مجال qsphere. يمكنك إما حلها باستخدام محرر الدائرة ونسخ الكود الذي يوفره ولصقه في الخلايا المعنية لإنشاء الدوائر الكمومية، أو يمكنك إدراج مجموعة من أسطر الكود التالية مباشرة في البرنامج لتطبيق البوابات المختلفة:

qc.x(0) # bit flip qc.y(0) # bit and phase flip qc.z(0) # phase flip qc.h(0) # superpostion qc.s(0) # quantum phase rotation by pi/2 (90 degrees) qc.sdg(0) # quantum phase rotation by -pi/2 (90 degrees)

يشير (0) إلى أننا نطبق هذه البوابة على الـQubit q0، وهو أول Qubit (والوحيد في هذه الحالة).

حاول بلوغ الحالة المعطاة على مجال qsphere في كل تمرين من التمارين التالية.

i) لنبدأ بتنفيذ قلب بت. الهدف هو الوصول إلى الحالة 1\vert1\rangle بدءاً من الحالة 0\vert0\rangle.


def create_circuit():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

# check solution
qc2 = create_circuit()
state = Statevector(qc2)

plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)

ii) بعد ذلك، لننشئ تراكباً فوقياً. الهدف هو الوصول إلى الحالة +=12(0+1)|+\rangle = \frac{1}{\sqrt{2}}\left(|0\rangle + |1\rangle\right).


def create_circuit2():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc3 = create_circuit2()
state = Statevector(qc3)
plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)

iii) لنجمع بين الاثنين. الهدف هو الوصول إلى الحالة =12(01)|-\rangle = \frac{1}{\sqrt{2}}\left(|0\rangle - |1\rangle\right).

هل يمكنك الجمع بين المهمتين أعلاه للتوصل إلى الحل؟

def create_circuit3():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc4 = create_circuit3()
state = Statevector(qc4)
plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)

iv) أخيراً، ننتقل إلى الأعداد المركبة. الهدف هو الوصول إلى الحالة =12(0i1)|\circlearrowleft\rangle = \frac{1}{\sqrt{2}}\left(|0\rangle - i|1\rangle\right)

def create_circuit4():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc5 = create_circuit4()
state = Statevector(qc5)

plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)

4. اختبار الكم مع بوابات الكيوبتات المتعددة

أحسنت! الآن بعد أن فهمت بوابات الـQubit المفرد، لنلقِ نظرة على البوابات التي تعمل على Qubits متعددة. ستُطلب منك هنا حل 4 اختبارات كمومية للحالات عن طريق دمج بوابات الـQubit المفرد مع بوابات الـQubits المتعددة. البوابات الأساسية على Qubitين هي:

qc.cx(c,t) # controlled-X (= CNOT) gate with control qubit c and target qubit t qc.cz(c,t) # controlled-Z gate with control qubit c and target qubit t qc.swap(a,b) # SWAP gate that swaps the states of qubit a and qubit b

إذا أردت الاطلاع على المزيد حول بوابات الـQubits المتعددة المختلفة وعلاقاتها، زر Quantum Information الخاصة بالأنظمة المتعددة، من دورة Basics of Quantum Information لجون.

لاحظ أنه في حالة Qubitين، تكون الحالة العامة على الشكل a00+b01+c10+d11a|00\rangle + b |01\rangle + c |10\rangle + d|11\rangle، حيث aa وbb وcc وdd أعداد مركبة تعطي مربعات قيمها المطلقة احتمال قياس الحالة المقابلة؛ فمثلاً، a2|a|^2 هو احتمال الحصول على الحالة '0' في كلا الـQubits. وهذا يعني أنه يمكن أن يكون لدينا الآن ما يصل إلى أربع نقاط على مجال qsphere.

نبدأ ببوابة الـQubits الثنائية القانونية، وهي بوابة NOT المتحكم بها (وتُعرف أيضاً بـ CNOT أو CX). هنا، كما هو الحال مع جميع البوابات الثنائية المتحكم بها، يُسمى أحد الـQubits "المتحكم" والآخر "الهدف". إذا كان الـQubit المتحكم في الحالة 0|0\rangle، فإنه يطبق بوابة الهوية II على الهدف، أي لا تُنفَّذ أي عملية. أما إذا كان الـQubit المتحكم في الحالة 1|1\rangle، فإنه يُطبَّق بوابة X على الـQubit الهدف. وبالتالي، مع كلا الـQubits في إحدى الحالتين الكلاسيكيتين 0|0\rangle أو 1|1\rangle، تقتصر بوابة CNOT على العمليات الكلاسيكية.

يتغير هذا الوضع تغيراً جذرياً عندما نطبق أولاً بوابة هادامار على الـQubit المتحكم، مما يضعه في حالة التراكب الفوقي +|+\rangle. يمكن أن ينتج عن تأثير بوابة CNOT على هذه المدخلات غير الكلاسيكية حالات متشابكة بدرجة عالية بين الـQubits المتحكم والهدف. إذا كان الـQubit الهدف في البداية في الحالة 0|0\rangle، فإن الحالة الناتجة تُرمز بـΦ+|\Phi^+\rangle، وهي إحدى ما يُعرف بـحالات بيل.

i) أنشئ حالة بيل Φ+=12(00+11)|\Phi^+\rangle = \frac{1}{\sqrt{2}}\left(|00\rangle + |11\rangle\right).

لهذه الحالة، يكون احتمال قياس "00" هو 12\frac{1}{2} واحتمال قياس "11" هو 12\frac{1}{2}. وبالتالي، تكون نتائج كلا الـQubits مترابطة بصورة تامة.


def create_circuit5():
qc = QuantumCircuit(2)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc6 = create_circuit5()
state = Statevector(qc6) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc6.draw(output='mpl') # we draw the circuit

بعد ذلك، حاول إنشاء حالة Qubits مضادة التوافق بصورة تامة. لاحظ إشارة الطرح هنا، التي تدل على الطور النسبي بين الحالتين.

ii) أنشئ حالة بيل Ψ=12(0110)\vert\Psi^-\rangle = \frac{1}{\sqrt{2}}\left(\vert01\rangle - \vert10\rangle\right).


def create_circuit6():
qc = QuantumCircuit(2)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc7 = create_circuit6()
state = Statevector(qc7) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc7.draw(output='mpl') # we draw the circuit

iii) لديك الدائرة الكمومية الموضحة في الدالة أدناه. قم بتبديل حالتَي Qubit الأول والثاني للحصول على QSphere هذا.

def create_circuit7():
qc = QuantumCircuit(2)
qc.rx(np.pi/3,0)
qc.x(1)
return qc

qc8 = create_circuit7()

#
#
# FILL YOUR CODE IN HERE
#
#

state = Statevector(qc8) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc8.draw(output='mpl') # we draw the circuit

iv) اكتب برنامجًا من الصفر يُنشئ حالة GHZ (على ثلاثة Qubits)، GHZ=12(000+111)\vert \text{GHZ}\rangle = \frac{1}{\sqrt{2}} \left(|000\rangle + |111 \rangle \right)


def create_circuit8():
#
#
# FILL YOUR CODE IN HERE
#
#
#
return qc

qc9 = create_circuit8()

pub4 = (qc9)

state = Statevector(qc9) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc9.draw(output='mpl') # we draw the circuit

5. شغِّل دائرتك وشاهد نتائج القياس على حاسوب كمومي حقيقي

الآن بعد أن تعلمنا كيفية بناء Circuit كمومية للتحكم في متجه الحالة لمجموعة من Qubits، حان وقت أكثر لحظات المشروع إثارةً: تشغيلها ومشاهدة المخرجات! هنا سنتعلم الأسلوب الحديث والفعّال لتنفيذ دوائرنا باستخدام Qiskit.

نمط Qiskit هو إطار عمل عام لتحليل المسائل الخاصة بمجالات بعينها وتأطير القدرات المطلوبة في مراحل متسلسلة. يُتيح ذلك قابلية تركيب سلسة للقدرات الجديدة التي يطوّرها باحثو IBM Quantum (وغيرهم)، ويُمهّد الطريق نحو مستقبل تُنفَّذ فيه مهام الحوسبة الكمومية على بنية تحتية حوسبية قوية وغير متجانسة (CPU/GPU/QPU).

الخطوات الأربع لنمط Qiskit هي كما يلي:

  1. التعيين: ربط المسألة بـ Circuits كمومية ومؤثرات
  2. التحسين: تهيئة الدوائر للعتاد المستهدف
  3. التنفيذ: تشغيل الدوائر على العتاد المستهدف
  4. معالجة النتائج: تفسير المخرجات

لقد أنهينا للتو الخطوة 1: التعيين ببناء Circuits كمومية لتوليد الحالة الكمومية المطلوبة. لنستعرض الآن الخطوات المتبقية لرؤية النتائج.

التحسين

هنا سنحدد Backend لتشغيل الدوائر — يمكنك اختيار أقل وحدات QPU ازدحامًا من بين مجموعات QPU المتاحة لك، أو اختيار محاكٍ إذا لم يتبقَّ لديك وقت GPU كافٍ. بعد اختيار Backend، سيقوم pass_manager بـ Transpile دوائرك إلى مجموعة البوابات الأصلية للـ Backend الذي اخترته وتحسينها للحصول على نتائج أفضل. يمكنك التصريح بـ pass_manager بسهولة باستخدام generate_preset_pass_manager وتحديد optimization_level، إذ تعني القيمة الأعلى مزيدًا من خطوات التحسين.

الخطوة التالية مثيرة — سنشغّل Circuit الكمومية باستخدام Qiskit Runtime!

سنفعل ذلك باستخدام أوليَّات Qiskit الاثنتين:

  1. Sampler يأخذ عيّنات من سجل المخرجات الناتج عن تنفيذ Circuit كمومية واحدة أو أكثر. مخرجاته عبارة عن أعداد القياسات لكل لقطة (per-shot).
  2. Estimator يحسب القيمة المتوقعة لمرصد (observable) واحد أو أكثر بالنسبة إلى الحالات التي تولّدها Circuit الكمومية. تتضمن مخرجاته القيم المتوقعة إلى جانب أخطائها المعيارية.

هنا سنستخدم Sampler لتنفيذ دوائرنا. تعرض خلية الكود أدناه كيفية تحديد Backend وpass manager الخاص به أولاً، ثم إضافة measurement إلى جميع الدوائر وإنشاء مصفوفة من الدوائر الكمومية (pub) لتمريرها إلى Sampler.


backend=service.least_busy()
#backend=AerSimulator()

pm = generate_preset_pass_manager(optimization_level=3, backend=backend)
sampler = Sampler(mode=backend)

pub = []
for qc in circ:
qc.measure_all()
pub.append(pm.run(qc))

التنفيذ

لنشغّل دوائرنا. في حالة وجود طابور انتظار طويل في السحابة، اطبع معرّف المهمة job_id واحفظه للاستخدام لاحقًا وتحقق من حالة المهمة. بعد أن ترى تغيُّر حالة المهمة إلى Done، استرجع نتيجة المهمة.

job = sampler.run(pub)
job_id = job.job_id()
print(job_id)
job.status()
job_retrived = service.job(job_id)
result = job.result()

معالجة النتائج

الخطوة الأخيرة هي تفسير التمثيل البياني لفهم الحالات الكمومية التي أنشأناها. قبل رسم عدة مخططات، لنجمع أعداد القياسات من جميع الدوائر، ثم سننشئ 4 مخططات بتصنيف الدوائر.

result = job.result()
counts_all = [result[k].data.meas.get_counts() for k in range(9)]

حالات Qubit الفردي

plot_distribution([counts_all[0], counts_all[1]], legend =['qc1', 'qc2'])

حالات Qubit الواحد في التراكب

plot_distribution([counts_all[2], counts_all[3], counts_all[4]], legend =['qc3', 'qc4', 'qc5'])

حالات Qubit الثنائي

plot_distribution([counts_all[5], counts_all[6], counts_all[7]],legend =['qc6', 'qc7', 'qc8'] )

حالات Qubit الثلاثي

plot_distribution(counts_all[8], legend=['qc9'])

تحدٍّ إضافي

هل لاحظت أي ضوضاء في نتائج التجارب الفعلية على Backend الحقيقي؟ إزالة ضوضاء Qubit هي أحد مجالات البحث النشطة. جرِّب خيارات تخفيف الأخطاء وقمعها المتنوعة في Qiskit Runtime لترى كيف تتغيّر الضوضاء في نتائج التنفيذ! (ملاحظة) تستلزم هذه الخيارات مزيدًا من وقت QPU.

معلومات إضافية

import qiskit, qiskit_ibm_runtime

print("Qiskit version:", qiskit.version.get_version_info())
print("Qiskit Runtime version:", qiskit_ibm_runtime.__version__)
Qiskit version: 2.1.1
Qiskit Runtime version: 0.40.1

أُعِدَّ بواسطة: Sophy Shin

راجعه: Nate Earnest-Noble

© IBM Corp., 2025

هذا المحتوى مرخَّص بموجب رخصة Apache 2.0. يمكنك الحصول على نسخة من هذه الرخصة في ملف LICENSE في الدليل الجذري لشجرة المصدر أو على الرابط: http://www.apache.org/licenses/LICENSE-2.0.

يجب أن تحتفظ أي تعديلات أو أعمال مشتقة من هذا المحتوى بإشعار حقوق الملكية هذا، وأن تحمل الملفات المعدَّلة إشعارًا يفيد بأنها طُرِئ عليها تعديل من النسخ الأصلية.