فهم خيارات القشرة المفتوحة مقابل القشرة المغلقة وتأثيرها على بناء الفضاء الجزئي
في هذا الدليل، سنوضح كيفية اختيار أبعاد الفضاء الجزئي في حزمة qiskit_addon_sqd لمعالجة العيّنات الكمّية لاحقًا باستخدام تقنية استعادة التكوين ذاتية الاتساق.
والأهم من ذلك، يسلّط هذا الدليل الضوء أيضًا على بعض الاختلافات في سلوك بناء الفضاء الجزئي عند التشغيل في وضع open_shell = False أو open_shell = True:
-
open_shell = Falseيعمل فقط عندما يكون عدد الإلكترونات ذات السبين الأعلى والأدنى متساويًا. -
يجب استخدام
open_shell = Trueعندما يكون عدد الإلكترونات ذات السبين الأعلى والأدنى مختلفًا. ويمكن استخدامه أيضًا عندما يكون العددان متساويين. ومع ذلك، في هذه الحالة الأخيرة، هناك فرق في أحجام الفضاءات الجزئية المتولّدة بينopen_shell = Falseوopen_shell = True، كما نناقش في هذا الدليل.
ملاحظة: بعض معالجات التكوينات الإلكترونية (سلاسل البتات) في هذه الحزمة هدفها الحفاظ على تناظر السبين الكلي . لا تستطيع حلّالات التفاعل الاعتباري للتكوينات المختارة (SCI) القياسية فرض حفظ بدقة. وبالتالي، تفعل ذلك تقريبيًا عبر مضروب لاغرانج.
يمكن أن يكون لاختيار التكوينات الإلكترونية الداخلة إلى حلّال الحالات الذاتية أثر كبير أيضًا في حفظ السبين. فمثلًا، في نظام (إلكترونان، مداران)، يمكن أخذ عيّنة للتكوين (الذي له إثارة واحدة بسبين أعلى فوق حالة RHF )، وهو تركيبة خطية من الحالتين المفردة والثلاثية ذواتَي القشرة المفتوحة، وهما على التوالي . وإذا لم تؤخذ عيّنة للتكوين |0110⟩، فلا يمكن بناء أي من الدالتين الذاتيتين للسبين الكلي، مما يؤدي إلى تلوّث السبين أو التكرار الزائد (التكوين |1001⟩ مشارك في حساب CI، لكن معامله في متجه CI يساوي 0). وبافتراض توليد عيّنة واحدة في الحاسوب الكمّي، فهكذا تتعامل حزمة sqd مع هذه الحالة:
-
open_shell = False:-
تُقسَّم سلسلة البتات إلى نصفين، يمثلان تكوينَي السبين الأعلى والأدنى: (أعلى) و (أدنى).
-
تُبنى قائمة التكوينات الفريدة المستقطبة بالسبين: .
-
ثم نعتبر جميع التركيبات الممكنة لعناصر لتشكيل الأساس: ، الذي يحتوي على الحالتين المفردة والثلاثية.
-
-
open_shell = True:- على خلاف حالة
open_shell = False، لا ندمج نصفَي سلسلة البتات لتشكيل الأساس.
- على خلاف حالة
القشرة المغلقة
يوضح هذا المثال كيفية معالجة سلاسل البتات في نظام (إلكترونان، 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]]
احصل على التمثيل العشري لسلاسل بتات السبين الأعلى والسبين الأدنى التي يستخدمها حلّال الحالات الذاتية.
العنصر الأول في الصف (tuple) يمثّل التمثيل العشري لتكوينات السبين الأعلى، بينما يمثّل العنصر الثاني التمثيل العشري لتكوينات السبين الأدنى:
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).
القشرة المفتوحة
يوضح هذا المثال كيفية معالجة سلاسل البتات في نظام (إلكترونان، 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]]
احصل على التمثيل العشري لسلاسل بتات السبين الأعلى والسبين الأدنى التي يستخدمها حلّال الحالات الذاتية.
العنصر الأول في الصف (tuple) يمثّل التمثيل العشري لتكوينات السبين الأعلى، بينما يمثّل العنصر الثاني التمثيل العشري لتكوينات السبين الأدنى:
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).