{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "6581d769-6f75-4b26-90e3-39c28f22a74c",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"변분 양자 고유값 해법기\"\n",
        "description: \"이 VQE 소개는 그 구성 요소, 기본 구현을 다루며 효율성과 유용성을 결정하는 요인들을 논의합니다.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore ansä IIIZ IZII IIZI ZIII IZIZ IIZZ ZIIZ IZZI ZZII ZIZI XXYY YYXX ansätze ansatze infty IZZX XIYX ZZXZ ZZZX IIXX IIXZ IZXZ IXXZ XZXZ ZIXZ */}\n",
        "\n",
        "<span id=\"the-variational-quantum-eigensolver-vqe\" />\n",
        "\n",
        "# 변분 양자 고유값 해법기(VQE)\n",
        "\n",
        "이 강의에서는 가변 양자 아이겐솔버를 소개하고, 양자 컴퓨팅의 기본 알고리즘으로서 그 중요성을 설명하며, 그 장단점을 살펴봅니다. 증강 방법 없이 VQE 자체만으로는 최신 유틸리티 규모의 양자 계산에 충분하지 않을 수 있습니다. 그럼에도 불구하고 이는 전형적인 클래식-퀀텀 하이브리드 방식으로서 더 많은 고급 알고리즘이 구축되는 중요한 기반이 됩니다.\n",
        "\n",
        "이 동영상에서는 VQE에 대한 개요와 효율성에 영향을 미치는 요인에 대해 설명합니다. 아래 텍스트는 더 자세한 내용을 추가하고 키스킷을 사용하여 VQE를 구현합니다.\n",
        "\n",
        "<IBMVideo id=\"134325519\" title=\"이 동영상에서는 크리스 포터가 가변 양자 아이겐솔버의 주요 구성 요소에 대해 설명합니다. 여기에는 해밀턴, 안사츠, 고전적 최적화 기법 및 추정기가 포함됩니다. 또한 VQE의 효율성에 영향을 미치는 요인에 대해서도 설명합니다.\" />\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "21115450-3f01-4e19-860d-48e31f401b1f",
      "metadata": {},
      "source": [
        "<span id=\"1-what-is-vqe\" />\n",
        "\n",
        "## 1. VQE란 무엇인가요?\n",
        "\n",
        "변분 양자 고유값 해법기는 고전 컴퓨팅과 양자 컴퓨팅을 결합하여 특정 작업을 수행하는 알고리즘입니다. VQE 계산에는 네 가지 주요 구성 요소가 있습니다:\n",
        "\n",
        "* **운영자** : 종종 해밀턴( $H$ )이라고 부르는데, 최적화하고자 하는 시스템의 속성을 설명합니다. 이를 다른 말로 표현하면 최소 고유값에 해당하는 이 연산자의 고유 벡터를 구하는 것입니다. 우리는 흔히 이 고유 벡터를 '접지 상태'라고 부릅니다.\n",
        "* \"**안사츠** \"('접근'을 뜻하는 독일어): 찾고자 하는 고유 벡터에 근사한 양자 상태를 준비하는 양자 회로입니다. 실제로 안사츠는 양자 회로의 일종으로, 안사츠의 일부 게이트는 매개변수화된, 즉 우리가 변경할 수 있는 파라미터가 공급되기 때문입니다. 이 양자 회로 제품군은 기저 상태에 근사한 양자 상태 제품군을 준비할 수 있습니다.\n",
        "* **추정량** : 현재 변분 양자 상태에 대해 연산자 $H$ 의 기대값을 추정하는 방법. 때로는 우리가 진정으로 중요하게 여기는 것이 바로 이 기대값이며, 이를 비용 함수라고 부릅니다. 때로는 하나 이상의 기대값을 바탕으로 표현할 수 있는, 좀 더 복잡한 함수에 관심을 두기도 합니다.\n",
        "* **고전적인 최적화** 도구: 비용 함수를 최소화하기 위해 매개 변수를 변경하는 알고리즘입니다.\n",
        "\n",
        "이러한 각 구성 요소에 대해 자세히 살펴보겠습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7dbd605e-a440-446b-bc05-e2e301796bf2",
      "metadata": {},
      "source": [
        "<span id=\"11-the-operator-hamiltonian\" />\n",
        "\n",
        "### 1.1 연산자(해밀토니안)\n",
        "\n",
        "VQE 문제의 핵심은 관심 있는 시스템을 설명하는 연산자입니다. 여기서는 이 연산자의 최저 고유값과 해당 고유 벡터가 어떤 과학적 또는 비즈니스 목적에 유용하다고 가정하겠습니다. 예를 들어 분자를 설명하는 화학 해밀턴은 연산자의 최저 고유값이 분자의 기저 상태 에너지에 해당하고 해당 고유 상태는 분자의 기하학적 구조 또는 전자 구성을 설명합니다. 또는 운영자는 최적화할 특정 프로세스의 비용을 설명할 수 있으며, 고유 상태는 경로 또는 관행에 해당할 수 있습니다. 물리학 같은 일부 분야에서 '해밀턴'은 거의 항상 물리 시스템의 에너지를 설명하는 연산자를 가리킵니다. 그러나 양자 컴퓨팅에서는 비즈니스 또는 물류 문제를 설명하는 양자 연산자를 '해밀턴 연산자'라고도 부르는 것이 일반적입니다. 이 규칙을 여기에 적용합니다.\n",
        "\n",
        "![원자 궤도의 이미지와, 수많은 노드와 그 사이의 연결로 이루어진 네트워크의 이미지.](https://quantum.cloud.ibm.com/learning/images/courses/quantum-diagonalization-algorithms/vqe/vqe-fig1.avif)\n",
        "\n",
        "물리 또는 최적화 문제를 큐비트에 매핑하는 것은 일반적으로 간단한 작업이 아니지만, 이 과정에서는 이러한 세부 사항은 다루지 않습니다. 문제를 양자 연산자에 매핑하는 일반적인 논의는 [실제로 양자 컴퓨팅에서](/learning/courses/quantum-computing-in-practice) 찾을 수 있습니다. 화학 문제를 양자 연산자로 매핑하는 방법에 대한 자세한 내용은 [양자 화학을 이용한 VQE에서](/learning/courses/quantum-chem-with-vqe) 확인할 수 있습니다.\n",
        "\n",
        "이 과정의 목적상 해밀턴의 형태가 알려져 있다고 가정하겠습니다. 예를 들어, 간단한 수소 분자에 대한 해밀토니안(특정 활성 공간 가정 하에서 조던-위그너 매퍼를 사용)은 다음과 같습니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "89b425d8-f54f-4f98-996e-c303f77edb25",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.quantum_info import SparsePauliOp\n",
        "\n",
        "hamiltonian = SparsePauliOp(\n",
        "    [\n",
        "        \"IIII\",\n",
        "        \"IIIZ\",\n",
        "        \"IZII\",\n",
        "        \"IIZI\",\n",
        "        \"ZIII\",\n",
        "        \"IZIZ\",\n",
        "        \"IIZZ\",\n",
        "        \"ZIIZ\",\n",
        "        \"IZZI\",\n",
        "        \"ZZII\",\n",
        "        \"ZIZI\",\n",
        "        \"YYYY\",\n",
        "        \"XXYY\",\n",
        "        \"YYXX\",\n",
        "        \"XXXX\",\n",
        "    ],\n",
        "    coeffs=[\n",
        "        -0.09820182 + 0.0j,\n",
        "        -0.1740751 + 0.0j,\n",
        "        -0.1740751 + 0.0j,\n",
        "        0.2242933 + 0.0j,\n",
        "        0.2242933 + 0.0j,\n",
        "        0.16891402 + 0.0j,\n",
        "        0.1210099 + 0.0j,\n",
        "        0.16631441 + 0.0j,\n",
        "        0.16631441 + 0.0j,\n",
        "        0.1210099 + 0.0j,\n",
        "        0.17504456 + 0.0j,\n",
        "        0.04530451 + 0.0j,\n",
        "        0.04530451 + 0.0j,\n",
        "        0.04530451 + 0.0j,\n",
        "        0.04530451 + 0.0j,\n",
        "    ],\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "14c20ee9-51ad-4cc9-be36-7a33fae6c56a",
      "metadata": {},
      "source": [
        "위의 해밀턴에서는 `ZZII` 및 `YYYY` 같은 용어가 서로 통용되지 않는다는 점에 유의하세요. 즉, `ZZII` 을 평가하려면 큐비트 3에서 폴리 Z 연산자를 측정해야 합니다(다른 측정 중에서도). 하지만 `YYYY` 을 평가하려면 동일한 큐비트인 큐비트 3에서 폴리 Y 연산자를 측정해야 합니다. 동일한 큐비트에서 Y 연산자와 Z 연산자 사이에는 불확실성 관계가 존재하며, 두 연산자를 동시에 측정할 수 없습니다. 이 점은 아래에서, 그리고 실제로 이 과정 전반에 걸쳐 다시 살펴보겠습니다.\n",
        "위의 해밀턴은 $16\\times 16$ 행렬 연산자입니다. 연산자를 대각선으로 대각선화하여 최저 에너지 고유값을 찾는 것은 어렵지 않습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "9703b61e-ff90-4e94-8999-242d0c6766c0",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The ground state energy is  -1.1459778447627311 hartrees\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "\n",
        "A = np.array(hamiltonian)\n",
        "eigenvalues, eigenvectors = np.linalg.eigh(A)\n",
        "print(\"The ground state energy is \", min(eigenvalues), \"hartrees\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "01a76c42-29e7-455a-acd6-55490f36121b",
      "metadata": {},
      "source": [
        "무차별 대입 방식의 고전적인 아이겐솔버는 약물이나 단백질처럼 매우 큰 원자 시스템의 에너지나 기하학적 구조를 설명할 수 있는 규모로 확장할 수 없습니다. VQE는 이 문제에서 양자 컴퓨팅을 활용하려는 초기 시도 중 하나입니다.\n",
        "\n",
        "이번 레슨에서는 위의 내용보다 훨씬 더 큰 해밀턴 사람들을 만나게 될 것입니다. 하지만 이 과정의 뒷부분에서 VQE를 보강하거나 대체할 수 있는 고급 도구를 소개하기 전에 VQE가 할 수 있는 일의 한계를 넘어서는 것은 낭비일 수 있습니다.\n",
        "\n",
        "<span id=\"12-ansatz\" />\n",
        "\n",
        "### 1.2 안쯔츠\n",
        "\n",
        "'안사츠'는 독일어로 '접근'이라는 뜻입니다. 독일어로 정확한 복수형은 \"ansätze\"이지만, \"ansatzes\" 또는 \"ansatze\"로 표기하는 경우가 많습니다. VQE의 맥락에서 안사츠는 연구 중인 시스템의 기저 상태에 가장 근접한 다중 큐비트 파동 함수를 생성하는 데 사용하는 양자 회로로, 연산자의 가장 낮은 기대값을 생성합니다. 이 양자 회로에는 변수 매개변수(종종 변수 벡터에 함께 수집되는 $\\vec{\\theta}$ )가 포함됩니다.\n",
        "\n",
        "![“theta”라고 표기된 변분 매개변수를 가진 양자 회로의 이미지.](https://quantum.cloud.ibm.com/learning/images/courses/quantum-diagonalization-algorithms/vqe/vqe-fig2.avif)\n",
        "\n",
        "가변 매개변수의 초기 값 세트 $\\vec{\\theta_0}$ 가 선택됩니다. 우리는 회로 $U_{\\text{var}}(\\vec{\\theta_0})$ 에서 안사츠의 단일 연산을 호출할 것입니다. 기본적으로 IBM® 양자 컴퓨터의 모든 큐비트는 $|0\\rangle$ 상태로 초기화됩니다. 회로가 실행되면 큐비트의 상태는 다음과 같습니다\n",
        "\n",
        "$$\n",
        "|\\psi(\\vec{\\theta_0})\\rangle=U_{\\text{var}}(\\vec{\\theta_0})|0\\rangle^{\\otimes N}\n",
        "$$\n",
        "\n",
        "물리 시스템의 언어를 사용하여 가장 낮은 에너지만 있으면 에너지를 여러 번 측정하고 가장 낮은 에너지를 취하는 것만으로 이를 추정할 수 있습니다. 하지만 일반적으로 가장 낮은 에너지 또는 고유값을 산출하는 구성도 원합니다. 따라서 다음 단계는 양자 측정을 통해 해밀턴의 기대값을 추정하는 것입니다. 여기에는 많은 것이 들어갑니다. 그러나 에너지 $E_j$ (다시 물리 시스템의 언어를 사용)를 측정할 확률 $P_j$ 이 기대값과 다음과 같이 관련되어 있다는 점에 주목하면 이 과정을 정성적으로 이해할 수 있습니다:\n",
        "\n",
        "$$\n",
        "\\langle \\psi(\\vec{\\theta_0}) |H|\\psi (\\vec{\\theta_0}) \\rangle\n",
        "$$\n",
        "\n",
        "확률 $P_j$ 은 또한 고유 상태 $|\\phi_j\\rangle$ 와 시스템의 현재 상태 $|\\psi(\\vec{\\theta_0})\\rangle$ 사이의 중첩과 관련이 있습니다:\n",
        "\n",
        "$$\n",
        "P_j=|\\langle \\phi_j|\\psi(\\vec{\\theta_0})\\rangle|^2 = |\\langle \\phi_j|U_{\\text{var}}(\\vec{\\theta_0})|0\\rangle^{\\otimes N}|^2\n",
        "$$\n",
        "\n",
        "따라서 해밀턴을 구성하는 폴리 연산자를 여러 번 측정하여 시스템의 현재 상태에서의 해밀턴의 기대값을 추정할 수 있습니다 $|\\psi(\\vec{\\theta_0})\\rangle$. 다음 단계는 매개변수 $\\vec{\\theta}$ 를 변경하여 시스템의 최저 에너지(접지) 상태에 더 가깝게 접근하는 것입니다. 안사츠의 변형 매개변수 때문에 이를 **변형 형식**이라고 부르기도 합니다.\n",
        "\n",
        "그 변분 과정을 다루기 전에, 상태를 “적절한 추정값” 상태에서 시작하는 것이 종종 유용하다는 점에 유의하십시오. 여러분은 자신의 시스템에 대해 충분히 잘 알고 있어서 $|0\\rangle^{\\otimes N}$ 보다 더 정확한 초기 추정을 할 수 있을지도 모릅니다. 예를 들어, 화학 분야에서는 큐비트를 하트리-팍(Hartree-Fock) 상태로 초기화하는 것이 일반적입니다. 변분 매개변수가 전혀 포함되지 않은 이 초기 추정은 **‘기준 상태’라고** 부릅니다. 기준 상태를 생성하는 데 사용되는 양자 회로를 $U_{ref}$ 라고 부르자. 기준 상태를 나머지 안자츠와 구별해야 할 때는 $U_{\\text{ansatz}}(\\vec{\\theta}) =U_{\\text{var}}(\\vec{\\theta})U_{\\text{ref}}$ 를 사용한다. 이와 동등하게\n",
        "\n",
        "$$\n",
        "\\begin{aligned}\n",
        "|\\psi_{\\text{ref}}\\rangle&=U_{\\text{ref}}|0\\rangle^{\\otimes N}\\\\\n",
        "|\\psi_{\\text{ansatz}}(\\vec{\\theta})\\rangle&=U_{var}(\\vec{\\theta})|\\psi_{\\text{ref}}\\rangle = U_{\\text{var}}(\\vec{\\theta})U_{\\text{ref}}|0\\rangle^{\\otimes N}.\n",
        "\\end{aligned}\n",
        "$$\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b7f66a1f-93cb-47ee-81c3-6fbf62392003",
      "metadata": {},
      "source": [
        "<span id=\"13-estimator\" />\n",
        "\n",
        "### 1.3 추정기\n",
        "\n",
        "특정 변형 상태 $|\\psi(\\vec{\\theta})\\rangle$ 에서 해밀턴의 기대값을 추정하는 방법이 필요합니다. 전체 연산자 $H$ 를 직접 측정할 수 있다면 여러 번(예: $N$ ) 측정하고 측정된 값의 평균을 구하는 것만큼 간단할 것입니다:\n",
        "\n",
        "$$\n",
        "\\langle \\psi(\\vec{\\theta})|H|\\psi(\\vec{\\theta})\\rangle _N \\approx \\frac{1}{N}\\sum_{j=1}^N {E_j}\n",
        "$$\n",
        "\n",
        "여기서 $\\approx$ 기호는 이 기대값이 $N\\rightarrow \\infty$ 과 같이 한계 내에서만 정확하게 맞을 수 있음을 알려줍니다. 그러나 회로에서 수천 개의 측정이 이루어지면 기대값의 샘플링 오차는 상당히 낮아집니다. 매우 정밀한 계산에 문제가 되는 소음과 같은 다른 고려 사항도 있습니다.\n",
        "\n",
        "그러나 일반적으로 $H$ 를 한 번에 모두 측정하는 것은 불가능합니다. $H$ 에는 서로 교환하지 않는 여러 개의 파울리 X, Y, Z 연산자가 포함될 수 있습니다. 따라서 해밀토니안은 동시에 측정할 수 있는 연산자 그룹으로 나뉘어야 하며, 각 그룹은 별도로 추정된 후 그 결과를 합쳐 기대값을 구해야 한다. 다음 강의에서 고전적 접근법과 양자적 접근법의 확장성에 대해 다룰 때, 이 주제를 더 자세히 다시 살펴보겠습니다. 측정 과정의 이러한 복잡성 때문에, 이러한 추정을 수행하기 위해서는 매우 효율적인 코드가 필요한 것입니다. 이번 강의와 이후 강의에서는 이러한 목적으로 ‘ IBM Quantum ’ 기본 추정기를 사용할 것입니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8b68d38e-80ad-4e02-815f-576806ec3e1c",
      "metadata": {},
      "source": [
        "<span id=\"14-classical-optimizers\" />\n",
        "\n",
        "### 1.4 고전적 최적화기\n",
        "\n",
        "고전적인 최적화 도구는 목표 함수의 극한값(일반적으로 최소값)을 찾도록 설계된 모든 고전적인 알고리즘입니다. 가능한 매개변수의 공간을 검색하여 관심 있는 일부 함수를 최소화하는 집합을 찾습니다. 크게 그라데이션 정보를 활용하는 그라데이션 기반 방식과 블랙박스 옵티마이저로 작동하는 그라데이션 프리 방식으로 분류할 수 있습니다. 특히 양자 하드웨어에 노이즈가 있는 경우, 기존 최적화 도구의 선택은 알고리즘의 성능에 큰 영향을 미칠 수 있습니다. 이 분야에서 널리 사용되는 최적화 도구로는 노이즈가 많은 환경에서 유망한 결과를 보여준 Adam, AMSGrad 및 SPSA가 있습니다. 보다 전통적인 최적화 도구로는 COBYLA와 SLSQP가 있습니다.\n",
        "\n",
        "일반적인 워크플로(섹션 3.3 )에서 설명한 대로 이러한 알고리즘 중 하나를 scipy의 `minimize` 함수와 같은 미니마이저 내부의 메서드로 사용하는 것이 좋습니다. 이것은 인수를 취합니다:\n",
        "\n",
        "* 일부 기능을 최소화할 수 있습니다. 이는 종종 에너지 기대치입니다. 하지만 이를 일반적으로 '비용 함수'라고 합니다.\n",
        "* 검색을 시작할 수 있는 매개변수 집합입니다. 종종 $x_0$ 또는 $\\theta_0$ 이라고도 합니다.\n",
        "* 인수, 비용 함수의 인수를 포함하여. Qiskit을 이용한 양자 컴퓨팅에서 이러한 인자에는 안자츠(ansatz), 해밀토니안(Hamiltonian), 그리고 다음 소절에서 더 자세히 다루게 될 에스티메이터(Estimator) 프리미티브가 포함됩니다.\n",
        "* 최소화하는 '방법'입니다. 이는 매개변수 공간을 검색하는 데 사용되는 특정 알고리즘을 나타냅니다. 여기에서 예를 들어 COBYLA 또는 SLSQP를 지정할 수 있습니다.\n",
        "* 옵션. 사용 가능한 옵션은 방법마다 다를 수 있습니다. 그러나 거의 모든 메서드에 포함될 수 있는 예는 검색을 종료하기 전 최적화 프로그램의 최대 반복 횟수입니다: 'maxiter'.\n",
        "\n",
        "![에너지를 나타내는 곡선과, 그 값의 최소값을 찾기 위해 여러 지점에서 검사가 이루어지고 있는 모습을 보여주는 그림.](https://quantum.cloud.ibm.com/learning/images/courses/quantum-diagonalization-algorithms/vqe/vqe-fig3.avif)\n",
        "\n",
        "각 반복 단계에서 해밀턴의 기대값은 많은 측정을 통해 추정됩니다. 이 추정 에너지는 비용 함수에 의해 반환되며, 최소화기는 에너지 환경에 대해 가지고 있는 정보를 업데이트합니다. 최적화 도구가 다음 단계를 선택하기 위해 정확히 무엇을 하는지는 방법마다 다릅니다. 일부는 경사도를 사용하고 가장 가파른 하강 방향을 선택합니다. 다른 사람들은 노이즈를 고려하여 실제 에너지가 그 방향으로 감소한다는 것을 받아들이기 전에 비용이 큰 폭으로 감소해야 할 수도 있습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "9e0642f5-8127-4647-b3f2-deceff0651ec",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Example syntax for minimization\n",
        "# from scipy.optimize import minimize\n",
        "# res = minimize(cost_func, x0, args=(ansatz, hamiltonian, estimator), method=\"cobyla\",\n",
        "# options={'maxiter': 200})"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5bbcff76-ea91-4fb6-acca-35e9e6675ed1",
      "metadata": {},
      "source": [
        "<span id=\"15-the-variational-principle\" />\n",
        "\n",
        "### 1.5 변분 원리\n",
        "\n",
        "이러한 맥락에서 변동 파동 함수는 기저 상태 파동 함수보다 낮은 에너지(또는 비용) 기대값을 산출할 수 없다는 변동 원리는 매우 중요합니다. 수학적으로,\n",
        "\n",
        "$$\n",
        "E_\\text{var}=\\langle \\psi_\\text{var}|H|\\psi_\\text{var}\\rangle \\geq E_\\text{min}=\\langle \\psi_\\text{0}|H|\\psi_\\text{0}\\rangle\n",
        "$$\n",
        "\n",
        "$H$ 의 모든 고유 상태 집합 $\\{|\\psi_0\\rangle, |\\psi_1\\rangle, |\\psi_2\\rangle, ...|\\psi_n \\rangle\\}$ 이 힐버트 공간의 완전한 기초를 형성한다는 점에 주목하면 이를 쉽게 확인할 수 있습니다. 즉, 모든 상태, 특히 $|\\psi_\\text{var}\\rangle$ 는 $H$ 의 이러한 고유 상태의 가중치(정규화된) 합으로 작성할 수 있습니다:\n",
        "\n",
        "$$\n",
        "|\\psi_\\text{var}\\rangle=\\sum_{i=0}^n c_i |\\psi_i\\rangle\n",
        "$$\n",
        "\n",
        "여기서 $c_i$ 은 결정할 상수이고 $\\sum_{i=0} |c_i|^2 = 1$ 은 결정할 상수입니다. 이것은 독자의 연습으로 남겨두겠습니다. 하지만 가장 낮은 에너지 기대값을 생성하는 변형 상태가 실제 접지 상태의 가장 좋은 *추정치라는* 점에 유의하세요.\n",
        "\n",
        "<span id=\"check-your-understanding\" />\n",
        "\n",
        "#### 이해도 점검\n",
        "\n",
        "어떤 변분 상태 $|\\psi_\\text{var}\\rangle$ 에 대해서든 $E_\\text{var}\\geq E_0$ 임을 수학적으로 증명하라.\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"답변\">\n",
        "    에너지 고유 상태의 관점에서 주어진 변형 상태의 확장을 사용합니다,\n",
        "\n",
        "    $$\n",
        "    |\\psi_\\text{var}\\rangle=\\sum_{i=0}^n c_i |\\psi_i\\rangle,\n",
        "    $$\n",
        "\n",
        "    를 사용하면 변동 에너지 기대값을 다음과 같이 쓸 수 있습니다\n",
        "\n",
        "    $$\n",
        "    \\begin{aligned}\n",
        "    E_\\text{var}&=\\langle \\psi_\\text{var}|H|\\psi_\\text{var}\\rangle =\\left(\\sum_{i=0}^n c^*_i \\langle \\psi_i|\\right)H\\left(\\sum_{j=0}^n c_j |\\psi_j\\rangle\\right)\\\\\n",
        "    &=\\left(\\sum_{i=0}^n c^*_i \\langle \\psi_i|\\right)\\left(\\sum_{j=0}^n c_j E_j|\\psi_j\\rangle\\right)\\\\\n",
        "    &=\\sum_{i,j=0}^n c^*_i c_j E_j \\langle \\psi_i|\\psi_j\\rangle\\\\\n",
        "    &=\\sum_{i,j=0}^n c^*_i c_j E_j \\delta_{i,j}\\\\\n",
        "    &=\\sum_{i=0}^n |c_i|^2 E_i.\n",
        "    \\end{aligned}\n",
        "    $$\n",
        "\n",
        "    모든 계수의 경우 $0\\leq|c_i|^2\\leq 1$. 따라서 다음과 같이 작성할 수 있습니다\n",
        "\n",
        "    $$\n",
        "    \\begin{aligned}\n",
        "    E_\\text{var}&=\\sum_{i=0}^n |c_i|^2 E_i\\geq \\sum_{i=0}^n |c_i|^2 E_0 = E_0 \\sum_{i=0}^n |c_i|^2 = E_0(1) \\\\\n",
        "    E_\\text{var}&\\geq E_0\n",
        "    \\end{aligned}\n",
        "    $$\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4d14d6df-7320-4f57-bc62-fbee4041957b",
      "metadata": {},
      "source": [
        "<span id=\"2-comparison-with-classical-workflow\" />\n",
        "\n",
        "## 2. 기존 워크플로와의 비교\n",
        "\n",
        "행과 열이 N개인 행렬에 관심이 있다고 가정해 보겠습니다. 행렬이 너무 커서 정확한 대각선화를 할 수 없다고 가정해 보겠습니다. 문제에 대해 충분히 알고 있어 대상 고유 상태의 전체 구조를 어느 정도 추측할 수 있고, 비용/에너지를 더 낮출 수 있는지 알아보기 위해 초기 추측과 유사한 상태를 조사하고 싶다고 가정해 보겠습니다. 이는 변형된 접근 방식이며, 정확한 대각선화를 사용할 수 없을 때 사용하는 방법 중 하나입니다.\n",
        "\n",
        "<span id=\"21-classical-workflow\" />\n",
        "\n",
        "### 2.1 전통적인 작업 흐름\n",
        "\n",
        "일반 컴퓨터를 사용하면 다음과 같이 작동합니다:\n",
        "\n",
        "* 몇 가지 매개변수 $\\vec{\\theta}_i$ 를 사용하여 추측 상태를 만듭니다( $|\\psi(\\vec{\\theta}_i)\\rangle$ ). 이 초기 추측이 무작위일 수도 있지만 이는 바람직하지 않습니다. 당면한 문제에 대한 지식을 최대한 활용하여 추측을 조정하고자 합니다.\n",
        "* 해당 상태의 시스템으로 운영자의 기대값을 계산합니다: $\\langle\\psi(\\vec{\\theta}_i)|H|\\psi(\\vec{\\theta}_i)\\rangle$\n",
        "* 변형 매개 변수를 변경하고 반복합니다: $\\vec{\\theta}_i\\rightarrow \\vec{\\theta}_{i+1}$.\n",
        "* 변형 하위 공간에서 가능한 상태의 풍경에 대한 축적된 정보를 사용하여 더 나은 추측을 하고 목표 상태에 접근하세요. 변형 원리는 변형 상태가 목표 기저 상태보다 낮은 고유값을 산출할 수 없음을 보장합니다. 따라서 기대값이 낮을수록 접지 상태의 근사치가 더 정확해집니다:\n",
        "\n",
        "$$\n",
        "\\min_{\\vec{\\theta}} \\{ E_{\\text{var},i} = \\langle\\psi(\\vec{\\theta_i})|H|\\psi(\\vec{\\theta_i})\\rangle \\} \\geq E_0\n",
        "$$\n",
        "\n",
        "이 접근 방식에서 각 단계가 얼마나 어려운지 살펴보겠습니다. 매개변수를 설정하거나 업데이트하는 것은 계산적으로 어렵지 않지만, 물리적으로 타당한 유용한 초기 매개변수를 선정하는 데 어려움이 있다. 이전 반복 과정에서 축적된 정보를 활용하여 기저 상태에 가까워지도록 매개변수를 업데이트하는 것은 결코 쉬운 일이 아니다. 하지만 이를 상당히 효율적으로 수행하는 고전적인 최적화 알고리즘들이 존재합니다. 이 고전적인 최적화 기법이 계산 비용이 많이 드는 이유는 많은 반복 과정이 필요할 수 있기 때문이며, 최악의 경우 반복 횟수가 N에 따라 지수적으로 증가할 수 있다. 계산적으로 가장 많은 자원을 소모하는 단일 단계는, 주어진 상태 $|\\psi(\\vec{\\theta_i})\\rangle$ 를 사용하여 행렬의 기대값을 계산하는 과정일 가능성이 매우 높습니다: $\\langle\\psi(\\vec{\\theta_i})|H|\\psi(\\vec{\\theta_i})\\rangle$.\n",
        "\n",
        "$N\\times N$ 행렬은 $N$ -요소 벡터에 대해 작동해야 하며, 이는 최악의 경우 $O(N^2)$ 곱셈 연산에 해당합니다. 이 작업은 매개변수를 반복할 때마다 수행해야 합니다. 매우 큰 행렬의 경우 계산 비용이 많이 듭니다.\n",
        "\n",
        "<span id=\"22-quantum-workflow-and-commuting-pauli-groups\" />\n",
        "\n",
        "### 2.2 양자 워크플로우와 통근 파울리 군\n",
        "\n",
        "이제 이 계산의 일부를 양자 컴퓨터로 돌린다고 상상해 보세요. 이 기대값을 계산하는 대신 변형 안사츠를 사용하여 양자 컴퓨터에서 상태 $|\\psi(\\vec{\\theta_i})\\rangle$ 를 준비한 다음 측정을 수행하여 추정합니다.\n",
        "\n",
        "$H$ 은 일반적으로 측정하기 쉽지 않습니다. 예를 들어 출퇴근하지 않는 많은 폴리 X, Y, Z 운영자로 구성될 수 있습니다. 그러나 $H$ 은 $h_\\alpha$ 이라는 용어의 선형 조합으로 작성할 **수 있으며**, 각 용어는 쉽게 측정할 수 있습니다(예: 폴리 연산자 또는 큐비트 단위로 통근하는 폴리 연산자의 그룹).\n",
        "어떤 상태 $|\\Psi\\rangle$ 에 대한 $H$ 의 기대값은 구성 용어 $h_\\alpha$ 의 기대값의 가중치 합입니다. 이 표현식은 모든 상태 $|\\Psi⟩$ 에 적용되지만, 특히 변형 상태 $|\\psi(\\theta_i)\\rangle$ 에 사용하겠습니다.\n",
        "\n",
        "$$\n",
        "H = \\sum_{\\alpha = 1}^T{c_\\alpha h_\\alpha}\n",
        "$$\n",
        "\n",
        "여기서 $h_\\alpha$ 은 `IZZX…XIYX` 과 같은 폴리 문자열이거나 서로 통용되는 여러 개의 문자열입니다. 따라서 양자 컴퓨터에서 측정의 현실과 더 밀접하게 일치하는 기대값에 대한 설명은 다음과 같습니다\n",
        "\n",
        "$$\n",
        "\\langle \\Psi |H|\\Psi \\rangle =\\sum_{\\alpha} c_\\alpha \\langle \\Psi | h_\\alpha|\\Psi \\rangle.\n",
        "$$\n",
        "\n",
        "그리고 변동 파동 함수의 맥락에서도 마찬가지입니다:\n",
        "\n",
        "$$\n",
        "\\langle \\psi(\\vec{\\theta}_i) |H|\\psi(\\vec{\\theta}_i) \\rangle =\\sum_{\\alpha} c_\\alpha \\langle \\psi(\\vec{\\theta}_i) | h_\\alpha|\\psi(\\vec{\\theta}_i) \\rangle\n",
        "$$\n",
        "\n",
        "각 용어 $h_\\alpha$ 를 $M$ 번 측정하여 측정 샘플 $s_{\\alpha j}$ 을 산출하고 $j=1…M$ 을 사용하여 기대값 $\\mu_\\alpha$ 과 표준 편차 $\\sigma_\\alpha$ 를 반환할 수 있습니다. 이러한 항을 합산하고 합계를 통해 오차를 전파하여 전체 기대값 $\\mu$ 과 표준 편차 $\\sigma$ 를 얻을 수 있습니다.\n",
        "\n",
        "$$\n",
        "\\begin{aligned}\n",
        "\\langle \\psi(\\vec{\\theta}_i) |h_\\alpha|\\psi(\\vec{\\theta}_i) \\rangle &\\simeq \\mu _\\alpha \\pm \\frac{\\sigma_\\alpha}{\\sqrt{M}} &\\qquad \\mu_\\alpha &=\\frac{1}{M}\\sum_j s_{\\alpha,j} &\\qquad \\sigma^2_\\alpha &=\\frac{1}{M-1}\\sum_j (s_{\\alpha,j}-\\mu_\\alpha)^2\\\\\n",
        "\n",
        "\\langle \\psi(\\vec{\\theta}_i) |H|\\psi(\\vec{\\theta}_i) \\rangle &\\simeq \\mu  \\pm \\sigma &\\qquad \\mu &= \\sum_\\alpha c_\\alpha \\mu_\\alpha &\\qquad \\sigma^2&=\\sum_\\alpha c^2_\\alpha \\frac{\\sigma^2_\\alpha }{M}\n",
        "\n",
        "\\end{aligned}\n",
        "$$\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ab02194a-bb0e-4bbc-81e1-c5f8f9582d9b",
      "metadata": {},
      "source": [
        "여기에는 대규모 곱셈이나 $N^2$ 와 같이 반드시 확장해야 하는 프로세스가 필요하지 않습니다. 대신 양자 컴퓨터에서 여러 번 측정해야 합니다. 너무 많이 필요하지 않다면 이 접근 방식이 효율적일 수 있습니다. 이것이 바로 VQE의 퀀텀 부분입니다.\n",
        "\n",
        "하지만 이것이 효율적이지 않을 수 있는 이유에 대해 이야기해 보겠습니다. 많은 측정값을 사용하는 이유 중 하나는 매우 정밀한 계산을 위해 추정치의 통계적 불확실성을 줄이기 위해서입니다. 또 다른 이유는 전체 매트릭스에 걸쳐 필요한 폴리 문자열의 수 때문입니다. 폴리 행렬(동일성: X, Y, Z, I)은 주어진 차원의 모든 연산자의 공간에 걸쳐 있으므로, 이전과 마찬가지로 관심 행렬을 폴리 연산자의 가중 합으로 작성할 수 있다는 것을 보장합니다.\n",
        "\n",
        "$$\n",
        "H = \\sum_{\\alpha = 1}^T{c_\\alpha h_\\alpha}\n",
        "$$\n",
        "\n",
        "여기서 $h_\\alpha$ 은 `IZZX…XIYX` 과 같이 시스템을 설명하는 모든 큐비트에 작용하는 폴리 문자열 또는 서로 통용되는 여러 개의 문자열입니다. 키스킷은 오른쪽의 $n^\\text{th}$ 폴리 연산자가 $n^\\text{th}$ 큐비트에서 작동하는 *작은 엔디안* 표기법을 사용한다는 점을 기억하세요. 따라서 일련의 폴리 연산자를 측정하여 연산자를 측정할 수 있습니다.\n",
        "\n",
        "하지만 우리는 그 모든 파울리 연산자를 동시에 측정할 수는 없다. 동일한 큐비트와 연관된 파울리 연산자(I를 제외한)는 서로 교환 법칙을 따르지 않는다. 예를 들어, 세 번째 큐비트에 대해 I와 Z를 동시에 측정할 수 있고, 첫 번째 큐비트에 대해 I와 X를 동시에 알 수 있으므로, 와 를 `ZZXZ` 동시에 측정할 `IZIZ` 수 있습니다. 그러나 Z와 X는 교환 법칙을 따르지 않으며, 둘 다 0번째 큐비트에 작용하기 때문에 와 를 `ZZZX` 동시에 측정할 `ZZZZ` 수는 없습니다. 경험이 풍부한 독자라면, 개별 큐비트의 측정 결과가 서로 교환 법칙을 따르지 않더라도 두 개의 파울리 연산자 집합은 전체적으로 교환 법칙을 따를 수 있다는 점을 기억하실 것입니다. 이 추정기는 (기저 회전을 통한) 텐서곱 파울리 측정법을 가정하며, 이는 큐비트 단위로 교환하는 그룹화 연산자에 해당합니다. 따라서 Estimator를 사용하여 두 개의 파울리 연산자열(A와 B)을 동시에 추정하려면, A와 B에 포함된 각 큐비트의 파울리 연산자가 교환관계를 이루어야 합니다. 즉, 와 를 `ZZXX` 동시에 측정할 `ZZZZ` 수도 없다는 뜻입니다.\n",
        "\n",
        "![서로 다른 파울리 끈을 나타낸 표로, 그중 일부는 교환 관계를 이루고 다른 일부는 그렇지 않습니다.](https://quantum.cloud.ibm.com/learning/images/courses/quantum-diagonalization-algorithms/vqe/vqe-fig4.avif)\n",
        "\n",
        "따라서 행렬 $H$ 을 서로 다른 큐비트에 작용하는 폴리의 합으로 분해합니다. 이 합계의 일부 요소는 한꺼번에 측정할 수 있는데, 이를 *통근 폴리스 그룹이라고* 부릅니다. 출퇴근을 하지 않는 기간의 수에 따라 이러한 그룹이 많이 필요할 수 있습니다. 이러한 통근 폴리 문자열 그룹의 수를 $N_\\text{GCP}$ 으로 호출합니다. $N_\\text{GCP}$ 이 작으면 잘 작동할 수 있습니다. $H$ 에 수백만 개의 그룹이 있는 경우 이 방법은 유용하지 않습니다.\n",
        "\n",
        "기대값을 추정하는 데 필요한 처리 과정들은 ‘Estimator’라는 IBM Quantum 의 기본 함수에 통합되어 있습니다. Estimator에 대해 자세히 알아보려면 IBM Quantum® 문서의 [API 참조](/docs/api/qiskit-ibm-runtime/estimator-v2) 를 확인하세요. Estimator를 직접 사용할 수도 있지만, Estimator는 단순히 최저 에너지 고유값뿐만 아니라 그보다 훨씬 더 많은 결과를 반환합니다. 예를 들어, 앙상블 표준 오차에 대한 정보도 반환합니다. 따라서 최소화 문제의 맥락에서, 비용 함수 내부에 추정량이 등장하는 경우가 종종 있습니다. Estimator의 입력 및 출력에 대해 자세히 알아보려면 IBM Quantum 문서에서 이 [가이드를](/docs/guides/primitive-input-output#pubs) 참조하세요.\n",
        "\n",
        "상태에서 사용되는 매개변수 집합 $\\vec{\\theta_i}$ 에 대한 기대값(또는 비용 함수)을 기록한 다음 매개변수를 업데이트합니다. 시간이 지남에 따라 예상값 또는 비용 함수 값을 사용하여 앤사츠에서 샘플링한 상태의 하위 공간에서 비용 함수의 기울기를 대략적으로 추정할 수 있습니다. 그라데이션 기반 및 그라데이션이 없는 고전적인 최적화 도구가 모두 존재합니다. 둘 다 여러 개의 로컬 최소값과 *불모의 고원이라고* 불리는 기울기가 거의 0에 가까운 매개변수 공간의 넓은 영역과 같은 잠재적인 훈련 가능성 문제를 안고 있습니다.\n",
        "\n",
        "최소값을 갖는 곡선의 ![두 가지 모습. 한 방법은 최소값을 찾기 위해 점들을 무작위로 검사하는 것이고, 다른 방법은 인접한 두 점 사이에 선을 그어 기울기를 추정하는 것입니다.](https://quantum.cloud.ibm.com/learning/images/courses/quantum-diagonalization-algorithms/vqe/vqe-fig5.avif)\n",
        "\n",
        "<span id=\"23-factors-that-determine-computational-cost\" />\n",
        "\n",
        "### 2.3 계산 비용을 결정하는 요소들\n",
        "\n",
        "VQE가 가장 어려운 양자 화학 문제를 모두 해결하지는 못합니다. 아니오. 하지만 모든 계산을 더 잘하는 것이 중요한 것은 아닙니다. 계산 비용을 결정하는 요소를 변경했습니다.\n",
        "\n",
        "고전적 접근법과 양자 변분적 접근법을 비교한 ![표. 두 가지 모두 정확한 초기 추측이 필요합니다. 전통적인 접근 방식에서는 계산 비용이 행렬의 차수의 제곱에 비례하는 반면, 양자적 접근 방식에서는 교환하는 파울리 연산자의 그룹 수가 몇 개인지에 따라 달라집니다.](https://quantum.cloud.ibm.com/learning/images/courses/quantum-diagonalization-algorithms/vqe/vqe-fig6.avif)\n",
        "\n",
        "복잡성이 행렬 차원에만 의존하는 프로세스에서 필요한 정밀도와 행렬을 구성하는 비교대 폴리 연산자의 수에 의존하는 프로세스로 전환했습니다. 마지막 비트는 클래식 컴퓨팅에서 아날로그가 없습니다.\n",
        "\n",
        "이러한 종속성을 기반으로 희소 행렬 또는 통근하지 않는 폴리 문자열이 거의 없는 행렬의 경우 이 프로세스가 유용할 수 있습니다. 예를 들어 상호 작용하는 스핀 시스템이 이에 해당합니다. 밀도가 높은 행렬의 경우 유용성이 떨어질 수 있습니다. 예를 들어 화학 시스템에는 종종 수백, 수천, 심지어 수백만 개의 폴리 문자열이 포함된 해밀턴계가 존재한다는 것을 알고 있습니다. 이 용어의 수를 줄이기 위한 흥미로운 작업이 진행되었습니다. 그러나 화학 시스템은 이 과정에서 논의할 다른 알고리즘 중 일부에 더 적합할 수 있습니다.\n",
        "\n",
        "<span id=\"check-your-understanding\" />\n",
        "\n",
        "#### 이해도 점검\n",
        "\n",
        "용어가 포함된 4개의 큐비트에 대한 해밀턴을 생각해 보세요:\n",
        "\n",
        "`IIXX`, `IIXZ`, `IIZZ`, `IZXZ`, `IXXZ`, `ZZXZ`, `XZXZ`, `ZIXZ`, `ZZZZ`, `XXXX`\n",
        "\n",
        "그룹에 있는 모든 용어를 동시에 측정할 수 있도록 이러한 용어를 그룹으로 정렬하려고 합니다. 모든 용어를 설명할 수 있도록 만들 수 있는 최소 그룹 수는 얼마인가요?\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"답변\">\n",
        "    4개 조로 나뉘어 진행할 수 있습니다. 이러한 해법은 일반적으로 유일하지 않다는 점에 유의하십시오.\n",
        "\n",
        "    `IIXX`, `XXXX`, `IIZZ`, `ZZZZ`\n",
        "\n",
        "    `IIXZ`, `IZXZ`, `ZIXZ`, `ZZXZ`\n",
        "\n",
        "    `IXXZ`\n",
        "\n",
        "    `XZXZ`\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n",
        "일반적으로 VQE를 이용한 양자 화학 연구를 어렵게 만드는 요인은 무엇이라고 생각하시나요? 해밀토니안의 항의 수가 많다는 점인가요, 아니면 적절한 근사 해법을 찾는 것이 어려운 점인가요?\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"답변\">\n",
        "    화학적 상황에 고도로 최적화된 분석 도구가 있다는 것이 밝혀졌습니다. 해밀턴의 용어 수와 이에 따라 필요한 측정 횟수가 많을수록 일반적으로 더 많은 문제를 일으킵니다.\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a9a687e3-ae98-49f7-9b5a-0a2700ecd278",
      "metadata": {},
      "source": [
        "<span id=\"3-example-hamiltonian\" />\n",
        "\n",
        "## 3. 해밀토니안 예시\n",
        "\n",
        "작은 해밀턴 행렬을 사용하여 이 알고리즘을 실행하여 각 단계에서 어떤 일이 일어나는지 확인해 보겠습니다. 저희는 키스킷 패턴 프레임워크를 사용할 것입니다:\n",
        "\n",
        "* **1단계** : 문제를 양자 회로 및 연산자에 매핑하기 - **2단계** : 대상 하드웨어에 최적화 - **3단계** : 대상 하드웨어에서 실행 - **4단계** : 사후 처리 결과\n",
        "\n",
        "<span id=\"31-step-1-map-the-problem-to-quantum-circuits-and-operators\" />\n",
        "\n",
        "### 3.1 1단계: 문제를 양자 회로와 연산자로 매핑하기\n",
        "\n",
        "위에서 정의한 화학 컨텍스트에서 정의한 것을 사용하겠습니다. 몇 가지 일반 수입품부터 시작하겠습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "acb6fb0c-4b8c-4ab3-b632-ed201e99b45f",
      "metadata": {},
      "outputs": [],
      "source": [
        "# General imports\n",
        "import numpy as np\n",
        "\n",
        "# SciPy minimizer routine\n",
        "from scipy.optimize import minimize\n",
        "\n",
        "# Plotting functions\n",
        "import matplotlib.pyplot as plt"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a713b494-ab7a-49c6-845c-db728c4635eb",
      "metadata": {},
      "source": [
        "다시 한 번, 관심 있는 해밀턴을 알고 있다고 가정합니다. 여기서는 극히 작은 해밀턴을 사용하겠습니다. 이 강좌에서 설명하는 다른 방법은 더 큰 문제를 해결하는 데 더 효율적이기 때문입니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "0908f251-58af-49f9-98a8-af98110f6c15",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The ground state energy is  -0.702930394459531\n"
          ]
        }
      ],
      "source": [
        "from qiskit.quantum_info import SparsePauliOp\n",
        "import numpy as np\n",
        "\n",
        "hamiltonian = SparsePauliOp.from_list(\n",
        "    [(\"YZ\", 0.3980), (\"ZI\", -0.3980), (\"ZZ\", -0.0113), (\"XX\", 0.1810)]\n",
        ")\n",
        "\n",
        "A = np.array(hamiltonian)\n",
        "eigenvalues, eigenvectors = np.linalg.eigh(A)\n",
        "print(\"The ground state energy is \", min(eigenvalues))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "75bf2097-1a9c-48d5-8eff-393e0c9eb2f9",
      "metadata": {},
      "source": [
        "키스킷에는 조립식 안사츠가 많이 준비되어 있습니다. `efficient_su2` 을 사용합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "84d6380e-8ee8-4340-a416-c07900fe4c5b",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "This circuit has  4 parameters\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/quantum-diagonalization-algorithms/vqe/extracted-outputs/84d6380e-8ee8-4340-a416-c07900fe4c5b-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Pre-defined ansatz circuit and operator class for Hamiltonian\n",
        "from qiskit.circuit.library import efficient_su2\n",
        "\n",
        "# Note that it is more common to place initial 'h' gates outside the ansatz.\n",
        "# Here we specifically wanted this layer structure.\n",
        "ansatz = efficient_su2(\n",
        "    hamiltonian.num_qubits, su2_gates=[\"h\", \"rz\", \"y\"], entanglement=\"circular\", reps=1\n",
        ")\n",
        "\n",
        "num_params = ansatz.num_parameters\n",
        "print(\"This circuit has \", num_params, \"parameters\")\n",
        "\n",
        "ansatz.decompose().draw(\"mpl\", style=\"iqp\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "15394107-6589-4d06-b611-8fa641784b33",
      "metadata": {},
      "source": [
        "안제마다 서로 다른 얽힘 구조와 회전 게이트가 있습니다. 여기에 표시된 것은 얽힘에는 CNOT 게이트를 사용하고, 회전에는 Y 게이트와 파라미터화된 RZ 게이트를 모두 사용합니다. 이 파라미터 공간의 크기에 주목하세요. 이는 4개의 변수(RZ 게이트의 파라미터)에 대한 비용 함수를 최소화해야 함을 의미합니다. 이 기능은 확장할 수 있지만 무한정 확장할 수는 없습니다. `efficient_su2` 에 대해 기본값 3회를 사용하여 4개의 큐비트에서 유사한 문제를 실행하면 16개의 가변 매개 변수가 산출됩니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "12ee2d18-b4db-4b94-ab19-8a0654ca4b2e",
      "metadata": {},
      "source": [
        "<span id=\"32-step-2-optimize-for-target-hardware\" />\n",
        "\n",
        "### 3.2 2단계: 대상 하드웨어에 최적화하기\n",
        "\n",
        "안사츠는 익숙한 게이트를 사용해 작성되었지만, 각 양자 컴퓨터에서 구현할 수 있는 기본 게이트를 활용하려면 회로를 변환해야 합니다. 가장 사용량이 적은 백엔드를 선택합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "ba1a1493-e807-44b8-b971-69f098981da2",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "<IBMBackend('ibm_torino')>\n"
          ]
        }
      ],
      "source": [
        "# runtime imports\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, Session\n",
        "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n",
        "\n",
        "# To run on hardware, select the backend with the fewest number of jobs in the queue\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "print(backend)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "84200023-d16f-41d4-9791-c6ef3488da90",
      "metadata": {},
      "source": [
        "이제 이 하드웨어에 대한 회로를 트랜스파일하고 트랜스파일된 앤사츠를 시각화할 수 있습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "4a1cdcf3-7d94-4a1f-b675-9549bf28d956",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/quantum-diagonalization-algorithms/vqe/extracted-outputs/4a1cdcf3-7d94-4a1f-b675-9549bf28d956-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
        "\n",
        "target = backend.target\n",
        "pm = generate_preset_pass_manager(target=target, optimization_level=3)\n",
        "\n",
        "ansatz_isa = pm.run(ansatz)\n",
        "\n",
        "ansatz_isa.draw(output=\"mpl\", idle_wires=False, style=\"iqp\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6066c477-2d43-459f-bfc6-650011279587",
      "metadata": {},
      "source": [
        "사용된 게이트가 변경되었으며, 추상 회로의 큐비트가 양자 컴퓨터에서 다른 번호의 큐비트에 매핑되었습니다. 해밀턴을 동일하게 매핑해야 의미 있는 결과를 얻을 수 있습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "3543e888-6f84-4f12-88a8-948dec7f3f55",
      "metadata": {},
      "outputs": [],
      "source": [
        "hamiltonian_isa = hamiltonian.apply_layout(layout=ansatz_isa.layout)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ba1ae1c5-c26c-42f8-b3af-411970d4d39d",
      "metadata": {},
      "source": [
        "<span id=\"33-step-3-execute-on-target-hardware\" />\n",
        "\n",
        "### 3.3 3단계: 대상 하드웨어에서 실행\n",
        "\n",
        "<span id=\"331-reporting-out-values\" />\n",
        "\n",
        "#### 3.3.1 값 보고\n",
        "\n",
        "여기서 우리는 이전 단계에서 구축한 구조들, 즉 매개변수, 근사식, 해밀토니안을 인수로 받는 비용 함수를 정의합니다. 또한 아직 정의하지 않은 Estimator도 사용합니다. 수렴 특성을 확인할 수 있도록, 비용 함수의 이력을 추적하는 코드를 포함시켰습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "bb1d8999-77aa-4c1a-adae-8974eda9e63b",
      "metadata": {},
      "outputs": [],
      "source": [
        "def cost_func(params, ansatz, hamiltonian, estimator):\n",
        "    \"\"\"Return estimate of energy from Estimator\n",
        "\n",
        "    Parameters:\n",
        "        params (ndarray): Array of ansatz parameters\n",
        "        ansatz (QuantumCircuit): Parameterized ansatz circuit\n",
        "        hamiltonian (SparsePauliOp): Operator representation of Hamiltonian\n",
        "        estimator (EstimatorV2): Estimator primitive instance\n",
        "        cost_history_dict: Dictionary for storing intermediate results\n",
        "\n",
        "    Returns:\n",
        "        float: Energy estimate\n",
        "    \"\"\"\n",
        "    pub = (ansatz, [hamiltonian], [params])\n",
        "    result = estimator.run(pubs=[pub]).result()\n",
        "    energy = result[0].data.evs[0]\n",
        "\n",
        "    cost_history_dict[\"iters\"] += 1\n",
        "    cost_history_dict[\"prev_vector\"] = params\n",
        "    cost_history_dict[\"cost_history\"].append(energy)\n",
        "    print(f\"Iters. done: {cost_history_dict['iters']} [Current cost: {energy}]\")\n",
        "\n",
        "    return energy\n",
        "\n",
        "\n",
        "cost_history_dict = {\n",
        "    \"prev_vector\": None,\n",
        "    \"iters\": 0,\n",
        "    \"cost_history\": [],\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "95537d30-ba5d-48ab-bf6a-82edc8f0a348",
      "metadata": {},
      "source": [
        "당면한 문제와 목표 상태의 특성에 대한 지식을 바탕으로 초기 매개변수 값을 선택할 수 있다면 매우 유리합니다. 당사는 이러한 지식을 가정하지 않고 임의의 초기 값을 사용합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "01a5d370-2947-4441-b71b-ffbdeddf52f0",
      "metadata": {},
      "outputs": [],
      "source": [
        "x0 = 2 * np.pi * np.random.random(num_params)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "8e0d33b8-7f9c-428d-a76d-d832747b8430",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Iters. done: 1 [Current cost: 0.010575798722044727]\n",
            "Iters. done: 2 [Current cost: 0.004040015974440895]\n",
            "Iters. done: 3 [Current cost: 0.0020213258785942503]\n",
            "Iters. done: 4 [Current cost: 0.18723082446726014]\n",
            "Iters. done: 5 [Current cost: -0.2746792152068885]\n",
            "Iters. done: 6 [Current cost: -0.3094547651648519]\n",
            "Iters. done: 7 [Current cost: -0.05281985428356641]\n",
            "Iters. done: 8 [Current cost: 0.00808560303514377]\n",
            "Iters. done: 9 [Current cost: -0.0014821685303514388]\n",
            "Iters. done: 10 [Current cost: -0.004759824281150161]\n",
            "Iters. done: 11 [Current cost: 0.09942328705995292]\n",
            "Iters. done: 12 [Current cost: 0.01092366214057508]\n",
            "Iters. done: 13 [Current cost: 0.05017497496069776]\n",
            "Iters. done: 14 [Current cost: 0.13028868414310696]\n",
            "Iters. done: 15 [Current cost: 0.013747803514376994]\n",
            "Iters. done: 16 [Current cost: 0.2583072432944498]\n",
            "Iters. done: 17 [Current cost: -0.14422125655131562]\n",
            "Iters. done: 18 [Current cost: -0.0004950150347678081]\n",
            "Iters. done: 19 [Current cost: 0.00681082268370607]\n",
            "Iters. done: 20 [Current cost: -0.0023377795527156544]\n",
            "Iters. done: 21 [Current cost: 0.6027665591169237]\n",
            "Iters. done: 22 [Current cost: 0.00596641373801917]\n",
            "Iters. done: 23 [Current cost: -0.008318769968051117]\n",
            "Iters. done: 24 [Current cost: -0.00026683306709265246]\n",
            "Iters. done: 25 [Current cost: -0.007648222843450479]\n",
            "Iters. done: 26 [Current cost: 0.004121086261980831]\n",
            "Iters. done: 27 [Current cost: -0.004075019968051117]\n",
            "Iters. done: 28 [Current cost: -0.004419369009584665]\n",
            "Iters. done: 29 [Current cost: 0.213185460054037]\n",
            "Iters. done: 30 [Current cost: -0.06505919572162797]\n",
            "Iters. done: 31 [Current cost: -0.5334241316590271]\n",
            "Iters. done: 32 [Current cost: 0.00218370607028754]\n",
            "Iters. done: 33 [Current cost: 0.09579352143666908]\n",
            "Iters. done: 34 [Current cost: -0.009274800319488819]\n",
            "Iters. done: 35 [Current cost: -0.44395141360688106]\n",
            "Iters. done: 36 [Current cost: 0.011747104632587858]\n",
            "Iters. done: 37 [Current cost: -0.003344149361022364]\n",
            "Iters. done: 38 [Current cost: 0.19138183916486304]\n",
            "Iters. done: 39 [Current cost: 0.013513931813145209]\n"
          ]
        }
      ],
      "source": [
        "# This required 13 min, 20 s QPU time on an Eagle processor, 28 min total time.\n",
        "with Session(backend=backend) as session:\n",
        "    estimator = Estimator(mode=session)\n",
        "    estimator.options.default_shots = 10000\n",
        "\n",
        "    res = minimize(\n",
        "        cost_func,\n",
        "        x0,\n",
        "        args=(ansatz_isa, hamiltonian_isa, estimator),\n",
        "        method=\"cobyla\",\n",
        "        options={\"maxiter\": 50},\n",
        "    )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fe98bde2-b435-47d1-b227-ee897aa3fe3e",
      "metadata": {},
      "source": [
        "원시 출력을 살펴볼 수 있습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "b1d07809-5f98-4c11-9bf6-fc5b5c5fb47f",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              " message: Return from COBYLA because the trust region radius reaches its lower bound.\n",
              " success: True\n",
              "  status: 0\n",
              "     fun: -0.5334241316590271\n",
              "       x: [ 1.024e+00  6.459e+00  3.625e+00  4.007e+00]\n",
              "    nfev: 39\n",
              "   maxcv: 0.0"
            ]
          },
          "execution_count": 14,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "res"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "80c958e5-f70e-4736-889a-f88a69c50890",
      "metadata": {},
      "source": [
        "<span id=\"34-step-4-post-process-results\" />\n",
        "\n",
        "### 3.4 4단계: 결과 후처리\n",
        "\n",
        "프로시저가 올바르게 종료되면 사전의 값은 각각 솔루션 벡터와 총 함수 평가 횟수와 같아야 합니다. 이는 쉽게 확인할 수 있습니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "e87046c1-bfe9-4bb3-b7fd-1e4da55149fe",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{'prev_vector': array([1.02397956, 6.45886604, 3.62479262, 4.00744128]),\n",
              " 'iters': 39,\n",
              " 'cost_history': [np.float64(0.010575798722044727),\n",
              "  np.float64(0.004040015974440895),\n",
              "  np.float64(0.0020213258785942503),\n",
              "  np.float64(0.18723082446726014),\n",
              "  np.float64(-0.2746792152068885),\n",
              "  np.float64(-0.3094547651648519),\n",
              "  np.float64(-0.05281985428356641),\n",
              "  np.float64(0.00808560303514377),\n",
              "  np.float64(-0.0014821685303514388),\n",
              "  np.float64(-0.004759824281150161),\n",
              "  np.float64(0.09942328705995292),\n",
              "  np.float64(0.01092366214057508),\n",
              "  np.float64(0.05017497496069776),\n",
              "  np.float64(0.13028868414310696),\n",
              "  np.float64(0.013747803514376994),\n",
              "  np.float64(0.2583072432944498),\n",
              "  np.float64(-0.14422125655131562),\n",
              "  np.float64(-0.0004950150347678081),\n",
              "  np.float64(0.00681082268370607),\n",
              "  np.float64(-0.0023377795527156544),\n",
              "  np.float64(0.6027665591169237),\n",
              "  np.float64(0.00596641373801917),\n",
              "  np.float64(-0.008318769968051117),\n",
              "  np.float64(-0.00026683306709265246),\n",
              "  np.float64(-0.007648222843450479),\n",
              "  np.float64(0.004121086261980831),\n",
              "  np.float64(-0.004075019968051117),\n",
              "  np.float64(-0.004419369009584665),\n",
              "  np.float64(0.213185460054037),\n",
              "  np.float64(-0.06505919572162797),\n",
              "  np.float64(-0.5334241316590271),\n",
              "  np.float64(0.00218370607028754),\n",
              "  np.float64(0.09579352143666908),\n",
              "  np.float64(-0.009274800319488819),\n",
              "  np.float64(-0.44395141360688106),\n",
              "  np.float64(0.011747104632587858),\n",
              "  np.float64(-0.003344149361022364),\n",
              "  np.float64(0.19138183916486304),\n",
              "  np.float64(0.013513931813145209)]}"
            ]
          },
          "execution_count": 15,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "cost_history_dict"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "a789373a-8d32-4761-ba21-6b2f98a7ae5a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/quantum-diagonalization-algorithms/vqe/extracted-outputs/a789373a-8d32-4761-ba21-6b2f98a7ae5a-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "fig, ax = plt.subplots()\n",
        "x = np.linspace(0, 10, 50)\n",
        "\n",
        "# Define the constant function\n",
        "constant = -0.7029\n",
        "y_constant = np.full_like(x, constant)\n",
        "ax.plot(\n",
        "    range(cost_history_dict[\"iters\"]), cost_history_dict[\"cost_history\"], label=\"VQE\"\n",
        ")\n",
        "ax.set_xlabel(\"Iterations\")\n",
        "ax.set_ylabel(\"Cost\")\n",
        "ax.plot(y_constant, label=\"Target\")\n",
        "plt.legend()\n",
        "plt.draw()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4be8cb84-ec8c-4c83-880f-b9c296282040",
      "metadata": {},
      "source": [
        "IBM 퀀텀은 VQE와 관련된 다른 업스킬링 서비스도 제공합니다. VQE를 실제로 사용할 준비가 되셨다면 튜토리얼을 참조하세요: [VQE를 사용한 하이젠베르크 체인의 기저 상태 에너지 추정을](/docs/tutorials/spin-chain-vqe) 참조하세요. 분자 해밀턴을 만드는 방법에 대한 자세한 내용은 [VQE를 사용한 양자 화학](/learning/courses/quantum-chem-with-vqe) 강좌에서 [이](/learning/courses/quantum-chem-with-vqe/hamiltonian-construction) 강의를 참조하세요. VQE와 같은 변형 알고리즘의 작동 방식에 대해 더 깊이 이해하고 싶다면 [변형 알고리즘 설계](/learning/courses/variational-algorithm-design/optimization-loops) 강좌를 추천합니다.\n",
        "\n",
        "<span id=\"check-your-understanding\" />\n",
        "\n",
        "#### 이해도 점검\n",
        "\n",
        "이 섹션에서는 해밀턴의 기저 상태 에너지를 계산했습니다. 이를 분자의 형상을 결정하는 데 적용하고 싶다면 어떻게 확장할 수 있을까요?\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"답변\">\n",
        "    원자 간 간격과 결합 사이의 각도에 대한 변수를 도입해야 합니다. 이를 변경해야 합니다. 이러한 모든 변형에 대해 새로운 해밀턴을 생성할 것입니다(에너지를 설명하는 연산자는 확실히 기하학에 따라 달라지기 때문입니다). 이러한 해밀턴이 생성되고 큐비트에 매핑될 때마다 위에서 수행한 것과 같은 최적화를 수행해야 합니다. 수많은 수렴 최적화 문제 중에서 가장 낮은 에너지를 생성하는 기하학적 구조가 자연에 의해 채택되는 것입니다. 이것은 위에 표시된 것보다 훨씬 더 복잡합니다. 이러한 계산은 가장 단순한 분자( $\\text{H}_2$, [여기](/learning/courses/quantum-chem-with-vqe/geometry) )에 대해 수행됩니다.\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "33231f54-a9c1-499c-a4ad-b4404b843909",
      "metadata": {},
      "source": [
        "<span id=\"4-vqes-relationship-to-other-methods\" />\n",
        "\n",
        "## 4. VQE와 다른 방법들의 관계\n",
        "\n",
        "이 섹션에서는 원래의 VQE 접근 방식의 장단점을 검토하고 다른 최신 알고리즘과의 관계를 짚어보겠습니다.\n",
        "\n",
        "<span id=\"41-the-strengths-and-weaknesses-of-vqe\" />\n",
        "\n",
        "### 4.1 VQE의 장점과 단점\n",
        "\n",
        "이미 몇 가지 강점이 지적되었습니다. 요소는 다음과 같습니다.\n",
        "\n",
        "* 최신 하드웨어에 대한 적합성: 일부 양자 알고리즘은 대규모 내결함성에 근접하는 훨씬 낮은 오류율을 요구합니다. VQE는 그렇지 않으며, 현재의 양자 컴퓨터에서 구현할 수 있습니다.\n",
        "* 얕은 회로: VQE는 종종 비교적 얕은 양자 회로를 사용합니다. 따라서 VQE는 누적된 게이트 오류에 덜 민감하며 다양한 오류 완화 기술에 적합합니다. 물론 회로가 항상 얕은 것은 아니며, 이는 사용된 안사츠에 따라 다릅니다.\n",
        "* 다용도성: VQE는 원칙적으로 고유값/고윳값 문제로 캐스팅할 수 있는 모든 문제에 적용할 수 있습니다. 일부 문제에 대해서는 VQE가 비실용적이거나 불리하게 작용할 수 있는 여러 가지 주의 사항이 있습니다. 이 중 일부는 아래에 요약되어 있습니다.\n",
        "\n",
        "VQE의 몇 가지 약점과 비실용적인 문제도 위에서 설명했습니다. 주요 내용은 다음과 같습니다.\n",
        "\n",
        "* 휴리스틱적 특성: VQE는 앤사츠 및 최적화 방법의 선택에 따라 성능이 달라지므로 정확한 기저 상태 에너지로의 수렴을 보장하지 않습니다 [\\[1-2\\]](#references). 원하는 접지 상태에 필요한 얽힘이 없는 불량 안사츠가 선택되면 어떤 고전적 최적화 도구도 해당 접지 상태에 도달할 수 없습니다.\n",
        "* 잠재적으로 수많은 매개변수: 매우 표현력이 풍부한 안사츠에는 매개변수가 너무 많아 최소화 반복에 많은 시간이 소요될 수 있습니다.\n",
        "* 높은 계산 부담: VQE에서는 해밀토니안의 각 항에 대한 기대값을 추정하기 위해 추정기를 사용합니다. 관심 대상인 대부분의 해밀턴 연산자에는 동시에 추정할 수 없는 항들이 포함되어 있을 것이다. 이로 인해 해밀토니안이 복잡한 대규모 시스템의 경우 VQE가 많은 자원을 소모할 수 있다 [\\[1\\]](#references).\n",
        "* 노이즈의 영향: 기존 최적화 도구가 최소값을 검색할 때 노이즈 계산으로 인해 혼동을 일으켜 실제 최소값에서 멀어지거나 수렴이 지연될 수 있습니다. 이에 대한 한 가지 가능한 해결책은 최신 오류 완화 및 오류 억제 기술 [\\[2-3\\]](#references) ( IBM 참조)을 활용하는 것입니다.\n",
        "* 불모의 고원: 이러한 소실 그라데이션 영역 [\\[2-3\\]](#references) 은 노이즈가 없어도 존재하지만, 노이즈로 인한 기대값의 변화가 이러한 불모의 영역에서 파라미터 업데이트에 따른 변화보다 클 수 있기 때문에 노이즈로 인해 더 문제가 됩니다.\n",
        "\n",
        "<span id=\"42-relationship-to-other-approaches\" />\n",
        "\n",
        "### 4.2 다른 접근법과의 관계\n",
        "\n",
        "<span id=\"adapt-vqe\" />\n",
        "\n",
        "#### Adapt-VQE\n",
        "\n",
        "**ADAPT-VQE** (적응형 미분 조립 의사 트로터 가변 양자 아이겐솔버) 알고리즘은 특히 양자 화학에서 양자 시뮬레이션의 효율성, 정확성, 확장성을 개선하도록 설계된 기존 VQE 알고리즘을 개선한 것입니다.\n",
        "\n",
        "이 단원에서 설명한 원래의 VQE 알고리즘은 미리 정의된 고정 안사츠를 사용하여 시스템의 접지 상태를 근사화합니다. 저희의 경우, `efficient_su2`, 단일 반복으로 Y 및 RZ 회전 게이트를 사용했습니다.  RZ 게이트의 파라미터는 변경되었지만, 이 안사츠의 구조와 사용된 게이트는 변경되지 않았습니다.\n",
        "\n",
        "적응형 안사츠 구성을 통해 VQE의 한계를 해결한 ADAPT-VQE. ADAPT-VQE는 고정된 답안으로 시작하는 대신 반복적으로 답안을 동적으로 작성합니다. 각 단계에서 미리 정의된 풀(예: 페르미온 여기 연산자)에서 에너지에 대한 기울기가 가장 큰 연산자를 선택합니다. 이렇게 하면 가장 영향력 있는 연산자만 추가되어 컴팩트하고 효율적인 분석 결과를 얻을 수 있습니다 [\\[4-6\\]](#references). 이 접근 방식은 몇 가지 유익한 효과를 가져올 수 있습니다:\n",
        "\n",
        "1. **회로 깊이 감소** : 아사츠를 점진적으로 증가시키고 필요한 연산자에만 집중함으로써 ADAPT-VQE는 기존 VQE 접근 방식에 비해 게이트 연산을 최소화합니다 [\\[5,7\\]](#references).\n",
        "2. **정확도 향상** : 적응형 특성으로 인해 각 단계에서 더 많은 상관관계 에너지를 복구할 수 있으므로 기존 VQE가 어려움을 겪는 강한 상관관계 시스템에서 특히 효과적입니다 [\\[8,9\\]](#references).\n",
        "3. **확장성 및 노이즈 견고성** : 컴팩트한 안사츠는 게이트 오류의 누적을 줄이고, 계산 오버헤드를 줄이며, 최소화해야 하는 가변 파라미터의 수를 제한합니다.\n",
        "\n",
        "ADAPT-VQE는 아직 완벽하지 않습니다. 경우에 따라 로컬 최소값에 의해 갇히거나 속도가 느려질 수 있으며 과도한 매개변수화로 인해 문제가 발생할 수 있습니다. 또한 많은 게이트 구조로 기울기를 계산하고 파라미터를 최적화해야 하므로 리소스를 상당히 많이 사용할 수 있습니다.\n",
        "\n",
        "<span id=\"quantum-phase-estimation-qpe\" />\n",
        "\n",
        "#### 양자 위상 추정(QPE)\n",
        "\n",
        "QPE는 VQE와 목적이 비슷하지만 구현 방식은 매우 다릅니다. QPE는 일반적으로 깊은 양자 회로와 높은 수준의 일관성이 필요하기 때문에 내결함성 양자 컴퓨터가 필요합니다. QPE를 구현할 수 있게 되면 VQE보다 더 정확해질 것입니다. 차이를 설명하는 한 가지 방법은 회로 깊이에 따른 정밀도를 통해 설명할 수 있습니다. QPE는 $O(1/\\epsilon)$ [\\[10\\]](#references) 과 같이 회로 깊이를 확장하여 $\\epsilon$ 정밀도를 달성합니다. VQE는 동일한 정밀도를 달성하기 위해 $O(1/\\epsilon^2)$ 샘플이 필요합니다 [\\[10,11\\]](#references).\n",
        "\n",
        "<span id=\"krylov-sqd-qsci-and-others-in-this-course\" />\n",
        "\n",
        "#### 크릴로프, SQD, QSCI 및 본 과정의 기타 내용\n",
        "\n",
        "VQE는 양자 컴퓨터의 작동뿐만 아니라 알고리즘의 상당 부분을 여전히 클래식 컴퓨터에 의존하는 양자 알고리즘을 확립하는 데 도움을 주었습니다. 이러한 몇 가지 알고리즘이 이 과정의 나머지 부분에서 중점적으로 다뤄집니다. 여기에서는 몇 가지에 대해 간략하게 설명하며 VQE와 비교하고 대조해 보겠습니다. 다음 강의에서 훨씬 더 자세히 설명할 예정입니다.\n",
        "\n",
        "**크릴로프 양자 대각선화(KQD)**\n",
        "\n",
        "**크릴로프 하위 공간 방법은** 행렬을 하위 공간에 투영하여 크기를 줄이고 관리하기 쉽게 만드는 동시에 가장 중요한 기능을 유지하는 방법입니다. 이 방법의 한 가지 비결은 이러한 특징을 유지하는 부분 공간을 생성하는 것입니다. 이 부분 공간을 생성하는 것은 양자 컴퓨터에서 **트로터화라고** 불리는 잘 알려진 방법과 밀접한 관련이 있는 것으로 밝혀졌습니다.\n",
        "\n",
        "퀀텀 크릴로프 방식에는 몇 가지 변형이 있지만 일반적으로 다음과 같은 접근 방식이 있습니다:\n",
        "\n",
        "* 양자 컴퓨터를 사용하여 트로터라이제이션을 통해 하위 공간(크릴로프 하위 공간)을 생성합니다\n",
        "* 관심 행렬을 해당 크릴로프 하위 공간에 투영합니다\n",
        "* 고전 컴퓨터를 사용하여 새로운 투영된 해밀턴을 대각선으로 대각선화합니다\n",
        "\n",
        "**샘플링 기반 양자 대각선화(SQD)**\n",
        "\n",
        "**샘플링 기반 양자 대각선화(SQD)** 는 주요 특징을 보존하면서 대각선화할 행렬의 차원을 줄이려고 한다는 점에서 크릴로프 방식과 유사합니다. SQD는 다음과 같은 방식으로 이를 수행합니다:\n",
        "\n",
        "* 접지 상태에 대한 초기 추측으로 시작하여 해당 접지 상태로 시스템을 준비합니다.\n",
        "* 샘플러를 사용하여 이 상태를 구성하는 비트스트링을 샘플링합니다.\n",
        "* 샘플러의 계산 기준 상태 컬렉션을 관심 행렬을 투영하는 하위 공간으로 사용합니다.\n",
        "* 기존 컴퓨터를 사용하여 더 작고 투영된 행렬을 대각선으로 대각선화합니다.\n",
        "\n",
        "이는 상당한 알고리즘 구성 요소에 클래식 및 양자 컴퓨팅을 활용한다는 점에서 VQE와 관련이 있습니다. 또한 두 가지 모두 좋은 초기 추측이나 답을 준비해야 한다는 공통점이 있습니다. 그러나 SQD에서 클래식 컴퓨터와 양자 컴퓨터 간의 작업 분배는 크릴로프 방식과 더 비슷합니다.\n",
        "\n",
        "실제로 최근 크릴로프 방식과 SQD가 결합되어 샘플링 기반 크릴로프 양자 대각선화(SKQD) 방식이 등장했습니다 [\\[12\\]](#references).\n",
        "\n",
        "**양자 하위 공간 구성 상호 작용**\n",
        "\n",
        "**양자 선택 구성 상호작용(QSCI)**[ \\[13\\]](#references) 은 시험 파동 함수를 샘플링하여 해밀턴의 근사 기저 상태를 생성하여 고전적 대각선화를 위한 하위 공간을 생성하기 위한 중요한 계산 기저 상태를 식별하는 알고리즘입니다.\n",
        "SQD와 QSCI는 모두 양자 컴퓨터를 사용하여 축소된 하위 공간을 구성합니다.  QSCI의 또 다른 강점은 특히 화학 문제와 관련된 상태 준비에 있습니다. 시간 진화 상태 [\\[14\\]](#references) 와 화학에서 영감을 얻은 일련의 분석 기법을 사용하는 등 다양한 전략을 활용합니다. 효율적인 상태 준비에 집중함으로써 QSCI는 높은 충실도를 유지하고 양자 상태 샘플링 기법의 잡음 견고성을 활용하면서 화학 해밀턴의 양자 계산 비용을 절감합니다 [\\[15\\]](#references). 또한 QSCI는 더 나은 결과를 위해 더 많은 분석을 제공하는 적응형 구성 기술을 제공합니다.\n",
        "\n",
        "화학 문제에 대한 QSCI의 기본 워크플로우는 다음과 같습니다:\n",
        "\n",
        "* 원하는 소프트웨어(예: SciPy )를 사용하여 분자 해밀턴을 구축합니다.\n",
        "* 적절한 초기 상태와 미리 선택된 매개 변수 세트를 사용하여 화학에서 영감을 얻은 안사츠를 선택하여 QSCI 알고리즘을 준비합니다.\n",
        "* 중요한 기저 상태를 샘플링하고 클래식 컴퓨터를 사용하여 해밀턴을 대각선으로 대각선화하여 기저 상태 에너지를 얻습니다.\n",
        "* 종종 구성 복원 [\\[16\\]](#references) 과 대칭 사후 선별 [\\[15\\]을](#references) 사후 처리 기법으로 활용한다.\n",
        "* 선택적으로 적응형 QSCI의 워크플로에는 임의의 초기 상태로 더 많은 분석을 사용하여 step2 에서 step3 로의 추가 최적화 루프가 있습니다.\n",
        "\n",
        "<span id=\"check-your-understanding\" />\n",
        "\n",
        "#### 이해도 점검\n",
        "\n",
        "VQE는 위에 나열된 다른 모든 방법들(자세히 설명되지 않은 QPE를 제외하고)과 어떤 공통점이 있습니까?\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"답변\">\n",
        "    모두 일종의 시험 상태 또는 파동 함수와 관련이 있습니다. 이 시험 상태에 대한 초기 추측이 우수할 때 모든 것이 가장 잘 작동합니다.\n",
        "\n",
        "    또 다른 정답은 해밀턴을 측정하기 쉬운 경우(상대적으로 적은 수의 출퇴근 폴리 연산자 그룹으로 분류할 수 있는 경우) 모두 구현하기 가장 쉽다는 것입니다.\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n",
        "VQE는 위에 나열된 다른 방법과 어떤 공통점이 있나요?\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"답변\">\n",
        "    클래식 옵티마이저. 다른 어떤 제품도 전통적인 최적화 알고리즘을 사용하여 가변 매개변수를 선택하지 않습니다.\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8086b6a5-daf2-457b-bc7a-84db943b333f",
      "metadata": {},
      "source": [
        "<span id=\"references\" />\n",
        "\n",
        "## 참조\n",
        "\n",
        "\\[2] [https://en.wikipedia.org/wiki/Variational\\양자\\_이겐솔버](https://en.wikipedia.org/wiki/Variational_quantum_eigensolver)\n",
        "\n",
        "\\[3] [https://journals.aps.org/prapplied/abstract/10.1103/PhysRevApplied.19.024047](https://journals.aps.org/prapplied/abstract/10.1103/PhysRevApplied.19.024047)\n",
        "\n",
        "\\[4] [https://arxiv.org/abs/2111.05176](https://arxiv.org/abs/2111.05176)\n",
        "\n",
        "\\[6] [https://inquanto.quantinuum.com/tutorials/InQ\\_tut\\_fe4n2\\_2.html](https://inquanto.quantinuum.com/tutorials/InQ_tut_fe4n2_2.html)\n",
        "\n",
        "\\[7] [https://www.nature.com/articles/s41467-019-10988-2](https://www.nature.com/articles/s41467-019-10988-2)\n",
        "\n",
        "\\[8] [https://arxiv.org/abs/2210.15438](https://arxiv.org/abs/2210.15438)\n",
        "\n",
        "\\[9] [https://journals.aps.org/prresearch/abstract/10.1103/PhysRevResearch.6.013254](https://journals.aps.org/prresearch/abstract/10.1103/PhysRevResearch.6.013254)\n",
        "\n",
        "\\[10] [https://arxiv.org/html/2403.09624v1](https://arxiv.org/html/2403.09624v1)\n",
        "\n",
        "\\[11] [https://www.nature.com/articles/s42005-023-01312-y](https://www.nature.com/articles/s42005-023-01312-y)\n",
        "\n",
        "\\[13] [https://arxiv.org/abs/1802.00171](https://arxiv.org/abs/1802.00171)\n",
        "\n",
        "\\[14] [https://arxiv.org/abs/2103.08505](https://arxiv.org/abs/2103.08505)\n",
        "\n",
        "\\[15] [https://arxiv.org/html/2501.09702v1](https://arxiv.org/html/2501.09702v1)\n",
        "\n",
        "\\[16] [https://quri-sdk.qunasys.com/docs/examples/quri-algo-vm/qsci/](https://quri-sdk.qunasys.com/docs/examples/quri-algo-vm/qsci/)\n",
        "\n",
        "\\[17] [https://arxiv.org/abs/2412.13839](https://arxiv.org/abs/2412.13839)\n",
        "\n",
        "\\[18] [https://arxiv.org/abs/2302.11320v1](https://arxiv.org/abs/2302.11320v1)\n",
        "\n",
        "\\[19] [https://arxiv.org/pdf/2405.05068v1](https://arxiv.org/pdf/2405.05068v1)\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": 2
}