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

تطبيق Qiskit

في الدرس السابق، ألقينا نظرة أولى على صنفَي Statevector وOperator في Qiskit، واستخدمناهما لمحاكاة العمليات والقياسات على كيوبت واحد. في هذا القسم، سنستخدم هذين الصنفين لاستكشاف سلوك كيوبتات متعددة.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
from qiskit import __version__

print(__version__)
2.1.1

سنبدأ باستيراد صنفَي Statevector وOperator، إضافةً إلى دالة الجذر التربيعي من NumPy. من الآن فصاعداً، سنحرص بشكل عام على تنفيذ جميع الاستيرادات المطلوبة في بداية كل درس.

from qiskit.quantum_info import Statevector, Operator
from numpy import sqrt

حاصل الضرب التنسوري

يمتلك الصنف Statevector دالةً تُسمى tensor، تُعيد حاصل الضرب التنسوري لهذا المتجه مع متجه آخر يُمرَّر كمعامل. يُفسَّر المعامل على أنه العامل التنسوري على اليمين.

على سبيل المثال، ننشئ في الكود أدناه متجهَي حالة يمثلان 0\vert 0\rangle و1\vert 1\rangle، ونستخدم دالة tensor لإنشاء متجه جديد ψ=01\vert \psi\rangle = \vert 0\rangle \otimes \vert 1\rangle. لاحظ أننا نستخدم دالة from_label لتعريف الحالتين 0\vert 0\rangle و1\vert 1\rangle، بدلاً من تعريفهما يدوياً.

zero = Statevector.from_label("0")
one = Statevector.from_label("1")
psi = zero.tensor(one)
display(psi.draw("latex"))

01 |01\rangle

تشمل التسميات المسموح بها أيضاً "+" و"-" للحالتين الموجبة والسالبة، وكذلك "r" و"l" (اختصاراً لـ"right" و"left") للحالتين

+i=120+i21andi=120i21.\vert {+i} \rangle = \frac{1}{\sqrt{2}} \vert 0 \rangle + \frac{i}{\sqrt{2}} \vert 1 \rangle \qquad\text{and}\qquad \vert {-i} \rangle = \frac{1}{\sqrt{2}} \vert 0 \rangle - \frac{i}{\sqrt{2}} \vert 1 \rangle.

هنا، تأتي كلمتا "+" و"-" أو "right" و"left" من سياق الدوران الكمي (spin) في الفيزياء الكمية، حيث قد يشير مركّب الدوران إلى اليسار أو اليمين في التجربة؛ ولا يقصد بها الكيوبت الأيمن أو الأيسر في أنظمة الكيوبتات المتعددة. إليك مثالاً على حاصل الضرب التنسوري لـ+\vert {+} \rangle وi\vert {-i} \rangle:

plus = Statevector.from_label("+")
minus_i = Statevector.from_label("l")
phi = plus.tensor(minus_i)
display(phi.draw("latex"))

1200i201+1210i211\frac{1}{2} |00\rangle- \frac{i}{2} |01\rangle+\frac{1}{2} |10\rangle- \frac{i}{2} |11\rangle

بديل آخر هو استخدام عملية ^ للضرب التنسوري، والتي تعطي بطبيعة الحال نفس النتائج.

display((plus ^ minus_i).draw("latex"))

1200i201+1210i211\frac{1}{2} |00\rangle- \frac{i}{2} |01\rangle+\frac{1}{2} |10\rangle- \frac{i}{2} |11\rangle

يمتلك الصنف Operator أيضاً دالة tensor (إضافةً إلى دالة from_label)، كما نرى في الأمثلة التالية.

H = Operator.from_label("H")
Id = Operator.from_label("I")
X = Operator.from_label("X")
display(H.tensor(Id).draw("latex"))
display(H.tensor(Id).tensor(X).draw("latex"))
[220220022022220220022022] \begin{bmatrix} \frac{\sqrt{2}}{2} & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & \frac{\sqrt{2}}{2} \\ \frac{\sqrt{2}}{2} & 0 & - \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & - \frac{\sqrt{2}}{2} \\ \end{bmatrix} [02200022002200022000000220002200220002200220002200220002200000022000220022000220] \begin{bmatrix} 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 \\ \end{bmatrix}

وكذلك، كما في حالة المتجهات، تُكافئ عملية ^ تماماً.

display((H ^ Id ^ X).draw("latex"))
[02200022002200022000000220002200220002200220002200220002200000022000220022000220] \begin{bmatrix} 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 \\ \end{bmatrix}

يمكن تطوير الحالات المركّبة باستخدام عمليات مركّبة كما هو متوقع — تماماً كما رأينا في الأنظمة المفردة في الدرس السابق. على سبيل المثال، يحسب الكود التالي الحالة (HI)ϕ(H\otimes I)\vert\phi\rangle حيث ϕ=+i\vert\phi\rangle = \vert + \rangle \otimes \vert {-i}\rangle (والذي تم تعريفه أعلاه بالفعل).

display(phi.evolve(H ^ Id).draw("latex"))

22002i201\frac{\sqrt{2}}{2} |00\rangle- \frac{\sqrt{2} i}{2} |01\rangle

إليك كوداً يعرّف عملية CXCX ويحسب CXψCX \vert\psi\rangle للحالة ψ=+0\vert\psi\rangle = \vert + \rangle \otimes \vert 0 \rangle. للتوضيح، هذه عملية CXCX تكون فيها الكيوبت اليسرى هي كيوبت التحكم والكيوبت اليمنى هي كيوبت الهدف. والنتيجة هي حالة بل ϕ+\vert\phi^{+}\rangle.

CX = Operator([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
psi = plus.tensor(zero)
display(psi.evolve(CX).draw("latex"))

2200+2211\frac{\sqrt{2}}{2} |00\rangle+\frac{\sqrt{2}}{2} |11\rangle

القياسات الجزئية

في الدرس السابق، استخدمنا دالة measure لمحاكاة قياس متجه الحالة الكمية. تُعيد هذه الدالة عنصرَين: نتيجة القياس المحاكاة، والـStatevector الجديدة بعد هذا القياس.

افتراضياً، تقيس measure جميع الكيوبتات في متجه الحالة. يمكننا بدلاً من ذلك تمرير قائمة من الأعداد الصحيحة كمعامل، مما يجعل القياس يشمل تلك الفهارس فقط. لتوضيح ذلك، ينشئ الكود أدناه الحالة

w=001+010+1003\vert w\rangle = \frac{\vert 001\rangle + \vert 010\rangle + \vert 100\rangle}{\sqrt{3}}

ويقيس الكيوبت رقم 0، وهو الكيوبت الأقصى يميناً. (يُرقّم Qiskit الكيوبتات بدءاً من 0، من اليمين إلى اليسار. سنعود إلى هذه الاتفاقية في الترقيم في الدرس القادم.)

w = Statevector([0, 1, 1, 0, 1, 0, 0, 0] / sqrt(3))
display(w.draw("latex"))

result, state = w.measure([0])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))

result, state = w.measure([0, 1])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))

33001+33010+33100\frac{\sqrt{3}}{3} |001\rangle+\frac{\sqrt{3}}{3} |010\rangle+\frac{\sqrt{3}}{3} |100\rangle

Measured: 0
State after measurement:

22010+22100\frac{\sqrt{2}}{2} |010\rangle+\frac{\sqrt{2}}{2} |100\rangle

Measured: 00
State after measurement:

100 |100\rangle