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

ה-Ansatz

צפו בהסבר של ויקטוריה ליפינסקה על מה זה ansatz ומדוע הוא חשוב בהקשר של פותר ערכים עצמיים קוונטי וריאציוני (VQE).

מקורות​

המאמרים הבאים מצוינים בסרטון לעיל.

קוד ה-Ansatz​

בשיעור הקודם יצרתם המילטוניאן המתאר את האנרגיה של המולקולה שאתם חוקרים, ומיפיתם אותו לפורמט שמחשב קוונטי יכול להשתמש בו. ה-VQE משתמש ב_מעגל וריאציוני_ להכנת מצבים קוונטיים. לאחר מכן אנחנו משתמשים במצבים אלה כדי לקבוע את ערך הציפייה של ההמילטוניאן (האנרגיה). הפרמטרים במעגל הוריאציוני משתנים עד שהחישוב מתכנס לערך ציפייה מינימלי. בהקשר של כימיה קוונטית, זו צריכה להיות אנרגיית מצב היסוד. שיעור זה מתמקד במעגל הוריאציוני, הנקרא גם ansatz (מילה גרמנית שפירושה "גישה" או "שיטה"). בשיעור זה תלמדו

  • את מגוון ה-ansaetze המוכנים מראש הזמינים בספריית המעגלים
  • כיצד לציין או לשנות את מאפייני ה-ansatz
  • כיצד לבנות ansatz משלכם
  • דוגמאות ל-ansaetze טובים ורעים

לספריית המעגלים של Qiskit יש קטגוריות רבות של מעגלים שניתן להשתמש בהם כ-ansatz. כאן, נגביל את הדיון למעגלים דו-מקומיים (מעגלים המורכבים משערים הפועלים על לכל היותר שני qubit-ים בכל פעם). Efficient SU2 הוא ansatz נפוץ.

מעגל efficient_su_2 מורכב משכבות של פעולות על qubit בודד הנפרשות על ידי SU(2) (קבוצת יחידה מיוחדת מדרגה 2, כמו Gate-י סיבוב פאולי) ושזירות CX. זוהי תבנית היוריסטית שיכולה להיות שימושית באלגוריתמים קוונטיים וריאציוניים כמו VQE ומעגלי סיווג בלמידת מכונה קוונטית (QML).

