{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "d0e7f54f-e951-44d4-8cd8-5b539cf5c91c",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"집행자 예시\"\n",
        "description: \"qiskit-ibm-runtime에서 Executor 프리미티브를 사용하는 실제 예시.\"\n",
        "---\n",
        "\n",
        "<span id=\"executor-examples\" />\n",
        "\n",
        "# 집행자 예시\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a53ccd93-5bca-4dfb-a8a0-fcf4ed046fa7",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "{/*\n",
        "  DO NOT EDIT THIS CELL!!!\n",
        "  This cell's content is generated automatically by a script. Anything you add\n",
        "  here will be removed next time the notebook is run. To add new content, create\n",
        "  a new cell before or after this one.\n",
        "  */}\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"패키지 버전\">\n",
        "    이 페이지의 코드는 다음 요구 사항을 바탕으로 개발되었습니다.\n",
        "    이 버전 이상을 사용하시기를 권장합니다.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.2\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    samplomatic~=0.21.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fed832ee-87a7-4261-874d-84002f3863b5",
      "metadata": {},
      "source": [
        "이 섹션의 예제는 Executor 기본 객체를 사용하는 몇 가지 일반적인 방법을 보여줍니다. 이 예제를 실행하기 전에, [‘Qiskit](/docs/guides/install-qiskit) 및 [Executor 설치’ 퀵스타트](/docs/guides/directed-execution-model) 가이드의 지침을 따르십시오.\n",
        "\n",
        "<span id=\"before-you-begin\" />\n",
        "\n",
        "## 시작하기 전에\n",
        "\n",
        "`samplex`이 페이지의 일부 코드 예제에서는 Samplomatic 패키지의 일부인 를 사용합니다.  따라서, 해당 코드 블록을 실행하기 전에 다음 코드 블록에 표시된 대로 Samplomatic을 설치해야 합니다.  자세한 내용은 [Samplomatic](https://qiskit.github.io/samplomatic) 문서를 참조하십시오.\n",
        "\n",
        "```python\n",
        "pip install samplomatic\n",
        "\n",
        "# For visualization support, include the visualization dependencies.\n",
        "# pip install samplomatic[vis]\n",
        "```\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "19549d62-4095-458d-a691-00b9bc456ed5",
      "metadata": {},
      "source": [
        "<span id=\"example-parameterized-circuit\" />\n",
        "\n",
        "## 예: 매개변수화 회로\n",
        "\n",
        "이 예제는 매개변수가 있는 회로 항목을 추가하는 방법과 samplex 항목을 추가하는 방법을 보여줍니다. 다음과 같은 단계로 구성됩니다:\n",
        "\n",
        "1. 회로 설정: 대상 회로를 생성하고 트랜스파일합니다.\n",
        "2. 샘플렉스 준비: 게이트와 측정값을 주석이 달린 상자로 묶고, 회로 템플릿과 샘플렉스 쌍을 생성합니다.\n",
        "3. 실행: 회로 항목과 샘플렉스 항목을 추가하고, 이를 `QuantumProgram` 단일 작업으로 실행합니다.\n",
        "\n",
        "<span id=\"set-up-the-circuit\" />\n",
        "\n",
        "### 회로 구성하기\n",
        "\n",
        "3큐비트 GHZ 상태를 준비하고, 큐비트를 파울리-Z 축을 중심으로 회전시킨 다음, 계산 기저에서 큐비트를 측정한다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "caf43d3e-ed55-4805-8d19-6c0980eeb1dc",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit import Parameter, QuantumCircuit\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, Executor\n",
        "from qiskit_ibm_runtime.quantum_program import QuantumProgram\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "import numpy as np\n",
        "from samplomatic import build\n",
        "from samplomatic.transpiler import generate_boxing_pass_manager\n",
        "\n",
        "# Generate the circuit\n",
        "circuit = QuantumCircuit(3)\n",
        "circuit.h(0)\n",
        "circuit.h(1)\n",
        "circuit.cz(0, 1)\n",
        "circuit.h(1)\n",
        "circuit.h(2)\n",
        "circuit.cz(1, 2)\n",
        "circuit.h(2)\n",
        "circuit.rz(Parameter(\"theta\"), 0)\n",
        "circuit.rz(Parameter(\"phi\"), 1)\n",
        "circuit.rz(Parameter(\"lam\"), 2)\n",
        "circuit.measure_all()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f95bc53d-ed01-4b94-988b-1e497916d0fa",
      "metadata": {},
      "source": [
        "백엔드를 지정하고, QPU에서 지원하는 명령어만 사용하도록 회로를 트랜스파일링합니다(이를 명령어 집합 아키텍처(ISA) 회로라고 합니다).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "bf633f01-372f-4519-b89d-ab4075255bd9",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Initialize the service and choose a backend\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Transpile the circuit to ISA\n",
        "preset_pass_manager = generate_preset_pass_manager(\n",
        "    backend=backend, optimization_level=3\n",
        ")\n",
        "isa_circuit = preset_pass_manager.run(circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fbecf32d-d1b9-4e12-ab56-0a1ede7ebf04",
      "metadata": {},
      "source": [
        "<span id=\"prepare-the-samplex\" />\n",
        "\n",
        "### 샘플렉스 준비하기\n",
        "\n",
        "편의 함수와 `generate_boxing_pass_manager` 그 트위링 매개변수를 사용하여 두 큐비트 게이트와 측정 연산을 상자로 묶고 트위링 주석을 적용합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "8d6d64ad-12ee-4c0c-a683-d1178600d3c7",
      "metadata": {},
      "outputs": [],
      "source": [
        "boxing_pm = generate_boxing_pass_manager(\n",
        "    # Add gate twirling\n",
        "    enable_gates=True,\n",
        "    # Add measurement twirling\n",
        "    enable_measures=True,\n",
        ")\n",
        "\n",
        "boxed_circuit = boxing_pm.run(isa_circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2e8fb1f9-4b15-4161-9f8f-1c24d64b0045",
      "metadata": {},
      "source": [
        "메서드를 `build` 사용하여 템플릿 회로와 샘플렉스를 생성합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "90e21ca1-7f39-4636-b65e-28685b610a3c",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Build the template circuit and the samplex\n",
        "template_circuit, samplex = build(boxed_circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "521a7263-8d2f-46fd-a261-c23ae56aa5b5",
      "metadata": {},
      "source": [
        "<span id=\"execute-the-circuits\" />\n",
        "\n",
        "### 서킷 운동 수행하기\n",
        "\n",
        "Executor는 객체를 실행합니다 `QuantumProgram` . 각각에는 `QuantumProgram` 여러 개의 항목이 포함될 수 있습니다. 이 예제에서는 실행할 회로 항목과 샘플렉스 항목을 추가합니다. 자세한 내용은 [Executor 입력 및 출력을](/docs/guides/executor-input-output) 참조하십시오.\n",
        "\n",
        "첫 번째 단계는 빈 프로그램을 초기화하고, 각 항목의 모든 구성에 대해 샷을 `1024` 요청하는 것입니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "85d7d9ef-a74c-42e4-a758-0f490e29275d",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Generate a quantum program\n",
        "program = QuantumProgram(shots=1024)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8869d18d-cc0e-4556-a195-cd6b590bcef7",
      "metadata": {},
      "source": [
        "`QuantumProgram`회로 항목을 에 추가하십시오. 이 회로 항목은 ISA 회로와 10세트의 매개변수 값으로 구성되어 있습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "19963674-3e72-473c-b24a-228316946dc5",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Append the circuit and the parameter values to the program\n",
        "program.append_circuit_item(\n",
        "    isa_circuit,\n",
        "    circuit_arguments=np.random.rand(10, 3),  # 10 sets of parameter values\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "41505f83-a7a6-4ea8-a7fc-a3fb45a2992a",
      "metadata": {},
      "source": [
        "다음 인수를 사용하여 samplex 항목을 에 `QuantumProgram` 추가하십시오:\n",
        "\n",
        "* 템플릿 회로와 해당 `build` 함수에 의해 생성된 샘플렉스\n",
        "* 원본 회로의 매개변수 값 10가지\n",
        "* 수행할 무작위 배정 횟수\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "d6b07700-5834-4baa-a08a-434516f5bc07",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Append the template circuit and samplex as a samplex item\n",
        "program.append_samplex_item(\n",
        "    template_circuit,\n",
        "    samplex=samplex,\n",
        "    samplex_arguments={\n",
        "        \"parameter_values\": np.random.rand(\n",
        "            10, 3\n",
        "        ),  # 10 sets of parameter values\n",
        "    },\n",
        "    shape=(2, 14, 10),\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f39e3e78-5953-4801-b521-dd48ae487acf",
      "metadata": {},
      "source": [
        "<span id=\"run-the-executor-job\" />\n",
        "\n",
        "### Executor 작업 실행\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "149addb2-e76f-427c-bac4-54b6a83ddb0a",
      "metadata": {},
      "outputs": [],
      "source": [
        "# initialize an Executor with default options\n",
        "executor = Executor(mode=backend)\n",
        "\n",
        "# Submit the job\n",
        "job = executor.run(program)\n",
        "\n",
        "# Retrieve the result\n",
        "result = job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "93698fec-cff7-4153-8cbb-f7e39c972d9a",
      "metadata": {},
      "source": [
        "각 작업에 대한 결과를 가져옵니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "77235bf8-bcac-43fb-89b0-9ba74b976053",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Access the results of the classical register of task #0, the CircuitItem\n",
        "result_0 = result[0][\"meas\"]\n",
        "\n",
        "# Access the results of the classical register of task #1, the SamplexItem\n",
        "result_1 = result[1][\"meas\"]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "64063941-87b5-4c5d-bbf9-8920c24a216f",
      "metadata": {},
      "source": [
        "<span id=\"example-perform-pec\" />\n",
        "\n",
        "## 예시: PEC 수행\n",
        "\n",
        "이 예제는 샘플렉스(Samplex) 항목을 사용하여 오차 완화를 위한 확률적 오차 상쇄( [PEC](/docs/guides/error-mitigation-and-suppression-techniques#pec) )를 수행하는 방법을 보여줍니다.\n",
        "\n",
        "10개의 큐비트와 두 개의 서로 다른 CX 게이트 층으로 구성된 회로의 대칭 버전을 생각해 보자. 주요 업무는 다음과 같습니다:\n",
        "\n",
        "* 회전을 곁들여 회로를 수행하세요.\n",
        "* 논문 [“노이즈가 있는 양자 프로세서에서 스파스 파울리-린드블라드 모델을 이용한 확률적 오차 보정(Probabilistic error cancellation with sparse Pauli-Lindblad models on noisy quantum processors)](https://arxiv.org/abs/2201.09866) ”에 제시된 바와 같이, PEC 보정 기법을 적용하여 회로를 실행하십시오.\n",
        "\n",
        "이 프로세스는 다음과 같은 단계로 구성됩니다:\n",
        "\n",
        "1. 설정: 대상 회로를 생성하고 각 연산 단계를 상자로 묶습니다.\n",
        "2. 학습: PEC를 통해 완화하고자 하는 명령어의 노이즈를 학습합니다.\n",
        "3. 실행: 백엔드에서 회로를 실행합니다.\n",
        "4. 분석: 결과를 후처리하고 분석합니다.\n",
        "\n",
        "비교를 위해 이 미러 회로를 두 번 실행해 보겠습니다. 한 번은 파울리 회전만 적용한 경우이고, 다른 한 번은 PEC 완화 효과를 적용한 경우입니다.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  이 예제의 실행 시간은 Heron r2 프로세서 기준 약 10분 정도 소요됩니다.\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"set-up-the-circuit\" />\n",
        "\n",
        "### 회로 구성하기\n",
        "\n",
        "백엔드를 선택하고 10큐비트 회로를 준비하십시오.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "f9e93b2c-154a-4d09-872d-f770bcc669c4",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/executor-examples/extracted-outputs/f9e93b2c-154a-4d09-872d-f770bcc669c4-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit_ibm_runtime import QiskitRuntimeService, Executor\n",
        "from qiskit_ibm_runtime.quantum_program import QuantumProgram\n",
        "from qiskit.circuit import QuantumCircuit, Parameter\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from samplomatic.transpiler import generate_boxing_pass_manager\n",
        "from samplomatic import build\n",
        "\n",
        "# Initialize the service and choose a backend\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Prepare a circuit\n",
        "\n",
        "num_qubits = 10\n",
        "num_layers = 10\n",
        "\n",
        "qubits = list(range(num_qubits))\n",
        "circuit = QuantumCircuit(num_qubits)\n",
        "\n",
        "for layer_idx in range(num_layers):\n",
        "    circuit.rx(Parameter(f\"theta_{layer_idx}\"), qubits)\n",
        "    for i in range(num_qubits // 2):\n",
        "        circuit.cz(qubits[2 * i], qubits[2 * i + 1])\n",
        "\n",
        "    circuit.rx(Parameter(f\"phi_{layer_idx}\"), qubits)\n",
        "    for i in range(num_qubits // 2 - 1):\n",
        "        circuit.cz(qubits[2 * i] + 1, qubits[2 * i + 1] + 1)\n",
        "\n",
        "circuit.draw(\"mpl\", scale=0.35, fold=100)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2d76f4f5-48b7-4123-8b6b-32eeaa06527d",
      "metadata": {},
      "source": [
        "이 회로와 그 역회로를 결합하여 대칭 회로를 만듭니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "f8ac3f75-88ca-40f9-8382-6a427303bb8e",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/executor-examples/extracted-outputs/f8ac3f75-88ca-40f9-8382-6a427303bb8e-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 11,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "mirror_circuit = circuit.compose(circuit.inverse())\n",
        "mirror_circuit.measure_all()\n",
        "\n",
        "mirror_circuit.draw(\"mpl\", scale=0.35, fold=100)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2bb0692c-3d4f-4a74-807e-6b93ef4ea8d2",
      "metadata": {},
      "source": [
        "몇 가지 매개변수 값을 설정합니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "c1974bff-c738-43a8-8e27-b85059e2428a",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "\n",
        "parameter_values = np.random.rand(mirror_circuit.num_parameters)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0ca9f203-008b-4190-9e86-affefb303938",
      "metadata": {},
      "source": [
        "패스 매니저를 사용하여 회로를 ISA 회로로 변환하십시오.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "224e0d6d-9238-4fae-aad8-f051c7e34938",
      "metadata": {},
      "outputs": [],
      "source": [
        "preset_pass_manager = generate_preset_pass_manager(\n",
        "    backend=backend,\n",
        "    optimization_level=3,\n",
        ")\n",
        "\n",
        "isa_circuit = preset_pass_manager.run(mirror_circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9dd71644-df3d-4cf3-9e4b-9c7624b54961",
      "metadata": {},
      "source": [
        "다음으로, 게이트와 측정값을 주석이 달린 상자로 묶으세요. 이 작업을 수동으로 수행하거나, 편의를 위해 Samplomatic의 함수를 `generate_boxing_pass_manager` 사용할 수 있습니다. 첫 번째 회로에는 회전 효과만 적용되므로 주석만 추가하면 `Twirl` 됩니다. 두 번째 회로는 PEC 완화 기능이 완전히 활성화된 상태에서 실행되며, 및 `InjectNoise` 주석이 모두 `Twirl` 필요합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "4afb22f1-b41f-40ed-87f7-c2d0b0f6730c",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Pass manager used to create twirled-annotated boxes.\n",
        "boxing_pm = generate_boxing_pass_manager(\n",
        "    enable_gates=True,\n",
        "    enable_measures=True,\n",
        ")\n",
        "\n",
        "mirror_circuit_twirl = boxing_pm.run(isa_circuit)\n",
        "\n",
        "# Pass manager used to create a new boxed circuit with\n",
        "# both Twirl and InjectNoise annotations.\n",
        "boxing_pm = generate_boxing_pass_manager(\n",
        "    enable_gates=True,\n",
        "    enable_measures=True,\n",
        "    inject_noise_targets=\"gates\",  # no measurement mitigation\n",
        "    inject_noise_strategy=\"uniform_modification\",\n",
        ")\n",
        "\n",
        "mirror_circuit_pec = boxing_pm.run(isa_circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bd0c7cc5-48ba-47ab-84bc-41f832af3d8d",
      "metadata": {},
      "source": [
        "<span id=\"learn-the-noise\" />\n",
        "\n",
        "### 소리를 익히세요\n",
        "\n",
        "`InjectNoise`노이즈 학습 실험 횟수를 최소화하려면, 두 번째 회로( 에 주석이 달린 상자가 있는 회로)에서 고유한 명령어를 식별하십시오. 고유성을 정의할 때, 다음 두 조건이 모두 충족될 경우 두 박스 명령어는 서로 동일합니다:\n",
        "\n",
        "* 단일 큐비트 게이트 수준까지는 두 내용의 내용이 동일합니다.\n",
        "* 그들의 `Twirl` 주석은 동일합니다(그 외의 주석은 모두 무시됩니다).\n",
        "\n",
        "이를 통해 세 가지 고유한 지침, 즉 홀수 및 짝수 게이트 상자와 최종 측정 상자가 도출됩니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "2f8b325a-ffa4-447a-bf32-8b26b7404b0a",
      "metadata": {},
      "outputs": [],
      "source": [
        "from samplomatic.utils import find_unique_box_instructions\n",
        "\n",
        "unique_box_instructions = find_unique_box_instructions(\n",
        "    mirror_circuit_pec.data\n",
        ")\n",
        "assert len(unique_box_instructions) == 3"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7d496c90-fb07-49e6-a233-451ad4306102",
      "metadata": {},
      "source": [
        "`NoiseLearnerV3`를 초기화하고, 옵션을 설정하여 학습 매개변수를 선택한 다음, 노이즈 학습 작업을 실행합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "d69204bb-4beb-4b31-b9dd-e8923889685e",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.noise_learner_v3 import NoiseLearnerV3\n",
        "\n",
        "learner = NoiseLearnerV3(backend)\n",
        "\n",
        "learner.options.shots_per_randomization = 128\n",
        "learner.options.num_randomizations = 32\n",
        "learner.options.layer_pair_depths = [0, 1, 2, 4, 16, 32]\n",
        "\n",
        "learner_job = learner.run(unique_box_instructions)\n",
        "\n",
        "learner_job.job_id()\n",
        "learner_result = learner_job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "efe80acb-f12d-4051-84ed-d61a5a93ca23",
      "metadata": {},
      "source": [
        "메서드를 `result.to_dict` 사용하여 samplex에서 요구하는 객체로 변환합니다 `result` .\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "fd63ad99-01ad-492b-9232-91f2377f97f6",
      "metadata": {},
      "outputs": [],
      "source": [
        "noise_maps = learner_result.to_dict(\n",
        "    instructions=unique_box_instructions, require_refs=False\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "89dd2022-db07-46f6-8737-644aa070dcdb",
      "metadata": {},
      "source": [
        "<span id=\"execute-the-circuits\" />\n",
        "\n",
        "### 서킷 운동 수행하기\n",
        "\n",
        "`Executor` 객체를 실행합니다 `QuantumProgram` . 각각에는 `QuantumProgram` 여러 *항목이* 포함될 수 있으며, 이 항목들은 프로그램에 추가됩니다. 각 항목은 프로그램이 수행해야 할 작업입니다.\n",
        "\n",
        "빈 프로그램을 초기화하고, 각 항목의 모든 구성에 대해 샷을 `1000` 요청합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "id": "b48b038e-6e7d-4a6a-8f9a-df1389b644fa",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.quantum_program import QuantumProgram\n",
        "\n",
        "# Initialize an empty QuantumProgram\n",
        "program = QuantumProgram(shots=1000)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "845a9fdb-6837-4bda-925c-8795613bb708",
      "metadata": {},
      "source": [
        "다음으로, 템플릿 회로와 samplex를 `mirror_circuit_twirl` 작성하여 프로그램에 추가하십시오. 또한 samplex에서 무작위 배정을 요청하십시오 `900` . 즉, 샘플렉스는 여러 세트의 매개변수를 생성하며 `900` , 각 세트는 QPU에서 (샷 수만큼) 실행됩니다 `1000` .\n",
        "\n",
        "이것이 이 프로그램의 첫 번째 작업입니다(결과 0).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "id": "38942fab-f68d-44ed-b613-362b38a1ca02",
      "metadata": {},
      "outputs": [],
      "source": [
        "template_twirl, samplex_twirl = build(mirror_circuit_twirl)\n",
        "\n",
        "program.append_samplex_item(\n",
        "    template_twirl,\n",
        "    samplex=samplex_twirl,\n",
        "    samplex_arguments={\"parameter_values\": parameter_values},\n",
        "    shape=(900,),\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a30d1536-5339-4f19-b351-1c26891a4817",
      "metadata": {},
      "source": [
        "`mirror_circuit_pec`마찬가지로, 를 위해 구축된 템플릿 회로와 samplex를 추가하고, 개의 무작위화를 요청합니다 `900` .  이것은 이 프로그램의 두 번째 과제입니다(결과 1).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "id": "16bbb410-b0b7-4011-b4d0-62ffbad30f41",
      "metadata": {},
      "outputs": [],
      "source": [
        "template_pec, samplex_pec = build(mirror_circuit_pec)\n",
        "\n",
        "program.append_samplex_item(\n",
        "    template_pec,\n",
        "    samplex=samplex_pec,\n",
        "    samplex_arguments={\n",
        "        \"parameter_values\": parameter_values,\n",
        "        \"pauli_lindblad_maps\": noise_maps,\n",
        "        \"noise_scales\": {\n",
        "            ref: -1.0 for ref in noise_maps\n",
        "        },  # Set the scales to -1 for PEC\n",
        "    },\n",
        "    shape=(900,),\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "abf9d679-0262-4447-b889-9b06ad3cd77d",
      "metadata": {},
      "source": [
        "작업을 가져와 `Executor` 제출합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "id": "6231e441-87f4-480a-886a-5fdd83631e60",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Twirl result keys:\n",
            " ['meas', 'measurement_flips.meas']\n",
            "\n",
            "Shape of results: (900, 1000, 10)\n",
            "PEC result keys:\n",
            " ['meas', 'measurement_flips.meas', 'pauli_signs']\n",
            "\n",
            "Shape of results: (900, 1000, 10)\n"
          ]
        }
      ],
      "source": [
        "from qiskit_ibm_runtime.executor import Executor\n",
        "\n",
        "executor = Executor(backend)\n",
        "executor_job = executor.run(program)\n",
        "\n",
        "executor_job.job_id()\n",
        "\n",
        "executor_results = executor_job.result()\n",
        "executor_results\n",
        "\n",
        "twirl_result = executor_results[0]\n",
        "\n",
        "print(f\"Twirl result keys:\\n {list(twirl_result.keys())}\\n\")\n",
        "print(f\"Shape of results: {twirl_result['meas'].shape}\")\n",
        "\n",
        "pec_result = executor_results[1]\n",
        "\n",
        "print(f\"PEC result keys:\\n {list(pec_result.keys())}\\n\")\n",
        "print(f\"Shape of results: {pec_result['meas'].shape}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "021b944c-5119-4554-b4e9-2af1cfc906d8",
      "metadata": {},
      "source": [
        "<span id=\"analyze-results\" />\n",
        "\n",
        "### 결과 분석\n",
        "\n",
        "마지막으로, 결과를 후처리하여 10개의 활성 큐비트 각각에 작용하는 단일 큐비트 파울리-Z 연산자의 기대값을 추정한다(기대값: `1.0`).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "id": "a24c1dd9-7f29-40b0-87ad-25c2a03e0431",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Qubit 0 -> 0.71\n",
            "Qubit 1 -> 0.72\n",
            "Qubit 2 -> 0.7\n",
            "Qubit 3 -> 0.68\n",
            "Qubit 4 -> 0.65\n",
            "Qubit 5 -> 0.64\n",
            "Qubit 6 -> 0.62\n",
            "Qubit 7 -> 0.66\n",
            "Qubit 8 -> 0.69\n",
            "Qubit 9 -> 0.75\n"
          ]
        }
      ],
      "source": [
        "# Undo measurement twirling\n",
        "twirl_result_unflipped = (\n",
        "    twirl_result[\"meas\"] ^ twirl_result[\"measurement_flips.meas\"]\n",
        ")\n",
        "\n",
        "# Calculate the expectation values of single-qubit Z operators\n",
        "exp_vals = 1 - 2 * twirl_result_unflipped.mean(axis=1).mean(axis=0)\n",
        "\n",
        "for qubit, val in enumerate(exp_vals):\n",
        "    print(f\"Qubit {qubit} -> {np.round(val, 2)}\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "id": "8aa25d47-c4fd-4b20-a36f-fa69d7bd0971",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Qubit 0 -> 0.98\n",
            "Qubit 1 -> 1.0\n",
            "Qubit 2 -> 0.99\n",
            "Qubit 3 -> 0.97\n",
            "Qubit 4 -> 0.97\n",
            "Qubit 5 -> 0.97\n",
            "Qubit 6 -> 0.96\n",
            "Qubit 7 -> 0.97\n",
            "Qubit 8 -> 0.97\n",
            "Qubit 9 -> 0.98\n"
          ]
        }
      ],
      "source": [
        "# Undo measurement twirling\n",
        "pec_result_unflipped = (\n",
        "    pec_result[\"meas\"] ^ pec_result[\"measurement_flips.meas\"]\n",
        ")\n",
        "\n",
        "# Calculate the signs for PEC mitigation\n",
        "signs = np.prod((-1) ** pec_result[\"pauli_signs\"], axis=-1)\n",
        "signs = signs.reshape((signs.shape[0], 1))\n",
        "\n",
        "# Calculate the expectation values of single-qubit Z operators as required by\n",
        "# PEC mitigation\n",
        "exp_vals = 1 - (2 * pec_result_unflipped.mean(axis=1) * signs).mean(axis=0)\n",
        "\n",
        "for qubit, val in enumerate(exp_vals):\n",
        "    print(f\"Qubit {qubit} -> {np.round(val, 2)}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cf25d17a-5e90-4e24-a3bf-c86f5bc3444b",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 다음 단계\n",
        "\n",
        "<Admonition type=\"tip\" title=\"권장사항\">\n",
        "  * [방송](/docs/guides/primitive-input-output#broadcasting) 개요를 확인해 주세요.\n",
        "  * [Executor 옵션](/docs/guides/executor-options) 사용 방법을 알아보세요.\n",
        "  * [지시형 실행](/docs/guides/directed-execution-model) 모델을 이해한다.\n",
        "  * [Samplomatic](https://qiskit.github.io/samplomatic/) 설명서를 확인해 보세요.\n",
        "  * [‘음영 처리된 라이트콘을](https://qiskit.github.io/qiskit-addon-slc/tutorials/01_getting_started.html) 이용한 확률적 오류 취소’ 튜토리얼에서 지향적 실행 모델을 사용할 때 다양한 오류 완화 기법을 결합하는 방법에 대해 알아보세요.\n",
        "</Admonition>\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": 4
}