{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "e6e50bd6-8ac4-40b1-ac0f-6e22b6af1377",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"TEM 함수를 사용하여 차동 이징 모델을 시뮬레이션합니다\"\n",
        "description: \"Algorithmiq의 Qiskit 함수인 TEM 소개: 텐서 네트워크를 활용한 소프트웨어 후처리 오류 완화 추정 계산\"\n",
        "---\n",
        "\n",
        "<span id=\"simulate-a-kicked-ising-model-with-the-tem-function\" />\n",
        "\n",
        "# TEM 함수를 사용하여 차동 이징 모델을 시뮬레이션합니다\n",
        "\n",
        "{/* cspell:ignore Floquet, linestyles */}\n",
        "\n",
        "알고리즘의 텐서 네트워크 오류 완화(TEM) 방법은 양자-고전 하이브리드 알고리즘으로, 노이즈 완화를 전적으로 고전적 후처리 단계 내에서 수행하도록 설계되었습니다. TEM을 통해 사용자는 관측 가능한 양자의 기대값을 계산할 수 있으며, 이는 양자 하드웨어에서 발생하는 불가피한 잡음 유발 오류를 정확도와 비용 효율성을 높여 완화시켜 양자 연구자와 산업 실무자 모두에게 매우 매력적인 선택지로 자리매김하고 있습니다.\n",
        "\n",
        "이 튜토리얼은 TEM이 양자 시스템의 역학에 대해 의미 있는 결과를 얻을 수 있는 방법을 보여줍니다. 이는 오류 완화 없이는 접근할 수 없으며, PEC 및 ZNE와 같은 다른 오류 완화 방법을 사용할 경우 훨씬 더 많은 양자 자원이 필요합니다.\n",
        "\n",
        "*사용량 추정치: 이 노트북은 Heron r3 장치에서 약 10 QPU 분을 사용합니다. 실행 시간은 선택한 장치에 따라 크게 달라질 수 있습니다. 섹션별 사용량 추정치는 아래에서 확인할 수 있습니다.*\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1f5e328d-fe93-4ee2-995b-2e70b36ea0de",
      "metadata": {},
      "source": [
        "<span id=\"run-error-mitigated-many-body-physics-experiments-with-the-tem-function\" />\n",
        "\n",
        "## TEM 기능을 사용하여 오류 완화 다체 물리 실험을 실행하십시오\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b63a662c-a4e9-4b5f-92fd-46352a2bd0bd",
      "metadata": {},
      "source": [
        "이 튜토리얼은 다음 참고 문헌을 기반으로 합니다: [L. E. Fischer 외, Nat. 실제 (2026)](https://www.nature.com/articles/s41567-025-03144-9). 이 참고문헌은 최대 91 큐비트 규모의 양자 하드웨어에서 수행된 실제 시뮬레이션에 대해 논의합니다. 이 튜토리얼에서는 더 작은 회로 크기로 유사한 시뮬레이션을 재현합니다.\n",
        "\n",
        "킥드 아이징 모델은 일반적인 아이징 모델에 대응한다:\n",
        "\n",
        "$\\hat{H}_{\\text{I}} = J \\sum_{n=0}^{N-2} \\hat{Z}_n \\hat{Z}_{n+1} + h \\sum_{n=0}^{N-1} \\hat{Z}_n$\n",
        "\n",
        "가로차기가 가해지는 대상:\n",
        "\n",
        "$\\hat{H}_{K} = b \\sum_{n=0}^{N-1} \\hat{X}_n$\n",
        "\n",
        "목표는 횡방향 킥 이징 해밀토니언 하에서 상태의 역학을 시뮬레이션하는 것이며, 그 시간 진화는 플로케 유니터리 $\\hat{U}_{\\text{KI}} = e^{-i \\hat{H}_K} e^{-i \\hat{H}_I} $ 로 구현될 수 있다. 진화시킬 초기 상태는 첫 번째 큐비트가 상태 $|+\\rangle$ 에 있고, 나머지 큐비트들은 쌍을 이루어 벨 상태 $(|00\\rangle + |11\\rangle)/\\sqrt{2}$ 로 설정된 상태이다.\n",
        "\n",
        "우리가 관찰하고자 하는 양은 상관 함수이다. [이](https://www.nature.com/articles/s41567-025-03144-9) 참고 논문은 이 양을 양자 큐비트( $n^{th}$ )에 대한 양자 파울리 연산자( $\\hat{X}$ )로 어떻게 재표현할 수 있는지 논의한다.\n",
        "일정 수의 물리적 시간 단계 $t$ 가 지난 후, 우리는 파울리 연산자 $\\hat{X}_{n=t}$ 의 값을 계산한다.\n",
        "시스템의 매개변수에 따라, 이 관측가능량의 값은 정확히 계산 가능한 값과 같거나, 근사적 방법으로만 시뮬레이션될 수 있다. 구체적으로, $|J|=|b|=\\pi/4$ 의 경우 $[\\cos(2h)]^t$ 와 동일하며, 이는 본 튜토리얼 결과 벤치마킹에 사용할 값입니다. 또한, 주어진 시간 단계 $t$ 에서, $\\langle\\hat{X}_{n\\neq t}\\rangle$ 는 0이다. 이러한 값을 얻는 방법과, 이러한 매개변수 범위를 벗어난 근사적 고전적 시뮬레이션 결과와의 비교에 대한 자세한 내용은 [L. E. Fischer 외, Nat. 실제 (2026)](https://www.nature.com/articles/s41567-025-03144-9).\n",
        "\n",
        "TEM은 먼저 회로 내 2-큐비트 게이트의 각 고유 레이어에 대한 노이즈를 특성화하고, 판독 오류를 특성화함으로써 작동합니다. 그런 다음, 회로가 양자 기계에서 실행됩니다. 마지막으로, 텐서 네트워크 오류 완화 처리가 IBM Cloud® 의 클래식 리소스에서 수행되며, 완화된 값이 반환됩니다. 이 예시에서 회로는 특성화할 두 개의 고유한 레이어를 가지고 있습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4b30f191-9759-49de-ba8f-7cc616b61ec6",
      "metadata": {},
      "source": [
        "<span id=\"setup\" />\n",
        "\n",
        "## 설정\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9cf6d15e-324b-474a-886c-c3dca5a24141",
      "metadata": {},
      "source": [
        "필수 조건으로, 필요한 종속성들이 설치되어 있는지 확인하십시오.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "1eeec332-29ca-4882-8129-d1c93ed82b2b",
      "metadata": {},
      "outputs": [],
      "source": [
        "%pip install numpy matplotlib qiskit qiskit-ibm-catalog qiskit-ibm-runtime pylatexenc qiskit_qasm3_import"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "ad0002b7-dbff-4699-af52-ba0df72ed200",
      "metadata": {},
      "outputs": [],
      "source": [
        "import os\n",
        "from matplotlib import pyplot as plt\n",
        "import numpy as np\n",
        "\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit.qasm3 import load\n",
        "\n",
        "from qiskit_ibm_catalog import QiskitFunctionsCatalog"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b95b9e75-37fe-4f86-a923-0a833c7960f8",
      "metadata": {},
      "source": [
        "<span id=\"error-mitigation-with-tem\" />\n",
        "\n",
        "## TEM을 통한 오류 완화\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "651a3f04-c8ba-4a39-8415-52d7e313ba2a",
      "metadata": {},
      "source": [
        "여기서 우리는 앞서 설명한 킥드 아이징 모델을 구현하는 회로를 제시한다. 회로는 다음과 같이 준비된다. 먼저, 상태 준비 단계가 있습니다. 이 단계에서 첫 번째 큐비트는 상태 $|+\\rangle$ 에 있으며, 나머지 큐비트들은 벨 쌍 $(|00\\rangle + |11\\rangle)/\\sqrt{2}$ 상태에 있습니다. 이어서 단위 진화 $\\hat{U}_{\\text{KI}}$ 를 구현하는 벽돌 구조가 적용됩니다. 물리적 시간 단계 수는 $t/2$ 회로 레이어 수에 해당합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "11e42656-76ba-452c-af22-8f4cd22ff174",
      "metadata": {},
      "source": [
        "다음 코드는 이 튜토리얼에 필요한 두 개의 QASM 파일을 다운로드합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "39bf7188-3771-4994-a6c6-e9cfcae3484f",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Download required QASM files\n",
        "import urllib\n",
        "\n",
        "urllib.request.urlretrieve(\n",
        "    \"https://ibm.box.com/shared/static/swy5jtq309b0xpzluzlmsmj908yphes8.qasm\",\n",
        "    \"ki_30q.qasm\",\n",
        ")\n",
        "urllib.request.urlretrieve(\n",
        "    \"https://ibm.box.com/shared/static/et3gkodonw6gsp2trs43lzaozrdtiu7s.qasm\",\n",
        "    \"ki_12q.qasm\",\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1f6f9970-63fb-40f4-9586-261cba23cb88",
      "metadata": {},
      "source": [
        "12개의 큐비트와 6개의 시간 단계로 구성된 회로의 축소 버전을 시각화할 수 있습니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "381a4e25-bc9c-47d0-b9f1-172eb5516484",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/simulate-kicked-ising-tem/extracted-outputs/381a4e25-bc9c-47d0-b9f1-172eb5516484-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Parameters of the kicked Ising model\n",
        "h = 0.0\n",
        "num_qubits = 12\n",
        "t_steps = 6\n",
        "\n",
        "# Load the circuit for the kicked Ising model\n",
        "small_circuit = load(\"ki_12q.qasm\")\n",
        "\n",
        "# Draw the circuit\n",
        "small_circuit.draw(\"mpl\", scale=0.25, fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a674e407-504d-4812-82bf-98e91ec9a4b4",
      "metadata": {},
      "source": [
        "다음으로 관측 가능 객체( $\\hat{X}_{n=t}$ )를 생성합니다. 이는 Qiskit에서 사용하는 순서와 일치하는 단순한 파울리 문자열로 구성됩니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "a9a87f6c-176d-4c85-85e5-6751aea0c90b",
      "metadata": {},
      "outputs": [],
      "source": [
        "def xt_observable(n_qubits, t_steps):\n",
        "    pauli_str = \"\".join([\"I\" * t_steps, \"X\", \"I\" * (n_qubits - t_steps - 1)])\n",
        "    pauli_str = pauli_str[::-1]  # Reverse the string to match qiskit order\n",
        "    return SparsePauliOp(data=pauli_str, coeffs=1.0)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ba5f7042-4abd-4ae7-a091-591678377e8f",
      "metadata": {},
      "source": [
        "우리의 작은 12큐비트 예시에서 관측 가능량은 다음과 같습니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "b2608df1-b4e4-4143-bea5-a65ab8045fd4",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "SparsePauliOp(['IIIIIXIIIIII'],\n",
            "              coeffs=[1.+0.j])\n"
          ]
        }
      ],
      "source": [
        "# Build the observable for the kicked Ising model\n",
        "small_observable = xt_observable(n_qubits=12, t_steps=6)\n",
        "print(small_observable)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e588fafe-8db8-4445-8893-a78190b27b64",
      "metadata": {},
      "source": [
        "Qiskit Functions PUB을 입력 수집 수단으로 사용하십시오. 우리의 경우, 단일 회로와 관측 가능량을 우리의 관측 가능 계량( PUB )으로 고려해 보자:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "fc48eb54-148b-4b0d-8424-a135cb92039e",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Collect the input PUBs, in this case composed of a\n",
        "# single circuit and observable\n",
        "pubs = [(small_circuit, [small_observable])]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9a4bcd8d-ae21-40ab-b0e2-510236ba92de",
      "metadata": {},
      "source": [
        "다음으로, TEM 기능에 접근할 수 있게 됩니다. 먼저 IBM Cloud 에 필요한 인증을 설정하고 사용 가능한 장치 중에서 백엔드를 선택합니다. 토큰, 사용 가능한 백엔드 및 해당 클라우드 리소스 이름(CRN) [은](/) IBM Quantum Platform 대시보드에서 계정에 로그인하여 확인할 수 있습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "6c9f80a8-4a65-4daa-94bb-a98edd6a1989",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Set IBM Quantum credentials and backend configuration\n",
        "personal_token = os.environ.get(\n",
        "    \"QISKIT_IBM_TOKEN\", \"<API-KEY>\"\n",
        ")  # Replace with your personal token or set the environment variable\n",
        "channel = \"ibm_quantum_platform\"\n",
        "crn = \"your_crn\"  # Replace with the Cloud Resource Name (CRN)\n",
        "\n",
        "# Select the QPU backend\n",
        "backend_name = \"ibm_qpu_name\"  # Replace with your desired backend's name"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "10df1803-5245-42b2-8eea-c0773cd655b6",
      "metadata": {},
      "source": [
        "[Qiskit Functions Catalog](/functions) 에서 TEM 함수를 불러옵니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "2473b284-108f-45fe-a8d8-3aed584137f6",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Load the TEM function from the Qiskit Functions Catalog\n",
        "catalog = QiskitFunctionsCatalog(\n",
        "    channel=channel,\n",
        "    token=personal_token,\n",
        "    instance=crn,\n",
        ")\n",
        "tem = catalog.load(\"algorithmiq/tem\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3c732819-4dca-421c-bc2b-45ff5a5912db",
      "metadata": {},
      "source": [
        "이제 TEM이 제공하는 오류 완화 기능을 적용하여 킥된 아이징 회로에 대한 실험을 수행할 수 있습니다. 기본 설정으로 TEM을 실행하면 QPU에 따라 예상 QPU 실행 시간이 약 2.5 분 정도로 간단하게 실행할 수 있습니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "b826e025-f36b-4fb5-90bd-e1ef36f5c1b2",
      "metadata": {},
      "outputs": [],
      "source": [
        "tem_job = tem.run(pubs=pubs, backend_name=backend_name)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4b692a80-5a10-4131-9d7f-785fedbe4221",
      "metadata": {},
      "source": [
        "기본 옵션으로 TEM 함수는 양자 컴퓨터에서 세 가지 작업을 실행합니다: 잡음 학습, 판독 완화, 회로 샘플링. 이들 각각이 사용하는 샷 수는 함수에 전달되는 옵션에서 변경할 수 있습니다. 기본적으로 이러한 매개변수는 완화된 기대값에서 0.05 의 정밀도를 달성하도록 설정됩니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "25b6f313-a928-493e-837f-45e6e7836aef",
      "metadata": {},
      "source": [
        "작업 상태는 [IBM Quantum Platform 대시보드](/) 에서 확인하거나 다음 명령어로 확인할 수 있습니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "05e202ff-5b86-4a93-a693-86fbb1cf3e02",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QUEUED\n"
          ]
        }
      ],
      "source": [
        "print(tem_job.status())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8e427c75-72fb-4a97-b723-97d695a692d3",
      "metadata": {},
      "source": [
        "상태가 일 때 `DONE`, 원시 결과와 완화된 결과를 확인할 수 있습니다. 아래에 정의된 `tem_evs` 는 요청된 관측량들의 기대값이며, 이 경우 단일 관측량인 $\\langle \\hat X_{n=t}\\rangle$ 에 해당하며, 와 `tem_std` 는 각각 대응하는 표준편차이다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "3ca34069-1363-4e37-9718-91639d817a82",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "TEM Result: 1.031 ± 0.046\n"
          ]
        }
      ],
      "source": [
        "# Get the results of the TEM job\n",
        "tem_results = tem_job.result()[\n",
        "    0\n",
        "]  # Get the first and only result from the job\n",
        "tem_evs = tem_results.data.evs[0]\n",
        "tem_std = tem_results.data.stds[0]\n",
        "\n",
        "print(f\"TEM Result: {tem_evs:.3f} ± {tem_std:.3f}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f90f503e-ab80-4550-a7cf-dfeea12babb0",
      "metadata": {},
      "source": [
        "각 호출에 사용된 양자 런타임의 양은 [IBM Quantum Platform]() 에서 확인하거나, Python 코드의 결과 메타데이터를 검사하여 확인할 수 있습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "b05818d6-b680-483e-9084-f3fd2de067ab",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "TEM Runtime: 155.0 seconds\n"
          ]
        }
      ],
      "source": [
        "# Get the TEM job runtime\n",
        "tem_runtime = tem_job.result().metadata[\"resource_usage\"][\n",
        "    \"RUNNING: EXECUTING_QPU\"\n",
        "][\"QPU_TIME\"]\n",
        "\n",
        "print(f\"TEM Runtime: {tem_runtime} seconds\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6be333a8-41c9-4ba9-b07d-a0ac50149add",
      "metadata": {},
      "source": [
        "<span id=\"customize-tem-parameters-and-advanced-options\" />\n",
        "\n",
        "## TEM 매개변수 및 고급 옵션 사용자 지정\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "abee6fc2-90d6-4608-ad21-c606c936dd94",
      "metadata": {},
      "source": [
        "TEM 기능은 오류 완화 워크플로를 사용자 정의할 수 있는 여러 고급 옵션을 제공합니다. 이러한 옵션을 통해 정밀도, 샷 수, 잡음 학습 전략 및 기타 매개변수를 제어하여 실험 요구사항과 사용 가능한 양자 자원에 더 잘 맞출 수 있습니다.\n",
        "\n",
        "일반적인 고급 옵션은 다음과 같습니다:\n",
        "\n",
        "* \\*\\*`precision`\\*\\*완화된 기대값에 대한 목표 정밀도를 지정하십시오.\n",
        "* \\*\\*`default_shots`\\*\\*대신 측정 작업에서 사용되는 샷 `precision` 수를 지정할 수 있습니다.\n",
        "* \\*\\*`tem_max_bond_dimension`\\*\\*텐서 네트워크에서 사용되는 최대 결합 차원.\n",
        "* \\*\\*`tem_compression_cutoff`\\*\\*텐서 네트워크에 사용할 컷오프 값.\n",
        "* **노이즈 학습 옵션** : 노이즈 특성화 방식을 구성합니다. 예를 들어 반복 횟수나 특정 교정 회로 등을 설정할 수 있습니다.\n",
        "* \\*\\*`private`\\*\\*회로 및 실험 결과가 본인에게만 비공개로 유지되도록 하고, 작업 결과의 다중 다운로드를 비활성화하십시오.\n",
        "\n",
        "지원되는 옵션의 전체 목록과 설명은 [TEM 문서](/docs/guides/algorithmiq-tem) 또는 [Qiskit Functions Catalog](/functions) 를 참조하십시오. 이러한 매개변수를 조정하여 실행 시간, 리소스 사용량 및 결과 정확도 간의 균형을 맞출 수 있습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "24db681c-b306-41e0-8507-626ef279b076",
      "metadata": {},
      "source": [
        "TEM 함수를 실행할 때 다음 옵션을 사전(dictionary) 형태로 인수로 `options` 전달할 수 있습니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "a2e9a032-91cb-4a18-9a00-00a149e60459",
      "metadata": {},
      "outputs": [],
      "source": [
        "options = {\n",
        "    \"default_shots\": 10_000,\n",
        "    \"tem_max_bond_dimension\": 512,\n",
        "    \"tem_compression_cutoff\": 1e-16,\n",
        "    # This option helps optimizing the measurement\n",
        "    # stage since the observable is strongly biased\n",
        "    # toward the X operator for all the qubits.\n",
        "    \"compute_shadows_bias_from_observable\": True,\n",
        "    # set to True to keep experiment results private,\n",
        "    # recommended for confidential circuits\n",
        "    \"private\": False,\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "db700868-4dae-48c8-be1a-668ef2e63177",
      "metadata": {},
      "source": [
        "노이즈 학습기를 위한 사용자 지정 옵션도 전달할 수 있습니다. 이 정의들은 에서 사용된 정의를 따릅니다: `qiskit-ibm-runtime`[`NoiseLearnerOptions`](/docs/api/qiskit-ibm-runtime/options-noise-learner-options)\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 29,
      "id": "30591014-3bc6-4548-ba0d-dc5cc22e9dcc",
      "metadata": {},
      "outputs": [],
      "source": [
        "nl_options = {\n",
        "    \"num_randomizations\": 32,\n",
        "    \"max_layers_to_learn\": 2,\n",
        "    \"shots_per_randomization\": 128,\n",
        "    \"layer_pair_depths\": [0, 1, 2, 4, 16, 32],\n",
        "}\n",
        "\n",
        "# add noise learning options to the overall options\n",
        "options |= nl_options"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "216ad12c-8c70-4073-8515-b07fd57f74d4",
      "metadata": {},
      "source": [
        "이 회로에 맞춰 조정된 사용자 지정 옵션으로 실험을 다시 실행하십시오. 예상 실행 시간은 약 4 QPU 분입니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 30,
      "id": "ebce8e14-433f-4858-96c6-9d90ff0353af",
      "metadata": {},
      "outputs": [],
      "source": [
        "tem_job_custom = tem.run(\n",
        "    pubs=pubs, backend_name=backend_name, options=options\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bd8d2c12-c9da-4ac3-97c0-d53be1455091",
      "metadata": {},
      "source": [
        "작업이 비공개로 설정되지 않은 경우, 나중에 결과를 복구할 수 있습니다. 이를 위해 여기에 출력된 작업 ID를 저장하고 사용하십시오 `tem_job_custom = catalog.get_job_by_id(\"your-job-id\")`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 31,
      "id": "0f99101b-9e72-45c8-8b00-9f3a257b8b3b",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Job ID: 1ba10094-a541-457a-9287-dbd49306d12d\n"
          ]
        }
      ],
      "source": [
        "job_id = tem_job_custom.job_id\n",
        "print(f\"Job ID: {job_id}\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 33,
      "id": "0c751dac-e856-4371-aaed-f67aca31061f",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "TEM Result: 0.956 ± 0.018\n"
          ]
        }
      ],
      "source": [
        "results_custom = tem_job_custom.result()\n",
        "tem_evs = results_custom[0].data.evs[0]\n",
        "tem_std = results_custom[0].data.stds[0]\n",
        "\n",
        "print(f\"TEM Result: {tem_evs:.3f} ± {tem_std:.3f}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "edfef6f9-6bac-42bb-8bd2-95f977f7b31b",
      "metadata": {},
      "source": [
        "이제 실험에 대한 통찰력을 얻기 위해 결과와 메타데이터를 확인할 수 있습니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 34,
      "id": "dd189b2d-860b-4b9a-88c2-7e5c62b1f160",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Unmitigated Result: 0.894 ± 0.015\n",
            "Exact Result: 1.0\n"
          ]
        }
      ],
      "source": [
        "metadata_custom = results_custom[0].metadata\n",
        "\n",
        "unmitigated_evs = metadata_custom[\"evs_non_mitigated\"][0]\n",
        "unmitigated_stds = metadata_custom[\"stds_non_mitigated\"][0]\n",
        "print(f\"Unmitigated Result: {unmitigated_evs:.3f} ± {unmitigated_stds:.3f}\")\n",
        "\n",
        "# Exact result for the kicked Ising model from the reference paper\n",
        "exact_evs = np.cos(2 * h) ** t_steps\n",
        "print(\"Exact Result:\", exact_evs)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 35,
      "id": "c3a2168d-98df-491e-a1f8-05de5684ab96",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/simulate-kicked-ising-tem/extracted-outputs/c3a2168d-98df-491e-a1f8-05de5684ab96-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# Plot comparing the different expectation values\n",
        "plt.bar(\n",
        "    [\"Unmitigated\", \"TEM\"],\n",
        "    [unmitigated_evs, tem_evs],\n",
        "    yerr=[unmitigated_stds, tem_std],\n",
        "    color=[\"grey\", \"c\"],\n",
        ")\n",
        "plt.hlines(y=exact_evs, xmin=-0.5, xmax=1.5, colors=\"r\", linestyles=\"dashed\")\n",
        "plt.ylabel(\"Expectation Value\")\n",
        "plt.ylim(0, 1.1)\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d643bdb4-22e0-4f55-b3a8-d5ef39f6e696",
      "metadata": {},
      "source": [
        "마지막으로, 사용자 정의 옵션이 QPU 및 클래식 런타임에 미치는 영향을 확인할 수 있습니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 27,
      "id": "09cf2226-c48c-483b-aa49-80186229ae95",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QPU Runtime: 342.0 seconds\n",
            "Classical Runtime: 107.632604 seconds\n"
          ]
        }
      ],
      "source": [
        "# Get the metadata of the TEM job\n",
        "job_metadata = results_custom.metadata\n",
        "\n",
        "# Get the runtime of the TEM job\n",
        "qpu_runtime = job_metadata[\"resource_usage\"][\"RUNNING: EXECUTING_QPU\"][\n",
        "    \"QPU_TIME\"\n",
        "]\n",
        "classical_runtime = (\n",
        "    job_metadata[\"resource_usage\"][\"RUNNING: OPTIMIZING_FOR_HARDWARE\"][\n",
        "        \"CPU_TIME\"\n",
        "    ]\n",
        "    + job_metadata[\"resource_usage\"][\"RUNNING: POST_PROCESSING\"][\"CPU_TIME\"]\n",
        ")\n",
        "\n",
        "print(f\"QPU Runtime: {qpu_runtime} seconds\")\n",
        "print(f\"Classical Runtime: {classical_runtime} seconds\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7cea6cf1-5530-4bf6-83da-ad2e9ff96806",
      "metadata": {},
      "source": [
        "<span id=\"scale-tem-to-large-circuits\" />\n",
        "\n",
        "## 대형 회로에 적용 가능한 TEM\n",
        "\n",
        "대형 회로는 원칙적으로 TEM 기능으로 실행될 수 있다. 그러나 TEM이 실행 시간이 매우 길 수 있는 IBM Cloud 러너에서 실행된다는 점을 고려할 때, 고전적 자원의 한계를 인지하는 것이 중요합니다. 매우 큰 회로의 경우, [qiskit\\ \\_ibm@algorithmiq.fi](mailto:qiskit_ibm@algorithmiq.fi) 으로 TEM 지원팀에 문의하십시오.\n",
        "\n",
        "여기서는 더 큰 유틸리티 규모인 30큐비트 회로로 예시를 실행하며, 정확도보다는 속도를 위해 TEM 매개변수를 최적화합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "f7ea1d3c-d745-48cc-8922-b070b2b5fd44",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Kicked Ising model parameters\n",
        "n_qubits = 30\n",
        "t_steps = 15\n",
        "h = 0.0\n",
        "\n",
        "# Load the circuit for the kicked Ising model\n",
        "circuit = load(\"ki_30q.qasm\")\n",
        "\n",
        "\n",
        "# Build the observable for the kicked Ising model\n",
        "observable = xt_observable(n_qubits=n_qubits, t_steps=t_steps)\n",
        "\n",
        "# Collect the input PUBs, in this case composed of a\n",
        "# single circuit and observable\n",
        "pubs = [(circuit, [observable])]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "854c3208-8c0f-4f7d-b260-0abba2bc71a0",
      "metadata": {},
      "source": [
        "성능 중심의 옵션을 정의해 보겠습니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 49,
      "id": "64882a71-3027-4e25-b714-9e9d6b13cd49",
      "metadata": {},
      "outputs": [],
      "source": [
        "options = {\n",
        "    \"num_randomizations\": 32,\n",
        "    \"max_layers_to_learn\": 2,\n",
        "    \"shots_per_randomization\": 128,\n",
        "    \"layer_pair_depths\": [0, 1, 2, 4, 16, 32, 64],\n",
        "    \"default_shots\": 5_000,\n",
        "    \"tem_max_bond_dimension\": 128,\n",
        "    \"tem_compression_cutoff\": 1e-10,\n",
        "    \"compute_shadows_bias_from_observable\": True,\n",
        "    \"private\": False,\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4ba36257-1974-4274-b04c-6daf3afe9d72",
      "metadata": {},
      "source": [
        "마지막으로 실험을 실행하고 결과를 얻은 후 시각화합니다. 이 작업에는 약 3.5 QPU 분이 소요될 것입니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 50,
      "id": "6faf7f80-dec9-49d2-80e7-d4e6fdea5100",
      "metadata": {},
      "outputs": [],
      "source": [
        "tem_job_large = tem.run(pubs=pubs, backend_name=backend_name, options=options)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 51,
      "id": "333b2335-b480-4bf9-854c-5155eedee900",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Job ID: 9f3f190f-f4b0-4dcb-bb83-5f71f37d0d77\n"
          ]
        }
      ],
      "source": [
        "job_id = tem_job_large.job_id\n",
        "print(f\"Job ID: {job_id}\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 53,
      "id": "a04dd421-a212-473c-a8a9-4c8edcfc3667",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "TEM Result: 0.794 ± 0.026\n",
            "QPU Runtime: 203.0 seconds\n",
            "Classical Runtime: 251.71805499999996 seconds\n"
          ]
        }
      ],
      "source": [
        "results_large = tem_job_large.result()\n",
        "tem_evs = results_large[0].data.evs[0]\n",
        "tem_std = results_large[0].data.stds[0]\n",
        "\n",
        "print(f\"TEM Result: {tem_evs:.3f} ± {tem_std:.3f}\")\n",
        "\n",
        "\n",
        "# Get the metadata of the TEM job\n",
        "job_metadata = tem_job_large.result().metadata\n",
        "\n",
        "# Get the runtime of the TEM job\n",
        "qpu_runtime = job_metadata[\"resource_usage\"][\"RUNNING: EXECUTING_QPU\"][\n",
        "    \"QPU_TIME\"\n",
        "]\n",
        "classical_runtime = (\n",
        "    job_metadata[\"resource_usage\"][\"RUNNING: OPTIMIZING_FOR_HARDWARE\"][\n",
        "        \"CPU_TIME\"\n",
        "    ]\n",
        "    + job_metadata[\"resource_usage\"][\"RUNNING: POST_PROCESSING\"][\"CPU_TIME\"]\n",
        ")\n",
        "\n",
        "print(f\"QPU Runtime: {qpu_runtime} seconds\")\n",
        "print(f\"Classical Runtime: {classical_runtime} seconds\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 54,
      "id": "24894c44-e399-4b9d-a3ff-38a28ff32ece",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/simulate-kicked-ising-tem/extracted-outputs/24894c44-e399-4b9d-a3ff-38a28ff32ece-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# Plot comparing the different expectation values\n",
        "metadata_large = results_large[0].metadata\n",
        "unmitigated_evs = metadata_large[\"evs_non_mitigated\"][0]\n",
        "unmitigated_stds = metadata_large[\"stds_non_mitigated\"][0]\n",
        "\n",
        "exact_evs = np.cos(2 * h) ** t_steps\n",
        "\n",
        "plt.bar(\n",
        "    [\"Unmitigated\", \"TEM\"],\n",
        "    [unmitigated_evs, tem_evs],\n",
        "    yerr=[unmitigated_stds, tem_std],\n",
        "    color=[\"grey\", \"c\"],\n",
        ")\n",
        "plt.hlines(y=exact_evs, xmin=-0.5, xmax=1.5, colors=\"r\", linestyles=\"dashed\")\n",
        "plt.ylabel(\"Expectation Value\")\n",
        "plt.ylim(0, 1.1)\n",
        "plt.show()"
      ]
    },
    {
      "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"
    },
    "hours": 1.5,
    "qpuSeconds": 600
  },
  "nbformat": 4,
  "nbformat_minor": 4
}