{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "49f6841f-a9e9-4a44-a162-a0147bd2f300",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"サンプルベース量子対角化法\"\n",
        "description: \"サンプルベース量子対角化（SQD）の重要な構成要素とベストプラクティスについて議論する。 この方法は次のレッスンで実装されます。\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore PVDZ eigvals eigvecs eigh */}\n",
        "\n",
        "<span id=\"sample-based-quantum-diagonalization-sqd\" />\n",
        "\n",
        "# サンプルベース量子対角化法（SQD）\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "65614f74-fe5b-4b8b-8118-ef9ac0847f34",
      "metadata": {},
      "source": [
        "サンプルベース量子対角化(SQD)は、古典的な線形代数と量子コンピュータのパワーを組み合わせ、ハミルトニアン(行列)を対角化し、その固有値と固有ベクトルを計算する。 行列の対角化は重要な数学的操作であり、科学、計算、最適化における多くの問題でこの手法が用いられている。\n",
        "\n",
        "以下のビデオでは、SQDの概要、その有用性を決定するもの、そして他の多くのアプローチよりもSQDが速い理由を説明している。 詳細は後述する。\n",
        "\n",
        "<IBMVideo id=\"134325501\" title=\"このビデオでは、クリス・ポーターが亜空間量子対角化の概要を説明する。 彼は、その効率性と有用性に影響を与える要因について述べている。 何が他のアプローチより速いのかを説明している。 詳細は以下の文章を参照されたい。\" />\n",
        "\n",
        "<span id=\"1-introduction-and-motivation\" />\n",
        "\n",
        "## 1. はじめにおよび動機\n",
        "\n",
        "シュレーディンガーによって有名になったエネルギー固有値方程式を例に考えてみよう。\n",
        "\n",
        "$$\n",
        "H \\vert \\psi \\rangle = E \\vert \\psi \\rangle\n",
        "$$\n",
        "\n",
        "$H$ は系のハミルトニアン、 $|\\psi\\rangle$ は波動関数（固有状態とも呼ばれる）、 $E$ は固有値である。 行列 $H$ の固有値は系のエネルギー準位を表す。 例えば、系が分子の場合、最小固有値は分子の基底状態エネルギーを表す。 多くの問題で、我々は基底状態のエネルギー推定に関心がある。\n",
        "\n",
        "線形代数学の厳密対角化技術を応用すれば、 $H$ の完全な行列を対角化することができる。 しかし、このアプローチは行列が大きくなるにつれて計算コストが高くなる（不可能にさえなる）。 例えば、小さな化学分子であっても、 $H$ は法外に大きくなることがある（例えば、cc-PVDZ基底を用いた $N_2$ 分子のハミルトニアンは、次のような次元になる）。 $65780 \\times 65780).$\n",
        "\n",
        "幸いなことに、ハミルトニアン $H$ のすべての固有値と固有ベクトルを常に必要とするわけではないので、多くの実用的なケースでは完全な行列の対角化は必要ない。 例えば、基底状態を推定する場合、最も小さい固有値とそれに対応する固有ベクトルに興味がある。 これにより、（有用な）部分空間への射影の概念を適用することができる。\n",
        "\n",
        "完全なベクトル空間（ヒルベルト空間）が $N$ （ $N$ は大きい）の次元を持つ $N \\times N$ 行列、 $H$ を考える。 次に、完全なHilbert空間の部分集合である次元 $M$ の部分空間( $\\mathcal{S}$ )を選択する。 $M$ は十分に小さい。 $H$ をこの部分空間に射影すると、射影された行列（例えば $H_\\mathcal{S}$ ）はより小さくなる（ $M \\times M$ ）。小さくなった $H_\\mathcal{S}$ は、適当な古典的数値計算法を用いて対角化し、その部分空間の固有値と固有ベクトルを生成することができる。\n",
        "\n",
        "**この部分空間は、目標とする（例えば地上の）固有状態を*サポートする*ものでなければならない。** 言い換えれば、投影されたハミルトニアン（ $H_\\mathcal{S}$ ）は、最低固有値を含む部分空間になければならない。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7f39fb3a",
      "metadata": {},
      "source": [
        "<span id=\"2-projection-and-diagonalization\" />\n",
        "\n",
        "## 2. 投影と対角化\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f8afe151-c2cf-4184-92c7-6a679f6be6e0",
      "metadata": {},
      "source": [
        "次の $8 \\times 8$ ハミルトニアン行列 $H$ の最小固有値と対応する固有ベクトルを求めたいと考える。\n",
        "\n",
        "$$\n",
        "H = \\begin{bmatrix}\n",
        " 0.2235 & -0.0390 & -0.1035 & -0.0818 &  0.1746 &  0.1091 &  0.1165 & -0.0104 \\\\\n",
        "-0.0390 &  0.6621 &  0.0706 & -0.1964 & -0.0782 &  0.2619 &  0.1095 &  0.0029 \\\\\n",
        "-0.1035 &  0.0706 &  0.9961 &  0.1724 &  0.1067 & -0.2299 & -0.1817 &  0.1571 \\\\\n",
        "-0.0818 & -0.1964 &  0.1724 & -0.1773 &  0.1019 & -0.4778 & -0.1272 & -0.0414 \\\\\n",
        " 0.1746 & -0.0782 &  0.1067 &  0.1019 &  0.1418 & -0.1359 & -0.1793 & -0.0766 \\\\\n",
        " 0.1091 &  0.2619 & -0.2299 & -0.4778 & -0.1359 &  0.1014 &  0.1696 &  0.0552 \\\\\n",
        " 0.1165 &  0.1095 & -0.1817 & -0.1272 & -0.1793 &  0.1696 &  0.4227 &  0.2702 \\\\\n",
        "-0.0104 &  0.0029 &  0.1571 & -0.0414 & -0.0766 &  0.0552 &  0.2702 &  0.4456 \\\\\n",
        "\\end{bmatrix}\n",
        "$$\n",
        "\n",
        "様々な部分空間に対する様々な投影バージョン( $H_\\mathcal{S}$ )とともに完全行列を対角化し、部分空間の選択のスケーラビリティと重要性を示す。\n",
        "\n",
        "行列 $H$ の基底状態エネルギー（最小固有値）は $-0.5357$、 *正確な*基底状態波動関数（固有ベクトル）は次のようになる：\n",
        "\n",
        "$$\n",
        "\\text{GS}_{\\text{exact}} = 0.8 * |011\\rangle + 0.6 * |101\\rangle.\n",
        "$$\n",
        "\n",
        "すなわち、行列の基底状態は、2つの計算基底状態（ベクトル） $\\vert 011 \\rangle$ と $\\vert 101 \\rangle$ によってスパンされる。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "b663cbd4-7836-4ec5-9236-fd8299f86fac",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Eigenvalues:\n",
            "[-0.5357 -0.1321  0.1049  0.1258  0.3616  0.6405  0.947   1.3039]\n",
            "Minimum eigenvalue: -0.5356560029438817\n",
            "\n",
            "Eigenvectors (columns represent vectors):\n",
            "[[-0.     -0.5612  0.098  -0.0024  0.8051 -0.0806  0.0643  0.1288]\n",
            " [-0.     -0.1403 -0.1985 -0.4249 -0.0092  0.585  -0.5952  0.2526]\n",
            " [ 0.      0.0416  0.3041  0.2122  0.1509 -0.0139 -0.5794 -0.7086]\n",
            " [ 0.8    -0.1936 -0.0127 -0.4376 -0.1081 -0.0838  0.1557 -0.2966]\n",
            " [ 0.      0.6716 -0.3535 -0.2552  0.5395  0.0954  0.1449 -0.1941]\n",
            " [ 0.6     0.258   0.017   0.5834  0.1441  0.1118 -0.2076  0.3954]\n",
            " [ 0.      0.3088  0.5504 -0.4197  0.0626 -0.468  -0.2625  0.3657]\n",
            " [-0.     -0.1146 -0.6559  0.0356 -0.0394 -0.6352 -0.3856  0.0418]]\n",
            "\n",
            "Eigenvector for the minimum eigenvalue (ground state)\n",
            "[-0.  -0.   0.   0.8  0.   0.6  0.  -0. ]\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "from scipy.linalg import eigh\n",
        "\n",
        "np.set_printoptions(precision=4, sign=\"-\", suppress=True, linewidth=100)\n",
        "\n",
        "H = np.array(\n",
        "    [\n",
        "        [0.2235, -0.039, -0.1035, -0.0818, 0.1746, 0.1091, 0.1165, -0.0104],\n",
        "        [-0.0390, 0.6621, 0.0706, -0.1964, -0.0782, 0.2619, 0.1095, 0.0029],\n",
        "        [-0.1035, 0.0706, 0.9961, 0.1724, 0.1067, -0.2299, -0.1817, 0.1571],\n",
        "        [-0.0818, -0.1964, 0.1724, -0.1773, 0.1019, -0.4778, -0.1272, -0.0414],\n",
        "        [0.1746, -0.0782, 0.1067, 0.1019, 0.1418, -0.1359, -0.1793, -0.0766],\n",
        "        [0.1091, 0.2619, -0.2299, -0.4778, -0.1359, 0.1014, 0.1696, 0.0552],\n",
        "        [0.1165, 0.1095, -0.1817, -0.1272, -0.1793, 0.1696, 0.4227, 0.2702],\n",
        "        [-0.0104, 0.0029, 0.1571, -0.0414, -0.0766, 0.0552, 0.2702, 0.4456],\n",
        "    ]\n",
        ")\n",
        "eigvals, eigvecs = eigh(H)\n",
        "\n",
        "print(\"Eigenvalues:\")\n",
        "print(eigvals)\n",
        "print(f\"Minimum eigenvalue: {eigvals.min()}\")\n",
        "\n",
        "print(\"\\nEigenvectors (columns represent vectors):\")\n",
        "print(eigvecs)\n",
        "print(\"\\nEigenvector for the minimum eigenvalue (ground state)\")\n",
        "print(eigvecs[:, np.argmin(eigvals)])"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cfaa9d24",
      "metadata": {},
      "source": [
        "次に、行列 $H$ をさまざまな部分空間に射影し、正確な基底状態が得られるかどうかをチェックする。 特に、行列を以下の部分空間に射影する：\n",
        "\n",
        "1. 正確な基底状態ベクトル( $\\vert 011 \\rangle$ と $\\vert 101 \\rangle$ )。\n",
        "2. ベクトル（例えば、 $\\vert 000 \\rangle$、 $\\vert 011 \\rangle$、 $\\vert 110 \\rangle$ ）。\n",
        "3. 正確な基底状態と基底状態でない状態の両方を含むベクトル（ただし、ヒルベルト空間のすべての可能なベクトルではない）。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8dc65713-f90d-4376-a3e3-d5a91d1c48a9",
      "metadata": {},
      "source": [
        "<span id=\"21-case-1-subspace-includes-ground-state\" />\n",
        "\n",
        "### 2.1 Case-1: サブスペースは基底状態を含む\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ceaef659-9aff-436b-a3bb-67a7e71f86e6",
      "metadata": {},
      "source": [
        "$x_1 = |011\\rangle$ と $x_2 = |101\\rangle$ の2つのベクトルによってスパンされる部分空間( $\\mathcal{S}$ )に $H$ を投影したいとする。投影されたハミルトニアンは次式で定義される：\n",
        "\n",
        "$$\n",
        "H_\\mathcal{S} = \\begin{bmatrix}\n",
        "\\langle x1 | H | x1 \\rangle & \\langle x1 | H | x2 \\rangle \\\\\n",
        "\\langle x2 | H | x1 \\rangle & \\langle x2 | H | x2 \\rangle\n",
        "\\end{bmatrix}\n",
        "$$\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "284bcb6a-1e59-4d8c-a2bb-ac8c6c6ee480",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[-0.1773 -0.4778]\n",
            " [-0.4778  0.1014]]\n"
          ]
        }
      ],
      "source": [
        "x1 = np.zeros(8)\n",
        "x1[3] = 1  # binary 011 is 3 in decimal. |011> = |3> = [0,0,0,1,0,0,0,0]\n",
        "\n",
        "x2 = np.zeros(8)\n",
        "x2[5] = 1  # binary 101 is 5 in decimal\n",
        "\n",
        "Hs = np.array([[x1 @ H @ x1.T, x1 @ H @ x2.T], [x2 @ H @ x1.T, x2 @ H @ x2.T]])\n",
        "print(Hs)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "86324b23-c718-4d58-afda-528b25fc1907",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Minimum eigenvalue: -0.535656000064295\n",
            "Eigenvector for minimum eigenvalue: [-0.8 -0.6]\n"
          ]
        }
      ],
      "source": [
        "eigvals, eigvecs = eigh(Hs)\n",
        "print(f\"Minimum eigenvalue: {eigvals.min()}\")\n",
        "print(f\"Eigenvector for minimum eigenvalue: {eigvecs[:,np.argmin(eigvals)]}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f86d7235-a177-40c5-9852-7a1652c90997",
      "metadata": {},
      "source": [
        "ここでいくつかの重要な見解を得ることができる。\n",
        "\n",
        "* つのベクトルで部分空間をスパンしたので、投影行列 ( $H_\\mathcal{S}$ ) の次元は $2 \\times 2$ となり、完全行列 $H$ ( $8 \\times 8$ ) よりも小さい。\n",
        "* 投影行列の最小固有値は、正確な基底状態の固有値と一致する。\n",
        "* 変数 `eigvecs` の値は、部分空間スパニングベクトルの振幅を表し、それを使って固有状態（基底状態）を再構成することができる。 この場合、（グローバル位相までの）正確な基底状態で終わる：\n",
        "\n",
        "$$\n",
        "|\\psi \\rangle = - (0.8 |011\\rangle + 0.6 |101\\rangle)\n",
        "$$\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "927650d6-0b89-4356-b7a1-9106c43123a0",
      "metadata": {},
      "source": [
        "<span id=\"22-case-2-subspace-excludes-some-or-all-ground-state-vectors\" />\n",
        "\n",
        "### 2.2 Case-2: 部分空間は基底状態ベクトルの一部または全てを除外する\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8d88696d-bc3d-4df1-9475-760ddaf89341",
      "metadata": {},
      "source": [
        "次に、 $H$ を、 $x_1 = |000\\rangle$、 $x_2 = |011\\rangle$、 $x_3 = |110\\rangle$ の3つのベクトルからなる部分空間に射影する。基底状態ベクトル( $\\vert 101 \\rangle$ )を除くようなベクトルを意図的に選ぶ。投影されたハミルトニアンは次式で定義される：\n",
        "\n",
        "$$\n",
        "H_\\mathcal{S} = \\begin{bmatrix}\n",
        "\\langle x1 | H | x1 \\rangle & \\langle x1 | H | x2 \\rangle & \\langle x1 | H | x3 \\rangle\\\\\n",
        "\\langle x2 | H | x1 \\rangle & \\langle x2 | H | x2 \\rangle & \\langle x2 | H | x3 \\rangle \\\\\n",
        "\\langle x3 | H | x1 \\rangle & \\langle x3 | H | x2 \\rangle & \\langle x3 | H | x3 \\rangle \\\\\n",
        "\\end{bmatrix}\n",
        "$$\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "bb6a7677-d840-4d89-bf46-8522774f071f",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[ 0.2235 -0.0818  0.1165]\n",
            " [-0.0818 -0.1773 -0.1272]\n",
            " [ 0.1165 -0.1272  0.4227]]\n"
          ]
        }
      ],
      "source": [
        "x1 = np.zeros(8)\n",
        "x1[0] = 1\n",
        "\n",
        "x2 = np.zeros(8)\n",
        "x2[3] = 1\n",
        "\n",
        "x3 = np.zeros(8)\n",
        "x3[6] = 1\n",
        "\n",
        "Hs = np.array(\n",
        "    [\n",
        "        [x1 @ H @ x1.T, x1 @ H @ x2.T, x1 @ H @ x3.T],\n",
        "        [x2 @ H @ x1.T, x2 @ H @ x2.T, x2 @ H @ x3.T],\n",
        "        [x3 @ H @ x1.T, x3 @ H @ x2.T, x3 @ H @ x3.T],\n",
        "    ]\n",
        ")\n",
        "print(Hs)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "48472db8-6d73-46f6-a332-c0185e2b6792",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Minimum eigenvalue: -0.21108858736702252\n"
          ]
        }
      ],
      "source": [
        "eigvals, eigvecs = eigh(Hs)\n",
        "print(f\"Minimum eigenvalue: {eigvals.min()}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "224ec6f4-2f0d-49bc-8810-bf9b34c59f71",
      "metadata": {},
      "source": [
        "この場合の固有値 $-0.2111$ は、完全なハミルトニアンの最小固有値 $-0.5357$ とは一致しない。 ここで重要なのは、部分的にせよ完全にせよ、ターゲット（基底）状態の基底状態を除外した部分空間に射影した場合、推定される基底状態は正確なものとは異なるということである。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a50be3fa-dade-4c76-ba07-29cea5a4cc64",
      "metadata": {},
      "source": [
        "<span id=\"23-case-3-subspace-includes-both-ground-state-and-non-ground-state-vectors\" />\n",
        "\n",
        "### 2.3 Case-3: 部分空間は基底状態ベクトルと非基底状態ベクトルの両方を包含する\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f954b02e-a807-4c7f-9ec8-02d825430311",
      "metadata": {},
      "source": [
        "次に、厳密な基底状態ベクトルと不要なベクトルを含むベクトルによって部分空間がスパンされる場合を示す。 我々の部分空間が、 $x_1 = |011\\rangle$、 $x_2 = |101\\rangle$ （正確な基底状態に存在）、 $x_3 = |111\\rangle$ （正確な基底状態に存在しない）によってスパンされているとする。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "a317bd5b-c8ad-4578-b288-e5dd234a9330",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[-0.1773 -0.4778 -0.0414]\n",
            " [-0.4778  0.1014  0.0552]\n",
            " [-0.0414  0.0552  0.4456]]\n"
          ]
        }
      ],
      "source": [
        "x1 = np.zeros(8)\n",
        "x1[3] = 1\n",
        "\n",
        "x2 = np.zeros(8)\n",
        "x2[5] = 1\n",
        "\n",
        "x3 = np.zeros(8)\n",
        "x3[7] = 1\n",
        "\n",
        "Hs = np.array(\n",
        "    [\n",
        "        [x1 @ H @ x1.T, x1 @ H @ x2.T, x1 @ H @ x3.T],\n",
        "        [x2 @ H @ x1.T, x2 @ H @ x2.T, x2 @ H @ x3.T],\n",
        "        [x3 @ H @ x1.T, x3 @ H @ x2.T, x3 @ H @ x3.T],\n",
        "    ]\n",
        ")\n",
        "print(Hs)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "f3e65657-b373-4a97-8b9b-42c47aaaca24",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Minimum eigenvalue: -0.53565600006461\n",
            "Eigenvector for minimum eigenvalue: [ 0.8  0.6 -0. ]\n"
          ]
        }
      ],
      "source": [
        "eigvals, eigvecs = eigh(Hs)\n",
        "print(f\"Minimum eigenvalue: {eigvals.min()}\")\n",
        "print(f\"Eigenvector for minimum eigenvalue: {eigvecs[:,np.argmin(eigvals)]}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "88dfda4c-102e-4597-8a81-243df6a03641",
      "metadata": {},
      "source": [
        "この場合も、完全行列（つまり正確な基底状態）と一致する最小固有値として $-0.5357$。 もうひとつの興味深い結果は、投影と対角化処理によって返される $x_3$ の振幅である。 振幅は $0$、計算された振幅とベクトルで波動関数（固有状態）を再構成すると、次のようになる：\n",
        "\n",
        "$$\n",
        "\\vert \\psi \\rangle = 0.8 |011\\rangle + 0.6 |101\\rangle + 0.0 |111\\rangle = 0.8 |011\\rangle + 0.6 |101\\rangle \\left( \\text{exact ground state} \\right)\n",
        "$$\n",
        "\n",
        "このように、部分空間に（完全なターゲット・ベクトル・セットとともに）非ターゲット・ベクトルが含まれていたとしても、投影と対角化処理によって非ターゲット・ベクトルの振幅を $0$ に設定することでフィルタリングするため、正しい固有値と固有状態を計算することができる。SQDのこの特性は、固有のノイズ耐性を提供する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4730d906-3503-4a6c-951c-a1984bfb4238",
      "metadata": {},
      "source": [
        "<span id=\"3-role-of-quantum-in-sqd\" />\n",
        "\n",
        "## 3. SQDにおける量子力学の役割\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3aa30fe6",
      "metadata": {},
      "source": [
        "以上の分析により、 *目標状態をサポート*しなければならない部分空間スパニング・ベクトルの重要性が確立された。 これは重要な問題を提起している： **どのようにして、部分空間構築のための目標状態のサポートを持つベクトルを選択するのか？**\n",
        "\n",
        "そこで登場するのが**量子コンピューター** だ。 量子力学的シナジーは、SQDパラダイムでは次のように働く：\n",
        "\n",
        "1. 適切な量子回路を使い、量子コンピューター上で目的の波動関数（例えば基底状態）が重要な支持を持つ基底状態を生成する状態を準備しようとする。 サンプリングされた基底状態（ビット列）は、ハミルトニアン投影のための部分空間にまたがる。\n",
        "2. 古典コンピュータは、ハミルトニアンを（量子コンピュータからのサンプル／ベクトルによってスパンされる）部分空間に投影し、適切な数値計算方法を用いて固有値と固有ベクトルを計算するために対角化する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2fdcc9e5-ca63-4a97-8a28-330cd81c95dc",
      "metadata": {},
      "source": [
        "SQDの量子成分と古典成分を示す![図。 量子力学では、対象の基底を準備してそこからサンプリングを行い、そのサンプリングされた部分空間に行列を古典的に射影し、射影された行列を対角化します。](https://quantum.cloud.ibm.com/learning/images/courses/quantum-diagonalization-algorithms/sqd1/sqd1-fig1.avif)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4ffbfb55-863f-480e-a21c-d929c810396b",
      "metadata": {},
      "source": [
        "このような量子状態を準備する方法はいくつかあり、問題によって変分的であったり非変分的であったりする。\n",
        "\n",
        "次の2つのレッスンでは、状態を準備し、そこからサンプリングする2つの具体例を示す。\n",
        "\n",
        "1. レッスン4では、化学問題（ $N_2$ 分子の基底状態エネルギー推定）のサンプルを生成するために、パラメータ化局所ユニタリー結合ジャストロー（LUCJ）アサッツを使用します。 古典的なクラスターシングル・アンド・ダブルス（CCSD）計算から得られたパラメータを用いてLUCJアサッツを初期化する。\n",
        "2. レッスン5では、クリロフ基底状態からサンプリングして、物性物理学の問題の部分空間にまたがるようにする。 このアプローチは本質的に非変数的である。\n",
        "\n",
        "上記の問題固有のアプローチに加えて、状態準備のための一般的なアプローチとして、古典的なオプティマイザを使ってアサッツパラメータを繰り返し更新する変分アサッツがある。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1aa0044f-d798-4510-bd67-736a3e574695",
      "metadata": {},
      "source": [
        "変分量子回路から量子サンプリングを経て、行列が射影され対角化される古典計算に至るまでのフローチャート![。 その後、その結果を従来の最適化アルゴリズムに投入して新しい変分パラメータを選択し、再び変分量子回路に戻ります。](https://quantum.cloud.ibm.com/learning/images/courses/quantum-diagonalization-algorithms/sqd1/sqd1-fig2.avif)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5addd026",
      "metadata": {},
      "source": [
        "フォールトトレラント以前の量子コンピュータからのサンプルは、ノイズが多い可能性がある。 SQDは、ノイズの多いサンプルを修正するために、自己無撞着な構成回復プロセスを採用している [\\[1\\]](#references)。 コンフィギュレーションリカバリープロセスについてさらに詳しく説明し、レッスン4では、化学問題の基底状態エネルギー推定を改良するために、ノイズの多いサンプルを反復的に修正するために応用します。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4af71b3d-2749-417f-b42d-4d7bbc4930b6",
      "metadata": {},
      "source": [
        "<span id=\"31-notes-on-ground-state-support\" />\n",
        "\n",
        "### 3.1 基底状態サポートに関する注記\n",
        "\n",
        "*基底状態支持の*概念についてもう少し説明しよう。 基底状態のサポートは、基底状態が（カットオフ閾値までの）非ゼロ振幅を持つ基底状態の集合として定義できる。\n",
        "\n",
        "$3$ -qubit問題の正確な基底状態が次のとおりであるとする\n",
        "\n",
        "$$\n",
        "\\vert \\psi \\rangle = \\frac{1}{\\sqrt{2}} \\vert 000 \\rangle + \\frac{1}{\\sqrt{2}} \\vert 111 \\rangle\n",
        "$$\n",
        "\n",
        "上記の状態をサンプリングすると、計算基底状態 $\\{\\vert 000 \\rangle$、 $\\vert 111 \\rangle \\}$ のセットが得られるはずである（他の計算基底状態は基底状態では振幅がゼロであるため、理想的にはサンプリング中には現れない）。\n",
        "\n",
        "理想的には、この状態の基底ベクトルのセットは $\\{ \\vert 000 \\rangle, \\vert 111 \\rangle \\}$ （言い換えれば、この状態の部分空間はこれら2つの基底ベクトルによってスパンされる）からなる。\n",
        "\n",
        "実際には、他の多くの状態をサンプリングしても同じベクトルセットが得られるので、正確な基底状態を用意する必要はない。 例:\n",
        "\n",
        "$$\n",
        "\\begin{align}\n",
        "\\vert \\psi_a \\rangle = 0.8 \\vert 000 \\rangle + 0.6 \\vert 111 \\rangle &\\xrightarrow{\\text{Sampling}} \\{ \\vert 000 \\rangle, \\vert 111 \\rangle \\} \\\\\n",
        "\\vert \\psi_b \\rangle = \\frac{1}{2} \\vert 000 \\rangle + \\frac{\\sqrt{3}}{2} \\vert 111 \\rangle &\\xrightarrow{\\text{Sampling}} \\{ \\vert 000 \\rangle, \\vert 111 \\rangle \\} \\\\\n",
        "\\vert \\psi_c \\rangle = \\frac{1}{2} \\vert 000 \\rangle + \\frac{1}{2} \\vert 111 \\rangle + \\frac{1}{\\sqrt{2}} \\vert 101 \\rangle &\\xrightarrow{\\text{Sampling}} \\{ \\vert 000 \\rangle, \\vert 101 \\rangle, \\vert 111 \\rangle \\}\n",
        "\\end{align}\n",
        "$$\n",
        "\n",
        "上記の状態のいずれかを準備し、そこからサンプリングすることで、基底*状態において*ゼロ以外の振幅を持つベクトルが生成される。 なお、 $\\vert \\psi_c \\rangle$ のサンプリングには、正確な基底状態で $0$ の振幅を持つ余分なベクトル $\\vert 101 \\rangle$ が1つ含まれている。 しかし、投影と対角化操作によって不要なベクトルの振幅が $0$ に設定され、期待される固有値を得ることができ、正しい固有状態を再構成することができるため、このようなベクトルを部分空間に含めても問題ないことを先に示した。\n",
        "\n",
        "正しいアンザッツの支え方と間違ったアンザッツの支え方の![図解。 優れたアンザッツは、基底状態の支持集合を完全に包含する支持集合を持つ。 不適切なアンザッツには、基底状態のサポートが一部しか含まれていないか、まったく含まれていない。](https://quantum.cloud.ibm.com/learning/images/courses/quantum-diagonalization-algorithms/sqd1/sqd1-fig3.avif)\n",
        "\n",
        "従って、正確な基底状態を準備し、そこからサンプリングする必要はない。 実際、正確な基底状態は*事前に*分からないため、これを行うのは難しい場合があり、特に波動関数（状態）が歪んでいていくつかの基底状態の確率が非常に高い場合は、正確な基底状態を準備してサンプリング**しない方**が有利な場合が多いです。 次の波動関数を考えてみよう：\n",
        "\n",
        "$$\n",
        "\\vert \\psi \\rangle = 0.7 \\vert 000 \\rangle - 0.7 \\vert 010 \\rangle + 0.1 \\vert 101 \\rangle - 0.01 \\vert 111 \\rangle\n",
        "$$\n",
        "\n",
        "これは歪んだ波動関数であり、基底状態 $\\vert 000 \\rangle$ と $\\vert 010 \\rangle$ は $\\vert 101 \\rangle$ と $\\vert 111 \\rangle$ に比べてはるかに大きな振幅を持つ。サンプリングすると、 $\\vert 000 \\rangle$ と $\\vert 010 \\rangle$ がより頻繁に得られます（ $\\text{sampling probability} = \\vert \\text{amplitude} \\vert^{2}$ $\\approx 49\\%$ は $\\vert 000 \\rangle$ と $\\vert 010 \\rangle$ それぞれに、 $\\approx 1\\%$ は $\\vert 101 \\rangle$ に、 $\\approx 0.01\\%$ は $\\vert 111 \\rangle$ に）。サンプリング予算 （*ショット* ）が有限の場合、サンプリングされた集合には $\\vert 000 \\rangle$ と $\\vert 010 \\rangle$ しか含まれない可能性が高い。先に示したように、このような欠落ベクトルを含む集合で部分空間をスパンすると、真の最小固有値を見つけることができなくなる。 したがって、地上波でサポートされている状態からサンプリングすることは有益（かつ必要）である。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "127754c4-74e1-4583-b252-ddd07cef23cd",
      "metadata": {},
      "source": [
        "<span id=\"32-a-case-against-uniform-sampling\" />\n",
        "\n",
        "### 3.2 均一サンプリングに対する反論\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5a51c9ce-356d-4ff0-956e-3fd42654d974",
      "metadata": {},
      "source": [
        "部分空間にまたがるように、一様分布からサンプルを引くのは魅力的かもしれない。 小さな問題には有効かもしれないが、より大きな、より現実的な問題では失敗し始めるだろう。 多数の量子ビットを含む大規模な問題では、ヒルベルト空間は法外に大きくなる可能性がある。 例えば、32量子ビットのヒルベルト空間には、 $4$ 億以上の可能な基底ベクトル( $2^{32} = 4,294,967,296$ )がある。その空間から有限のサンプルバジェット（対角化プロセスが実行可能であるように、 $10000$ のベクトル）で一様にサンプリングすると、プロセスがランダムになるため、基底状態をサポートするベクトルを除外する部分空間が多くなる可能性があります。 **したがって、量子回路を活用して基底状態からサンプリングする体系的な方法が必要である。**\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7ad257c8-834e-4343-b37a-5ff7d082b778",
      "metadata": {},
      "source": [
        "<span id=\"4-sqd-and-sparsity-of-the-wave-function\" />\n",
        "\n",
        "## 4. SQDと波動関数の疎性\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5094d2ae-c6fc-4e13-b476-ca7ebfd0c356",
      "metadata": {},
      "source": [
        "完全なヒルベルト空間と実現可能な部分空間の次元のギャップは、SQDのもう一つの重要な側面をもたらす。 SQDアプローチは、基底状態のごく一部が無視できない振幅を持つような、疎な波動関数や集中した波動関数に対して効果的である。 その背景には2つの理由がある：\n",
        "\n",
        "1. もし波動関数がブロードで（つまり、多くの基底状態が無視できない振幅を持つ）、部分空間にターゲット状態のサポートを持つベクトルが含まれていない場合、誤った固有値と固有ベクトルが得られる可能性がある。\n",
        "2. 上記の問題を避けるためには、部分空間に多くのベクトルを含める必要がある。 しかし、投影されたハミルトニアンの次元は、部分空間の次元と直接関係している。 部分空間が大きくなれば、ハミルトニアンも大きくなり、対角化が不可能になる可能性がある。\n",
        "\n",
        "この問題を次の行列( $H_{new}$ )で示す。 $H_{new}$ の最低固有値は $-2.2081$ であり、対応する波動関数（固有状態）はブロードである：\n",
        "\n",
        "$$\n",
        "|\\psi\\rangle = \\frac{|000\\rangle + |001\\rangle + |010\\rangle + |011\\rangle + |100\\rangle + |101\\rangle + |110\\rangle + |111\\rangle}{\\sqrt{8}}\n",
        "$$\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "0a53cd27-478c-44e8-907e-9dc67093bc95",
      "metadata": {},
      "outputs": [],
      "source": [
        "H_new = np.array(\n",
        "    [\n",
        "        [-0.958, 0.1853, -0.2663, -0.3875, -0.0524, -0.3779, -0.0145, -0.3369],\n",
        "        [0.1853, -0.4081, -0.8549, -0.2312, 0.0615, -0.2493, -0.3804, -0.3312],\n",
        "        [-0.2663, -0.8549, -0.6929, -0.0063, -0.0478, -0.0236, -0.2494, -0.0669],\n",
        "        [-0.3875, -0.2312, -0.0063, -0.4468, -0.6301, -0.4627, -0.1188, 0.0753],\n",
        "        [-0.0524, 0.0615, -0.0478, -0.6301, -0.6664, -0.1514, -0.3571, -0.3644],\n",
        "        [-0.3779, -0.2493, -0.0236, -0.4627, -0.1514, -0.9605, 0.0137, 0.0035],\n",
        "        [-0.0145, -0.3804, -0.2494, -0.1188, -0.3571, 0.0137, -1.1449, 0.0433],\n",
        "        [-0.3369, -0.3312, -0.0669, 0.0753, -0.3644, 0.0035, 0.0433, -1.2307],\n",
        "    ]\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "751bd77e",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Minimum eigenvalue: -2.208137504726661\n",
            "Eigenvector for minimum eigenvalue: [0.3536 0.3536 0.3536 0.3536 0.3535 0.3536 0.3535 0.3535]\n"
          ]
        }
      ],
      "source": [
        "eigvals, eigvecs = eigh(H_new)\n",
        "print(f\"Minimum eigenvalue: {eigvals.min()}\")\n",
        "print(f\"Eigenvector for minimum eigenvalue: {eigvecs[:,np.argmin(eigvals)]}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "331030ee-7831-4b41-8863-e9c8647124a9",
      "metadata": {},
      "source": [
        "$H_{new}$ を4つのベクトルからなる部分空間に投影し、固有値を計算するとする： $|000\\rangle$ $|010\\rangle$, $|101\\rangle$, $|110\\rangle$ の4つのベクトルにまたがる部分空間に投影し、固有値を計算するとする。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "2591384f-ba2e-46ee-a607-4ac401f342a9",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[-0.958  -0.2663 -0.3779 -0.0145]\n",
            " [-0.2663 -0.6929 -0.0236 -0.2494]\n",
            " [-0.3779 -0.0236 -0.9605  0.0137]\n",
            " [-0.0145 -0.2494  0.0137 -1.1449]]\n"
          ]
        }
      ],
      "source": [
        "x1 = np.zeros(8)\n",
        "x1[0] = 1\n",
        "\n",
        "x2 = np.zeros(8)\n",
        "x2[2] = 1\n",
        "\n",
        "x3 = np.zeros(8)\n",
        "x3[5] = 1\n",
        "\n",
        "x4 = np.zeros(8)\n",
        "x4[6] = 1\n",
        "\n",
        "H_new_s = np.array(\n",
        "    [\n",
        "        [x1 @ H_new @ x1.T, x1 @ H_new @ x2.T, x1 @ H_new @ x3.T, x1 @ H_new @ x4.T],\n",
        "        [x2 @ H_new @ x1.T, x2 @ H_new @ x2.T, x2 @ H_new @ x3.T, x2 @ H_new @ x4.T],\n",
        "        [x3 @ H_new @ x1.T, x3 @ H_new @ x2.T, x3 @ H_new @ x3.T, x3 @ H_new @ x4.T],\n",
        "        [x4 @ H_new @ x1.T, x4 @ H_new @ x2.T, x4 @ H_new @ x3.T, x4 @ H_new @ x4.T],\n",
        "    ]\n",
        ")\n",
        "print(H_new_s)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "0f388339-cf0b-4584-bf83-90afb3ec13cc",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Minimum eigenvalue: -1.4266552340586673\n"
          ]
        }
      ],
      "source": [
        "eigvals, eigvecs = eigh(H_new_s)\n",
        "print(f\"Minimum eigenvalue: {eigvals.min()}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "27b0d944-57a8-4cf5-a207-2363fa69a298",
      "metadata": {},
      "source": [
        "上の例は、波動関数がブロードで、基底状態を部分空間に含めない場合、固有値計算が不正確になることを示している。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9cbdb4ce-fb6f-49e4-8eff-649d40345366",
      "metadata": {},
      "source": [
        "<span id=\"5-sqd-vs-vqe\" />\n",
        "\n",
        "## 5. SQD対VQE\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8abdcd50-617b-40a6-82db-f1495078ca4e",
      "metadata": {},
      "source": [
        "先に述べたように、SQDは、基底状態のサポートを準備し、そこからサンプリングするために、変分量子回路と反復的なパラメータ更新を必要とする可能性がある。 この反復パラメータ更新ルーチンはVQEと似ているので、これらの方法はどう違うのか、VQEに対するSQDの利点は何なのかを問うことができる このセクションでは、最小基底セット(`sto-3g`)で記述された $N_2$ 分子を例として、SQDの手法を比較し、その利点を議論する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0de2cec1-65b2-4186-9ea1-fab2fd48f413",
      "metadata": {},
      "source": [
        "|              | ブイキューイー                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | SQD                                                                                                                                                                                                                                                     |\n",
        "| :----------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n",
        "| 測定オーバーヘッド    | **多くのパウリ項、多くの測定回路：** 分子のハミルトニアンには、 $2951$ ユニークなパウリ項がある。 パウリ項は $X$ と $Y$ の項を含むことができ、典型的な量子測定は $Z$ -basisで行われるため、これらの項を評価するためには測定基底を変更する必要がある。 測定用に最適化された場合、 $2951$ 項を $1187$ グループにグループ化することができ、各グループは単一の回路を使用して評価することができる。 したがって、すべてのパウリ項を評価するためには、少なくとも $1187$。 **1サーキットあたりのショット数が多いので、ばらつきが少ない**。 ここでも、各パウリ項の評価された期待値には、 $\\sqrt{shots}$ に反比例して依存する分散がついている。 したがって、各項を正確に推定するためには、回路ごとに多くのショットを割り当てる必要がある。 例えば、化学的精度（ $1$ kcal/mol）を達成するためには、通常、回路あたり $10^5$ - $10^7$ のオーダーのショットが必要である。 従って、VQEは多くの測定回路を必要とし、各回路は一定のショット数を持つ。 実用的なケースでは、この測定オーバーヘッドは制約となりうる。 | SQDでは、グループ化されたパウリ項ごとに異なる測定回路は必要ない。 通常、1つの回路を一定のショット数で測定する。 問題によってはショット数を大きく設定することもあるが、オーバーヘッドはVQEよりはるかに小さいままだ。 また、対角化処理によるエネルギー推定は厳密である。つまり、計算された固有値はその部分空間において厳密であり、VQEのように分散を持たない。 (クリロフ基底状態サンプリング（レッスン5）の場合、複数の回路を測定する必要があるが、回路数はVQEよりはるかに少ないままである）。 |\n",
        "| 推定エネルギー・バウンド | VQEでは、エネルギー推定値は境界がなく、ノイズのために真の最小値よりも低くなる可能性がある。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | SQDのエネルギー推定プロセスは、常に基底状態のエネルギーに対する上限を生成し、推定されたエネルギーが真の基底状態のエネルギーより低くなることはない。                                                                                                                                                                             |\n",
        "| ノイズ耐性        | VQEエネルギー推定は、フォールト・トレラント量子コンピュータからのノイズの影響を受けやすい。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | SQDにはノイズに対する固有の耐性がある。 フォールト・トレラント量子コンピュータは、ノイズの多いサンプルを生成することができる。 仮にそれらのサンプルを部分空間に含めたとしても、その後の対角化によって、それらのサンプルの振幅をゼロに設定することで、それらのサンプルを抑制することができる。 また、SQDに関連して、SQDノイズ耐性をさらに向上させる*コンフィギュレーション・リカバリーと*呼ばれる手法についても説明する。                                     |\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "de8f1df2-1ef9-4eea-9621-e17db8489c4c",
      "metadata": {},
      "source": [
        "<span id=\"6-summary\" />\n",
        "\n",
        "## 6. まとめ\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "103dfaf0-89c9-4b5d-bd70-fcdba4b5b4da",
      "metadata": {},
      "source": [
        "1. SQDでは、量子コンピュータがサンプルを生成し、古典コンピュータがサンプルによってスパンされる部分空間にハミルトニアンを投影して対角化し、固有値と固有ベクトルを計算する。\n",
        "2. 生成されるサンプルは、ターゲット（基底）状態のサポートからのものでなければならない。\n",
        "3. 問題に応じて、量子状態の準備とサンプル生成のフローは反復的または非反復的である。\n",
        "4. SQDはスパースな波動関数に最適です。 広範な波動関数は、正確な解を得るために大きな部分空間を必要とするため、古典的な射影と対角化操作はコストがかかる。\n",
        "5. SQDは、VQEよりも測定オーバーヘッドが少なく、推定基底状態エネルギーに上限があるなど、いくつかの利点があり、よりスケーラブルである。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "56c2ca63",
      "metadata": {},
      "source": [
        "<span id=\"references\" />\n",
        "\n",
        "## 参照\n",
        "\n",
        "\\[1] J. ロブレド＝モレノら、 「量子中心スパコンで厳密解を超える化学」（2024年）。 [arXiv:quant-ph/2405.05068](https://arxiv.org/abs/2405.05068).\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
}