Sari la conținutul principal
Acest proiect este în versiune beta. Ai găsit o eroare? Deschide un issue pe GitHub. Ai o întrebare sau o idee? Întreabă în Discussions — ne-ar plăcea să aflăm părerea ta!
Cum este calitatea traducerii pe această pagină?

Înțelege opțiunile pentru strat deschis versus strat închis și efectul asupra construcției subspațiului

În acest ghid vom arăta cum să alegi dimensiunile subspațiului în pachetul qiskit_addon_sqd pentru a post-procesa eșantioane cuantice folosind tehnica de recuperare auto-consistentă a configurațiilor.

Mai important, acest ghid evidențiază și unele diferențe de comportament în construcția subspațiului atunci când se rulează în modurile open_shell = False sau open_shell = True:

  • open_shell = False funcționează doar când numărul de electroni cu spin în sus și cu spin în jos este același.

  • open_shell = True trebuie folosit când numărul de electroni cu spin în sus și cu spin în jos este diferit. Poate fi folosit și când numărul de electroni cu spin în sus și cu spin în jos este același. Totuși, în acest ultim caz, există o diferență între dimensiunile subspațiilor generate de open_shell = False și open_shell = True, după cum se discută în acest ghid.

NOTĂ: Unele dintre manipulările configurațiilor electronice (șiruri de biți) din acest pachet au ca scop păstrarea simetriei de spin total S2S^2. Solverele standard de Interacțiune de Configurații Selectate (SCI) nu pot impune exact conservarea lui S2S^2. În consecință, o fac aproximativ printr-un multiplicator Lagrange.

Alegerea configurațiilor electronice care intră în solverul de stări proprii poate avea, de asemenea, un efect puternic asupra conservării spinului. De exemplu, într-un sistem (2 electroni, 2 orbitali), se poate eșantiona configurația ∣1001⟩|1001\rangle (având o singură excitație cu spin în sus peste starea RHF ∣0101⟩|0101\rangle), care este o combinație liniară a stărilor singlet și triplet cu strat deschis, respectiv (∣1001⟩±∣0110⟩)/2(|1001\rangle ± |0110\rangle) /\sqrt{2}. Dacă configurația |0110⟩ nu este eșantionată, nu se poate construi nici una dintre funcțiile proprii de spin total, ceea ce duce la contaminare de spin sau redundanță (configurația |1001⟩ este implicată într-un calcul CI, dar are coeficientul 0 în vectorul CI). Dat fiind că în computerul cuantic se generează un singur eșantion ∣1001⟩|1001\rangle, iată cum gestionează pachetul sqd această situație:

  • open_shell = False:

    1. Șirul de biți 10011001 este împărțit în jumătate, reprezentând configurațiile cu spin în sus și cu spin în jos: 1010 (sus) și 0101 (jos).

    2. Se construiește lista configurațiilor unice polarizate în spin: U=[01,10]\mathcal{U} = [01, 10].

    3. Considerăm apoi toate combinațiile posibile ale elementelor lui U\mathcal{U} pentru a forma baza: {∣0101⟩,∣0110⟩,∣1001⟩,∣1010⟩}\left \{ |0101\rangle, |0110\rangle , |1001\rangle , |1010\rangle \right \}, care conține stările singlet și triplet.

  • open_shell = True:

    1. Spre deosebire de cazul open_shell = False, nu combinăm jumătățile șirului de biți pentru a forma baza.

Strat închis​

Acest exemplu arată cum sunt manipulate șirurile de biți într-un sistem (2 electroni, 4 orbitali).

# 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

Specifică manual un dicționar de rezultate ale măsurătorilor:

counts_dict = {
"00010010": 1 / 2.0 - 0.01,
"01001000": 1 / 2.0 - 0.01,
"00010001": 0.02,
}

Transformă dict-ul de numărători într-o matrice de șiruri de biți și un tablou de probabilități pentru post-procesare:

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]

Subeșantionează un singur lot de dimensiune doi:

  • n_batches = 1: Numărul de loturi de configurații folosite de diferitele apeluri ale solverului de stări proprii

  • samples_per_batch = 2: Numărul de configurații unice incluse în fiecare lot

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]]

