Porozumění možnostem otevřených versus uzavřených slupek a jejich vlivu na konstrukci podprostoru
V tomto návodu ukážeme, jak v balíčku qiskit_addon_sqd zvolit dimenze podprostorů pro následné zpracování kvantových vzorků pomocí techniky self-consistent configuration recovery.
Co je důležitější, tento návod také zdůrazňuje některé rozdíly v chování při konstrukci podprostoru v režimech open_shell = False a open_shell = True:
-
open_shell = Falsefunguje pouze tehdy, když je počet elektronů se spinem nahoru a dolů stejný. -
open_shell = Truese musí použít, když je počet elektronů se spinem nahoru a dolů různý. Lze jej použít i tehdy, když je počet elektronů se spinem nahoru a dolů stejný. V tomto posledním případě se však velikosti generovaných podprostorů meziopen_shell = Falseaopen_shell = Trueliší, jak je popsáno v tomto návodu.
POZNÁMKA: Některé manipulace s elektronovými konfiguracemi (bitovými řetězci) v tomto balíčku mají za cíl zachovat celkovou spinovou symetrii . Standardní řešiče Selected Configuration Interaction (SCI) nedokážou zachování vynutit přesně. V důsledku toho to provádějí přibližně pomocí Lagrangeova multiplikátoru.
Volba elektronových konfigurací vstupujících do řešiče vlastních stavů může mít také silný vliv na zachování spinu. Například v systému (2 elektrony, 2 orbitaly) lze vzorkovat konfiguraci (s jednou excitací spinu nahoru nad stavem RHF ), která je lineární kombinací singletového a tripletového stavu s otevřenou slupkou, tedy . Pokud konfigurace |0110⟩ není vzorkována, nelze sestavit ani jednu vlastní funkci celkového spinu, což vede ke spinové kontaminaci nebo redundanci (konfigurace |1001⟩ vstupuje do výpočtu CI, ale má v CI vektoru koeficient 0). Vzhledem k tomu, že kvantový počítač vygeneruje jediný vzorek , balíček sqd tuto situaci řeší takto:
-
open_shell = False:-
Bitový řetězec se rozdělí na poloviny, které představují konfigurace se spinem nahoru a dolů: (nahoru) a (dolů).
-
Sestaví se seznam jedinečných spinově polarizovaných konfigurací: .
-
Poté uvažujeme všechny možné kombinace prvků pro vytvoření báze: , která obsahuje singletový i tripletový stav.
-
-
open_shell = True:- Na rozdíl od případu
open_shell = Falsenekombinujeme poloviny bitového řetězce pro vytvoření báze.
- Na rozdíl od případu
Uzavřené slupky
Tento příklad ukazuje, jak se manipuluje s bitovými řetězci v systému (2 elektrony, 4 orbitaly).
# 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
Ručně zadej slovník výsledků měření:
counts_dict = {
"00010010": 1 / 2.0 - 0.01,
"01001000": 1 / 2.0 - 0.01,
"00010001": 0.02,
}
Převeď počty dict na matici bitových řetězců a pole pravděpodobností pro následné zpracování:
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]
Vyber podvzorek jediné dávky o velikosti dva:
-
n_batches = 1: Počet dávek konfigurací používaných různými voláními řešiče vlastních stavů -
samples_per_batch = 2: Počet jedinečných konfigurací zahrnutých do každé dávky
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]]
Získej desítkovou reprezentaci bitových řetězců se spinem nahoru a dolů používaných řešičem vlastních stavů.
První prvek n-tice odpovídá desítkové reprezentaci konfigurací se spinem nahoru, zatímco druhý prvek n-tice odpovídá desítkové reprezentaci konfigurací se spinem dolů:
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))
Všimni si, že ačkoli je počet vzorků na dávku dva a vzorkované bitové řetězce jsou a , pro každý druh spinu se generují čtyři elektronové konfigurace. V tomto případě je množina jedinečných spinově polarizovaných konfigurací dána:
jejíž desítková reprezentace je
Báze podprostoru:
Řešič vlastních stavů bere všechny možné dvojice bitových řetězců se spinem nahoru a dolů, aby sestavil bázi podprostoru:
-
Prvek 1:
-
Prvek 2:
-
Prvek 3:
-
Prvek 4:
-
Prvek 5:
-
Prvek 6:
-
Prvek 7:
-
Prvek 8:
-
Prvek 9:
-
Prvek 10:
-
Prvek 11:
-
Prvek 12:
-
Prvek 13:
-
Prvek 14:
-
Prvek 15:
-
Prvek 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>
Dimenze podprostoru je shora omezena hodnotou: (samples_per_batch).
Otevřené slupky
Tento příklad ukazuje, jak se manipuluje s bitovými řetězci v systému (2 elektrony, 4 orbitaly).
# Specify molecule properties
num_orbitals = 4
num_elec_a = num_elec_b = 1
open_shell = True
Ručně zadej slovník výsledků měření:
counts_dict = {
"00010010": 1 / 2.0 - 0.01,
"01001000": 1 / 2.0 - 0.01,
"00010001": 0.02,
}
Převeď počty dict na matici bitových řetězců a pole pravděpodobností pro následné zpracování:
# 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]
Vyber podvzorek jediné dávky o velikosti dva:
-
n_batches = 1: Počet dávek konfigurací používaných různými voláními řešiče vlastních stavů -
samples_per_batch = 2: Počet jedinečných konfigurací zahrnutých do každé dávky
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]]
Získej desítkovou reprezentaci bitových řetězců se spinem nahoru a dolů používaných řešičem vlastních stavů.
První prvek n-tice odpovídá desítkové reprezentaci konfigurací se spinem nahoru, zatímco druhý prvek n-tice odpovídá desítkové reprezentaci konfigurací se spinem dolů:
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))
Pokud zadáme open_shell = True, nezahrneme všechny jedinečné poloviční bitové řetězce jako konfigurace se spinem nahoru a dolů, a získáme tak menší bázi než při zadání open_shell = False.
Báze podprostoru:
Řešič vlastních stavů bere všechny možné dvojice bitových řetězců se spinem nahoru a dolů, aby sestavil bázi podprostoru:
-
Prvek 1:
-
Prvek 2:
-
Prvek 3:
-
Prvek 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>
Dimenze podprostoru je shora omezena hodnotou: (samples_per_batch).