{
  "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궤도) 시스템에서, RHF 상태 $|0101\\rangle$ 에 비해 단일 스핀-업 여기 상태를 갖는 구성 $|1001\\rangle$ 을 샘플링할 수 있는데, 이는 각각 개방 껍질 싱글렛 상태 $(|1001\\rangle ± |0110\\rangle) /\\sqrt{2}$ 와 트리플렛 상태의 선형 조합이다. 만약 |0110⟩ 구성이 샘플링되지 않는다면, 총 스핀의 고유함수를 구성할 수 없게 되어 스핀 오염이나 중복이 발생하게 된다(|1001⟩ 구성은 CI 계산에 포함되지만, CI 벡터에서 계수가 0이다). 양자 컴퓨터에서 단일 샘플 $|1001\\rangle$ 이 생성된 경우, 이 `sqd` 패키지는 다음과 같은 방식으로 해당 상황을 처리합니다:\n",
        "\n",
        "* `open_shell = False`:\n",
        "\n",
        "  1. $1001$ 비트열은 두 부분으로 나뉘며, 각각 스핀 업(spin-up) 및 스핀 다운(spin-down) 구성을 나타냅니다: $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": [
        "측정 결과 사전(dictionary)을 수동으로 지정하십시오:\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": [
        "고유상태 솔버에서 사용하는 스핀-업 및 스핀-다운 비트열의 십진수 표현을 구합니다.\n",
        "\n",
        "튜플의 첫 번째 요소는 스핀-업 상태의 10진수 표현에 해당하고, 튜플의 두 번째 요소는 스핀-다운 상태의 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": [
        "한 배치당 샘플 수는 2개이며, 샘플링된 비트열은 $00010010$ 및 $01001000$ 이지만, 스핀 종류당 4개의 전자 배열이 생성된다는 점에 유의하십시오. 이 경우, 고유한 스핀 편극 배열의 집합은 다음과 같이 주어집니다:\n",
        "\n",
        "$$\n",
        "\\mathcal{U} = \\{ 0001, 0010, 0100, 1000 \\}\n",
        "$$\n",
        "\n",
        "base-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": [
        "측정 결과 사전(dictionary)을 수동으로 지정하십시오:\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": [
        "고유상태 솔버에서 사용하는 스핀-업 및 스핀-다운 비트열의 십진수 표현을 구합니다.\n",
        "\n",
        "튜플의 첫 번째 요소는 스핀-업 상태의 10진수 표현에 해당하고, 튜플의 두 번째 요소는 스핀-다운 상태의 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
}