Obține reprezentarea zecimală a șirurilor de biți cu spin în sus și cu spin în jos folosite de solverul de stări proprii.

Primul element din tuplu corespunde reprezentării zecimale a configurațiilor cu spin în sus, iar al doilea element din tuplu corespunde reprezentării zecimale a configurațiilor cu spin în jos:

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))

Observă că, deși numărul de eșantioane per lot este doi, iar șirurile de biți eșantionate sunt: 0001001000010010 și 0100100001001000, se generează patru configurații electronice per specie de spin. În acest caz, mulțimea configurațiilor unice polarizate în spin este dată de:

U={0001,0010,0100,1000}\mathcal{U} = \{ 0001, 0010, 0100, 1000 \}

cu reprezentarea zecimală în baza 10

U10={1,2,4,8}\mathcal{U}_{10} = \{ 1, 2, 4, 8 \}

Baza subspațiului:

Solverul de stări proprii ia toate perechile posibile de șiruri de biți cu spin în sus și cu spin în jos pentru a construi baza B\mathcal{B} a subspațiului:

  • Elementul 1: ∣00010001⟩|00010001\rangle

  • Elementul 2: ∣00010010⟩|00010010\rangle

  • Elementul 3: ∣00010100⟩|00010100\rangle

  • Elementul 4: ∣00011000⟩|00011000\rangle

  • Elementul 5: ∣00100001⟩|00100001\rangle

  • Elementul 6: ∣00100010⟩|00100010\rangle

  • Elementul 7: ∣00100100⟩|00100100\rangle

  • Elementul 8: ∣00101000⟩|00101000\rangle

  • Elementul 9: ∣01000001⟩|01000001\rangle

  • Elementul 10: ∣01000010⟩|01000010\rangle

  • Elementul 11: ∣01000100⟩|01000100\rangle

  • Elementul 12: ∣01001000⟩|01001000\rangle

  • Elementul 13: ∣10000001⟩|10000001\rangle

  • Elementul 14: ∣10000010⟩|10000010\rangle

  • Elementul 15: ∣10000100⟩|10000100\rangle

  • Elementul 16: ∣10001000⟩|10001000\rangle

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>

Dimensiunea subspațiului este limitată superior de: 2⋅2 \cdot (samples_per_batch)2^2.

Strat deschis​

Acest exemplu arată cum sunt manipulate șirurile de biți într-un sistem (2 electroni, 4 orbitali).

# Specify molecule properties
num_orbitals = 4
num_elec_a = num_elec_b = 1
open_shell = True

Specifică manual un dicționar de rezultate ale măsurătorilor:

counts_dict = {
"00010010": 1 / 2.0 - 0.01,
"01001000": 1 / 2.0 - 0.01,
"00010001": 0.02,
}

Transformă dict-ul de numărători într-o matrice de șiruri de biți și un tablou de probabilități pentru post-procesare:

# 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]

Subeșantionează un singur lot de dimensiune doi:

  • n_batches = 1: Numărul de loturi de configurații folosite de diferitele apeluri ale solverului de stări proprii

  • samples_per_batch = 2: Numărul de configurații unice incluse în fiecare lot

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]]

Obține reprezentarea zecimală a șirurilor de biți cu spin în sus și cu spin în jos folosite de solverul de stări proprii.

Primul element din tuplu corespunde reprezentării zecimale a configurațiilor cu spin în sus, iar al doilea element din tuplu corespunde reprezentării zecimale a configurațiilor cu spin în jos:

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))

Dacă specificăm open_shell = True, nu includem toate jumătățile unice de șiruri de biți ca configurații cu spin în sus și cu spin în jos, obținând astfel o bază mai mică decât atunci când se specifică open_shell = False. Baza subspațiului:

Solverul de stări proprii ia toate perechile posibile de șiruri de biți cu spin în sus și cu spin în jos pentru a construi baza B\mathcal{B} a subspațiului:

  • Elementul 1: ∣00010010⟩|00010010\rangle

  • Elementul 2: ∣00011000⟩|00011000\rangle

  • Elementul 3: ∣01000010⟩|01000010\rangle

  • Elementul 4: ∣01001000⟩|01001000\rangle

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>

Dimensiunea subspațiului este limitată superior de: (samples_per_batch)2^2.