{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "c52e7bba-1230-4974-8e86-2dbe8f6f219b",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Depurar trabajos de Qiskit Runtime\"\n",
        "description: \"Utilice el módulo y `Neat` la clase de herramientas de depuración de Qiskit Runtime para depurar y analizar trabajos.\"\n",
        "---\n",
        "\n",
        "<span id=\"debug-qiskit-runtime-jobs\" />\n",
        "\n",
        "# Depurar trabajos de Qiskit Runtime\n",
        "\n",
        "{/* cspell:ignore ZIIIII, IZIIII,IIZIII, IIIZII, IIIIZI, IIIIIZ, rdiff */}\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d0599f3e",
      "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=\"Versiones del paquete\">\n",
        "    El código de esta página se ha desarrollado teniendo en cuenta los siguientes requisitos.\n",
        "    Recomendamos utilizar estas versiones o versiones más recientes.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.0\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    qiskit-aer~=0.17\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "80d0a1da-8d98-49e1-9cb0-0006093bf44c",
      "metadata": {},
      "source": [
        "Puedes utilizar la `Neat` clase para analizar el impacto del ruido en una carga de trabajo de Estimator. Para verificar la sintaxis, utiliza [el modo de prueba local](/docs/guides/local-testing-mode).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b08f0589",
      "metadata": {},
      "source": [
        "<span id=\"neat-class-usage\" />\n",
        "\n",
        "## `Neat` uso de la clase\n",
        "\n",
        "Antes de enviar una carga de trabajo de Qiskit Runtime que consuma muchos recursos para que se ejecute en hardware, puede utilizar la clase Qiskit Runtime [`Neat` (Noisy Estimator Analyzer Tool)](/docs/api/qiskit-ibm-runtime/debug-tools-neat#neat) para verificar que la carga de trabajo de Estimator está configurada correctamente, que es probable que devuelva resultados precisos, que utiliza las opciones más adecuadas para el problema especificado, etc.\n",
        "\n",
        "`Neat` Cliffordiza los circuitos de entrada para una simulación eficaz, conservando su estructura y profundidad. Los circuitos Clifford sufren niveles similares de ruido y son un buen sustituto para estudiar el circuito original de interés.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0dc5bf2a-e536-4141-a77c-0ee407cbd9b2",
      "metadata": {},
      "source": [
        "En primer lugar, importe los paquetes pertinentes y [autentíquese en el servicio Qiskit Runtime](/docs/guides/cloud-setup).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d653e186-7ec3-4f1b-b0e9-b322055dd6c8",
      "metadata": {},
      "source": [
        "<span id=\"prepare-the-environment\" />\n",
        "\n",
        "### Prepare el entorno\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "2f28c824-3158-43e6-ab3c-fd96c31859f0",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "import random\n",
        "\n",
        "from qiskit.circuit import QuantumCircuit\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator\n",
        "from qiskit_ibm_runtime.debug_tools import Neat\n",
        "\n",
        "from qiskit_aer.noise import NoiseModel, depolarizing_error"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "a45a6d9e-de39-4586-8395-a7f580f0e0dc",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Choose the least busy backend\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Generate a preset pass manager\n",
        "# This will be used to convert the abstract circuit to an equivalent\n",
        "# Instruction Set Architecture (ISA) circuit.\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=0)\n",
        "\n",
        "# Set the random seed\n",
        "random.seed(10)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "67572a70-da01-40fe-b299-b5599561164a",
      "metadata": {},
      "source": [
        "<span id=\"initialize-a-target-circuit\" />\n",
        "\n",
        "### Inicializar un circuito objetivo\n",
        "\n",
        "Consideremos un circuito de seis qubits que tiene las siguientes propiedades:\n",
        "\n",
        "* Alterna entre rotaciones aleatorias `RZ` y capas de puertas `CNOT`.\n",
        "* Tiene una estructura especular, es decir, aplica un `U` unitario seguido de su inverso.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "df19af55-897d-4b1f-baf8-fac2641ae87d",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/debug-qiskit-runtime-jobs/extracted-outputs/df19af55-897d-4b1f-baf8-fac2641ae87d-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "def generate_circuit(n_qubits, n_layers):\n",
        "    r\"\"\"\n",
        "    A function to generate a pseudo-random a circuit with ``n_qubits`` qubits\n",
        "    and ``2*n_layers`` entangling layers of the type used in this notebook.\n",
        "    \"\"\"\n",
        "    # An array of random angles\n",
        "    angles = [\n",
        "        [random.random() for q in range(n_qubits)] for s in range(n_layers)\n",
        "    ]\n",
        "\n",
        "    qc = QuantumCircuit(n_qubits)\n",
        "    qubits = list(range(n_qubits))\n",
        "\n",
        "    # do random circuit\n",
        "    for layer in range(n_layers):\n",
        "        # rotations\n",
        "        for q_idx, qubit in enumerate(qubits):\n",
        "            qc.rz(angles[layer][q_idx], qubit)\n",
        "\n",
        "        # cx gates\n",
        "        control_qubits = (\n",
        "            qubits[::2] if layer % 2 == 0 else qubits[1 : n_qubits - 1 : 2]\n",
        "        )\n",
        "        for qubit in control_qubits:\n",
        "            qc.cx(qubit, qubit + 1)\n",
        "\n",
        "    # undo random circuit\n",
        "    for layer in range(n_layers)[::-1]:\n",
        "        # cx gates\n",
        "        control_qubits = (\n",
        "            qubits[::2] if layer % 2 == 0 else qubits[1 : n_qubits - 1 : 2]\n",
        "        )\n",
        "        for qubit in control_qubits:\n",
        "            qc.cx(qubit, qubit + 1)\n",
        "\n",
        "        # rotations\n",
        "        for q_idx, qubit in enumerate(qubits):\n",
        "            qc.rz(-angles[layer][q_idx], qubit)\n",
        "\n",
        "    return qc\n",
        "\n",
        "\n",
        "# Generate a random circuit\n",
        "qc = generate_circuit(6, 3)\n",
        "# Convert the abstract circuit to an equivalent ISA circuit.\n",
        "isa_qc = pm.run(qc)\n",
        "\n",
        "qc.draw(\"mpl\", idle_wires=0)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0167329b-c6a6-4b2c-98fc-bf9aba9b7ee6",
      "metadata": {},
      "source": [
        "Elija operadores `Z` de un solo Pauli como observables y utilícelos para inicializar los bloques unificados primitivos (PUB).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "830b1dcc-2669-46cc-bff8-01a96a05c6ab",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Observables: ['ZIIIII', 'IZIIII', 'IIZIII', 'IIIZII', 'IIIIZI', 'IIIIIZ']\n"
          ]
        }
      ],
      "source": [
        "# Initialize the observables\n",
        "obs = [\"ZIIIII\", \"IZIIII\", \"IIZIII\", \"IIIZII\", \"IIIIZI\", \"IIIIIZ\"]\n",
        "print(f\"Observables: {obs}\")\n",
        "\n",
        "# Map the observables to the backend's layout\n",
        "isa_obs = [SparsePauliOp(o).apply_layout(isa_qc.layout) for o in obs]\n",
        "\n",
        "# Initialize the PUBs, which consist of six-qubit circuits\n",
        "# with `n_layers` 1, ..., 6\n",
        "all_n_layers = [1, 2, 3, 4, 5, 6]\n",
        "\n",
        "pubs = [(pm.run(generate_circuit(6, n)), isa_obs) for n in all_n_layers]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2a49fc84-0c82-4cbb-a557-6e676e57c9fa",
      "metadata": {},
      "source": [
        "<span id=\"cliffordize-the-circuits\" />\n",
        "\n",
        "### Cliffordizar los circuitos\n",
        "\n",
        "Los circuitos PUB definidos anteriormente no son Clifford, lo que dificulta su simulación clásica. Sin embargo, puede utilizar el método `Neat` [`to_clifford`](/docs/api/qiskit-ibm-runtime/debug-tools-neat#to_clifford) para convertirlos en circuitos Clifford y conseguir una simulación más eficaz.  El método [`to_clifford`](/docs/api/qiskit-ibm-runtime/debug-tools-neat#to_clifford) es una envoltura del método [`ConvertISAToClifford`](/docs/api/qiskit-ibm-runtime/transpiler-passes-convert-isa-to-clifford) que también puede utilizarse de forma independiente. En concreto, sustituye las puertas single-qubit no Clifford del circuito original por puertas single-qubit Clifford, pero no muta las puertas two-qubit, el número de qubits ni la profundidad del circuito.\n",
        "\n",
        "Consulte [Simulación eficiente de circuitos estabilizadores con primitivas Qiskit Aer](/docs/guides/simulate-stabilizer-circuits) para obtener más información sobre la simulación de circuitos Clifford.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7a86d99e-4431-4d62-8227-c49d17856369",
      "metadata": {},
      "source": [
        "En primer lugar, inicializa `Neat`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "4b5bbd4c-bd7f-4679-9348-d41da74d26eb",
      "metadata": {},
      "outputs": [],
      "source": [
        "# You could specify a custom `NoiseModel` here. If `None`, `Neat`\n",
        "# pulls the noise model from the given backend\n",
        "noise_model = None\n",
        "\n",
        "# Initialize `Neat`\n",
        "analyzer = Neat(backend, noise_model)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b740dcdf-660e-41e2-b5e6-e8cc288af38b",
      "metadata": {},
      "source": [
        "A continuación, Cliffordiza los PUB.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "3ad78f41-a2f8-4381-826a-ae728e081ad6",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/debug-qiskit-runtime-jobs/extracted-outputs/3ad78f41-a2f8-4381-826a-ae728e081ad6-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "clifford_pubs = analyzer.to_clifford(pubs)\n",
        "\n",
        "clifford_pubs[0].circuit.draw(\"mpl\", idle_wires=0)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "83c3ff81-9f18-43eb-ba6e-57c5ef3d118f",
      "metadata": {},
      "source": [
        "<span id=\"application-1-analyze-the-impact-of-noise-on-the-circuit-outputs\" />\n",
        "\n",
        "## Aplicación 1: Analizar el impacto del ruido en las salidas del circuito\n",
        "\n",
        "Este ejemplo muestra cómo utilizar `Neat` para estudiar el impacto de diferentes modelos de ruido en los PUB en función de la profundidad del circuito, ejecutando simulaciones tanto en condiciones ideales ([`ideal_sim`](/docs/api/qiskit-ibm-runtime/debug-tools-neat#ideal_sim)) como ruidosas ([`noisy_sim`](/docs/api/qiskit-ibm-runtime/debug-tools-neat#noisy_sim)). Esto puede resultar útil para establecer expectativas sobre la calidad de los resultados experimentales antes de ejecutar un trabajo en una QPU. Para obtener más información sobre los modelos de ruido, consulte [Simulación exacta y ruidosa con primitivas Aer de Qiskit](/docs/guides/simulate-with-qiskit-aer#exact-and-noisy-simulation-with-qiskit-aer-primitives).\n",
        "\n",
        "Los resultados simulados admiten operaciones matemáticas, por lo que pueden compararse entre sí (o con resultados experimentales) para calcular cifras de mérito.\n",
        "\n",
        "<Admonition type=\"caution\">\n",
        "  Una QPU puede verse afectada por distintos tipos de ruido. El modelo de ruido Qiskit Aer utilizado aquí sólo simula algunos de ellos y, por tanto, es probable que sea menos grave que el ruido de una QPU real.\n",
        "\n",
        "  Para más detalles sobre qué errores se incluyen al inicializar un modelo de ruido desde una QPU, consulte la referencia de la API Aer [`NoiseModel`](https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.noise.NoiseModel.html#qiskit_aer.noise.NoiseModel.from_backend) API reference.\n",
        "</Admonition>\n",
        "\n",
        "Comience realizando simulaciones clásicas ideales y ruidosas.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "23859a99-2455-460e-98ea-17b36ea59c36",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Ideal results:\n",
            " NeatResult([NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.]))])\n",
            "\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Noisy results:\n",
            " NeatResult([NeatPubResult(vals=array([0.99414062, 0.99414062, 0.99804688, 0.99609375, 0.98828125,\n",
            "       0.99023438])), NeatPubResult(vals=array([0.9765625 , 0.97851562, 0.9765625 , 0.98632812, 0.98828125,\n",
            "       0.99414062])), NeatPubResult(vals=array([0.953125  , 0.9609375 , 0.9609375 , 0.97265625, 0.97851562,\n",
            "       0.97460938])), NeatPubResult(vals=array([0.953125  , 0.94335938, 0.94140625, 0.97070312, 0.96679688,\n",
            "       0.99414062])), NeatPubResult(vals=array([0.94335938, 0.92382812, 0.95703125, 0.96875   , 0.96679688,\n",
            "       0.97265625])), NeatPubResult(vals=array([0.92773438, 0.90429688, 0.91210938, 0.93554688, 0.95117188,\n",
            "       0.97265625]))])\n",
            "\n"
          ]
        }
      ],
      "source": [
        "# Perform a noiseless simulation\n",
        "ideal_results = analyzer.ideal_sim(clifford_pubs)\n",
        "print(f\"Ideal results:\\n {ideal_results}\\n\")\n",
        "\n",
        "# Perform a noisy simulation with the backend's noise model\n",
        "noisy_results = analyzer.noisy_sim(clifford_pubs)\n",
        "print(f\"Noisy results:\\n {noisy_results}\\n\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a000a77a-0285-4b72-a69f-8f144f2c2a80",
      "metadata": {},
      "source": [
        "A continuación, aplica operaciones matemáticas para calcular la diferencia absoluta. En el resto de la guía se utiliza la diferencia absoluta como cifra de mérito para comparar resultados ideales con resultados ruidosos o experimentales, pero pueden establecerse cifras de mérito similares.\n",
        "\n",
        "La diferencia absoluta muestra que el impacto del ruido crece con el tamaño de los circuitos.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "cd61e437-bd2f-4349-a667-7edab51c4a6e",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Mean absolute difference between ideal and noisy results for circuits with 1 layers:\n",
            "  0.65%\n",
            "\n",
            "Mean absolute difference between ideal and noisy results for circuits with 2 layers:\n",
            "  1.66%\n",
            "\n",
            "Mean absolute difference between ideal and noisy results for circuits with 3 layers:\n",
            "  3.32%\n",
            "\n",
            "Mean absolute difference between ideal and noisy results for circuits with 4 layers:\n",
            "  3.84%\n",
            "\n",
            "Mean absolute difference between ideal and noisy results for circuits with 5 layers:\n",
            "  4.46%\n",
            "\n",
            "Mean absolute difference between ideal and noisy results for circuits with 6 layers:\n",
            "  6.61%\n",
            "\n"
          ]
        }
      ],
      "source": [
        "# Figure of merit: Absolute difference\n",
        "def rdiff(res1, re2):\n",
        "    r\"\"\"The absolute difference between `res1` and re2`.\n",
        "\n",
        "    --> The closer to `0`, the better.\n",
        "    \"\"\"\n",
        "    d = abs(res1 - re2)\n",
        "    return np.round(d.vals * 100, 2)\n",
        "\n",
        "\n",
        "for idx, (ideal_res, noisy_res) in enumerate(\n",
        "    zip(ideal_results, noisy_results)\n",
        "):\n",
        "    vals = rdiff(ideal_res, noisy_res)\n",
        "\n",
        "    # Print the mean absolute difference for the observables\n",
        "    mean_vals = np.round(np.mean(vals), 2)\n",
        "    print(\n",
        "        f\"Mean absolute difference between ideal and noisy results \"\n",
        "        f\"for circuits with {all_n_layers[idx]} layers:\\n  {mean_vals}%\\n\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7abcd001-9eac-4015-97a3-d6250ea4b667",
      "metadata": {},
      "source": [
        "Puedes seguir estas pautas aproximadas y simplificadas para mejorar los circuitos de este tipo:\n",
        "\n",
        "* Si la diferencia absoluta media es superior al 90%, es probable que la mitigación no sirva de nada.\n",
        "* Si la diferencia absoluta media es inferior al 90%, es probable que [la Amplificación Probabilística de Errores (PEA)](/docs/guides/error-mitigation-and-suppression-techniques#probabilistic-error-amplification-pea) pueda mejorar los resultados.\n",
        "* Si la diferencia absoluta media es inferior al 80%, es probable que [la ZNE con plegado de compuerta](/docs/guides/error-mitigation-and-suppression-techniques#zero-noise-extrapolation-zne) también pueda mejorar los resultados.\n",
        "\n",
        "Dado que todas las diferencias absolutas anteriores son inferiores al 90%, es de esperar que la aplicación de PEA al circuito original mejore la calidad de sus resultados.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c64c936b-5b8f-4fd2-861d-8b1ded2a0ad4",
      "metadata": {},
      "source": [
        "Puede especificar diferentes modelos de ruido en el analizador. El siguiente ejemplo realiza la misma prueba pero añade un modelo de ruido personalizado.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "0835c562-55c9-4dbe-879e-7271f8bed280",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Mean absolute difference between ideal and noisy results for circuits with 1 layers:\n",
            "  0.0%\n",
            "\n",
            "Mean absolute difference between ideal and noisy results for circuits with 2 layers:\n",
            "  0.0%\n",
            "\n",
            "Mean absolute difference between ideal and noisy results for circuits with 3 layers:\n",
            "  0.0%\n",
            "\n",
            "Mean absolute difference between ideal and noisy results for circuits with 4 layers:\n",
            "  0.0%\n",
            "\n",
            "Mean absolute difference between ideal and noisy results for circuits with 5 layers:\n",
            "  0.0%\n",
            "\n",
            "Mean absolute difference between ideal and noisy results for circuits with 6 layers:\n",
            "  0.0%\n",
            "\n"
          ]
        }
      ],
      "source": [
        "# Set up a noise model with strength 0.02 on every two-qubit gate\n",
        "noise_model = NoiseModel()\n",
        "for qubits in backend.coupling_map:\n",
        "    noise_model.add_quantum_error(\n",
        "        depolarizing_error(0.02, 2), [\"ecr\", \"cx\"], qubits\n",
        "    )\n",
        "\n",
        "# Update the analyzer's noise model\n",
        "analyzer.noise_model = noise_model\n",
        "\n",
        "# Perform a noiseless simulation\n",
        "ideal_results = analyzer.ideal_sim(clifford_pubs)\n",
        "\n",
        "# Perform a noisy simulation with the backend's noise model\n",
        "noisy_results = analyzer.noisy_sim(clifford_pubs)\n",
        "\n",
        "# Compare the results\n",
        "for idx, (ideal_res, noisy_res) in enumerate(\n",
        "    zip(ideal_results, noisy_results)\n",
        "):\n",
        "    values = rdiff(ideal_res, noisy_res)\n",
        "\n",
        "    # Print the mean absolute difference for the observables\n",
        "    mean_values = np.round(np.mean(values), 2)\n",
        "    print(\n",
        "        f\"Mean absolute difference between ideal and noisy results \"\n",
        "        f\"for circuits with {all_n_layers[idx]} layers:\\n  {mean_values}%\\n\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f2408ca9-3e3c-4a2f-a99a-ce413d5d470f",
      "metadata": {},
      "source": [
        "Como se muestra, dado un modelo de ruido, se puede tratar de cuantificar el impacto del ruido en la (versión Cliffordizada de los) PUBs de interés antes de ejecutarlos en una QPU.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ddd6da5f-4e84-4bf4-aaeb-0403f21275db",
      "metadata": {},
      "source": [
        "<span id=\"application-2-benchmark-different-strategies\" />\n",
        "\n",
        "## Aplicación 2: Comparar diferentes estrategias\n",
        "\n",
        "Este ejemplo utiliza `Neat` para ayudar a identificar las mejores opciones para sus PUBs. Para ello, considere la posibilidad de ejecutar un problema de estimación con PEA, que no puede simularse con `qiskit_aer`. Puede utilizar `Neat` para ayudar a determinar qué factores de amplificación de ruido funcionarán mejor, y luego utilizar esos factores cuando ejecute el experimento original en una QPU.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "358bb82a-4bc9-46c2-98a0-e745ffc6788f",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Generate a circuit with six qubits and six layers\n",
        "isa_qc = pm.run(generate_circuit(6, 3))\n",
        "\n",
        "# Use the same observables as previously\n",
        "pubs = [(isa_qc, isa_obs)]\n",
        "clifford_pubs = analyzer.to_clifford(pubs)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "5774cb3f-c999-4242-a83a-7dcc0c57510b",
      "metadata": {},
      "outputs": [],
      "source": [
        "noise_factors = [\n",
        "    [1, 1.1],\n",
        "    [1, 1.1, 1.2],\n",
        "    [1, 1.5, 2],\n",
        "    [1, 1.5, 2, 2.5, 3],\n",
        "    [1, 4],\n",
        "]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "0b9900e6-84fe-4776-9bb5-08c6c729be29",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Run the PUBs on a QPU\n",
        "estimator = Estimator(backend)\n",
        "estimator.options.default_shots = 100000\n",
        "estimator.options.twirling.enable_gates = True\n",
        "estimator.options.twirling.enable_measure = True\n",
        "estimator.options.twirling.shots_per_randomization = 100\n",
        "estimator.options.resilience.measure_mitigation = True\n",
        "estimator.options.resilience.zne_mitigation = True\n",
        "estimator.options.resilience.zne.amplifier = \"pea\"\n",
        "\n",
        "jobs = []\n",
        "for factors in noise_factors:\n",
        "    estimator.options.resilience.zne.noise_factors = factors\n",
        "    jobs.append(estimator.run(clifford_pubs))\n",
        "\n",
        "results = [job.result() for job in jobs]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "16c18377-059a-4751-9ab1-afee0ed5b089",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Perform a noiseless simulation\n",
        "ideal_results = analyzer.ideal_sim(clifford_pubs)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "7db531a1-c417-4d5b-bdc3-7a4ad3385fd4",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Mean absolute difference for factors [1, 1.1]:\n",
            "  4.57%\n",
            "\n",
            "Mean absolute difference for factors [1, 1.1, 1.2]:\n",
            "  5.24%\n",
            "\n",
            "Mean absolute difference for factors [1, 1.5, 2]:\n",
            "  2.62%\n",
            "\n",
            "Mean absolute difference for factors [1, 1.5, 2, 2.5, 3]:\n",
            "  2.4%\n",
            "\n",
            "Mean absolute difference for factors [1, 4]:\n",
            "  2.05%\n",
            "\n"
          ]
        }
      ],
      "source": [
        "# Look at the mean absolute difference to quickly determine\n",
        "# the best choice for your options\n",
        "for factors, res in zip(noise_factors, results):\n",
        "    d = rdiff(ideal_results[0], res[0])\n",
        "    print(\n",
        "        f\"Mean absolute difference for factors \"\n",
        "        f\"{factors}:\\n  {np.round(np.mean(d), 2)}%\\n\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0c37ef7b-df56-4f5f-9e11-10f209f105f9",
      "metadata": {},
      "source": [
        "El resultado con la menor diferencia sugiere qué opciones elegir.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2530a3e9-21a6-4841-9449-fe181c54aca4",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximos pasos\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendaciones\">\n",
        "  * Lee una descripción general de [las herramientas de depuración de Qiskit](/docs/guides/debugging-tools).\n",
        "  * Aprenda sobre [la simulación exacta y ruidosa con las primitivas Aer de Qiskit](/docs/guides/simulate-with-qiskit-aer).\n",
        "  * Infórmese sobre [las opciones disponibles de Qiskit Runtime](/docs/guides/runtime-options-overview).\n",
        "  * Aprenda sobre [las técnicas de mitigación y supresión de errores](/docs/guides/error-mitigation-and-suppression-techniques).\n",
        "  * Visita el tema [Transpile con gestores de pases](transpile-with-pass-managers).\n",
        "  * Aprenda [a transpilear circuitos](/docs/guides/circuit-transpilation-settings#compare-transpiler-settings) como parte de los flujos de trabajo de patrones de Qiskit utilizando Qiskit Runtime.\n",
        "  * Revisa la [documentación de la API de herramientas de depuración](/docs/api/qiskit-ibm-runtime/debug-tools).\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
}