{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "frontmatter",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"開放殻と閉殻の選択肢の違い、およびそれらが部分空間の構築に及ぼす影響を理解する\"\n",
        "description: \"最新バージョンのサンプルベース量子対角化（SQD）において、オープンシェルとクローズドシェルのオプションの違い、およびそれらが部分空間の構築に及ぼす影響について理解する\"\n",
        "---\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "72420c62-2716-4f64-ad5b-73394b481cc1",
      "metadata": {},
      "source": [
        "<span id=\"understand-open-shell-versus-closed-shell-options-and-the-effect-on-subspace-construction\" />\n",
        "\n",
        "# 開放殻と閉殻の選択肢の違い、およびそれらが部分空間の構築に及ぼす影響を理解する\n",
        "\n",
        "このガイドでは、 [自己一貫性構成復元法](https://arxiv.org/abs/2405.05068)を用いて量子サンプルを後処理するために、パッケージ `qiskit_addon_sqd` 内で部分空間の次元をどのように選択するかを説明します。\n",
        "\n",
        "さらに重要なことに、このガイドでは、または `open_shell = True` モードで `open_shell = False` 実行した場合の、部分空間の構築における挙動の違いについてもいくつか取り上げています：\n",
        "\n",
        "* `open_shell = False` これは、スピンアップ電子とスピンダウン電子の数が同じ場合にのみ成立する。\n",
        "\n",
        "* `open_shell = True` スピンアップ電子とスピンダウン電子の数が異なる場合には、これを使用しなければならない。 また、スピンアップ電子とスピンダウン電子の数が同じ場合にも使用できます。 `open_shell = True`ただし、この最後のケースでは、このガイドで説明したように、と `open_shell = False` によって生成される部分空間の大きさに違いがあります。\n",
        "\n",
        "**注：** このパッケージにおける電子配置（ビット列）の操作の一部は、総スピン対称性 $S^2$ を保つことを目的としています。標準的な選択配置相互作用（SCI）ソルバーでは、 $S^2$ の保存則を厳密に満たすことはできません。 したがって、彼らは概ねラグランジュ乗数法を用いてこれを行う。\n",
        "\n",
        "固有状態ソルバーに入力される電子配置の選択も、スピンの保存に大きな影響を及ぼす可能性がある。 例えば、（2電子、2軌道）系において、 $|1001\\rangle$ という配置（RHF状態 $|0101\\rangle$ に対して単一のスピンアップ励起を持つ）をサンプリングすることができる。これは、それぞれ $(|1001\\rangle ± |0110\\rangle) /\\sqrt{2}$ であるオープンシェル・シングレット状態とトリプレット状態の線形結合である。 もし配置 |0110⟩ がサンプリングされない場合、総スピンの固有関数を構築することができず、スピン汚染や冗長性が生じる（配置 |1001⟩ は CI 計算に含まれているが、CI ベクトルにおける係数は 0 である）。 量子コンピュータ内で単一のサンプル $|1001\\rangle$ が生成された場合、この `sqd` パッケージでは次のようにこの状況に対処します：\n",
        "\n",
        "* `open_shell = False`:\n",
        "\n",
        "  1. $1001$ というビット列は2つに分割され、スピンアップおよびスピンダウンの構成を表します。 $10$ （アップ）および $01$ （ダウン）です。\n",
        "\n",
        "  2. 固有のスピン偏極配置のリストは、 $\\mathcal{U} = [01, 10]$ として構築される。\n",
        "\n",
        "  3. 次に、基底を構成する $\\mathcal{U}$ 個の要素のすべての組み合わせについて検討する： $\\left \\{ |0101\\rangle, |0110\\rangle , |1001\\rangle , |1010\\rangle \\right \\}$。これには、シングレット状態とトリプレット状態が含まれる。\n",
        "\n",
        "* `open_shell = True`:\n",
        "\n",
        "  1. その `open_shell = False` 例とは異なり、ビット列の両半分を組み合わせて基底を形成することはありません。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a6755afb-ca1e-4473-974b-ba89acc8abce",
      "metadata": {},
      "source": [
        "<span id=\"closed-shell\" />\n",
        "\n",
        "### 閉殻\n",
        "\n",
        "この例では、（2電子、4軌道）系においてビット列がどのように操作されるかを示しています。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "677f54ac-b4ed-47e3-b5ba-5366d3a520f9",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Specify molecule properties\n",
        "num_orbitals = 4\n",
        "num_elec_a = num_elec_b = 1\n",
        "open_shell = False"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c58e988c-a109-44cd-a975-9df43250c318",
      "metadata": {},
      "source": [
        "測定結果の辞書を手動で指定します：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "e9506e0b-ed64-48bb-a97a-ef851b604af1",
      "metadata": {},
      "outputs": [],
      "source": [
        "counts_dict = {\n",
        "    \"00010010\": 1 / 2.0 - 0.01,\n",
        "    \"01001000\": 1 / 2.0 - 0.01,\n",
        "    \"00010001\": 0.02,\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "851bc98e-9c08-4e78-9472-36301abc11d8",
      "metadata": {},
      "source": [
        "後処理のために、カウント `dict` 値をビット文字列行列と確率配列に変換します：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "7a102a7f-aae6-4583-ab82-ae40fcb5496a",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[False False False  True False False  True False]\n",
            " [False  True False False  True False False False]\n",
            " [False False False  True False False False  True]]\n",
            "[0.49 0.49 0.02]\n"
          ]
        }
      ],
      "source": [
        "from qiskit_addon_sqd.counts import counts_to_arrays\n",
        "\n",
        "# Convert counts into bitstring and probability arrays\n",
        "bitstring_matrix_full, probs_arr_full = counts_to_arrays(counts_dict)\n",
        "print(bitstring_matrix_full)\n",
        "print(probs_arr_full)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "eb704101-0fe8-4d12-b572-b1d844e35a90",
      "metadata": {},
      "source": [
        "サイズ2の単一バッチをサブサンプリングする：\n",
        "\n",
        "* `n_batches = 1`: 固有状態ソルバーへのさまざまな呼び出しで使用される構成のバッチ数\n",
        "* `samples_per_batch = 2`: 各バッチに含める固有の構成の数\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "fe60aee2",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[False False False  True False False  True False]\n",
            " [False  True False False  True False False False]]\n"
          ]
        }
      ],
      "source": [
        "from qiskit_addon_sqd.subsampling import postselect_and_subsample\n",
        "\n",
        "n_batches = 1\n",
        "samples_per_batch = 2\n",
        "\n",
        "# seed for random number generator\n",
        "rand_seed = 48\n",
        "\n",
        "# Generate the batches\n",
        "batches = postselect_and_subsample(\n",
        "    bitstring_matrix_full,\n",
        "    probs_arr_full,\n",
        "    hamming_right=num_elec_a,\n",
        "    hamming_left=num_elec_b,\n",
        "    samples_per_batch=samples_per_batch,\n",
        "    num_batches=n_batches,\n",
        "    rand_seed=rand_seed,\n",
        ")\n",
        "\n",
        "print(batches[0])"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "93a6d05a",
      "metadata": {},
      "source": [
        "固有状態ソルバーで使用されるスピンアップおよびスピンダウンのビット列の10進表記を取得します。\n",
        "\n",
        "タプルの最初の要素はスピンアップ状態の10進数表現に対応し、タプルの2番目の要素はスピンダウン状態の10進数表現に対応します：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "ef90e039",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "(array([1, 2, 4, 8], dtype=int64), array([1, 2, 4, 8], dtype=int64))\n"
          ]
        }
      ],
      "source": [
        "from qiskit_addon_sqd.fermion import bitstring_matrix_to_ci_strs\n",
        "\n",
        "ci_strs = bitstring_matrix_to_ci_strs(batches[0], open_shell=open_shell)\n",
        "print(ci_strs)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "70d7883c",
      "metadata": {},
      "source": [
        "なお、1バッチあたりのサンプル数は2つであり、サンプリングされたビット列は $00010010$ および $01001000$ ですが、スピン種ごとに4つの電子配置が生成されることに注意してください。 この場合、一意なスピン偏極配置の集合は次のように与えられる：\n",
        "\n",
        "$$\n",
        "\\mathcal{U} = \\{ 0001, 0010, 0100, 1000 \\}\n",
        "$$\n",
        "\n",
        "その base-10 の10進表記は\n",
        "\n",
        "$$\n",
        "\\mathcal{U}_{10} = \\{ 1, 2, 4, 8 \\}\n",
        "$$\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "03b32ed5",
      "metadata": {},
      "source": [
        "部分空間の基底：\n",
        "\n",
        "固有状態ソルバーは、スピンアップとスピンダウンのビット列のすべての可能な組み合わせを取り、部分空間の基底 $\\mathcal{B}$ を構成する：\n",
        "\n",
        "* 要素 1： $|00010001\\rangle$\n",
        "\n",
        "* 要素 2： $|00010010\\rangle$\n",
        "\n",
        "* 要素 3： $|00010100\\rangle$\n",
        "\n",
        "* 要素 4： $|00011000\\rangle$\n",
        "\n",
        "* 要素 5： $|00100001\\rangle$\n",
        "\n",
        "* 要素 6： $|00100010\\rangle$\n",
        "\n",
        "* 要素 7： $|00100100\\rangle$\n",
        "\n",
        "* 要素 8： $|00101000\\rangle$\n",
        "\n",
        "* 要素 9： $|01000001\\rangle$\n",
        "\n",
        "* 要素 10： $|01000010\\rangle$\n",
        "\n",
        "* 要素 11： $|01000100\\rangle$\n",
        "\n",
        "* 要素 12： $|01001000\\rangle$\n",
        "\n",
        "* 要素13： $|10000001\\rangle$\n",
        "\n",
        "* Element 14： $|10000010\\rangle$\n",
        "\n",
        "* 元素15： $|10000100\\rangle$\n",
        "\n",
        "* 第16元素： $|10001000\\rangle$\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "11c924ee",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Basis elements of the subspace:\n",
            "|00010001>\n",
            "|00010010>\n",
            "|00010100>\n",
            "|00011000>\n",
            "|00100001>\n",
            "|00100010>\n",
            "|00100100>\n",
            "|00101000>\n",
            "|01000001>\n",
            "|01000010>\n",
            "|01000100>\n",
            "|01001000>\n",
            "|10000001>\n",
            "|10000010>\n",
            "|10000100>\n",
            "|10001000>\n"
          ]
        }
      ],
      "source": [
        "ci_strs_up, ci_strs_dn = ci_strs\n",
        "\n",
        "print(\"Basis elements of the subspace:\")\n",
        "\n",
        "for ci_str_up in ci_strs_up:\n",
        "    for ci_str_dn in ci_strs_dn:\n",
        "        format_name = \"{0:0\" + str(num_orbitals) + \"b}\"\n",
        "        print(\n",
        "            \"|\"\n",
        "            + format_name.format(ci_str_up)\n",
        "            + format_name.format(ci_str_dn)\n",
        "            + \">\"\n",
        "        )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "aa43a4fc",
      "metadata": {},
      "source": [
        "**この部分空間の次元は、以下の式によって上界が定められる** ： $2 \\cdot$ (`samples_per_batch`) $^2$。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9412e52b",
      "metadata": {},
      "source": [
        "<span id=\"open-shell\" />\n",
        "\n",
        "### オープンシェル\n",
        "\n",
        "この例では、（2電子、4軌道）系においてビット列がどのように操作されるかを示しています。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "9b515b8a",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Specify molecule properties\n",
        "num_orbitals = 4\n",
        "num_elec_a = num_elec_b = 1\n",
        "open_shell = True"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9ef78560",
      "metadata": {},
      "source": [
        "測定結果の辞書を手動で指定します：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "06b2185a",
      "metadata": {},
      "outputs": [],
      "source": [
        "counts_dict = {\n",
        "    \"00010010\": 1 / 2.0 - 0.01,\n",
        "    \"01001000\": 1 / 2.0 - 0.01,\n",
        "    \"00010001\": 0.02,\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "08b32957",
      "metadata": {},
      "source": [
        "後処理のために、カウント `dict` 値をビット文字列行列と確率配列に変換します：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "90561893",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[False False False  True False False  True False]\n",
            " [False  True False False  True False False False]\n",
            " [False False False  True False False False  True]]\n",
            "[0.49 0.49 0.02]\n"
          ]
        }
      ],
      "source": [
        "# Convert counts into bitstring and probability arrays\n",
        "bitstring_matrix_full, probs_arr_full = counts_to_arrays(counts_dict)\n",
        "print(bitstring_matrix_full)\n",
        "print(probs_arr_full)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "416bfb6c",
      "metadata": {},
      "source": [
        "サイズ2の単一バッチをサブサンプリングする：\n",
        "\n",
        "* `n_batches = 1`: 固有状態ソルバーへのさまざまな呼び出しで使用される構成のバッチ数\n",
        "* `samples_per_batch = 2`: 各バッチに含める固有の構成の数\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "cf4fe11d",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[False False False  True False False  True False]\n",
            " [False  True False False  True False False False]]\n"
          ]
        }
      ],
      "source": [
        "n_batches = 1\n",
        "samples_per_batch = 2\n",
        "\n",
        "# seed for random number generator\n",
        "rand_seed = 48\n",
        "\n",
        "# Generate the batches\n",
        "batches = postselect_and_subsample(\n",
        "    bitstring_matrix_full,\n",
        "    probs_arr_full,\n",
        "    hamming_right=num_elec_a,\n",
        "    hamming_left=num_elec_b,\n",
        "    samples_per_batch=samples_per_batch,\n",
        "    num_batches=n_batches,\n",
        "    rand_seed=rand_seed,\n",
        ")\n",
        "\n",
        "print(batches[0])"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "54d699ca",
      "metadata": {},
      "source": [
        "固有状態ソルバーで使用されるスピンアップおよびスピンダウンのビット列の10進表記を取得します。\n",
        "\n",
        "タプルの最初の要素はスピンアップ状態の10進数表現に対応し、タプルの2番目の要素はスピンダウン状態の10進数表現に対応します：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "b40b049b",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "(array([2, 8], dtype=int64), array([1, 4], dtype=int64))\n"
          ]
        }
      ],
      "source": [
        "ci_strs = bitstring_matrix_to_ci_strs(batches[0], open_shell=open_shell)\n",
        "print(ci_strs)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "28921e56",
      "metadata": {},
      "source": [
        "`open_shell = False``open_shell = True`を指定した場合、すべての固有のハーフビット列をスピンアップおよびスピンダウンの構成として含めるわけではないため、を指定した場合よりも基底の数が少なくなります。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e1959b72",
      "metadata": {},
      "source": [
        "部分空間の基底：\n",
        "\n",
        "固有状態ソルバーは、スピンアップとスピンダウンのビット列のすべての可能な組み合わせを取り、部分空間の基底 $\\mathcal{B}$ を構成する：\n",
        "\n",
        "* 要素 1： $|00010010\\rangle$\n",
        "\n",
        "* 要素 2： $|00011000\\rangle$\n",
        "\n",
        "* 要素 3： $|01000010\\rangle$\n",
        "\n",
        "* 要素 4： $|01001000\\rangle$\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "a550aba2",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Basis elements of the subspace:\n",
            "|00100001>\n",
            "|00100100>\n",
            "|10000001>\n",
            "|10000100>\n"
          ]
        }
      ],
      "source": [
        "ci_strs_up, ci_strs_dn = ci_strs\n",
        "\n",
        "print(\"Basis elements of the subspace:\")\n",
        "\n",
        "for ci_str_up in ci_strs_up:\n",
        "    for ci_str_dn in ci_strs_dn:\n",
        "        format_name = \"{0:0\" + str(num_orbitals) + \"b}\"\n",
        "        print(\n",
        "            \"|\"\n",
        "            + format_name.format(ci_str_up)\n",
        "            + format_name.format(ci_str_dn)\n",
        "            + \">\"\n",
        "        )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7317bc49",
      "metadata": {},
      "source": [
        "**この部分空間の次元は、次の式によって上界が与えられる** ： (`samples_per_batch`) $^2$。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}