דלג לתוכן הראשי
פרויקט זה בשלב בטא. מצאת באג? פתח issue ב-GitHub. יש שאלה או רעיון? שאל ב-Discussions — נשמח לשמוע ממך!
מה איכות התרגום בדף זה?

מימוש ב-Qiskit

בשיעור הקודם, הצצנו לראשונה למחלקות Statevector ו-Operator ב-Qiskit, והשתמשנו בהן לסימולציה של פעולות ומדידות על qubit בודד. בחלק הזה, נשתמש במחלקות אלה כדי לחקור את ההתנהגות של Qubitים מרובים.

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"numpy": "numpy", "qiskit": "qiskit"}
_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 import __version__

print(__version__)
2.1.1

נתחיל בייבוא המחלקות Statevector ו-Operator, וכן פונקציית השורש הריבועי מ-NumPy. מכאן ואילך, באופן כללי, נדאג לכל הייבואים הנדרשים בתחילת כל שיעור.

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

מכפלות טנסוריות​

למחלקה Statevector יש מתודה בשם tensor, שמחזירה את המכפלה הטנסורית של אותו Statevector עם אחר הניתן כארגומנט. הארגומנט מתפרש כגורם הטנסורי מצד ימין.

למשל, בקוד הבא אנחנו יוצרים שני וקטורי מצב המייצגים את ∣0⟩\vert 0\rangle ו-∣1⟩,\vert 1\rangle, ומשתמשים במתודה tensor כדי ליצור וקטור חדש, ∣ψ⟩=∣0⟩⊗∣1⟩.\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⟩=12∣0⟩+i2∣1⟩and∣−i⟩=12∣0⟩−i2∣1⟩.\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" מגיעים מההקשר של ספין במכניקת הקוונטים, שבו רכיב ספין יכול להצביע שמאלה או ימינה בניסוי; זה לא מתייחס לה-Qubit הימני או השמאלי ביותר במערכות של Qubitים מרובים. הנה דוגמה למכפלה הטנסורית של ∣+⟩\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"))

12∣00⟩−i2∣01⟩+12∣10⟩−i2∣11⟩\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"))

12∣00⟩−i2∣01⟩+12∣10⟩−i2∣11⟩\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"))
[220220022022220−2200220−22] \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} [0220002200220002200000022000220022000220022000−220022000−2200000022000−220022000−220] \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"))
[0220002200220002200000022000220022000220022000−220022000−2200000022000−220022000−220] \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}

ניתן להפעיל פעולות מורכבות על מצבים מורכבים (לקדם אותם בזמן) כפי שהיינו מצפים — בדיוק כפי שראינו עבור מערכות בודדות בשיעור הקודם. לדוגמה, הקוד הבא מחשב את המצב (H⊗I)∣ϕ⟩(H\otimes I)\vert\phi\rangle עבור ∣ϕ⟩=∣+⟩⊗∣−i⟩\vert\phi\rangle = \vert + \rangle \otimes \vert {-i}\rangle (שכבר הוגדר לעיל).

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

22∣00⟩−2i2∣01⟩\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 שבה ה-Qubit השמאלי הוא קיוביט הבקרה וה-Qubit הימני הוא קיוביט המטרה. התוצאה היא מצב Bell ∣ϕ+⟩\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"))

22∣00⟩+22∣11⟩\frac{\sqrt{2}}{2} |00\rangle+\frac{\sqrt{2}}{2} |11\rangle

מדידות חלקיות​

בשיעור הקודם, השתמשנו במתודה measure לסימולציה של מדידה של וקטור מצב קוונטי. מתודה זו מחזירה שני פריטים: תוצאת המדידה המסומלצת, וה-Statevector החדש בהינתן מדידה זו.

כברירת מחדל, measure מודדת את כל ה-Qubitים בוקטור המצב. לחלופין, ניתן לספק רשימה של מספרים שלמים כארגומנט, מה שגורם למדידה של אינדקסי qubit אלה בלבד. כדי להדגים זאת, הקוד הבא יוצר את המצב

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

ומודד את qubit מספר 0, שהוא ה-Qubit הימני ביותר. (Qiskit ממספר Qubitים החל מ-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"))

33∣001⟩+33∣010⟩+33∣100⟩\frac{\sqrt{3}}{3} |001\rangle+\frac{\sqrt{3}}{3} |010\rangle+\frac{\sqrt{3}}{3} |100\rangle

Measured: 0
State after measurement:

22∣010⟩+22∣100⟩\frac{\sqrt{2}}{2} |010\rangle+\frac{\sqrt{2}}{2} |100\rangle

Measured: 00
State after measurement:

∣100⟩ |100\rangle