{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "0998165a-381f-4561-a79a-bf584aed9687",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"REST API를 활용한 추정기\"\n",
        "description: \"REST API에서 Estimator 프리미티브를 사용하는 방법.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore IIZII, XIZZZ, accum */}\n",
        "\n",
        "<span id=\"estimator-with-the-rest-api\" />\n",
        "\n",
        "# REST API를 활용한 추정기\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "da948b6b-2ead-4359-aed4-b824e43ccbfb",
      "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",
        "<details>\n",
        "  <summary><b>패키지 버전</b></summary>\n",
        "\n",
        "  이 페이지의 코드는 다음 요구 사항을 바탕으로 개발되었습니다.\n",
        "  이 버전 이상을 사용하시기를 권장합니다.\n",
        "\n",
        "  ```\n",
        "  qiskit[all]~=2.3.0\n",
        "  ```\n",
        "</details>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3d9ef591-91fd-4a49-a065-5e2cda4d41be",
      "metadata": {},
      "source": [
        "이 주제의 단계에서는 REST API를 사용하여 워크로드를 실행하고 구성하는 방법을 설명하며, 원하는 프로그램에서 이를 호출하는 방법을 보여줍니다.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  이 문서는 REST API를 시연하기 위해 Python `requests` 모듈을 사용합니다. 그러나 이 워크플로는 REST API를 지원하는 모든 언어나 프레임워크를 사용하여 실행할 수 있습니다. 자세한 내용은 [API 참조](/docs/api/qiskit-runtime-rest) 문서를 참조하십시오.\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"1-initialize-the-account\" />\n",
        "\n",
        "## 1. 계정 초기화\n",
        "\n",
        "Estimator는 관리형 서비스이므로, 먼저 계정을 초기화해야 합니다. 그런 다음 기대값을 계산하는 데 사용할 장치를 선택할 수 있습니다.\n",
        "\n",
        "[이](/docs/guides/cloud-setup-rest-api) 주제에서 계정 초기화 방법, 사용 가능한 백엔드 확인 방법, 토큰 무효화 방법에 대한 자세한 내용을 확인하세요.\n",
        "\n",
        "<span id=\"2-create-a-qasm-circuit\" />\n",
        "\n",
        "## 2. QASM 회로 만들기\n",
        "\n",
        "Estimator 프리미티브의 입력으로 최소한 하나의 회로가 필요합니다.\n",
        "\n",
        "QASM 양자 회로를 정의하시오. 예를 들어,\n",
        "\n",
        "```python\n",
        "qasm_string='''\n",
        "OPENQASM 3;\n",
        "include \"stdgates.inc\";\n",
        "qreg q[2];\n",
        "creg c[2];\n",
        "x q[0];\n",
        "cx q[0], q[1];\n",
        "c[0] = measure q[0];\n",
        "c[1] = measure q[1];\n",
        "'''\n",
        "```\n",
        "\n",
        "다음 코드 조각은 가 새로운 `qasm_string` 문자열 로 `resulting_qasm`변환되었다고 가정합니다.\n",
        "\n",
        "<span id=\"3-run-the-quantum-circuit-using-the-estimator-v2-api\" />\n",
        "\n",
        "## 3. Estimator V2 API를 사용하여 양자 회로를 실행합니다\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  다음 작업들은 IBM Quantum V2 기본 기능을 사용합니다. 와 `SamplerV2` 모두 하나 이상의 기본 통합 블록(PUB)을 입력으로 `EstimatorV2` 받습니다. 각 `PUB`는 하나의 회로와 해당 회로에 브로드캐스트된 데이터(여러 관측 가능 변수 및 매개변수로 구성될 수 있음)를 포함하는 튜플입니다. 각 PUB 는 결과를 반환합니다.\n",
        "</Admonition>\n",
        "\n",
        "```python\n",
        "import requests\n",
        "\n",
        "url = 'https://quantum.cloud.ibm.com/api/v1/jobs'\n",
        "auth_id = \"Bearer <YOUR_BEARER_TOKEN>\"\n",
        "crn = \"<SERVICE-CRN>\"\n",
        "backend = \"<BACKEND_NAME>\"\n",
        "\n",
        "headers = {\n",
        "    'Content-Type': 'application/json',\n",
        "    'Authorization':auth_id,\n",
        "    'Service-CRN': crn\n",
        "    }\n",
        "\n",
        "job_input = {\n",
        "    'program_id': 'estimator',\n",
        "    \"backend\": backend,\n",
        "    \"params\": {\n",
        "        \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each.\n",
        "            [resulting_qasm, # QASM circuit\n",
        "             {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n",
        "             None # parameter values\n",
        "             ]]\n",
        "}}\n",
        "\n",
        "response = requests.post(url, headers=headers, json=job_input)\n",
        "\n",
        "if response.status_code == 200:\n",
        "    job_id = response.json().get('id')\n",
        "    print(\"Job created:\",response.text)\n",
        "else:\n",
        "    print(f\"Error: {response.status_code}\")\n",
        "```\n",
        "\n",
        "<span id=\"4-check-job-status-and-get-results\" />\n",
        "\n",
        "## 4. 작업 상태 확인 및 결과 확인\n",
        "\n",
        "다음으로, 를 `job_id` API에 전달합니다:\n",
        "\n",
        "```python\n",
        "response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)\n",
        "response_status_singlejob.json().get('state')\n",
        "```\n",
        "\n",
        "출력\n",
        "\n",
        "```text\n",
        ">>> Job ID: 58223448-5100-4dec-a47a-942fb30edcad\n",
        ">>> Job Status: JobStatus.RUNNING\n",
        "```\n",
        "\n",
        "채용 결과 보기:\n",
        "\n",
        "```python\n",
        "response_result= requests.get(url+'/'+job_id+'/results', headers=headers)\n",
        "\n",
        "res_dict=response_result.json()\n",
        "\n",
        "estimator_result=res_dict['results']\n",
        "print(estimator_result)\n",
        "```\n",
        "\n",
        "출력\n",
        "\n",
        "```text\n",
        "[{'data': {'evs': 0.7428980350102542, 'stds': 0.029884014518789213, 'ensemble_standard_error': 0.03261147170624149}, 'metadata': {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}}]\n",
        "```\n",
        "\n",
        "<span id=\"5-work-with-options\" />\n",
        "\n",
        "## 5. 옵션 활용하기\n",
        "\n",
        "오류 완화 기법은 사용자가 실행 시점에 장치 노이즈를 모델링함으로써 회로 오류를 완화할 수 있게 해줍니다. 이는 일반적으로 모델 훈련과 관련된 양자 전처리 오버헤드와, 생성된 모델을 사용하여 원시 결과의 오류를 보정하기 위한 고전적 후처리 오버헤드를 초래합니다.\n",
        "\n",
        "프라이머리트에 내장된 오류 완화 기법은 고급 복원력 옵션입니다. 이러한 옵션을 지정하려면 작업을 제출할 때 옵션을 `resilience_level` 사용하십시오.\n",
        "\n",
        "다음 예제는 동적 디커플링, 트위링, TREX + ZNE의 기본 옵션을 보여줍니다. 자세한 내용과 추가 옵션은 [‘오류 완화 및 억제 기법’](/docs/guides/error-mitigation-and-suppression-techniques) 항목에서 확인하세요.\n",
        "\n",
        "<span id=\"trex-+-zne\" />\n",
        "\n",
        "### TREX + ZNE\n",
        "\n",
        "```python\n",
        "import requests\n",
        "\n",
        "url = 'https://quantum.cloud.ibm.com/api/v1/jobs'\n",
        "auth_id = \"Bearer <YOUR_BEARER_TOKEN>\"\n",
        "crn = \"<SERVICE-CRN>\"\n",
        "backend = \"BACKEND_NAME\"\n",
        "\n",
        "headers = {\n",
        "    'Content-Type': 'application/json',\n",
        "    'Authorization':auth_id,\n",
        "    'Service-CRN': crn\n",
        "    }\n",
        "job_input = {\n",
        "    'program_id': 'estimator',\n",
        "    \"backend\": backend,\n",
        "    \"params\": {\n",
        "        \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each\n",
        "            [resulting_qasm, # QASM circuit\n",
        "             {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n",
        "             None # parameter values\n",
        "             ]]\n",
        "        \"options\": {\n",
        "            \"resilience\": {\n",
        "              \"measure_mitigation\": True,\n",
        "              \"zne_mitigation\": True,\n",
        "              \"zne\": {\n",
        "                  \"extrapolator\":[\"exponential\", \"linear\"],\n",
        "                  \"noise_factors\":[1, 3, 5],\n",
        "              },\n",
        "          },\n",
        "        },\n",
        "    }\n",
        "}\n",
        "\n",
        "response = requests.post(url, headers=headers, json=job_input)\n",
        "\n",
        "if response.status_code == 200:\n",
        "    job_id = response.json().get('id')\n",
        "    print(\"Job created:\",response.text)\n",
        "else:\n",
        "    print(f\"Error: {response.status_code}\")\n",
        "```\n",
        "\n",
        "<span id=\"dynamical-decoupling\" />\n",
        "\n",
        "### 동적 분리\n",
        "\n",
        "```python\n",
        "import requests\n",
        "\n",
        "url = 'https://quantum.cloud.ibm.com/api/v1/jobs'\n",
        "auth_id = \"Bearer <YOUR_BEARER_TOKEN>\"\n",
        "crn = \"<SERVICE-CRN>\"\n",
        "backend = \"BACKEND_NAME\"\n",
        "\n",
        "headers = {\n",
        "    'Content-Type': 'application/json',\n",
        "    'Authorization':auth_id,\n",
        "    'Service-CRN': crn\n",
        "    }\n",
        "job_input = {\n",
        "    'program_id': 'estimator',\n",
        "    \"backend\": backend,\n",
        "    \"params\": {\n",
        "        \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each\n",
        "            [resulting_qasm, # QASM circuit\n",
        "             {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n",
        "             None # parameter values\n",
        "             ]]\n",
        "        \"options\": {\n",
        "            \"dynamical_decoupling\": {\n",
        "                \"enable\": True,\n",
        "                \"sequence_type\": 'XpXm',\n",
        "                \"extra_slack_distribution\": 'middle',\n",
        "                \"scheduling_method\": 'alap',\n",
        "            },\n",
        "        },\n",
        "    }\n",
        "}\n",
        "\n",
        "response = requests.post(url, headers=headers, json=job_input)\n",
        "\n",
        "if response.status_code == 200:\n",
        "    job_id = response.json().get('id')\n",
        "    print(\"Job created:\",response.text)\n",
        "else:\n",
        "    print(f\"Error: {response.status_code}\")\n",
        "```\n",
        "\n",
        "<span id=\"twirling\" />\n",
        "\n",
        "### 빙글빙글 돌다\n",
        "\n",
        "```python\n",
        "import requests\n",
        "\n",
        "url = 'https://quantum.cloud.ibm.com/api/v1/jobs'\n",
        "auth_id = \"Bearer <YOUR_BEARER_TOKEN>\"\n",
        "crn = \"<SERVICE-CRN>\"\n",
        "backend = \"BACKEND_NAME\"\n",
        "\n",
        "headers = {\n",
        "    'Content-Type': 'application/json',\n",
        "    'Authorization':auth_id,\n",
        "    'Service-CRN': crn\n",
        "    }\n",
        "job_input = {\n",
        "    'program_id': 'estimator',\n",
        "    \"backend\": backend,\n",
        "    \"params\": {\n",
        "        \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each\n",
        "            [resulting_qasm, # QASM circuit\n",
        "             {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n",
        "             None # parameter values\n",
        "             ]]\n",
        "        \"options\": {\n",
        "            \"twirling\": {\n",
        "                \"enable_gates\": True,\n",
        "                \"enable_measure\": True,\n",
        "                \"num_randomizations\": \"auto\",\n",
        "                \"shots_per_randomization\": \"auto\",\n",
        "                \"strategy\": \"active-accum\",\n",
        "                },\n",
        "        },\n",
        "    }\n",
        "}\n",
        "\n",
        "response = requests.post(url, headers=headers, json=job_input)\n",
        "\n",
        "if response.status_code == 200:\n",
        "    job_id = response.json().get('id')\n",
        "    print(\"Job created:\",response.text)\n",
        "else:\n",
        "    print(f\"Error: {response.status_code}\")\n",
        "```\n",
        "\n",
        "<span id=\"parameterized-circuits\" />\n",
        "\n",
        "## 매개변수화 회로\n",
        "\n",
        "<span id=\"1-initialize-the-account-1\" />\n",
        "\n",
        "### 1. 계정 초기화\n",
        "\n",
        "먼저 계정을 초기화해야 합니다. 그런 다음 계산을 수행할 기기를 선택할 수 있습니다.\n",
        "\n",
        "[이](/docs/guides/cloud-setup-rest-api) 주제에서 계정 초기화 방법, 사용 가능한 백엔드 확인 방법, 토큰 무효화 방법에 대한 자세한 내용을 확인하세요.\n",
        "\n",
        "<span id=\"2-define-parameters\" />\n",
        "\n",
        "### 2. 매개변수 정의\n",
        "\n",
        "```python\n",
        "import requests\n",
        "import qiskit_ibm_runtime\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.qasm3 import dumps\n",
        "from qiskit import QuantumCircuit\n",
        "from qiskit.circuit import Parameter\n",
        "from qiskit import transpile\n",
        "\n",
        "service = QiskitRuntimeService(channel='ibm_quantum')\n",
        "backend = service.backend(\"<SPECIFY BACKEND>\")\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "\n",
        "theta = Parameter('theta')\n",
        "phi = Parameter('phi')\n",
        "parameter_values = {'theta': 1.57, 'phi': 3.14}   # In case we want to pass a dictionary\n",
        "```\n",
        "\n",
        "<span id=\"3-create-a-quantum-circuit-and-add-parameterized-gates\" />\n",
        "\n",
        "### 3. 양자 회로를 생성하고 매개변수화된 게이트를 추가합니다\n",
        "\n",
        "```python\n",
        "qc = QuantumCircuit(2)\n",
        "\n",
        "# Add parameterized gates\n",
        "qc.rx(theta, 0)\n",
        "qc.ry(phi, 1)\n",
        "qc.cx(0, 1)\n",
        "qc.measure_all()\n",
        "\n",
        "# Draw the original circuit\n",
        "qc.draw('mpl')\n",
        "\n",
        "# Get an ISA circuit\n",
        "isa_circuit = pm.run(qc)\n",
        "```\n",
        "\n",
        "<span id=\"4-generate-qasm-3-code\" />\n",
        "\n",
        "### 4. QASM 3 코드 생성\n",
        "\n",
        "```python\n",
        "qasm_str = dumps(isa_circuit)\n",
        "print(\"Generated QASM 3 code:\")\n",
        "print(qasm_str)\n",
        "```\n",
        "\n",
        "<span id=\"5-run-the-quantum-circuit-using-estimator-v2-api\" />\n",
        "\n",
        "### 5. Estimator V2 API를 사용하여 양자 회로를 실행합니다\n",
        "\n",
        "```python\n",
        "import requests\n",
        "\n",
        "url = 'https://quantum.cloud.ibm.com/api/v1/jobs'\n",
        "auth_id = \"Bearer <YOUR_BEARER_TOKEN>\"\n",
        "crn = \"<SERVICE-CRN>\"\n",
        "backend = \"<BACKEND_NAME>\"\n",
        "\n",
        "headers = {\n",
        "    'Content-Type': 'application/json',\n",
        "    'Authorization':auth_id,\n",
        "    'Service-CRN': crn\n",
        "    }\n",
        "\n",
        "job_input = {\n",
        "    'program_id': 'estimator',\n",
        "    \"backend\": backend,\n",
        "    \"params\": {\n",
        "        # Choose one option: direct parameter transfer or through a dictionary\n",
        "        #\"pubs\": [[qasm_str,[1,2],500]], # primitive unified blocs (PUBs) containing one circuit each.\n",
        "        \"pubs\": [[qasm_str,parameter_values,500]], # primitive unified blocs (PUBs) containing one circuit each.\n",
        "}}\n",
        "\n",
        "response = requests.post(url, headers=headers, json=job_input)\n",
        "\n",
        "if response.status_code == 200:\n",
        "    job_id = response.json().get('id')\n",
        "    print(f\"Job created: {response.text}\")\n",
        "else:\n",
        "    print(f\"Error: {response.status_code}\")\n",
        "```\n",
        "\n",
        "```python\n",
        "print(response.text)\n",
        "```\n",
        "\n",
        "<span id=\"6-check-job-status-and-get-results\" />\n",
        "\n",
        "### 6. 작업 상태 확인 및 결과 확인\n",
        "\n",
        "다음으로, 를 `job_id` API에 전달합니다:\n",
        "\n",
        "```python\n",
        "response_status_singlejob = requests.get(f\"{url}/{job_id}\", headers=headers)\n",
        "response_status_singlejob.json().get('state')\n",
        "```\n",
        "\n",
        "출력\n",
        "\n",
        "```text\n",
        "{'status': 'Completed'}\n",
        "```\n",
        "\n",
        "채용 결과 보기:\n",
        "\n",
        "```python\n",
        "response_result = requests.get(f\"{url}/{job_id}/results\", headers=headers)\n",
        "\n",
        "res_dict=response_result.json()\n",
        "\n",
        "# Get results for the first PUB\n",
        "counts=res_dict['results'][0]['data']['c']['samples']\n",
        "\n",
        "print(counts[:20])\n",
        "```\n",
        "\n",
        "출력\n",
        "\n",
        "```text\n",
        "['0x1', '0x2', '0x1', '0x2', '0x1', '0x2', '0x0', '0x2', '0x1', '0x1', '0x2', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1']\n",
        "```\n",
        "\n",
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 다음 단계\n",
        "\n",
        "<Admonition type=\"tip\" title=\"권장사항\">\n",
        "  * 요구에 따라 워크로드를 실행하는 방법에는 작업 모드, 세션 모드, 배치 모드 등 여러 가지가 있습니다. [‘실행 모드](/docs/guides/execution-modes-rest-api) ’ 항목에서 세션 모드와 일괄 처리 모드를 사용하는 방법을 알아보세요. Open Plan 사용자는 세션 작업을 제출할 수 없음을 유의하시기 바랍니다.\n",
        "  * REST API를 사용하여 [계정을 초기화하는](/docs/guides/cloud-setup-rest-api) 방법을 알아보세요.\n",
        "  * IBM Quantum® Learning 의 [‘Cost’ 함수](/learning/courses/variational-algorithm-design/cost-functions) 강의를 따라가며 기본형(primitives)을 연습해 보세요.\n",
        "  * [‘트랜스파일’](/docs/guides/transpile) 섹션에서 로컬 환경에서 트랜스파일하는 방법을 알아보세요.\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
}