Pahami opsi open-shell versus closed-shell dan pengaruhnya terhadap konstruksi subruang
Di panduan ini, kita akan tunjukkan cara memilih dimensi subruang di paket qiskit_addon_sqd untuk pasca-proses sampel kuantum memakai teknik pemulihan konfigurasi self-consistent.
Yang lebih penting, panduan ini juga menyoroti beberapa perbedaan perilaku konstruksi subruang saat dijalankan dalam mode open_shell = False atau open_shell = True:
-
open_shell = Falsehanya bekerja jika jumlah elektron spin-up dan spin-down sama. -
open_shell = Trueharus dipakai jika jumlah elektron spin-up dan spin-down berbeda. Mode ini juga bisa dipakai jika jumlah elektron spin-up dan spin-down sama. Namun, pada kasus terakhir ini, ukuran subruang yang dihasilkan berbeda antaraopen_shell = Falsedanopen_shell = True, seperti dibahas di panduan ini.
CATATAN: Beberapa manipulasi konfigurasi elektronik (bitstring) di paket ini bertujuan menjaga simetri spin total . Solver Selected Configuration Interaction (SCI) standar tidak bisa memaksakan kekekalan secara eksak. Akibatnya, mereka melakukannya secara aproksimasi lewat pengali Lagrange.
Pilihan konfigurasi elektronik yang masuk ke eigenstate solver juga bisa sangat memengaruhi kekekalan spin. Misalnya, pada sistem (2 elektron, 2 orbital), kita bisa mensampel konfigurasi (yang punya satu eksitasi spin-up dari keadaan RHF ), yang merupakan kombinasi linear dari keadaan singlet dan triplet open-shell, masing-masing . Jika konfigurasi |0110⟩ tidak disampel, kita tidak bisa membangun eigenfunction spin total mana pun, sehingga terjadi kontaminasi spin atau redundansi (konfigurasi |1001⟩ ikut dalam perhitungan CI, tetapi punya koefisien 0 di vektor CI). Jika hanya satu sampel yang dihasilkan di komputer kuantum, beginilah cara paket sqd menangani situasi ini:
-
open_shell = False:-
Bitstring dibelah dua, mewakili konfigurasi spin-up dan spin-down: (up) dan (down).
-
Daftar konfigurasi terpolarisasi-spin yang unik dibentuk: .
-
Lalu kita pertimbangkan semua kombinasi yang mungkin dari elemen untuk membentuk basis: , yang memuat keadaan singlet dan triplet.
-
-
open_shell = True:- Berbeda dengan kasus
open_shell = False, kita tidak menggabungkan kedua belahan bitstring untuk membentuk basis.
- Berbeda dengan kasus
Kulit tertutup
Contoh ini menunjukkan cara bitstring dimanipulasi pada sistem (2 elektron, 4 orbital).
# 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
Tentukan secara manual sebuah dictionary berisi hasil pengukuran:
counts_dict = {
"00010010": 1 / 2.0 - 0.01,
"01001000": 1 / 2.0 - 0.01,
"00010001": 0.02,
}
Ubah dict counts menjadi matriks bitstring dan array probabilitas untuk pasca-proses:
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]
Subsampling satu batch berukuran dua:
-
n_batches = 1: Jumlah batch konfigurasi yang dipakai oleh berbagai panggilan ke eigenstate solver -
samples_per_batch = 2: Jumlah konfigurasi unik yang disertakan di setiap batch
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]]
Dapatkan representasi desimal dari bitstring spin-up dan spin-down yang dipakai oleh eigenstate solver.
Elemen pertama dalam tuple sesuai dengan representasi desimal dari konfigurasi spin-up, sedangkan elemen kedua dalam tuple sesuai dengan representasi desimal dari konfigurasi spin-down:
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))
Perhatikan bahwa meski jumlah sampel per batch adalah dua, dan bitstring yang disampel adalah dan , empat konfigurasi elektronik dihasilkan per spesies spin. Dalam kasus ini, himpunan konfigurasi terpolarisasi-spin yang unik adalah:
dengan representasi desimal basis-10
Basis dari subruang:
Eigenstate solver mengambil semua pasangan mungkin dari bitstring spin-up dan spin-down untuk membangun basis dari subruang:
-
Elemen 1:
-
Elemen 2:
-
Elemen 3:
-
Elemen 4:
-
Elemen 5:
-
Elemen 6:
-
Elemen 7:
-
Elemen 8:
-
Elemen 9:
-
Elemen 10:
-
Elemen 11:
-
Elemen 12:
-
Elemen 13:
-
Elemen 14:
-
Elemen 15:
-
Elemen 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>
Dimensi subruang dibatasi dari atas oleh: (samples_per_batch).
Kulit terbuka
Contoh ini menunjukkan cara bitstring dimanipulasi pada sistem (2 elektron, 4 orbital).
# Specify molecule properties
num_orbitals = 4
num_elec_a = num_elec_b = 1
open_shell = True
Tentukan secara manual sebuah dictionary berisi hasil pengukuran:
counts_dict = {
"00010010": 1 / 2.0 - 0.01,
"01001000": 1 / 2.0 - 0.01,
"00010001": 0.02,
}
Ubah dict counts menjadi matriks bitstring dan array probabilitas untuk pasca-proses:
# 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]
Subsampling satu batch berukuran dua:
-
n_batches = 1: Jumlah batch konfigurasi yang dipakai oleh berbagai panggilan ke eigenstate solver -
samples_per_batch = 2: Jumlah konfigurasi unik yang disertakan di setiap batch
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]]
Dapatkan representasi desimal dari bitstring spin-up dan spin-down yang dipakai oleh eigenstate solver.
Elemen pertama dalam tuple sesuai dengan representasi desimal dari konfigurasi spin-up, sedangkan elemen kedua dalam tuple sesuai dengan representasi desimal dari konfigurasi spin-down:
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))
Jika kita menetapkan open_shell = True, kita tidak menyertakan semua bitstring setengah yang unik sebagai konfigurasi spin-up dan spin-down, sehingga basisnya lebih kecil daripada saat menetapkan open_shell = False.
Basis dari subruang:
Eigenstate solver mengambil semua pasangan mungkin dari bitstring spin-up dan spin-down untuk membangun basis dari subruang:
-
Elemen 1:
-
Elemen 2:
-
Elemen 3:
-
Elemen 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>
Dimensi subruang dibatasi dari atas oleh: (samples_per_batch).