נתחיל עם דוגמה של מעגל efficient_su2 בעל ארבעה qubits עם שני סוגי שערי SU(2), נניח rx ו-y. אנחנו גם מציינים סכמת שזירה ומספר החזרות. אם פשוט תבצעו .draw() למעגלים, תקבלו ייצוג מופשט למדי. דיאגרמת מעגל מובנת יותר מתקבלת באמצעות שימוש ב-.decompose().draw(), וכאן נשתמש ב-`output = "mpl"'.

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

_needed = {"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.circuit.library import efficient_su2

SU2_ansatz = efficient_su2(4, su2_gates=["rx", "y"], entanglement="linear", reps=1)
print(SU2_ansatz.draw())
SU2_ansatz.decompose().draw(output="mpl")
┌──────────┐┌───┐ ┌──────────┐ ┌───┐
q_0: ┤ Rx(θ[0]) ├┤ Y ├──■──┤ Rx(θ[4]) ├───┤ Y ├─────────────────────
├──────────┤├───┤┌─┴─┐└──────────┘┌──┴───┴───┐ ┌───┐
q_1: ┤ Rx(θ[1]) ├┤ Y ├┤ X ├─────■──────┤ Rx(θ[5]) ├───┤ Y ├─────────
├──────────┤├───┤└───┘ ┌─┴─┐ └──────────┘┌──┴───┴───┐┌───┐
q_2: ┤ Rx(θ[2]) ├┤ Y ├────────┤ X ├─────────■──────┤ Rx(θ[6]) ├┤ Y ├
├──────────┤├───┤ └───┘ ┌─┴─┐ ├──────────┤├───┤
q_3: ┤ Rx(θ[3]) ├┤ Y ├────────────────────┤ X ├────┤ Rx(θ[7]) ├┤ Y ├
└──────────┘└───┘ └───┘ └──────────┘└───┘

Output of the previous code cell

שערי SU(2) מופיעים בהתחלה ובסוף עם הסדר והאיברים כפי שצוינו ב-su2_gates = [...]. סכמת השזירה linear פירושה ששערי CX עוברים דרך ה-qubits הממוספרים, ושוזרים 0 ו-1, ואז 1 ו-2, וכן הלאה, לאורך קו אלכסוני במעגל. כפי שניתן לצפות, הגדרת reps = 2 פשוט מוסיפה שכבת שזירה ושכבת SU(2) מסיימת. הגדרת reps = n מתאימה ל-n שכבות שזירה, עם שכבות SU(2) ביניהן ובכל קצה.

SU2_ansatz2 = efficient_su2(
4, su2_gates=["rx", "y", "z"], entanglement="linear", reps=2
)
SU2_ansatz2.decompose().draw(output="mpl")

Output of the previous code cell

ישנן עוד כמה סכמות שזירה. שתיים שכדאי להזכיר הן circular ו-full. שזירה מעגלית זהה לשזירה ליניארית, אך עם Gate CX נוסף המשזר את ה-Qubit הראשון והאחרון. סכמת השזירה המלאה כוללת Gate CX בין כל זוג qubit-ים. שימו לב שעבור Circuit בן N qubit-ים, מדובר ב-N(N−1)/2N(N-1)/2 Gate-י CXCX, שיכול להפוך ליקר מבחינה חישובית.

SU2_ansatz3 = efficient_su2(
4, su2_gates=["rx", "y", "z"], entanglement="circular", reps=1
)
SU2_ansatz3.decompose().draw(output="mpl")

Output of the previous code cell

SU2_ansatz4 = efficient_su2(4, su2_gates=["rx", "y", "z"], entanglement="full", reps=1)
SU2_ansatz4.decompose().draw(output="mpl")

Output of the previous code cell

ניתן לנטר את עומקי המעגל שלכם על ידי שימוש ב-.depth(), או לעיתים ב-.decompose().depth().

print(SU2_ansatz4.decompose().depth())
11

הכללה של ה-efficient_su2 היא המעגל הדו-מקומי, שהוא עצמו מקרה פרטי של מעגלי n-מקומי. המעגלים הדו-מקומיים מכילים גם בלוקי SU(2) (או בלוקי סיבוב) ובלוקי שזירה. כאן, אנחנו חופשיים לציין את סוג Gate-י השזירה שרוצים להשתמש בהם, למשל Gate-י CRX. בדוגמה זו, כל ה-Gate-ים מקבלים פרמטר, אך זה לא חייב להיות כך. אפשר להשתמש ב-Gate-י סיבוב Y וב-Gate-י שזירה CX, למשל.

from qiskit.circuit.library import n_local

rotation_blocks = ["ry"]
entanglement_blocks = ["crx"]
two_ansatz = n_local(
4, rotation_blocks, entanglement_blocks, "linear", insert_barriers=True, reps=2
)
two_ansatz.decompose().draw(output="mpl")

Output of the previous code cell

ה-ansatz האחרון שנדון בו בשמו הוא ה-Pauli-two-design. מעגל זה מכיל סיבוב ראשוני של RY(pi/4)RY(pi/4), ושכבות הסיבוב מכילות סיבובי פאולי של qubit בודד, כאשר הציר נבחר באופן אחיד ואקראי להיות X,‏ Y או Z. שכבות השזירה מורכבות משערי CZ זוגיים בעומק כולל של שתיים. שימו לב להבדל בעומק השזירה (ועומק המעגל הכולל) בין ה-pauli_two_design הזה לבין, לדוגמה, ה-efficient_su2.

from qiskit.circuit.library import pauli_two_design

PtwoD_ansatz = pauli_two_design(5, reps=1, seed=10599, insert_barriers=True)
PtwoD_ansatz.decompose().draw(output="mpl")

Output of the previous code cell

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

כדי לבנות ansatz משלכם, פשוט בנו Circuit קוונטי כאשר חלק מה-Gate-ים הם פונקציות של אלמנטים של וקטור פרמטרים ("theta" בדוגמה בת שלושת ה-Qubit-ים למטה).

from qiskit import QuantumCircuit
from qiskit.circuit import ParameterVector

n = 3

theta = ParameterVector("θ", length=n)
qc = QuantumCircuit(n)
qc.h(0)
qc.h(2)
for i in range(n - 1):
qc.cx(i, i + 1)
qc.cz(0, n - 1)
qc.barrier()
for i in range(n):
qc.ry(theta[i], i)
qc.barrier()
qc.cz(0, n - 1)
for i in reversed(range(n - 1)):
qc.cx(i, i + 1)
qc.h(0)
qc.h(1)
own_ansatz = qc
print(own_ansatz.depth())
qc.draw("mpl")
9

Output of the previous code cell

בדרך כלל, בחירת ה-ansatz הטוב ביותר היא אומנות; ה-ansatz הטוב ביותר הוא זה שעוזר לכם להגיע למטרה במספר מינימלי של צעדי אופטימיזציה. קל יותר לזהות ansaetze שסביר להניח שיהיו גרועים. לדוגמה, עומק מעגל גדול יותר נוטה לגרום להצטברות שגיאות. צמצום שגיאות יכול לעזור עם זה, אבל זוהי שיטת עבודה טובה לשמור על עומק המעגל נמוך ככל הסביר. אבל אל תדלגו על שזירה שהכרחית. ייתכן שיש לכם מצב מטרה הדורש סכמת שזירה מלאה. שתי דוגמאות מוצגות להלן שסביר להניח שהן בחירות גרועות מסיבות די ברורות. בחירת ansatz טוב תיבדק מחדש בחלקים מאוחרים יותר בהקשר של מבחני התכנסות.

המעגל הראשון הוא כנראה בחירה גרועה מפני שה-Qubit האחרון אינו שזור עם האחרים כלל. למעשה, אין שום פעולה משמעותית מבחינה חישובית על ה-Qubit האחרון. ככל הנראה, צריך לשזור את ה-Qubit האחרון עם האחרים, או להסיר אותו מהחישוב.

n = 4

theta = ParameterVector("θ", length=n)
qc = QuantumCircuit(n)
qc.h(0)
qc.h(2)
for i in range(n - 2):
qc.cx(i, i + 1)
qc.cz(0, n - 2)
qc.barrier()
for i in range(n):
qc.ry(theta[i], i)
qc.barrier()
qc.cz(0, n - 2)
for i in reversed(range(n - 2)):
qc.cx(i, i + 1)
qc.h(0)
qc.h(1)
own_ansatz2 = qc
print(own_ansatz2.depth())
qc.draw("mpl")
9

Output of the previous code cell

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

su2_ansatz_long = efficient_su2(
4, su2_gates=["rx", "y", "z"], entanglement="linear", reps=4
)
print(su2_ansatz_long.decompose().depth())
su2_ansatz_long.decompose().draw(output="mpl")
24

Output of the previous code cell

מעגלים אלה אינם "שלמים" במובן שעדיין יש פרמטרים לא ידועים ומשתנים שצריך להכניס לרבים מה-Gate-ים. פרמטרים אלה נבחרים על ידי ניחושים עוקבים ועדכון הפרמטרים כדי להוריד את ערך הציפייה של פונקציית העלות (בהקשר הכימי, בדרך כלל אנרגיית מצב היסוד). בממד אחד, או אפילו בכמה ממדים, זה טריוויאלי. אבל למעגל לעיל יש 20 פרמטרים וריאציוניים, מה שאומר שמציאת מצב המטרה עם האנרגיה המינימלית אומרת חיפוש במרחב בן 20 ממדים (סיבה נוספת לא לכלול Gate-י מעגל מיותרים). כאן נכנסים לתמונה אלגוריתמי אופטימיזציה קלאסיים, וזה הנושא של השיעור הבא.