הבנת האפשרויות של קליפה פתוחה לעומת קליפה סגורה וההשפעה על בניית תת-המרחב
במדריך הזה נראה איך לבחור ממדים של תת-מרחבים בחבילה qiskit_addon_sqd כדי לעבד לאחר מכן דגימות קוונטיות בעזרת טכניקת שחזור הקונפיגורציות העקבית-עצמית.
חשוב מזה, המדריך הזה גם מדגיש כמה הבדלים בהתנהגות של בניית תת-המרחב כשרצים במצב open_shell = False או open_shell = True:
-
open_shell = Falseעובד רק כשמספר אלקטרוני הספין-למעלה והספין-למטה זהה. -
חובה להשתמש ב-
open_shell = Trueכשמספר אלקטרוני הספין-למעלה והספין-למטה שונה. אפשר להשתמש בו גם כשהמספר זהה. עם זאת, במקרה האחרון הזה יש הבדל בגדלים של תת-המרחבים שנוצרים ביןopen_shell = Falseל-open_shell = True, כפי שנדון במדריך הזה.
הערה: חלק מהמניפולציות של קונפיגורציות אלקטרוניות (מחרוזות ביטים) בחבילה הזו נועדו לשמר את סימטריית הספין הכולל . פותרי Selected Configuration Interaction (SCI) רגילים אינם יכולים לכפות שימור של באופן מדויק. לכן הם עושים זאת באופן מקורב באמצעות כופל לגראנז'.
גם לבחירת הקונפיגורציות האלקטרוניות שנכנסות לפותר המצבים העצמיים יכולה להיות השפעה חזקה על שימור הספין. לדוגמה, במערכת של (2 אלקטרונים, 2 אורביטלים) אפשר לדגום את הקונפיגורציה (שיש בה עירור יחיד של ספין-למעלה מעל מצב RHF ), שהיא צירוף לינארי של מצב הסינגלט ומצב הטריפלט של קליפה פתוחה, בהתאמה . אם הקונפיגורציה |0110⟩ לא נדגמת, אי אפשר לבנות אף אחת מפונקציות העצמיות של הספין הכולל, וזה מוביל לזיהום ספין או ליתירות (הקונפיגורציה |1001⟩ משתתפת בחישוב CI, אבל המקדם שלה בוקטור ה-CI הוא 0). בהינתן שדגימה בודדת נוצרת במחשב הקוונטי, כך החבילה sqd מטפלת במצב הזה:
-
open_shell = False:-
מחרוזת הביטים מפוצלת לשני חצאים, שמייצגים קונפיגורציות ספין-למעלה וספין-למטה: (למעלה) ו- (למטה).
-
נבנית רשימה של קונפיגורציות מקוטבות-ספין ייחודיות: .
-
לאחר מכן אנחנו שוקלים את כל הצירופים האפשריים של אברי כדי ליצור את הבסיס: , שמכיל את מצבי הסינגלט והטריפלט.
-
-
open_shell = True:- בניגוד למקרה של
open_shell = False, אנחנו לא משלבים את חצאי מחרוזת הביטים כדי ליצור את הבסיס.
- בניגוד למקרה של
קליפה סגורה
הדוגמה הזו מראה איך מחרוזות הביטים עוברות מניפולציה במערכת של (2 אלקטרונים, 4 אורביטלים).
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"qiskit_addon_sqd": "qiskit-addon-sqd"}
_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")
# Specify molecule properties
num_orbitals = 4
num_elec_a = num_elec_b = 1
open_shell = False
נציין ידנית מילון של תוצאות מדידה:
counts_dict = {
"00010010": 1 / 2.0 - 0.01,
"01001000": 1 / 2.0 - 0.01,
"00010001": 0.02,
}
נהפוך את ה-dict של הספירות למטריצת מחרוזות ביטים ולמערך הסתברויות לעיבוד לאחר:
from qiskit_addon_sqd.counts import counts_to_arrays
# Convert counts into bitstring and probability arrays
bitstring_matrix_full, probs_arr_full = counts_to_arrays(counts_dict)
print(bitstring_matrix_full)
print(probs_arr_full)
[[False False False True False False True False]
[False True False False True False False False]
[False False False True False False False True]]
[0.49 0.49 0.02]
נדגום תת-קבוצה של אצווה אחת בגודל שניים:
-
n_batches = 1: מספר האצוות של קונפיגורציות שבהן משתמשות הקריאות השונות לפותר המצבים העצמיים -
samples_per_batch = 2: מספר הקונפיגורציות הייחודיות שייכללו בכל אצווה
from qiskit_addon_sqd.subsampling import (
postselect_by_hamming_right_and_left,
subsample,
)
n_batches = 1
samples_per_batch = 2
# seed for random number generator
rand_seed = 48
# Post-select the configurations with the correct Hamming weight on each half
bitstring_matrix_postsel, probs_arr_postsel = (
postselect_by_hamming_right_and_left(
bitstring_matrix_full,
probs_arr_full,
hamming_right=num_elec_a,
hamming_left=num_elec_b,
)
)
# Generate the batches
batches = subsample(
bitstring_matrix_postsel,
probs_arr_postsel,
samples_per_batch,
n_batches,
rand_seed=rand_seed,
)
print(batches[0])
[[False False False True False False True False]
[False True False False True False False False]]
נקבל את הייצוג העשרוני של מחרוזות הביטים של ספין-למעלה וספין-למטה שבהן משתמש פותר המצבים העצמיים.
האיבר הראשון בצמד מתאים לייצוג העשרוני של קונפיגורציות ספין-למעלה, והאיבר השני בצמד מתאים לייצוג העשרוני של קונפיגורציות ספין-למטה:
from qiskit_addon_sqd.fermion import bitstring_matrix_to_ci_strs
ci_strs = bitstring_matrix_to_ci_strs(batches[0], open_shell=open_shell)
print(ci_strs)
(array([1, 2, 4, 8], dtype=int64), array([1, 2, 4, 8], dtype=int64))
שימו לב שמספר הדגימות בכל אצווה הוא שתיים, ומחרוזות הביטים שנדגמו הן: ו-, ובכל זאת נוצרות ארבע קונפיגורציות אלקטרוניות לכל סוג ספין. במקרה הזה, קבוצת הקונפיגורציות המקוטבות-ספין הייחודיות היא:
והייצוג העשרוני שלה בבסיס 10 הוא
הבסיס של תת-המרחב:
פותר המצבים העצמיים לוקח את כל הזוגות האפשריים של מחרוזות ביטים של ספין-למעלה וספין-למטה כדי לבנות את הבסיס של תת-המרחב:
-
איבר 1:
-
איבר 2:
-
איבר 3:
-
איבר 4:
-
איבר 5:
-
איבר 6:
-
איבר 7:
-
איבר 8:
-
איבר 9:
-
איבר 10:
-
איבר 11:
-
איבר 12:
-
איבר 13:
-
איבר 14:
-
איבר 15:
-
איבר 16:
ci_strs_up, ci_strs_dn = ci_strs
print("Basis elements of the subspace:")
for ci_str_up in ci_strs_up:
for ci_str_dn in ci_strs_dn:
format_name = "{0:0" + str(num_orbitals) + "b}"
print(
"|"
+ format_name.format(ci_str_up)
+ format_name.format(ci_str_dn)
+ ">"
)
Basis elements of the subspace:
|00010001>
|00010010>
|00010100>
|00011000>
|00100001>
|00100010>
|00100100>
|00101000>
|01000001>
|01000010>
|01000100>
|01001000>
|10000001>
|10000010>
|10000100>
|10001000>
ממד תת-המרחב חסום מלמעלה על ידי: (samples_per_batch).
קליפה פתוחה
הדוגמה הזו מראה איך מחרוזות הביטים עוברות מניפולציה במערכת של (2 אלקטרונים, 4 אורביטלים).
# Specify molecule properties
num_orbitals = 4
num_elec_a = num_elec_b = 1
open_shell = True
נציין ידנית מילון של תוצאות מדידה:
counts_dict = {
"00010010": 1 / 2.0 - 0.01,
"01001000": 1 / 2.0 - 0.01,
"00010001": 0.02,
}
נהפוך את ה-dict של הספירות למטריצת מחרוזות ביטים ולמערך הסתברויות לעיבוד לאחר:
# Convert counts into bitstring and probability arrays
bitstring_matrix_full, probs_arr_full = counts_to_arrays(counts_dict)
print(bitstring_matrix_full)
print(probs_arr_full)
[[False False False True False False True False]
[False True False False True False False False]
[False False False True False False False True]]
[0.49 0.49 0.02]
נדגום תת-קבוצה של אצווה אחת בגודל שניים:
-
n_batches = 1: מספר האצוות של קונפיגורציות שבהן משתמשות הקריאות השונות לפותר המצבים העצמיים -
samples_per_batch = 2: מספר הקונפיגורציות הייחודיות שייכללו בכל אצווה
n_batches = 1
samples_per_batch = 2
# seed for random number generator
rand_seed = 48
# Post-select the configurations with the correct Hamming weight on each half
bitstring_matrix_postsel, probs_arr_postsel = (
postselect_by_hamming_right_and_left(
bitstring_matrix_full,
probs_arr_full,
hamming_right=num_elec_a,
hamming_left=num_elec_b,
)
)
# Generate the batches
batches = subsample(
bitstring_matrix_postsel,
probs_arr_postsel,
samples_per_batch,
n_batches,
rand_seed=rand_seed,
)
print(batches[0])
[[False False False True False False True False]
[False True False False True False False False]]
נקבל את הייצוג העשרוני של מחרוזות הביטים של ספין-למעלה וספין-למטה שבהן משתמש פותר המצבים העצמיים.
האיבר הראשון בצמד מתאים לייצוג העשרוני של קונפיגורציות ספין-למעלה, והאיבר השני בצמד מתאים לייצוג העשרוני של קונפיגורציות ספין-למטה:
ci_strs = bitstring_matrix_to_ci_strs(batches[0], open_shell=open_shell)
print(ci_strs)
(array([2, 8], dtype=int64), array([1, 4], dtype=int64))
אם נציין open_shell = True, אנחנו לא כוללים את כל חצאי מחרוזות הביטים הייחודיים כקונפיגורציות ספין-למעלה וספין-למטה, ולכן מתקבל בסיס קטן יותר מאשר כשמציינים open_shell = False.
הבסיס של תת-המרחב:
פותר המצבים העצמיים לוקח את כל הזוגות האפשריים של מחרוזות ביטים של ספין-למעלה וספין-למטה כדי לבנות את הבסיס של תת-המרחב:
-
איבר 1:
-
איבר 2:
-
איבר 3:
-
איבר 4:
ci_strs_up, ci_strs_dn = ci_strs
print("Basis elements of the subspace:")
for ci_str_up in ci_strs_up:
for ci_str_dn in ci_strs_dn:
format_name = "{0:0" + str(num_orbitals) + "b}"
print(
"|"
+ format_name.format(ci_str_up)
+ format_name.format(ci_str_dn)
+ ">"
)
Basis elements of the subspace:
|00100001>
|00100100>
|10000001>
|10000100>
ממד תת-המרחב חסום מלמעלה על ידי: (samples_per_batch).