SQD לאמידת אנרגיה של המילטוניאן כימי
בשיעור זה נשתמש ב-SQD כדי לאמוד את אנרגיית מצב הבסיס של מולקולה.
בפרט, נדון בנושאים הבאים תוך שימוש בגישת ה-4 שלבים של Qiskit:
- שלב 1: מיפוי הבעיה ל-Circuit קוונטיי ם ואופרטורים
- הגדרת ההמילטוניאן המולקולרי עבור .
- הסבר על ה-ansatz המקומי של אשכול יוניטרי Jastrow (LUCJ) בהשראת כימיה ותואם חומרה [1]
- שלב 2: אופטימיזציה לחומרת היעד
- אופטימיזציה של ספירת ה-Gate ופריסת ה-ansatz להרצה על חומרה
- שלב 3: הרצה על חומרת היעד
- הרצת ה-Circuit המאופטמז על QPU אמיתי ליצירת דגימות של תת-המרחב.
- שלב 4: עיבוד תוצאות לאחר ביצוע
- הצגת לולאת שחזור התצורה העצמית-עקבית [2]
- עיבוד לאחר ביצוע של כלל מחרוזות הביט, תוך שימוש בידע מוקדם על מספר החלקי קים ותפוסת האורביטל הממוצעת המחושבת בסבב האחרון.
- יצירה הסתברותית של אצוות תת-דגימות ממחרוזות הביט ששוחזרו.
- הטלה ואלכסון של ההמילטוניאן המולקולרי על כל תת-מרחב דגוּם.
- שמירת אנרגיית מצב הבסיס המינימלית שנמצאה בכל האצוות ועדכון תפוסת האורביטל הממוצעת.
- הצגת לולאת שחזור התצורה העצמית-עקבית [2]
נשתמש במספר חבילות תוכנה לאורך השיעור.
PySCFלהגדרת המולקולה והכנת ההמילטוניאן.- חבילת
ffsimלבניית ה-ansatz של LUCJ. Qiskitלטרנספילציה של ה-ansatz להרצה על חומרה.Qiskit IBM Runtimeלהרצת ה-Circuit על QPU ואיסוף דגימות.Qiskit addon SQDלשחזור תצורה ואמידת אנרגיית מצב הבסיס באמצעות הטלת תת-מרחב ואלכסון מטריצות.
1. מיפוי הבעיה ל-Circuit קוונטיים ואופרטורים
המילטוניאן מולקולרי
המילטוניאן מולקולרי לוקח את הצורה הכללית:
/ הם אופרטורי היצירה/השמדה הפרמיונ יים המשויכים לאלמנט ה- של קבוצת הבסיס ולספין . ו- הם האינטגרלים האלקטרוניים חד-גופניים ודו-גופניים. באמצעות pySCF נגדיר את המולקולה ונחשב את האינטגרלים חד-הגוף ודו-הגוף של ההמילטוניאן עבור קבוצת הבסיס 6-31g.
# Added by doQumentation — required packages for this notebook
!pip install -q ffsim matplotlib numpy pyscf qiskit qiskit-addon-sqd qiskit-ibm-runtime
import warnings
import pyscf
import pyscf.cc
import pyscf.mcscf
warnings.filterwarnings("ignore")
# Specify molecule properties
open_shell = False
spin_sq = 0
# Build N2 molecule
mol = pyscf.gto.Mole()
mol.build(
atom=[["N", (0, 0, 0)], ["N", (1.0, 0, 0)]], # Two N atoms 1 angstrom apart
basis="6-31g",
symmetry="Dooh",
)
# Define active space
n_frozen = 2
active_space = range(n_frozen, mol.nao_nr())
# Get molecular integrals
scf = pyscf.scf.RHF(mol).run()
num_orbitals = len(active_space)
n_electrons = int(sum(scf.mo_occ[active_space]))
num_elec_a = (n_electrons + mol.spin) // 2
num_elec_b = (n_electrons - mol.spin) // 2
cas = pyscf.mcscf.CASCI(scf, num_orbitals, (num_elec_a, num_elec_b))
mo = cas.sort_mo(active_space, base=0)
hcore, nuclear_repulsion_energy = cas.get_h1cas(mo) # hcore: one-body integrals
eri = pyscf.ao2mo.restore(1, cas.get_h2cas(mo), num_orbitals) # eri: two-body integrals
# Compute exact energy for comparison
exact_energy = cas.run().e_tot
converged SCF energy = -108.835236570774
CASCI E = -109.046671778080 E(CI) = -32.8155692383188 S^2 = 0.0000000
בשיעור זה נשתמש בטרנספורמציית Jordan-Wigner (JW) כדי למפות פונקציית גל פרמיונית לפונקציית גל קוונטית, כך שניתן יהיה להכין אותה באמצעות Circuit קוונטי. טרנספורמציית JW ממפה את מרחב פוק של פרמיונים ב-M אורביטלים מרחביים אל מרחב הילברט של 2M Qubitים, כלומר, אורביטל מרחבי מפוצל לשני אורביטלי ספין, אחד המשויך לאלקטרון עם ספין למעלה () ואחר עם ספין למטה (). אורביטל ספין יכול להיות תפוס או פנוי. בדרך כלל, כשאנחנו מדברים על מספר אורביטלים, הכוונה היא למספר האורביטלים המרחביים. מספר אורביטלי הספין יהיה כפול. ב-Circuit קוונטיים, נייצג כל אורביטל ספין באמצעות Qubit אחד. כך, קבוצה אחת של Qubitים תייצג אורביטלי ספין-למעלה או , וקבוצה אחרת תייצג אורביטלי ספין-למטה או . למשל, מולקולת עבור קבוצת בסיס 6-31g מכילה אורביטלים מרחביים (כלומר, + = אורביטלי ספין). לפיכך, נזדקק ל-Circuit קוונטי של Qubitים (ייתכן שנזדקק ל-Qubitי עזר נוספים כפי שיידון בהמשך). ה-Qubitים נמדדים בבסיס חישובי כדי לייצר מחרוזות ביט, המייצגות תצורות אלקטרוניות או דטרמיננטים (של סלייטר). לאורך שיעור זה נשתמש במונחים מחרוזות ביט, תצורות ודטרמיננטים לסירוגין. מחרוזות הביט מספרות לנו על תפוסת האלקטרונים באורביטלי הספין: במיקום ביט מסוים פירושו שאורביטל הספין המתאים תפוס, ו- פירושו שהוא פנוי. מכיוון שבעיות מבנה אלקטרוני שומרות על מספר חלקיקים, מספר קבוע של אורביטלי ספין חייב להיות תפוס. למולקולת יש אלקטרונים עם ספין-למעלה () ו- אלקטרונים עם ספין-למטה (). לפיכך, כל מחרוזת ביט המייצגת את האורביטלים ו- חייבת להכיל חמישה ים לכל מולקולת .
1.1 Circuit קוונטי לייצור דגימות: ה-ansatz של LUCJ
בשיעור זה נשתמש ב-ansatz של אשכול יוניטרי מקומי Jastrow (LUCJ) \[1\] להכנת מצב קוונטי ודגימה עוקבת. ראשית, נסביר את אבני הבניין השונות של ה-ansatz המלא של UCJ ואת ההפשטות שנעשו בגרסה המקומית שלו. לאחר מכן, באמצעות חבילת ffsim, נבנה את ה-ansatz של LUCJ ונמטב אותו באמצעות Transpiler של Qiskit להרצה על חומרה.
ל-ansatz של UCJ יש את הצורה הבאה (עבור מכפלה של שכבות או חזרות של אופרטור UCJ):
כאשר, הוא מצב ייחוס, שנלקח בדרך כלל כמצב Hartree-Fock (HF). מכיוון שמצב Hartree-Fock מוגדר ככזה שבו האורביטלים בעלי המספר הנמוך ביותר תפוסים, הכנת מצב HF תכלול החלת Gate X על Qubitים המתאימים לאורביטלים תפוסים. למשל, בלוק הכנת מצב HF עבור 4 אורביטלים מרחביים עם 2 אלקטרוני ספין-למעלה ו-2 ספין-למטה עשוי להיראות כך:
חזרה בודדת של אופרטור UCJ מורכבת מאבולוציית קולון אלכסונית () מוקפת בסיבובי אורביטלים ( ו-).
בלוקי סיבוב האורביטלים פועלים על מין ספין יחיד ( (ספין-למעלה)/ (ספין-למטה)). עבור כל מין אלקטרוני, סיבוב האורביטל מורכב משכבת Gate חד-Qubit אחת, ולאחריה סדרה של Gate סיבוב גיבנס דו-Qubit ( gates).
ה-Gate דו-ה-Qubit פועלים על אורביטלי ספין סמוכים (Qubitים שכנים ביניהם), ולכן ניתן לממשם על QPU של IBM® ללא צורך ב-Gate SWAP.
ה-, המכונה גם אופרטור קולון אלכסוני, מורכב משלושה בלוקים. שניים מהם פועלים על סקטורי ספין זהים ( ו-), ואחד פועל בין שני סקטורי הספין ().
כל הבלוקים ב- מורכבים מ-Gate מספר-מספר [1]. ניתן לפרק Gate לתוך Gate ואחריו שני Gate חד-Qubit הפועלים על שני Qubitים נפרדים.
לרכיבי ספין זהה ( ו-) יש Gate בין כל הזוגות האפשריים של Qubitים. אולם, מכיוון של-QPU מוליכי-על יש קישוריות מגבילה, יש להחליף Qubitים כדי לממש Gate בין Qubitים לא-סמוכים.
למשל, נחשוב על הבלוק הבא (או ) עבור אורביטלים מרחביים. עבור קישוריות Qubit לינארית, שלושת ה-Gate האחרונים אינם מיושמים ישירות כיוון שהם פועלים בין Qubit ים לא-סמוכים (למשל, Q0 ו-Q2 אינם מחוברים ישירות). לפיכך, נזדקק ל-Gate SWAP כדי להפוך אותם לסמוכים (האיור הבא מציג דוגמה עם Gate SWAP).
לאחר מכן, ה- מממש Gate בין או רביטלים בעלי אינדקס זהה מסקטורי ספין שונים (למשל, בין ו-). באופן דומה, אם ה-Qubitים אינם פיזית סמוכים על QPU, גם Gate אלו ידרשו SWAP.
מהדיון לעיל, ה-ansatz של UCJ מתמודד עם כמה מכשולים להרצה על חומרה כיוון שהוא דורש Gate SWAP בשל אינטראקציות בין Qubitים לא-סמוכים. הגרסה המקומית של ה-ansatz של UCJ, LUCJ, מתמודדת עם אתגר זה על ידי הסרת חלק מ- מאופרטור קולון האלכסוני.
בבלוקים של אלקטרונים מאותו מין, ו-), אנחנו שומרים רק את Gate התואמים לקישוריות שכנים קרובים ומסירים Gate בין Qubitים לא-סמוכים בגרסת LUCJ. האיור הבא מציג את בלוק LUCJ לאחר הסרת ה-Gate הלא-סמוכים.
לאחר מכן, גרסת LUCJ של בלוק ה- הפועל בין מיני אלקטרונים שונים יכולה ללבוש צורות שונות בהתאם לטופולוגיית המכשיר.
גם כאן, גרסת LUCJ מסלקת Gate לא-תואמים. האיור למטה מציג וריאנטים של בלוק ה- עבור טופולוגיות Qubit שונות כולל רשת ריבועית, משושה, heavy-hex ולינארית.
- ריבועית: ניתן לקיים Gate בין כל האורביטלים ו- ללא SWAP כלשהם, ולפיכך אין צורך להסיר Gate כלשהם.
- Heavy-hex: האינטראקציות - נשמרות בין כל אורביטל עם אינדקס כפולה של (כגון ה-0, ה-4 וה-8) ומתווכות על ידי Qubit עזר, כלומר, נדרשים Qubitי עזר בין השרשראות הלינאריות המייצגות את האורביטלים ו-. סידור זה דורש מספר מוגבל של SWAP.
- משושה: כל אורביטל שני, כגון אורביטלים עם אינדקס 0, 2 ו-4, הופכים לשכנים קרובים כאשר ו- מסודרים בשתי שרשראות לינאריות סמוכות.
- לינארי: רק אורביטל אחד ואורביטל אחד מחוברים, כלומר בלוק ה- יכיל רק Gate אחד.
בעוד שהסרת Gate מה-ansatz של UCJ לבניית גרסת LUCJ הופכת אותו ליותר תואם חומרה, ה-ansatz מאבד מעט מיכולת ההבעה שלו. לפיכך, ייתכן שיידרשו יותר חזרות () של אופרטור UCJ המשונה בעת שימוש ב-ansatz של LUCJ.
1.2 אתחול ה-ansatz של LUCJ
ה-LUCJ הוא ansatz פרמטרי, ועלינו לאתחל את הפרמטרים לפני הרצה על חומרה. דרך אחת לאתחל ansatz היא באמצעות ערכי הרחבות t1 ו-t2 מהשיטה הקלאסית של אשכול מצמד בודד וכפול (CCSD), כאשר ערכי t1 הם המקדמים של אופרטורי עירור בודד וערכי t2 הם עבור אופרטורי עירור כפול.
שים לב שלמרות שאתחול ה-ansatz של LUCJ עם ערכי הרחבות t1 ו-t2 מני ב תוצאות סבירות, ייתכן שפרמטרי ה-ansatz יזדקקו לאופטימיזציה נוספת.
# Get CCSD t2 amplitudes for initializing the ansatz
ccsd = pyscf.cc.CCSD(
scf, frozen=[i for i in range(mol.nao_nr()) if i not in active_space]
)
ccsd.run()
t1 = ccsd.t1
t2 = ccsd.t2
E(CCSD) = -109.0398256929733 E_corr = -0.20458912219883
1.3 בניית ה-ansatz של LUCJ באמצעות ffsim
נשתמש בחבילת ffsim כדי ליצור ולאתחל את ה-ansatz עם ערכי הרחבות t1 ו-t2 שחושבו לעיל. מכיוון שלמולקולה שלנו יש מצב Hartree-Fock עם קליפה סגורה, נשתמש בגרסה המאוזנת-ספין של ה-ansatz של UCJ, UCJOpSpinBalanced.
מכיוון שלחומרת IBM יש טופולוגיית heavy-hex, נאמץ את התבנית zig-zag המשמשת ב-[1] ומוסברת לעיל לאינטראקציות Qubit. בתבנית זו, אורביטלים (Qubitים) עם אותו ספין מחוברים בטופולוגיית קו (עיגולים אדומים וכחולים). עקב טופולוגיית heavy-hex, לאורביטלים עם ספינים שונים יש חיבורים בין כל אורביטל רביעי, כלומר, האורביטל ה-0, ה-4, ה-8 וכן הלאה (עיגולים סגולים).

