Skip to main content
IBM Quantum Platform

開放殻と閉殻の選択肢の違い、およびそれらが部分空間の構築に及ぼす影響を理解する

このガイドでは、 自己一貫性構成復元法を用いて量子サンプルを後処理するために、パッケージ qiskit_addon_sqd 内で部分空間の次元をどのように選択するかを説明します。

さらに重要なことに、このガイドでは、または open_shell = True モードで open_shell = False 実行した場合の、部分空間の構築における挙動の違いについてもいくつか取り上げています:

  • open_shell = False これは、スピンアップ電子とスピンダウン電子の数が同じ場合にのみ成立する。

  • open_shell = True スピンアップ電子とスピンダウン電子の数が異なる場合には、これを使用しなければならない。 また、スピンアップ電子とスピンダウン電子の数が同じ場合にも使用できます。 open_shell = Trueただし、この最後のケースでは、このガイドで説明したように、と open_shell = False によって生成される部分空間の大きさに違いがあります。

注: このパッケージにおける電子配置(ビット列)の操作の一部は、総スピン対称性 S2S^2 を保つことを目的としています。標準的な選択配置相互作用(SCI)ソルバーでは、 S2S^2 の保存則を厳密に満たすことはできません。 したがって、彼らは概ねラグランジュ乗数法を用いてこれを行う。

固有状態ソルバーに入力される電子配置の選択も、スピンの保存に大きな影響を及ぼす可能性がある。 例えば、(2電子、2軌道)系において、 1001|1001\rangle という配置(RHF状態 0101|0101\rangle に対して単一のスピンアップ励起を持つ)をサンプリングすることができる。これは、それぞれ (1001±0110)/2(|1001\rangle ± |0110\rangle) /\sqrt{2} であるオープンシェル・シングレット状態とトリプレット状態の線形結合である。 もし配置 |0110⟩ がサンプリングされない場合、総スピンの固有関数を構築することができず、スピン汚染や冗長性が生じる(配置 |1001⟩ は CI 計算に含まれているが、CI ベクトルにおける係数は 0 である)。 量子コンピュータ内で単一のサンプル 1001|1001\rangle が生成された場合、この sqd パッケージでは次のようにこの状況に対処します:

  • open_shell = False:

    1. 10011001 というビット列は2つに分割され、スピンアップおよびスピンダウンの構成を表します。 1010 (アップ)および 0101 (ダウン)です。

    2. 固有のスピン偏極配置のリストは、 U=[01,10]\mathcal{U} = [01, 10] として構築される。

    3. 次に、基底を構成する U\mathcal{U} 個の要素のすべての組み合わせについて検討する: {0101,0110,1001,1010}\left \{ |0101\rangle, |0110\rangle , |1001\rangle , |1010\rangle \right \}。これには、シングレット状態とトリプレット状態が含まれる。

  • open_shell = True:

    1. その open_shell = False 例とは異なり、ビット列の両半分を組み合わせて基底を形成することはありません。

閉殻

この例では、(2電子、4軌道)系においてビット列がどのように操作されるかを示しています。

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

測定結果の辞書を手動で指定します:

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

後処理のために、カウント dict 値をビット文字列行列と確率配列に変換します:

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]

サイズ2の単一バッチをサブサンプリングする:

  • n_batches = 1: 固有状態ソルバーへのさまざまな呼び出しで使用される構成のバッチ数
  • samples_per_batch = 2: 各バッチに含める固有の構成の数
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]]

固有状態ソルバーで使用されるスピンアップおよびスピンダウンのビット列の10進表記を取得します。

タプルの最初の要素はスピンアップ状態の10進数表現に対応し、タプルの2番目の要素はスピンダウン状態の10進数表現に対応します:

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

なお、1バッチあたりのサンプル数は2つであり、サンプリングされたビット列は 0001001000010010 および 0100100001001000 ですが、スピン種ごとに4つの電子配置が生成されることに注意してください。 この場合、一意なスピン偏極配置の集合は次のように与えられる:

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

その base-10 の10進表記は

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

部分空間の基底:

固有状態ソルバーは、スピンアップとスピンダウンのビット列のすべての可能な組み合わせを取り、部分空間の基底 B\mathcal{B} を構成する:

  • 要素 1: 00010001|00010001\rangle

  • 要素 2: 00010010|00010010\rangle

  • 要素 3: 00010100|00010100\rangle

  • 要素 4: 00011000|00011000\rangle

  • 要素 5: 00100001|00100001\rangle

  • 要素 6: 00100010|00100010\rangle

  • 要素 7: 00100100|00100100\rangle

  • 要素 8: 00101000|00101000\rangle

  • 要素 9: 01000001|01000001\rangle

  • 要素 10: 01000010|01000010\rangle

  • 要素 11: 01000100|01000100\rangle

  • 要素 12: 01001000|01001000\rangle

  • 要素13: 10000001|10000001\rangle

  • Element 14: 10000010|10000010\rangle

  • 元素15: 10000100|10000100\rangle

  • 第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>

この部分空間の次元は、以下の式によって上界が定められる22 \cdot (samples_per_batch) 2^2

オープンシェル

この例では、(2電子、4軌道)系においてビット列がどのように操作されるかを示しています。

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

測定結果の辞書を手動で指定します:

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

後処理のために、カウント dict 値をビット文字列行列と確率配列に変換します:

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

サイズ2の単一バッチをサブサンプリングする:

  • n_batches = 1: 固有状態ソルバーへのさまざまな呼び出しで使用される構成のバッチ数
  • samples_per_batch = 2: 各バッチに含める固有の構成の数
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]]

固有状態ソルバーで使用されるスピンアップおよびスピンダウンのビット列の10進表記を取得します。

タプルの最初の要素はスピンアップ状態の10進数表現に対応し、タプルの2番目の要素はスピンダウン状態の10進数表現に対応します:

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

open_shell = False``open_shell = Trueを指定した場合、すべての固有のハーフビット列をスピンアップおよびスピンダウンの構成として含めるわけではないため、を指定した場合よりも基底の数が少なくなります。

部分空間の基底:

固有状態ソルバーは、スピンアップとスピンダウンのビット列のすべての可能な組み合わせを取り、部分空間の基底 B\mathcal{B} を構成する:

  • 要素 1: 00010010|00010010\rangle

  • 要素 2: 00011000|00011000\rangle

  • 要素 3: 01000010|01000010\rangle

  • 要素 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>

この部分空間の次元は、次の式によって上界が与えられる : (samples_per_batch) 2^2

このページは役に立ちましたか?
バグや誤字の報告、またはコンテンツの要求はGitHubで行ってください。