{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "7e51aef7-70db-4772-a53f-100af6ad6902",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"견적서 예시\"\n",
        "description: \"IBM Quantum 추정기 프리미티브 사용에 대한 실제 예시.\"\n",
        "---\n",
        "\n",
        "<span id=\"estimator-examples\" />\n",
        "\n",
        "# 견적서 예시\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "10cf3d45-503c-41c9-b0a1-51c23e32bc5f",
      "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",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3a98beb8-d1df-4daf-80ce-d51e4dc31cfa",
      "metadata": {},
      "source": [
        "이 섹션의 예제들은 Estimator를 사용하는 몇 가지 일반적인 방법을 보여줍니다. 이 예제를 실행하기 전에 [‘Qiskit](install-qiskit) 설치’에 있는 지침을 따르십시오.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  이 예제들은 모두 `IBM Quantum` 기본 함수를 사용하지만, 대신 기본 함수를 사용할 수도 있습니다.\n",
        "</Admonition>\n",
        "\n",
        "Estimator를 사용하여 다양한 알고리즘에 필요한 양자 연산자의 기대값을 효율적으로 계산하고 해석할 수 있습니다. 분자 모델링, 기계 학습 및 복잡한 최적화 문제에서의 활용 사례를 살펴보세요.\n",
        "\n",
        "<span id=\"run-a-single-experiment\" />\n",
        "\n",
        "## 단일 실험 실행\n",
        "\n",
        "Estimator를 사용하여 단일 회로-관측값 쌍의 기대값을 구하십시오.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "6bc4a6a3-612e-4ad8-9fe3-3d56a4cb9a8f",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            " > Expectation value: 0.012658227848101266\n",
            " > Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "from qiskit.circuit.library import iqp\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.quantum_info import SparsePauliOp, random_hermitian\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator\n",
        "\n",
        "n_qubits = 50\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(\n",
        "    operational=True, simulator=False, min_num_qubits=n_qubits\n",
        ")\n",
        "\n",
        "mat = np.real(random_hermitian(n_qubits, seed=1234))\n",
        "circuit = iqp(mat)\n",
        "observable = SparsePauliOp(\"Z\" * 50)\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "isa_circuit = pm.run(circuit)\n",
        "isa_observable = observable.apply_layout(isa_circuit.layout)\n",
        "\n",
        "estimator = Estimator(mode=backend)\n",
        "job = estimator.run([(isa_circuit, isa_observable)])\n",
        "result = job.result()\n",
        "\n",
        "print(f\" > Expectation value: {result[0].data.evs}\")\n",
        "print(f\" > Metadata: {result[0].metadata}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c8594feb-0516-4cca-9064-232906b980a4",
      "metadata": {},
      "source": [
        "<span id=\"run-multiple-experiments-in-a-single-job\" />\n",
        "\n",
        "## 단일 작업에서 여러 실험을 실행합니다\n",
        "\n",
        "Estimator를 사용하여 여러 회로-관측값 쌍의 기대값을 구하십시오.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "662e73e9-8454-470a-b6aa-e84343005ca6",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            ">>> Expectation values for PUB 0: -0.2650103519668737\n",
            ">>> Standard errors for PUB 0: 0.49439861538856356\n",
            ">>> Expectation values for PUB 1: -0.02099609375\n",
            ">>> Standard errors for PUB 1: 0.013489459956524228\n",
            ">>> Expectation values for PUB 2: 0.2788671023965142\n",
            ">>> Standard errors for PUB 2: 0.4836236522960098\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "from qiskit.circuit.library import iqp\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.quantum_info import SparsePauliOp, random_hermitian\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator\n",
        "\n",
        "n_qubits = 50\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(\n",
        "    operational=True, simulator=False, min_num_qubits=n_qubits\n",
        ")\n",
        "\n",
        "rng = np.random.default_rng()\n",
        "mats = [np.real(random_hermitian(n_qubits, seed=rng)) for _ in range(3)]\n",
        "\n",
        "pubs = []\n",
        "circuits = [iqp(mat) for mat in mats]\n",
        "observables = [\n",
        "    SparsePauliOp(\"X\" * 50),\n",
        "    SparsePauliOp(\"Y\" * 50),\n",
        "    SparsePauliOp(\"Z\" * 50),\n",
        "]\n",
        "\n",
        "# Get ISA circuits\n",
        "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n",
        "\n",
        "for qc, obs in zip(circuits, observables):\n",
        "    isa_circuit = pm.run(qc)\n",
        "    isa_obs = obs.apply_layout(isa_circuit.layout)\n",
        "    pubs.append((isa_circuit, isa_obs))\n",
        "\n",
        "estimator = Estimator(backend)\n",
        "job = estimator.run(pubs)\n",
        "job_result = job.result()\n",
        "\n",
        "for idx in range(len(pubs)):\n",
        "    pub_result = job_result[idx]\n",
        "    print(f\">>> Expectation values for PUB {idx}: {pub_result.data.evs}\")\n",
        "    print(f\">>> Standard errors for PUB {idx}: {pub_result.data.stds}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5176c806-e00d-4def-93b4-64216bf8cc64",
      "metadata": {},
      "source": [
        "<span id=\"run-parameterized-circuits\" />\n",
        "\n",
        "## 매개변수화된 회로 실행\n",
        "\n",
        "Estimator를 사용하여 단일 작업 내에서 세 가지 실험을 수행하고, 매개변수 값을 활용하여 회로의 재사용성을 높입니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "3f991c86-8bcd-4d9e-bed1-a6a7ac0cabb6",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            ">>> Expectation values: [[ 0.9665404   0.90476418  0.77027221  0.53367788  0.27327396 -0.04118414\n",
            "  -0.32496864 -0.5686415  -0.78657426 -0.91870673 -0.95667336 -0.91656172\n",
            "  -0.78249875 -0.55877446 -0.2855005   0.0278851   0.31638861  0.58322755\n",
            "   0.78829027  0.92428375  0.96267938]\n",
            " [ 0.01930507  0.31831912  0.5969556   0.80630833  0.92535625  0.96525339\n",
            "   0.91312971  0.7689852   0.55062343  0.27992348 -0.01158304 -0.30287506\n",
            "  -0.57679253 -0.80158932 -0.90562218 -0.96246488 -0.90669469 -0.77606373\n",
            "  -0.55641496 -0.29193553  0.01630206]\n",
            " [-0.04719017 -0.35950326 -0.63599473 -0.84427497 -0.9669694  -1.00193302\n",
            "  -0.93565229 -0.77992474 -0.53861139 -0.25782991  0.05898771  0.34834922\n",
            "   0.62998871  0.83655294  0.95817487  1.00021701  0.93307828  0.77606373\n",
            "   0.54547542  0.26662444 -0.06670973]\n",
            " [ 0.9969995   0.93543779  0.76426619  0.55963247  0.24967888 -0.06241972\n",
            "  -0.35221024 -0.63620924 -0.83440793 -0.96568239 -1.00536503 -0.93415078\n",
            "  -0.77949574 -0.56284998 -0.26855494  0.05362519  0.35070873  0.61797667\n",
            "   0.84212996  0.97104491  0.99850101]]\n",
            ">>> Standard errors: [[0.00518482 0.00616652 0.00723301 0.01064988 0.01139583 0.01174119\n",
            "  0.01301757 0.01155567 0.00848267 0.00690879 0.00492396 0.00613768\n",
            "  0.00678488 0.00840832 0.01404782 0.01184222 0.00982484 0.00854968\n",
            "  0.00764619 0.00774419 0.00621175]\n",
            " [0.01590044 0.01095813 0.01205478 0.00872719 0.00609088 0.0043678\n",
            "  0.00579195 0.00857024 0.01184119 0.01191681 0.01262258 0.01090978\n",
            "  0.01346398 0.00940893 0.00709353 0.00454548 0.00795003 0.00900232\n",
            "  0.00768466 0.01225787 0.01271092]\n",
            " [0.01265687 0.01230849 0.00961079 0.00725756 0.00469446 0.00444008\n",
            "  0.00683132 0.00804195 0.01140408 0.01165563 0.01001761 0.01300941\n",
            "  0.01014068 0.00822676 0.00511424 0.00465829 0.00659315 0.00633185\n",
            "  0.00865837 0.0101667  0.01090357]\n",
            " [0.00399857 0.0064308  0.0071202  0.00974728 0.01066452 0.01082351\n",
            "  0.01311009 0.01053503 0.00801145 0.00501261 0.00499458 0.00673144\n",
            "  0.00871285 0.00998373 0.01241673 0.01345925 0.00835253 0.00686725\n",
            "  0.00814337 0.00466632 0.00432618]]\n",
            ">>> Metadata: {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "\n",
        "from qiskit.circuit import QuantumCircuit, Parameter\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Step 1: Map classical inputs to a quantum problem\n",
        "theta = Parameter(\"θ\")\n",
        "\n",
        "chsh_circuit = QuantumCircuit(2)\n",
        "chsh_circuit.h(0)\n",
        "chsh_circuit.cx(0, 1)\n",
        "chsh_circuit.ry(theta, 0)\n",
        "\n",
        "number_of_phases = 21\n",
        "phases = np.linspace(0, 2 * np.pi, number_of_phases)\n",
        "individual_phases = [[ph] for ph in phases]\n",
        "\n",
        "ZZ = SparsePauliOp.from_list([(\"ZZ\", 1)])\n",
        "ZX = SparsePauliOp.from_list([(\"ZX\", 1)])\n",
        "XZ = SparsePauliOp.from_list([(\"XZ\", 1)])\n",
        "XX = SparsePauliOp.from_list([(\"XX\", 1)])\n",
        "ops = [ZZ, ZX, XZ, XX]\n",
        "\n",
        "# Step 2: Optimize problem for quantum execution.\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "chsh_isa_circuit = pm.run(chsh_circuit)\n",
        "isa_observables = [\n",
        "    operator.apply_layout(chsh_isa_circuit.layout) for operator in ops\n",
        "]\n",
        "\n",
        "# Step 3: Execute using IBM Quantum primitives.\n",
        "\n",
        "# Reshape observable array for broadcasting\n",
        "reshaped_ops = np.fromiter(isa_observables, dtype=object)\n",
        "reshaped_ops = reshaped_ops.reshape((4, 1))\n",
        "\n",
        "estimator = Estimator(backend, options={\"default_shots\": int(1e4)})\n",
        "job = estimator.run([(chsh_isa_circuit, reshaped_ops, individual_phases)])\n",
        "# Get results for the first (and only) PUB\n",
        "pub_result = job.result()[0]\n",
        "print(f\">>> Expectation values: {pub_result.data.evs}\")\n",
        "print(f\">>> Standard errors: {pub_result.data.stds}\")\n",
        "print(f\">>> Metadata: {pub_result.metadata}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "117454c0-c8df-48cd-8503-f4fd137d6991",
      "metadata": {},
      "source": [
        "<span id=\"use-batches-and-advanced-options\" />\n",
        "\n",
        "## 일괄 처리 및 고급 옵션 사용\n",
        "\n",
        "QPU에서 회로 성능을 최적화하기 위해 일괄 [실행 모드와](/docs/guides/execution-modes) 고급 옵션을 살펴보세요.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "f009e993-98fe-451c-96f5-738153005543",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            " > Expectation value: 0.026385707741639945\n",
            " > Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n",
            " > Another Expectation value: 0.0134052163776774\n",
            " > More Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "from qiskit.circuit.library import iqp\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.quantum_info import SparsePauliOp, random_hermitian\n",
        "from qiskit_ibm_runtime import (\n",
        "    QiskitRuntimeService,\n",
        "    Batch,\n",
        "    EstimatorV2 as Estimator,\n",
        ")\n",
        "\n",
        "n_qubits = 15\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(\n",
        "    operational=True, simulator=False, min_num_qubits=n_qubits\n",
        ")\n",
        "\n",
        "rng = np.random.default_rng(1234)\n",
        "mat = np.real(random_hermitian(n_qubits, seed=rng))\n",
        "circuit = iqp(mat)\n",
        "mat = np.real(random_hermitian(n_qubits, seed=rng))\n",
        "another_circuit = iqp(mat)\n",
        "observable = SparsePauliOp(\"X\" * n_qubits)\n",
        "another_observable = SparsePauliOp(\"Y\" * n_qubits)\n",
        "\n",
        "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n",
        "isa_circuit = pm.run(circuit)\n",
        "another_isa_circuit = pm.run(another_circuit)\n",
        "isa_observable = observable.apply_layout(isa_circuit.layout)\n",
        "another_isa_observable = another_observable.apply_layout(\n",
        "    another_isa_circuit.layout\n",
        ")\n",
        "\n",
        "# The context manager automatically closes the batch.\n",
        "with Batch(backend=backend) as batch:\n",
        "    estimator = Estimator(mode=batch)\n",
        "\n",
        "    estimator.options.resilience_level = 1\n",
        "\n",
        "    job = estimator.run([(isa_circuit, isa_observable)])\n",
        "    another_job = estimator.run(\n",
        "        [(another_isa_circuit, another_isa_observable)]\n",
        "    )\n",
        "    result = job.result()\n",
        "    another_result = another_job.result()\n",
        "\n",
        "    # first job\n",
        "    print(f\" > Expectation value: {result[0].data.evs}\")\n",
        "    print(f\" > Metadata: {result[0].metadata}\")\n",
        "\n",
        "    # second job\n",
        "    print(f\" > Another Expectation value: {another_result[0].data.evs}\")\n",
        "    print(f\" > More Metadata: {another_result[0].metadata}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e207719d-da1b-4af2-ae63-4cb033865a1b",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 다음 단계\n",
        "\n",
        "<Admonition type=\"tip\" title=\"권장사항\">\n",
        "  * [고급 런타임 옵션을 지정합니다](runtime-options-overview).\n",
        "  * IBM Quantum® Learning 의 [‘Cost’ 함수](/learning/courses/variational-algorithm-design/cost-functions) 강의를 따라가며 기본형(primitives)을 연습해 보세요.\n",
        "  * [‘트랜스파일’](/docs/guides/transpile/) 섹션에서 로컬 환경에서 트랜스파일하는 방법을 알아보세요.\n",
        "  * [‘트랜스파일러 설정 비교’](/docs/guides/circuit-transpilation-settings) 가이드를 확인해 보세요.\n",
        "  * IBM® QPU로 작업을 전송할 때 [작업 제한](/docs/guides/job-limits) 사항을 숙지하십시오.\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
}