Skip to main content
IBM Quantum Platform

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 = False funktioniert nur, wenn die Anzahl der Elektronen im Spin-up- und Spin-down-Zustand gleich ist.

  • open_shell = True muss 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 zwischen open_shell = False und 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 S2S^2 zu bewahren. Standardmäßige SCI-Löser (Selected Configuration Interaction) können die Erhaltung von S2S^2 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 ∣1001⟩|1001\rangle abtasten (mit einer einzelnen Spin-up-Anregung über dem RHF-Zustand ∣0101⟩|0101\rangle ), die eine Linearkombination der Singulett- bzw. Triplett-Zustände der offenen Schale ist (∣1001⟩±∣0110⟩)/2(|1001\rangle ± |0110\rangle) /\sqrt{2}. 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 ∣1001⟩|1001\rangle generiert wird, geht das sqd Paket wie folgt mit dieser Situation um:

  • open_shell = False:

    1. Die Bitfolge „ 10011001 “ wird in zwei Hälften geteilt, die die Konfigurationen „Spin-up“ und „Spin-down“ darstellen: „ 1010 “ (up) und „ 0101 “ (down).

    2. Die Liste der eindeutigen spinpolarisierten Konfigurationen wurde erstellt: U=[01,10]\mathcal{U} = [01, 10].

    3. Anschließend betrachten wir alle möglichen Kombinationen der Elemente „ U\mathcal{U} “, um die Basis zu bilden: „ {∣0101⟩,∣0110⟩,∣1001⟩,∣1010⟩}\left \{ |0101\rangle, |0110\rangle , |1001\rangle , |1010\rangle \right \} “, die den Singulett- und den Triplettzustand enthält.

  • open_shell = True:

    1. Im Gegensatz zu diesem open_shell = False Fall fügen wir die beiden Hälften der Bitfolge nicht zu einer Basis zusammen.

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 = False

Legen 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 werden
  • samples_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: 0001001000010010 und 0100100001001000, pro Spin-Spezies jedoch vier elektronische Konfigurationen erzeugt werden. In diesem Fall ergibt sich die Menge der eindeutigen spinpolarisierten Konfigurationen wie folgt:

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

dessen Dezimaldarstellung base-10 lautet

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

Basis des Unterraums:

Der Eigenzustandslöser berücksichtigt alle möglichen Paare von Bitstrings mit „Spin-up“ und „Spin-down“, um die Basis B\mathcal{B} en des Unterraums zu bilden:

  • Element 1: ∣00010001⟩|00010001\rangle

  • Element 2: ∣00010010⟩|00010010\rangle

  • Element 3: ∣00010100⟩|00010100\rangle

  • Element 4: ∣00011000⟩|00011000\rangle

  • Element 5: ∣00100001⟩|00100001\rangle

  • Element 6: ∣00100010⟩|00100010\rangle

  • Element 7: ∣00100100⟩|00100100\rangle

  • Element 8: ∣00101000⟩|00101000\rangle

  • Element 9: ∣01000001⟩|01000001\rangle

  • Element 10: ∣01000010⟩|01000010\rangle

  • Element 11: ∣01000100⟩|01000100\rangle

  • Element 12: ∣01001000⟩|01001000\rangle

  • Element 13: ∣10000001⟩|10000001\rangle

  • Element 14: ∣10000010⟩|10000010\rangle

  • Element 15: ∣10000100⟩|10000100\rangle

  • Element 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)
            + ">"
        )

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 : 2⋅2 \cdot (samples_per_batch) 2^2.

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 = True

Legen 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 werden
  • samples_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 B\mathcal{B} en des Unterraums zu bilden:

  • Element 1: ∣00010010⟩|00010010\rangle

  • Element 2: ∣00011000⟩|00011000\rangle

  • Element 3: ∣01000010⟩|01000010\rangle

  • Element 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)
            + ">"
        )

Output:

Basis elements of the subspace:
|00100001>
|00100100>
|10000001>
|10000100>

Die Dimension des Unterraums ist nach oben begrenzt durch : (samples_per_batch) 2^2.

War diese Seite hilfreich?
Melden Sie auf GitHub einen Fehler, einen Tippfehler oder fordern Sie Inhalte an.