{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "0998165a-381f-4561-a79a-bf584aed9687",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Strumento di stima con l'API REST\"\n",
        "description: \"Come utilizzare la primitiva Estimator con l'API REST.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore IIZII, XIZZZ, accum */}\n",
        "\n",
        "<span id=\"estimator-with-the-rest-api\" />\n",
        "\n",
        "# Strumento di stima con 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>Versioni del pacchetto</b></summary>\n",
        "\n",
        "  Il codice presente in questa pagina è stato sviluppato sulla base dei seguenti requisiti.\n",
        "  Si consiglia di utilizzare queste versioni o quelle più recenti.\n",
        "\n",
        "  ```\n",
        "  qiskit[all]~=2.3.0\n",
        "  ```\n",
        "</details>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3d9ef591-91fd-4a49-a065-5e2cda4d41be",
      "metadata": {},
      "source": [
        "I passaggi descritti in questa sezione spiegano come eseguire e configurare i carichi di lavoro tramite l'API REST e mostrano come richiamarli in qualsiasi programma a propria scelta.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  La presente documentazione utilizza il modulo `requests` Python per illustrare l'API REST. Tuttavia, questo flusso di lavoro può essere eseguito utilizzando qualsiasi linguaggio o framework che supporti l'utilizzo delle API REST. Per ulteriori dettagli, consultare la [documentazione di riferimento dell'API](/docs/api/qiskit-runtime-rest).\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"1-initialize-the-account\" />\n",
        "\n",
        "## 1. Inizializza l'account\n",
        "\n",
        "Poiché Estimator è un servizio gestito, devi prima configurare il tuo account. A questo punto è possibile selezionare il dispositivo che si desidera utilizzare per calcolare il valore atteso.\n",
        "\n",
        "In questa [sezione](/docs/guides/cloud-setup-rest-api) troverai informazioni su come configurare il tuo account, visualizzare i backend disponibili e invalidare i token.\n",
        "\n",
        "<span id=\"2-create-a-qasm-circuit\" />\n",
        "\n",
        "## 2. Creare un circuito QASM\n",
        "\n",
        "È necessario almeno un circuito come input per la primitiva Estimator.\n",
        "\n",
        "Definire un circuito quantistico QASM. Ad esempio:\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",
        "I seguenti frammenti di codice presuppongono che sia `qasm_string` stato transpilato in una nuova stringa `resulting_qasm`.\n",
        "\n",
        "<span id=\"3-run-the-quantum-circuit-using-the-estimator-v2-api\" />\n",
        "\n",
        "## 3. Eseguire il circuito quantistico utilizzando l'API Estimator dell' V2\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Le seguenti operazioni utilizzano le primitive IBM Quantum V2. Sia `SamplerV2` che `EstimatorV2` accettano come input uno o più blocchi primitivi unificati (PUB). Ogni \" PUB \" è una tupla che contiene un circuito e i dati trasmessi a tale circuito, che possono essere più osservabili e parametri. Ogni PUB restituisce un risultato.\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. Controllare lo stato del lavoro e visualizzare i risultati\n",
        "\n",
        "Successivamente, invia il dato `job_id` all'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",
        "Emissione\n",
        "\n",
        "```text\n",
        ">>> Job ID: 58223448-5100-4dec-a47a-942fb30edcad\n",
        ">>> Job Status: JobStatus.RUNNING\n",
        "```\n",
        "\n",
        "Visualizza i risultati di ricerca:\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",
        "Emissione\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. Utilizzo delle opzioni\n",
        "\n",
        "Le tecniche di mitigazione degli errori consentono agli utenti di ridurre gli errori di circuito modellando il rumore del dispositivo al momento dell'esecuzione. Ciò comporta solitamente un sovraccarico di elaborazione quantistica nella fase di addestramento del modello e un sovraccarico di elaborazione classica nella fase di post-elaborazione, al fine di correggere gli errori presenti nei risultati grezzi utilizzando il modello generato.\n",
        "\n",
        "Le tecniche di mitigazione degli errori integrate nelle primitive rappresentano opzioni avanzate di resilienza. Per specificare queste opzioni, utilizza `resilience_level` l'opzione al momento dell'invio del lavoro.\n",
        "\n",
        "Gli esempi seguenti illustrano le opzioni predefinite per il disaccoppiamento dinamico, il twirling e TREX + ZNE. Per ulteriori opzioni e dettagli, consultare l'argomento \" [Tecniche di mitigazione e soppressione degli errori](/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",
        "### Disaccoppiamento dinamico\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",
        "### Girare\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",
        "## Circuiti parametrizzati\n",
        "\n",
        "<span id=\"1-initialize-the-account-1\" />\n",
        "\n",
        "### 1. Inizializza l'account\n",
        "\n",
        "Per prima cosa devi configurare il tuo account. A questo punto puoi selezionare il dispositivo su cui desideri eseguire i calcoli.\n",
        "\n",
        "In questa [sezione](/docs/guides/cloud-setup-rest-api) troverai informazioni su come configurare il tuo account, visualizzare i backend disponibili e invalidare i token.\n",
        "\n",
        "<span id=\"2-define-parameters\" />\n",
        "\n",
        "### 2. Definire i parametri\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. Creare un circuito quantistico e aggiungere porte parametrizzate\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. Generare codice 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. Eseguire il circuito quantistico utilizzando l'API Estimator dell' 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. Controllare lo stato del lavoro e visualizzare i risultati\n",
        "\n",
        "Successivamente, invia il dato `job_id` all'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",
        "Emissione\n",
        "\n",
        "```text\n",
        "{'status': 'Completed'}\n",
        "```\n",
        "\n",
        "Visualizza i risultati di ricerca:\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",
        "Emissione\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",
        "## Passi successivi\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Suggerimenti\">\n",
        "  * Esistono diversi modi per eseguire i carichi di lavoro, a seconda delle proprie esigenze: modalità job, modalità sessione e modalità batch. Scopri come utilizzare la modalità sessione e la modalità batch [nell'argomento](/docs/guides/execution-modes-rest-api) dedicato alle modalità di esecuzione. Si noti che gli utenti di Open Plan non possono inviare lavori di sessione.\n",
        "  * Scopri come [configurare il tuo account](/docs/guides/cloud-setup-rest-api) tramite l'API REST.\n",
        "  * Esercitati con le primitive seguendo la [lezione](/learning/courses/variational-algorithm-design/cost-functions) sulla funzione «Cost» disponibile su IBM Quantum® Learning.\n",
        "  * Scopri come eseguire la transpilazione in locale nella sezione \" [Transpilazione](/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
}