import ffsim
from qiskit import QuantumCircuit, QuantumRegister
n_reps = 2
alpha_alpha_indices = [(p, p + 1) for p in range(num_orbitals - 1)]
alpha_beta_indices = [(p, p) for p in range(0, num_orbitals, 4)]
ucj_op = ffsim.UCJOpSpinBalanced.from_t_amplitudes(
t2=t2,
t1=t1,
n_reps=n_reps,
interaction_pairs=(alpha_alpha_indices, alpha_beta_indices),
)
nelec = (num_elec_a, num_elec_b)
# create an empty quantum circuit
qubits = QuantumRegister(2 * num_orbitals, name="q")
circuit = QuantumCircuit(qubits)
# prepare Hartree-Fock state as the reference state and append it to the quantum circuit
circuit.append(ffsim.qiskit.PrepareHartreeFockJW(num_orbitals, nelec), qubits)
# apply the UCJ operator to the reference state
circuit.append(ffsim.qiskit.UCJOpSpinBalancedJW(ucj_op), qubits)
circuit.measure_all()
# circuit.decompose().draw("mpl", scale=0.5, fold=-1)
ניתן לאמטב את ה-ansatz של LUCJ עם שכבות חוזרות על ידי מיזוג בלוקים סמוכים מסוימים. נחשוב על מקרה של n_reps=2. שני בלוקי סיבוב האורביטלים האמצעיים ניתנים למיזוג לתוך בלוק סיבוב אורביטלים בודד. לחבילת ffsim יש מנהל מעבר בשם ffsim.qiskit.PRE_INIT לאופטימיזציה של ה-Circuit על ידי מיזוג בלוקים סמוכים כאלה.

