{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "0998165a-381f-4561-a79a-bf584aed9687",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Estimateur avec l'API REST\"\n",
        "description: \"Comment utiliser la primitive « Estimator » avec l'API REST.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore IIZII, XIZZZ, accum */}\n",
        "\n",
        "<span id=\"estimator-with-the-rest-api\" />\n",
        "\n",
        "# Estimateur avec l'API REST\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>Versions de package</b></summary>\n",
        "\n",
        "  Le code présenté sur cette page a été développé en tenant compte des exigences suivantes.\n",
        "  Nous vous recommandons d'utiliser ces versions ou des versions plus récentes.\n",
        "\n",
        "  ```\n",
        "  qiskit[all]~=2.3.0\n",
        "  ```\n",
        "</details>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3d9ef591-91fd-4a49-a065-5e2cda4d41be",
      "metadata": {},
      "source": [
        "Les étapes décrites dans cette rubrique expliquent comment exécuter et configurer des charges de travail à l'aide de l'API REST, et montrent comment les appeler depuis n'importe quel programme de votre choix.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Cette documentation utilise le `requests` module Python pour présenter l'API REST. Toutefois, ce workflow peut être exécuté à l'aide de n'importe quel langage ou framework prenant en charge l'utilisation des API REST. Pour plus de détails, consultez la [documentation de référence](/docs/api/qiskit-runtime-rest) de l'API.\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"1-initialize-the-account\" />\n",
        "\n",
        "## 1. Créer le compte\n",
        "\n",
        "Estimator étant un service géré, vous devez d'abord configurer votre compte. Vous pouvez ensuite sélectionner l'appareil que vous souhaitez utiliser pour calculer la valeur attendue.\n",
        "\n",
        "Vous trouverez dans cette [rubrique](/docs/guides/cloud-setup-rest-api) des informations détaillées sur la manière d'initialiser votre compte, de consulter les backends disponibles et d'invalider des jetons.\n",
        "\n",
        "<span id=\"2-create-a-qasm-circuit\" />\n",
        "\n",
        "## 2. Créer un circuit QASM\n",
        "\n",
        "Vous devez fournir au moins un circuit en entrée à la primitive Estimator.\n",
        "\n",
        "Définissez un circuit quantique QASM. Par exemple :\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",
        "Les extraits de code suivants partent du principe que `qasm_string` a été transcompilé en une nouvelle chaîne `resulting_qasm`.\n",
        "\n",
        "<span id=\"3-run-the-quantum-circuit-using-the-estimator-v2-api\" />\n",
        "\n",
        "## 3. Exécuter le circuit quantique à l'aide de l'API Estimator d' V2\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Les tâches suivantes utilisent les primitives IBM Quantum V2. Les deux, et `SamplerV2` , prennent `EstimatorV2` en entrée un ou plusieurs blocs unifiés primitifs (PUB). Chaque « PUB » est un tuple contenant un circuit et les données diffusées sur ce circuit, qui peuvent être plusieurs observables et paramètres. Chaque PUB renvoie un résultat.\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. Vérifier l'état d'avancement de la tâche et obtenir les résultats\n",
        "\n",
        "Ensuite, transmettez le `job_id` à l'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",
        "Sortie\n",
        "\n",
        "```text\n",
        ">>> Job ID: 58223448-5100-4dec-a47a-942fb30edcad\n",
        ">>> Job Status: JobStatus.RUNNING\n",
        "```\n",
        "\n",
        "Obtenir les résultats de la recherche d'emploi :\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",
        "Sortie\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. Utiliser les options\n",
        "\n",
        "Les techniques d'atténuation des erreurs permettent aux utilisateurs d'atténuer les erreurs de circuit en modélisant le bruit du dispositif au moment de l'exécution. Cela entraîne généralement une charge de travail de prétraitement quantique liée à l'entraînement du modèle, ainsi qu'une charge de travail de post-traitement classique visant à corriger les erreurs présentes dans les résultats bruts à l'aide du modèle généré.\n",
        "\n",
        "Les techniques d'atténuation des erreurs intégrées aux primitives constituent des options avancées de résilience. Pour définir ces options, utilisez `resilience_level` l'option lors de l'envoi de votre tâche.\n",
        "\n",
        "Les exemples suivants illustrent les options par défaut pour le découplage dynamique, le twirling et TREX + ZNE. Vous trouverez d'autres options et des informations complémentaires dans la rubrique «[ Techniques d'atténuation et de suppression des erreurs](/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",
        "### Découplage dynamique\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",
        "### Tourbillon\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",
        "## Circuits paramétrés\n",
        "\n",
        "<span id=\"1-initialize-the-account-1\" />\n",
        "\n",
        "### 1. Créer le compte\n",
        "\n",
        "Vous devez d'abord configurer votre compte. Vous pouvez ensuite sélectionner l'appareil sur lequel vous souhaitez effectuer vos calculs.\n",
        "\n",
        "Vous trouverez dans cette [rubrique](/docs/guides/cloud-setup-rest-api) des informations détaillées sur la manière d'initialiser votre compte, de consulter les backends disponibles et d'invalider des jetons.\n",
        "\n",
        "<span id=\"2-define-parameters\" />\n",
        "\n",
        "### 2. Définir les paramètres\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. Créer un circuit quantique et ajouter des portes paramétrées\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. Générer du code 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. Exécuter le circuit quantique à l'aide de l'API Estimator d' V2\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. Vérifier l'état de la tâche et obtenir les résultats\n",
        "\n",
        "Ensuite, transmettez le `job_id` à l'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",
        "Sortie\n",
        "\n",
        "```text\n",
        "{'status': 'Completed'}\n",
        "```\n",
        "\n",
        "Obtenir les résultats de la recherche d'emploi :\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",
        "Sortie\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",
        "## Etapes suivantes\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recommandations\">\n",
        "  * Il existe plusieurs façons d'exécuter des charges de travail, en fonction de vos besoins : le mode tâche, le mode session et le mode batch. Découvrez comment utiliser le mode session et le mode batch dans [la rubrique consacrée aux modes d'exécution](/docs/guides/execution-modes-rest-api). Veuillez noter que les utilisateurs d'Open Plan ne peuvent pas soumettre de tâches de session.\n",
        "  * Découvrez comment [configurer votre compte](/docs/guides/cloud-setup-rest-api) à l'aide de l'API REST.\n",
        "  * Entraînez-vous avec les primitives en suivant la [leçon](/learning/courses/variational-algorithm-design/cost-functions) sur la fonction « Cost » dans « IBM Quantum® Learning ».\n",
        "  * Découvrez comment effectuer une transpilation en local dans la section «[ Transpilation](/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
}