Die Unterschiede zwischen Optionen mit offener und geschlossener Schale sowie deren Auswirkungen auf die Konstruktion von Unterräumen verstehen
In dieser Anleitung zeigen wir, wie man im qiskit_addon_sqd Paket die Dimensionen des Unterraums auswählt, um Quantenproben mithilfe der selbstkonsistenten Konfigurationswiederherstellungstechnik nachzubearbeiten.
Noch wichtiger ist, dass dieser Leitfaden auch einige Unterschiede im Verhalten bei der Unterraumkonstruktion hervorhebt, wenn diese im open_shell = False oder open_shell = True Modus ausgeführt wird:
-
open_shell = Falsefunktioniert nur, wenn die Anzahl der Elektronen im Spin-up- und Spin-down-Zustand gleich ist. -
open_shell = Truemuss verwendet werden, wenn die Anzahl der Elektronen im Spin-up- und Spin-down-Zustand unterschiedlich ist. Es kann auch angewendet werden, wenn die Anzahl der Elektronen im Spin-up- und im Spin-down-Zustand gleich ist.open_shell = TrueIm letztgenannten Fall besteht jedoch ein Unterschied in der Größe der zwischenopen_shell = Falseund erzeugten Unterräume, wie in diesem Leitfaden erläutert wird.
HINWEIS: Einige der in diesem Paket enthaltenen Manipulationen der elektronischen Konfiguration (Bitfolge) zielen darauf ab, die Gesamtspinsymmetrie zu bewahren. Standardmäßige SCI-Löser (Selected Configuration Interaction) können die Erhaltung von nicht exakt gewährleisten. Folglich tun sie dies im Wesentlichen mithilfe eines Lagrange-Multiplikators.
Die Wahl der elektronischen Konfigurationen, die in den Eigenzustandslöser eingegeben werden, kann ebenfalls einen starken Einfluss auf die Spin-Erhaltung haben. Beispielsweise kann man in einem (2-Elektronen-, 2-Orbital-)System die Konfiguration abtasten (mit einer einzelnen Spin-up-Anregung über dem RHF-Zustand ), die eine Linearkombination der Singulett- bzw. Triplett-Zustände der offenen Schale ist . Wird die Konfiguration |0110⟩ nicht berücksichtigt, lässt sich keine Eigenfunktion des Gesamtspins konstruieren, was zu einer Spinverunreinigung oder Redundanz führt (die Konfiguration |1001⟩ ist zwar in einer CI-Berechnung enthalten, hat jedoch im CI-Vektor den Koeffizienten 0). Da im Quantencomputer ein einzelnes Beispiel generiert wird, geht das sqd Paket wie folgt mit dieser Situation um:
-
open_shell = False:-
Die Bitfolge „ “ wird in zwei Hälften geteilt, die die Konfigurationen „Spin-up“ und „Spin-down“ darstellen: „ “ (up) und „ “ (down).
-
Die Liste der eindeutigen spinpolarisierten Konfigurationen wurde erstellt: .
-
Anschließend betrachten wir alle möglichen Kombinationen der Elemente „ “, um die Basis zu bilden: „ “, die den Singulett- und den Triplettzustand enthält.
-
-
open_shell = True:- Im Gegensatz zu diesem
open_shell = FalseFall fügen wir die beiden Hälften der Bitfolge nicht zu einer Basis zusammen.
- Im Gegensatz zu diesem
Geschlossene Schale
Dieses Beispiel veranschaulicht, wie die Bitfolgen in einem System mit zwei Elektronen und vier Orbitalen bearbeitet werden.
# Specify molecule properties
num_orbitals = 4
num_elec_a = num_elec_b = 1
open_shell = FalseLegen Sie manuell ein Verzeichnis der Messergebnisse fest:
counts_dict = {
"00010010": 1 / 2.0 - 0.01,
"01001000": 1 / 2.0 - 0.01,
"00010001": 0.02,
}Wandeln Sie die Zählwerte dict zur weiteren Verarbeitung in eine Bitstring-Matrix und ein Wahrscheinlichkeits-Array um:
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)Output:
[[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]
Entnehmen Sie eine Teilstichprobe aus einer einzelnen Charge der Größe zwei:
n_batches = 1: Anzahl der Konfigurationssätze, die von den verschiedenen Aufrufen des Eigenzustandslösers verwendet werdensamples_per_batch = 2: Anzahl der eindeutigen Konfigurationen, die in jeden Stapel aufgenommen werden sollen
from qiskit_addon_sqd.subsampling import postselect_and_subsample
n_batches = 1
samples_per_batch = 2
# seed for random number generator
rand_seed = 48
# Generate the batches
batches = postselect_and_subsample(
bitstring_matrix_full,
probs_arr_full,
hamming_right=num_elec_a,
hamming_left=num_elec_b,
samples_per_batch=samples_per_batch,
num_batches=n_batches,
rand_seed=rand_seed,
)
print(batches[0])Output:
[[False False False True False False True False]
[False True False False True False False False]]
Ermitteln Sie die Dezimaldarstellung der vom Eigenzustandslöser verwendeten Bitstrings für „Spin-up“ und „Spin-down“.
Das erste Element des Tupels entspricht der Dezimaldarstellung der Spin-up-Konfigurationen, während das zweite Element des Tupels der Dezimaldarstellung der Spin-down-Konfigurationen entspricht:
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)Output:
(array([1, 2, 4, 8], dtype=int64), array([1, 2, 4, 8], dtype=int64))
Beachten Sie, dass zwar die Anzahl der Stichproben pro Charge zwei beträgt und die erfassten Bitstrings wie folgt lauten: und , pro Spin-Spezies jedoch vier elektronische Konfigurationen erzeugt werden. In diesem Fall ergibt sich die Menge der eindeutigen spinpolarisierten Konfigurationen wie folgt:
dessen Dezimaldarstellung base-10 lautet
Basis des Unterraums:
Der Eigenzustandslöser berücksichtigt alle möglichen Paare von Bitstrings mit „Spin-up“ und „Spin-down“, um die Basis en des Unterraums zu bilden:
-
Element 1:
-
Element 2:
-
Element 3:
-
Element 4:
-
Element 5:
-
Element 6:
-
Element 7:
-
Element 8:
-
Element 9:
-
Element 10:
-
Element 11:
-
Element 12:
-
Element 13:
-
Element 14:
-
Element 15:
-
Element 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)
+ ">"
)Output:
Basis elements of the subspace:
|00010001>
|00010010>
|00010100>
|00011000>
|00100001>
|00100010>
|00100100>
|00101000>
|01000001>
|01000010>
|01000100>
|01001000>
|10000001>
|10000010>
|10000100>
|10001000>
Die Dimension des Unterraums ist nach oben begrenzt durch : (samples_per_batch) .
Offene Schale
Dieses Beispiel veranschaulicht, wie die Bitfolgen in einem System mit zwei Elektronen und vier Orbitalen bearbeitet werden.
# Specify molecule properties
num_orbitals = 4
num_elec_a = num_elec_b = 1
open_shell = TrueLegen Sie manuell ein Verzeichnis der Messergebnisse fest:
counts_dict = {
"00010010": 1 / 2.0 - 0.01,
"01001000": 1 / 2.0 - 0.01,
"00010001": 0.02,
}Wandeln Sie die Zählwerte dict zur weiteren Verarbeitung in eine Bitstring-Matrix und ein Wahrscheinlichkeits-Array um:
# 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)Output:
[[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]
Entnehmen Sie eine Teilstichprobe aus einer einzelnen Charge der Größe zwei:
n_batches = 1: Anzahl der Konfigurationssätze, die von den verschiedenen Aufrufen des Eigenzustandslösers verwendet werdensamples_per_batch = 2: Anzahl der eindeutigen Konfigurationen, die in jeden Stapel aufgenommen werden sollen
n_batches = 1
samples_per_batch = 2
# seed for random number generator
rand_seed = 48
# Generate the batches
batches = postselect_and_subsample(
bitstring_matrix_full,
probs_arr_full,
hamming_right=num_elec_a,
hamming_left=num_elec_b,
samples_per_batch=samples_per_batch,
num_batches=n_batches,
rand_seed=rand_seed,
)
print(batches[0])Output:
[[False False False True False False True False]
[False True False False True False False False]]
Ermitteln Sie die Dezimaldarstellung der vom Eigenzustandslöser verwendeten Bitstrings für „Spin-up“ und „Spin-down“.
Das erste Element des Tupels entspricht der Dezimaldarstellung der Spin-up-Konfigurationen, während das zweite Element des Tupels der Dezimaldarstellung der Spin-down-Konfigurationen entspricht:
ci_strs = bitstring_matrix_to_ci_strs(batches[0], open_shell=open_shell)
print(ci_strs)Output:
(array([2, 8], dtype=int64), array([1, 4], dtype=int64))
Wenn wir festlegen, dass open_shell = True, werden nicht alle eindeutigen Halbbitstrings als „Spin-up“- und „Spin-down“-Konfigurationen berücksichtigt, was zu einer kleineren Basis führt als bei der Festlegung von open_shell = False.
Basis des Unterraums:
Der Eigenzustandslöser berücksichtigt alle möglichen Paare von Bitstrings mit „Spin-up“ und „Spin-down“, um die Basis en des Unterraums zu bilden:
-
Element 1:
-
Element 2:
-
Element 3:
-
Element 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)
+ ">"
)Output:
Basis elements of the subspace:
|00100001>
|00100100>
|10000001>
|10000100>
Die Dimension des Unterraums ist nach oben begrenzt durch : (samples_per_batch) .