2. אופטימיזציה לחומרת היעד
ראשית, אנחנו מביאים Backend לבחירתנו. נמטב את ה-Circuit שלנו עבור ה-Backend, ולאחר מכן נריץ את ה-Circuit המאופטמז על אותו Backend כדי לייצר דגימות לתת-המרחב.
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
# Use the least-busy backend or specify a quantum computer using the syntax commented out below.
backend = service.least_busy(operational=True, simulator=False)
# backend = service.backend("ibm_brisbane")
לאחר מכן, אנחנו ממליצים על השלבים הבאים לאופטימיזציה של ה-ansatz והפיכתו לתואם חומרה.
- בחירת Qubitים פיזיים (
initial_layout) מהחומרה הנבחרת התואמים את תבנית ה-zig-zag (שתי שרשראות לינאריות עם Qubit עזר ביניהן) המתוארת לעיל. פריסת Qubitים בתבנית זו מובילה ל-Circuit תואם חומרה יעיל עם פחות Gate. - יצירת מנהל מעבר שלבי באמצעות הפונקציה
generate_preset_pass_managerמ-Qiskit עם ה-backendו-initial_layoutהנבחרים. - הגדרת שלב ה-
pre_initשל מנהל המעבר השלבי ל-ffsim.qiskit.PRE_INIT. ffsim.qiskit.PRE_INITכולל מעברי Transpiler של Qiskit שמפרקים Gate לסיבובי אורביטלים ולאחר מכן ממזגים את סיבובי האורביטלים, מה שמביא לפחות Gate ב-Circuit הסופי. - הרצת מנהל המעבר על ה-Circuit שלך.
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
spin_a_layout = [0, 14, 18, 19, 20, 33, 39, 40, 41, 53, 60, 61, 62, 72, 81, 82]
spin_b_layout = [2, 3, 4, 15, 22, 23, 24, 34, 43, 44, 45, 54, 64, 65, 66, 73]
initial_layout = spin_a_layout + spin_b_layout
pass_manager = generate_preset_pass_manager(
optimization_level=3, backend=backend, initial_layout=initial_layout
)
# without PRE_INIT passes
isa_circuit = pass_manager.run(circuit)
print(f"Gate counts (w/o pre-init passes): {isa_circuit.count_ops()}")
# with PRE_INIT passes
# We will use the circuit generated by this pass manager for hardware execution
pass_manager.pre_init = ffsim.qiskit.PRE_INIT
isa_circuit = pass_manager.run(circuit)
print(f"Gate counts (w/ pre-init passes): {isa_circuit.count_ops()}")
Gate counts (w/o pre-init passes): OrderedDict({'rz': 7579, 'sx': 6106, 'ecr': 2316, 'x': 336, 'measure': 32, 'barrier': 1})
Gate counts (w/ pre-init passes): OrderedDict({'rz': 4088, 'sx': 3125, 'ecr': 1262, 'x': 201, 'measure': 32, 'barrier': 1})
3. הרצה על חומרת היעד
אחרי שאופטמנו את ה-Circuit לביצוע על חומרה, אנחנו מוכנים להריץ אותו על החומרה היעד ולאסוף דגימות לאומדן אנרגיית מצב היסוד. מכיוון שיש לנו רק Circuit אחד, נשתמש ב-מצב ביצוע Job של Qiskit Runtime ונריץ את ה-Circuit.
from qiskit_ibm_runtime import SamplerV2 as Sampler
sampler = Sampler(mode=backend)
sampler.options.dynamical_decoupling.enable = True
job = sampler.run([isa_circuit], shots=10_000) # Takes approximately 5sec of QPU time
# Run cell after IQX job completion
primitive_result = job.result()
pub_result = primitive_result[0]
counts = pub_result.data.meas.get_counts()
4. עיבוד תוצאות לאחר הריצה
את שלב העיבוד שלאחר הריצה של זרימת העבודה של SQD אפשר לסכם בעזרת הדיאגרמה הבאה.
דגימת ה-LUCJ ansatz בבסיס המחשוב יוצרת מאגר של קונפיגורציות רועשות , שמשמשות בשגרת העיבוד שלאחר הריצה. השגרה כוללת שיטה הנקראת (פרטים יידונו בהמשך) שחזור קונפיגורציות, שמתקנת קונפיגורציות עם מספר אלקטרונים שגוי בצורה הסתברותית. קונפיגורציות עם מספר אלקטרונים נכון בלבד נדגמות מחדש ומתחלקות למספר אצוות בהתבסס על תדירות ההופעה של כל קונפיגורציה ייחודית. כל אצווה של דגימות מגדירה תת-מרחב (). לאחר מכן, ה-Hamiltonian המולקולרי, , מוקרן על תת-המרחבים:
כל Hamiltonian מוקרן מוזן לפותר ערכים עצמיים, שם הוא מאלכסן כדי לחשב ערכים עצמיים ווקטורים עצמיים ולשחזור מצב עצמי. בשיעור זה אנחנו מקרינים ומאלכסנים את ה-Hamiltonian בעזרת חבילת qiskit-addon-sqd שמשתמשת בשיטת Davidson מ-PySCF לאלכסון.
לאחר מכן אנחנו אוספים את ערך הייגן הנמוך ביותר (האנרגיה) מהאצוות, ומחשבים גם תפוסת אורביטל ממוצעת, . מידע התפוסה הממוצעת משמש בשלב שחזור הקונפיגורציות לתיקון הסתברותי של קונפיגורציות רועשות.
בהמשך נסביר בפירוט את לולאת שחזור הקונפיגורציות העצמית-עקבית ונציג דוגמאות קוד קונקרטיות לביצוע השלבים שתוארו לעיל לאומדן אנרגיית מצב היסוד של ה-Hamiltonian של .
4.1 שחזור קונפיגורציות: סקירה
כל סיביה (bit) במחרוזת סיביות (Slater determinant) מייצגת אורביטל ספין. המחצית הימנית של מחרוזת הסיביות מייצגת אורביטלי ספין-עלייה, והמחצית השמאלית מייצגת אורביטלי ספין-ירידה. 1 פירושו שהאורביטל מאוכלס על ידי אלקטרון, ו-0 פירושו שהאורביטל ריק. אנחנו יודעים מראש את מספר החלקיקים הנכון (הן אלקטרוני ספין-עלייה והן אלקטרוני ספין-ירידה). נניח שיש לנו דטרמיננטה עם אלקטרונים (כלומר יש מספר של 1-ות במחרוזת) בה. מספר החלקיקים הנכון הוא . אם , אנחנו יודעים שמחרוזת הסיביות הושחתה על ידי רעש. שגרת הקונפיגורציה העצמית-עקבית מנסה לתקן את מחרוזת הסיביות על ידי היפוך סיביות בצורה הסתברותית תוך שימוש במידע תפוסת אורביטל ממוצעת. תפוסת האורביטל הממוצעת () מספרת לנו עד כמה סביר שאורביטל מסוים יהיה מאוכלס על ידי אלקטרון. אם , יש לנו פחות אלקטרונים וצריך להפוך כמה 0-ות ל-1-ות ולהיפך.
ההסתברות להיפוך יכולה להיות עבור אורביטל ספין i-תי. ב-[2], המחברים השתמשו בהסתברות היפוך משוקללת בעזרת פונקציית ReLU מותאמת.
כאן מגדיר את מיקום ה"פינה" של פונקציית ReLU, והפרמטר מגדיר את ערך פונקציית ReLU בפינה. עבור , הופכת לפונקציית ReLU אמיתית, ועבור היא הופכת ל-ReLU מותאמת. במאמר, המחברים השתמשו ב- ו- מספר חלקיקי alpha (או beta) / מספר אורביטלי ספין alpha (או beta) (גורם מילוי).
תפוסת האורביטל הממוצעת () אינה ידועה מראש. האיטרציה הראשונה של אומדן מצב היסוד מתחילה עם קונפיגורציות שיש בהן רק מספר חלקיקים נכון בשני מיני הספין. אחרי האיטרציה הראשונה יש לנו אומדן של מצב היסוד, ובעזרתו אנחנו יכולים לבנות את הניחוש הראשון של . ניחוש זה משמש לשחזור קונפיגורציות, להרצת האיטרציה הבאה של אומדן מצב היסוד, ולשיפור עצמי-עקבי של ניחוש . התהליך חוזר על עצמו עד שמתקיים קריטריון עצירה.
נשקול את הדוגמה הבאה עבור ו- (). צריך להפוך אחד מהאפסים ל-1 כדי לתקן את מספר החלקיקים, והאפשרויות הן 1100, 1010, ו-1001. בהתבסס על הסתברות ההיפוך, אחת מהאפשרויות תיבחר כ-קונפיגורציה משוחזרת (או מחרוזת הסיביות עם מספר חלקיקים נכון).
נניח שבאיטרציה הראשונה מריצים שתי אצוות, ומצבי היסוד המוערכים מהן הם:
בעזרת מצבי הבסיס החישובי ומשרעותיהם, אנחנו יכולים לחשב את ההסתברות לתפוסת אלקטרון (בקיצור תפוסות) לכל אורביטל-ספין (Qubit) (שימו לב שהסתברות = |משרעת|). להלן ריכוז תפוסות Qubit-אחד-אחד לכל מחרוזת סיביות המופיעה במצב היסוד המוערך, וחישוב תפוסת האורביטל הכוללת לאצווה. שימו לב שלפי אמנת הסדר של Qiskit, הסיביה הימנית ביותר מייצגת qubit-0 (Q0), והסיביה השמאלית ביותר מייצגת Q3.
תפוסה (Batch0):
| Q3 | Q2 | Q1 | Q0 | |
|---|---|---|---|---|
| 1001 | 0.64 | 0.0 | 0.0 | 0.64 |
| 0110 | 0.0 | 0.36 | 0.36 | 0.0 |
| n (Batch0) | 0.64 | 0.36 | 0.36 | 0.64 |
תפוסה (Batch1)
| Q3 | Q2 | Q1 | Q0 | |
|---|---|---|---|---|
| 1001 | 0.33 | 0.00 | 0.00 | 0.33 |
| 0101 | 0.0 | 0.33 | 0.00 | 0.33 |
| 0110 | 0.0 | 0.33 | 0.33 | 0.00 |
| n (Batch1) | 0.33 | 0.66 | 0.33 | 0.66 |
תפוסה (ממוצע על פני האצוות)
| Q3 | Q2 | Q1 | Q0 | |
|---|---|---|---|---|
| n (Batch0) | 0.64 | 0.36 | 0.36 | 0.64 |
| n (Batch1) | 0.33 | 0.66 | 0.33 | 0.66 |
| n (average) | 0.49 | 0.51 | 0.35 | 0.65 |
בעזרת תפוסת האורביטל הממוצעת שחושבה לעיל, אנחנו יכולים למצוא את הסתברויות ההיפוך עבור אורביטלים שונים בקונפיגורציה . מכיוון שהאורביטל המיוצג על ידי Q3 כבר מאוכלס ואינו צריך היפוך, קובעים שה-p(flip) שלו הוא . לשאר האורביטלים, שאינם מאוכלסים, הסתברות ההיפוך היא כל אחד. לצד p(flip), אנחנו גם מחשבים את משקל ההסתברות הקשור להיפוך בעזרת פונקציית ReLU המותאמת המתוארת לעיל.
הסתברות היפוך (, , )
| Q3 | Q2 | Q1 | Q0 | |
|---|---|---|---|---|
| p(flip) () | 0 | 0.51 | 0.35 | 0.65 |
| w(p(flip)) | 0 | 0.03 | 0.007 | 0.31 |
לבסוף, בעזרת ההסתברויות המשוקללות שלעיל, אנחנו יכולים להפוך אחד מהאורביטלים הלא-מאוכלסים Q2, Q1, ו-Q0. בהתבסס על הערכים לעיל, Q0 ייהפך ברוב הסיכויים, וקונפיגורציה משוחזרת אפשרית יכולה להיות .
את תהליך שחזור הקונפיגורציות העצמי-עקבי המלא אפשר לסכם כך:
איטרציה ראשונה: נניח שמחרוזות הסיביות (קונפיגורציות או Slater determinants) שנוצרו על ידי המחשב הקוונטי מרכיבות קבוצה , שכוללת הן קונפיגורציות עם מספר חלקיקים נכון () והן עם מספר שגוי () בכל ענף ספין.
- קונפיגורציות מ-() נדגמות באקראי ליצירת אצוות של וקטורים להקרנה לתת-מרחב. מספר האצוות ומספר הדגימות בכל אצווה הם פרמטרים שמוגדרים על ידי המשתמש. ככל שמספר הדגימות בכל אצווה גדול יותר, כך ממד תת-המרחב גדול יותר והאלכסון דורש יותר משאבי חישוב קלאסי. מצד שני, מספר דגימות קטן מדי עלול להחמיץ וקטורי תמיכה של מצב היסוד ולהוביל לאומדן שגוי.
- מריצים את פותר הייגן-מצב (כלומר הקרנה לתת-מרחב ואלכסון) על האצוות ומקבלים מצבים עצמיים מקורבים. .
- מהמצבים העצמיים המקורבים בונים את הניחוש הראשון של .
איטרציות עוקבות:
- בעזרת מתקנים את הקונפיגורציות עם מספר חלקיקים שגוי ב-. נניח שנקרא להן . אז, מרכיבה את הקבוצה החדשה של קונפיגורציות עם מספר חלקיקים נכון.
- נדגמת ליצירת אצוות .
- פותר הייגן-מצב רץ עם האצוות החדשות ומייצר אומדנים חדשים למצבי היסוד