{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "dde95705",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Gestión del rendimiento - una función Qiskit de Q-CTRL Fire Opal\"\n",
        "description: \"Aplique la supresión automática de errores utilizando Fire Opal Performance Management de Q-CTRL\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore fontsize, Mundada, Yamauchi, supersymmetric, Paterakis, Gharibyan */}\n",
        "\n",
        "<span id=\"performance-management-a-qiskit-function-by-q-ctrl-fire-opal\" />\n",
        "\n",
        "# Gestión del rendimiento: una función Qiskit de Q-CTRL Fire Opal\n",
        "\n",
        "*Consulte la [referencia de la API](/docs/api/functions/q-ctrl-performance-management)*\n",
        "\n",
        "<Admonition type=\"note\" title=\"Nota\">\n",
        "  Las funciones Qiskit son una función experimental disponible únicamente para los usuarios de los planes IBM Quantum® Premium Plan, Flex Plan y On-Prem (a través de IBM Quantum Platform API). Se trata de versiones preliminares sujetas a cambios.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ace2ed13",
      "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 siguiendo los siguientes requisitos.\n",
        "    Recomendamos utilizar estas versiones o posteriores.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.3.1\n",
        "    qiskit-ibm-runtime~=0.45.1\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c1732b45",
      "metadata": {},
      "source": [
        "<span id=\"overview\" />\n",
        "\n",
        "## Visión general\n",
        "\n",
        "La gestión del rendimiento de Fire Opal facilita a cualquiera la obtención de resultados significativos de los ordenadores cuánticos a escala sin necesidad de ser expertos en hardware cuántico. Cuando se ejecutan circuitos con Fire Opal Performance Management, se aplican automáticamente técnicas de supresión de errores basadas en IA, lo que permite escalar problemas más grandes con más puertas y qubits. Este enfoque reduce el número de disparos necesarios para llegar a la respuesta correcta, sin sobrecarga añadida, lo que supone un ahorro significativo tanto en tiempo de cálculo como en costes.\n",
        "\n",
        "La gestión del rendimiento suprime los errores y aumenta la probabilidad de obtener la respuesta correcta en hardware ruidoso. En otras palabras, aumenta la relación señal/ruido. La siguiente imagen muestra cómo la mayor precisión que permite la Gestión del Rendimiento puede reducir la necesidad de disparos adicionales en el caso de un algoritmo de Transformada Cuántica de Fourier de 10 qubits. Con sólo 30 disparos, Q-CTRL alcanza el umbral de confianza del 99%, mientras que el predeterminado (`QiskitRuntime` Sampler, `optimization_level`=3 y `resilience_level`=1, `ibm_sherbrooke`) requiere 170.000 disparos. Al obtener la respuesta correcta más rápidamente, se ahorra un tiempo de ejecución de cálculo considerable.\n",
        "\n",
        "![Visualización del tiempo de ejecución mejorado](https://quantum.cloud.ibm.com/docs/images/guides/qctrl-performance-management/achieve_more.svg)\n",
        "\n",
        "La función de gestión del rendimiento se puede utilizar con cualquier algoritmo, y se puede emplear fácilmente en lugar de las [primitivas](/docs/guides/primitives) estándar de « Qiskit Runtime ». Entre bastidores, varias técnicas de supresión de errores actúan conjuntamente para evitar que se produzcan errores durante la ejecución. Todos los métodos de canalización de Fire Opal vienen preconfigurados y son independientes del algoritmo, lo que significa que siempre obtienes el mejor rendimiento desde el primer momento.\n",
        "\n",
        "Para acceder a la gestión del rendimiento, [póngase en contacto con Q-CTRL](https://form.typeform.com/to/uOAVDnGg?typeform-source=q-ctrl.com).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5f761442",
      "metadata": {},
      "source": [
        "<span id=\"description\" />\n",
        "\n",
        "## Descripción\n",
        "\n",
        "Fire Opal Performance Management dispone de dos opciones de ejecución similares a las primitivas de Qiskit Runtime, por lo que puede intercambiar fácilmente el Q-CTRL Sampler y el Estimator. El flujo de trabajo general para utilizar la función de Gestión del Rendimiento es el siguiente:\n",
        "\n",
        "1. Defina su circuito (y operadores en el caso del Estimador).\n",
        "2. Pon en marcha el circuito.\n",
        "3. Recuperar los resultados.\n",
        "\n",
        "Para reducir el ruido del hardware, Fire Opal emplea una serie de técnicas de supresión de errores basadas en IA que se muestran en la siguiente imagen. Con Fire Opal, todo el proceso está completamente automatizado sin necesidad de configuración.\n",
        "\n",
        "La canalización de Fire Opal elimina la necesidad de sobrecargas adicionales, como un mayor tiempo de ejecución cuántica o qubits físicos adicionales. Tenga en cuenta que el tiempo de procesamiento clásico sigue siendo un factor (consulte la sección de [puntos de referencia](#benchmarks) para obtener estimaciones, donde \"Tiempo total\" refleja tanto el procesamiento clásico como el cuántico). A diferencia de la mitigación de errores, que requiere una sobrecarga en forma de muestreo, la supresión de errores de Fire Opal funciona tanto a nivel de puerta como de pulso para abordar diversas fuentes de ruido y evitar la probabilidad de que se produzca un error. Al evitar errores, se elimina la necesidad de un costoso tratamiento posterior.\n",
        "\n",
        "La siguiente imagen muestra los métodos de supresión de errores automatizados por Fire Opal Performance Management.\n",
        "\n",
        "![Visualización del proceso de supresión de errores](https://quantum.cloud.ibm.com/docs/images/guides/qctrl-performance-management/error_suppression.svg)\n",
        "\n",
        "La función ofrece dos primitivas, «Sampler» y «Estimator», y las entradas y salidas de ambas amplían la especificación implementada para [las primitivas](/docs/guides/primitive-input-output#pubs) de Qiskit Runtime V2.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "64534d1a",
      "metadata": {},
      "source": [
        "<span id=\"benchmarks\" />\n",
        "\n",
        "## Referencias comparativas\n",
        "\n",
        "Los resultados [de las pruebas comparativas algorítmicas publicadas](https://journals.aps.org/prapplied/abstract/10.1103/PhysRevApplied.20.024034) demuestran una mejora significativa del rendimiento en varios algoritmos, como Bernstein-Vazirani, la transformada cuántica de Fourier, la búsqueda de Grover, el algoritmo de optimización aproximada cuántica y el eigensolver cuántico variacional. El resto de esta sección proporciona más detalles sobre los tipos de algoritmos que puede ejecutar, así como el rendimiento y los tiempos de ejecución esperados.\n",
        "\n",
        "Los siguientes estudios independientes demuestran cómo la gestión del rendimiento de Q-CTRL permite la investigación algorítmica a una escala sin precedentes:\n",
        "\n",
        "* [Núcleos cuánticos parametrizados energéticamente eficientes para el diagnóstico de fallos en servicios de red](https://arxiv.org/abs/2405.09724v1) : aprendizaje de núcleos cuánticos de hasta 50 qubits\n",
        "* [Estimación cuántica de la diferencia de fase basada en tensores para demostraciones a gran escala](https://arxiv.org/abs/2408.04946) : estimación cuántica de fase de hasta 33 qubits\n",
        "* [Hierarchical Learning for Quantum ML: Novel Training Technique for Large-Scale Variational Quantum Circuits](https://arxiv.org/abs/2311.12929) - up to 21-qubit quantum data loading\n",
        "\n",
        "La siguiente tabla ofrece una guía aproximada de la precisión y los tiempos de ejecución de pruebas comparativas anteriores en `ibm_fez`. El rendimiento en otros dispositivos puede variar. El tiempo de uso se basa en una hipótesis de 10.000 disparos por circuito. El \"Número de qubits\" indicado no es una limitación rígida, sino que representa umbrales aproximados en los que se puede esperar una precisión de solución extremadamente consistente. Se han resuelto con éxito problemas de mayor envergadura, por lo que se recomienda realizar pruebas más allá de estos límites.\n",
        "\n",
        "| Ejemplo                                                          | Número de qubits | Precisión | Medida de la precisión                                                                                               | Tiempo total (s)        | Tiempo de ejecución (s) | Primitivo (Modo) |\n",
        "| ---------------------------------------------------------------- | ---------------- | --------- | -------------------------------------------------------------------------------------------------------------------- | ----------------------- | ----------------------- | ---------------- |\n",
        "| Bernstein-Vazirani                                               | 50Q              | 100 %     | Tasa de éxito (porcentaje de ejecuciones en las que la respuesta correcta es la cadena de bits de recuento más alto) | 10                      | 8                       | Muestreador      |\n",
        "| Transformada cuántica de Fourier                                 | 30Q              | 100 %     | Tasa de éxito (porcentaje de ejecuciones en las que la respuesta correcta es la cadena de bits de recuento más alto) | 10                      | 8                       | Muestreador      |\n",
        "| Estimación cuántica de fase                                      | 30Q              | 99.9998%  | Precisión del ángulo encontrado: `1- abs(real_angle - angle_found)/pi`                                               | 10                      | 8                       | Muestreador      |\n",
        "| Simulación cuántica: Modelo de Ising (15 pasos)                  | 20Q              | 99.775%   | $A$ (definidos a continuación)                                                                                       | 60 (por paso)           | 15 (por paso)           | Estimador        |\n",
        "| Simulación cuántica 2: dinámica molecular (20 puntos temporales) | 34Q              | 96.78%    | $A_{mean}$ (definidos a continuación)                                                                                | 10 (por punto temporal) | 6 (por punto temporal)  | Estimador        |\n",
        "\n",
        "Definición de la precisión de la medición de un valor de expectativa: la métrica $A$ se define del siguiente modo:\n",
        "\n",
        "$$\n",
        "A = 1 - \\frac{|\\epsilon^{ideal} - \\epsilon^{meas}|}{\\epsilon^{ideal}_{max} - \\epsilon^{ideal}_{min}},\n",
        "$$\n",
        "\n",
        "donde $\\epsilon^{ideal}$ = valor de expectativa ideal, $\\epsilon^{meas}$ = valor de expectativa medido, $\\epsilon^{ideal}_{max} $ = valor máximo ideal y $\\epsilon^{ideal}_{min}$ = valor mínimo ideal. $A_{mean}$ es simplemente la media del valor de $A$ en múltiples mediciones.\n",
        "\n",
        "Esta métrica se utiliza porque es invariable a los cambios globales y a la escala en el rango de valores alcanzables. En otras palabras, independientemente de si se desplaza el rango de posibles valores de expectativas hacia arriba o hacia abajo o se aumenta la dispersión, el valor de $A$ debería permanecer constante.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "870af0fe",
      "metadata": {},
      "source": [
        "<span id=\"get-started\" />\n",
        "\n",
        "## Cómo empezar\n",
        "\n",
        "Fire Opal Performance Management utiliza Qiskit v`2.0.0`, que es la versión recomendada. Las versiones compatibles son Qiskit >= v`2.0.0`.\n",
        "Autentíquese utilizando su [clave API IBM Quantum Platform](http://quantum.cloud.ibm.com/) y seleccione la función Qiskit de la siguiente manera. (En este fragmento de código se da por hecho que ya has [guardado tu cuenta](/docs/guides/functions-get-started#install-qiskit-functions-catalog-client) en tu entorno local.)\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "11af8fb4",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "[QiskitFunction(qunova/hivqe-chemistry),\n",
              " QiskitFunction(global-data-quantum/quantum-portfolio-optimizer),\n",
              " QiskitFunction(algorithmiq/tem),\n",
              " QiskitFunction(qedma/qesem),\n",
              " QiskitFunction(multiverse/singularity),\n",
              " QiskitFunction(ibm/circuit-function),\n",
              " QiskitFunction(q-ctrl/optimization-solver),\n",
              " QiskitFunction(colibritd/quick-pde),\n",
              " QiskitFunction(q-ctrl/performance-management),\n",
              " QiskitFunction(kipu-quantum/iskay-quantum-optimizer)]"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit_ibm_catalog import QiskitFunctionsCatalog\n",
        "\n",
        "catalog = QiskitFunctionsCatalog(channel=\"ibm_quantum_platform\")\n",
        "\n",
        "# verify that you have access to the function\n",
        "catalog.list()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "736255e4-1c1f-42a7-bf76-1487878c9e76",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Access Function\n",
        "perf_mgmt = catalog.load(\"q-ctrl/performance-management\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d4657810",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\" title=\"¿Esta función es compatible con todos los servidores de fondo de IBM?\">\n",
        "  Si deseas utilizar un backend que esta función no admite actualmente, [ponte en contacto con Q-CTRL](https://form.typeform.com/to/iuujEAEI?typeform-source=q-ctrl.com) para que lo incorporen.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2947b5c3",
      "metadata": {},
      "source": [
        "<span id=\"estimator-primitive\" />\n",
        "\n",
        "## Primitiva estimadora\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "df2788d5",
      "metadata": {},
      "source": [
        "<span id=\"estimator-example\" />\n",
        "\n",
        "### Ejemplo de estimador\n",
        "\n",
        "Utilice la primitiva Estimator de Fire Opal Performance Management para determinar el valor esperado de un único par circuito-observable.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "82932760",
      "metadata": {},
      "source": [
        "Además de los paquetes `qiskit-ibm-catalog` y `qiskit` , también utilizará el paquete `numpy` para ejecutar este ejemplo. Puedes instalar este paquete descomentando la siguiente celda si estás ejecutando este ejemplo en un notebook usando el kernel IPython.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "70bb93ef",
      "metadata": {},
      "outputs": [],
      "source": [
        "# %pip install numpy"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "02b2a79a",
      "metadata": {},
      "source": [
        "**1. Crear el circuito**\n",
        "\n",
        "Como ejemplo, genere un operador Hermitiano aleatorio y un observable para introducirlo en la función de Gestión del Rendimiento.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "32037218",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "from qiskit.circuit.library import iqp\n",
        "from qiskit.quantum_info import random_hermitian, SparsePauliOp\n",
        "\n",
        "n_qubits = 50\n",
        "\n",
        "# Generate a random circuit\n",
        "mat = np.real(random_hermitian(n_qubits, seed=1234))\n",
        "circuit = iqp(mat)\n",
        "circuit.measure_all()\n",
        "\n",
        "# Define observables as a string\n",
        "observable = SparsePauliOp(\"Z\" * n_qubits)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "476fae6a",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Create PUB tuple\n",
        "estimator_pubs = [(circuit, observable)]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "09e64cd7",
      "metadata": {},
      "source": [
        "**2. Ejecutar el circuito**\n",
        "\n",
        "Ejecute el circuito y defina opcionalmente el fondo y el número de disparos.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "26952e1f",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Run the circuit using Estimator\n",
        "qctrl_estimator_job = perf_mgmt.run(\n",
        "    primitive=\"estimator\",\n",
        "    pubs=estimator_pubs,\n",
        "    backend_name=backend_name,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c07af9d0",
      "metadata": {},
      "source": [
        "Puedes utilizar las conocidas [API de « Qiskit Serverless »](/docs/guides/serverless) para comprobar el estado de tu carga de trabajo de Qiskit Function:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "2b309861",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'QUEUED'"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qctrl_estimator_job.status()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "23556c8e",
      "metadata": {},
      "source": [
        "**3. Recuperar el resultado**\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "8be67088",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Retrieve the counts from the result list\n",
        "result = qctrl_estimator_job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7375fcad",
      "metadata": {},
      "source": [
        "Los resultados tienen el mismo formato que [los resultados de](/docs/guides/estimator-input-output) Estimator:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "id": "ef85a036",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The result of the submitted job had 1 PUB\n",
            "The result of the submitted job had 1 PUB and has a value:\n",
            " PubResult(data=DataBin(evs=0.0195, stds=0.9998098569228051), metadata={'precision': None})\n",
            "\n",
            "The associated PubResult of this job has the following DataBins:\n",
            "DataBin(evs=0.0195, stds=0.9998098569228051)\n",
            "\n",
            "And this DataBin has attributes: dict_keys(['evs', 'stds'])\n",
            "The expectation values measured from this PUB are:\n",
            "0.0195\n"
          ]
        }
      ],
      "source": [
        "import numpy\n",
        "\n",
        "result_str = str(result)\n",
        "\n",
        "with numpy.printoptions(threshold=200):\n",
        "    print(\n",
        "        f\"The result of the submitted job had {len(result)} PUB \"\n",
        "        f\"and has a value:\\n {result[0]}\\n\"\n",
        "    )\n",
        "\n",
        "print(\"The associated PubResult of this job has the following DataBins:\")\n",
        "print(f\"{result[0].data}\\n\")\n",
        "\n",
        "print(f\"And this DataBin has attributes: {result[0].data.keys()}\")\n",
        "\n",
        "print(\"The expectation values measured from this PUB are:\")\n",
        "print(f\"{result[0].data.evs}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a78ce8bd",
      "metadata": {},
      "source": [
        "<span id=\"sampler-primitive\" />\n",
        "\n",
        "## Primitiva de muestreador\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b1300f06",
      "metadata": {},
      "source": [
        "<span id=\"sampler-example\" />\n",
        "\n",
        "### Ejemplo de muestreador\n",
        "\n",
        "Utilice la primitiva Sampler de Fire Opal Performance Management para ejecutar un circuito Bernstein-Vazirani. Este algoritmo, utilizado para encontrar una cadena oculta a partir de las salidas de una función de caja negra, es un algoritmo de evaluación comparativa habitual porque hay una única respuesta correcta.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "144e48f3",
      "metadata": {},
      "source": [
        "**1. Crear el circuito**\n",
        "\n",
        "Defina la respuesta correcta para el algoritmo, la cadena de bits oculta y el circuito Bernstein-Vazirani. Puedes ajustar la anchura del circuito simplemente cambiando la dirección `circuit_width`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "2cd807b1",
      "metadata": {},
      "outputs": [],
      "source": [
        "import qiskit\n",
        "\n",
        "circuit_width = 35\n",
        "hidden_bitstring = \"1\" * circuit_width\n",
        "\n",
        "# Create circuit, reserving one qubit for BV oracle\n",
        "bv_circuit = qiskit.QuantumCircuit(circuit_width + 1, circuit_width)\n",
        "bv_circuit.x(circuit_width)\n",
        "bv_circuit.h(range(circuit_width + 1))\n",
        "for input_qubit, bit in enumerate(reversed(hidden_bitstring)):\n",
        "    if bit == \"1\":\n",
        "        bv_circuit.cx(input_qubit, circuit_width)\n",
        "bv_circuit.barrier()\n",
        "bv_circuit.h(range(circuit_width + 1))\n",
        "bv_circuit.barrier()\n",
        "for input_qubit in range(circuit_width):\n",
        "    bv_circuit.measure(input_qubit, input_qubit)\n",
        "\n",
        "# Create PUB tuple\n",
        "sampler_pubs = [(bv_circuit,)]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "85d3c00b",
      "metadata": {},
      "source": [
        "**2. Ejecutar el circuito**\n",
        "\n",
        "Ejecute el circuito y defina opcionalmente el fondo y el número de disparos.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "2595df84",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Run the circuit using Sampler\n",
        "qctrl_sampler_job = perf_mgmt.run(\n",
        "    primitive=\"sampler\",\n",
        "    pubs=sampler_pubs,\n",
        "    backend_name=backend_name,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3c49fbba",
      "metadata": {},
      "source": [
        "Comprueba [el estado](/docs/guides/functions-get-started#check-job-status) de tu carga de trabajo de Qiskit Function o obtén [los resultados](/docs/guides/functions-get-started#retrieve-results) de la siguiente manera:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "b7acbb7f",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "60fe2fa1-a860-43e4-8615-c6ac4180f93b\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "'QUEUED'"
            ]
          },
          "execution_count": 14,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Print the ID so you can use it later, if necessary\n",
        "print(qctrl_sampler_job.job_id)\n",
        "\n",
        "qctrl_sampler_job.status()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "35921605",
      "metadata": {},
      "source": [
        "**3. Recuperar el resultado**\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "2d4f5f7d",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Retrieve the job results\n",
        "sampler_result = qctrl_sampler_job.result()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "7a359d99",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Counts for the meas output register (limited to 30 results):\n",
            "  11111111111111111111111111111111111: 1661\n",
            "  11111111111111111111111111110111111: 60\n",
            "  11111111111111111111111111111101111: 54\n",
            "  11111111111111111111111111111110111: 54\n",
            "  11111111111111011111111111111111111: 46\n",
            "  11111111111111111110111111111111111: 44\n",
            "  11111111111111111111111101111111111: 42\n",
            "  11111111111111111111111110111111111: 42\n",
            "  11111111111111110111111111111111111: 41\n",
            "  11111111111111111111111111111111101: 39\n",
            "  11111111111111111111101111111111111: 38\n",
            "  11111111111111111111110111111111111: 38\n",
            "  11111111111111111111111111101111111: 37\n",
            "  11111111111111111111111111111111110: 36\n",
            "  11111111111110111111111111111111111: 35\n",
            "  11111111111111111111111111111011111: 32\n",
            "  11111111111111101111111111111111111: 32\n",
            "  01111111111111111111111111111111111: 27\n",
            "  11111111111111111011111111111111111: 23\n",
            "  11111111101111111111111111111111111: 22\n",
            "  11111111111111111111111111111111011: 21\n",
            "  11111111011111111111111111111111111: 20\n",
            "  00000000000000011111111111111111111: 18\n",
            "  11111111111111111111110101111111111: 18\n",
            "  00000001111111111111111111111111111: 17\n",
            "  11111111001111111111111111111111111: 16\n",
            "  11101111111111111111111111111111111: 16\n",
            "  11111111111101111111111111111111111: 16\n",
            "  00000101111111111111111111111111111: 13\n",
            "  11111111111111111111111011111111111: 13\n",
            "  11111111111111111111111110101111111: 13\n",
            "  11111111111111111101111111111111111: 12\n",
            "  10111111111111111111111111111111111: 12\n",
            "  11111111111111111111111110001111111: 12\n",
            "  00000000000000000011111111111111111: 11\n",
            "  11111111111111111111111111111110110: 10\n",
            "  00000000000000000000000001111111111: 10\n",
            "  11111111111011111111111111111111111: 9\n",
            "  11111111111111101011111111111111111: 9\n",
            "  00000000011111111111111111111111111: 8\n",
            "  10101111111111111111111111111111111: 8\n",
            "  00000000000000000000000001011111111: 8\n",
            "  11111111111111111111111111111111001: 8\n",
            "  00000111111111111111111111111111111: 7\n",
            "  11111111111111111111111111111101110: 7\n",
            "  11111111110111111111111111111111111: 7\n",
            "  00000000000001011111111111111111111: 6\n",
            "  00000000000000001111111111111111111: 6\n",
            "  00000000000000000001011111111111111: 6\n",
            "  11111111111111111111111111011111111: 6\n",
            "  ... (1050 more items)\n"
          ]
        }
      ],
      "source": [
        "# Get results for the first (and only) PUB\n",
        "pub_result = sampler_result[0]\n",
        "counts = pub_result.data.c.get_counts()\n",
        "\n",
        "print(\"Counts for the meas output register (limited to 30 results):\")\n",
        "for i, (bitstring, count) in enumerate(counts.items()):\n",
        "    if i >= 50:\n",
        "        print(f\"  ... ({len(counts) - 30} more items)\")\n",
        "        break\n",
        "    print(f\"  {bitstring}: {count}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d920922e",
      "metadata": {},
      "source": [
        "**3. Trazar las cadenas de bits superiores**\n",
        "\n",
        "Traza la cadena de bits con los recuentos más altos para ver si la cadena de bits oculta era el modo.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "cefa2234",
      "metadata": {},
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\n",
        "\n",
        "\n",
        "def plot_top_bitstrings(counts_dict, hidden_bitstring=None):\n",
        "    # Sort and take the top 100 bitstrings\n",
        "    top_100 = sorted(counts_dict.items(), key=lambda x: x[1], reverse=True)[\n",
        "        :100\n",
        "    ]\n",
        "    if not top_100:\n",
        "        print(\"No bitstrings found in the input dictionary.\")\n",
        "        return\n",
        "\n",
        "    # Unzip the bitstrings and their counts\n",
        "    bitstrings, counts = zip(*top_100)\n",
        "\n",
        "    # Assign colors: purple if the bitstring matches hidden_bitstring,\n",
        "    # otherwise gray\n",
        "    colors = [\n",
        "        \"#680CE9\" if bit == hidden_bitstring else \"gray\" for bit in bitstrings\n",
        "    ]\n",
        "\n",
        "    # Create the bar plot\n",
        "    plt.figure(figsize=(15, 8))\n",
        "    plt.bar(\n",
        "        range(len(bitstrings)), counts, tick_label=bitstrings, color=colors\n",
        "    )\n",
        "\n",
        "    # Rotate the bitstrings for better readability\n",
        "    plt.xticks(rotation=90, fontsize=8)\n",
        "    plt.xlabel(\"Bitstrings\")\n",
        "    plt.ylabel(\"Counts\")\n",
        "    plt.title(\"Top 100 Bitstrings by Counts\")\n",
        "\n",
        "    # Show the plot\n",
        "    plt.tight_layout()\n",
        "    plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1d9d3b69",
      "metadata": {},
      "source": [
        "La cadena de bits oculta aparece resaltada en morado y debe ser la cadena de bits con el mayor número de cuentas.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "id": "8106d906",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/q-ctrl-performance-management/extracted-outputs/8106d906-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plot_top_bitstrings(counts, hidden_bitstring)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d8104000b3d94c69",
      "metadata": {},
      "source": [
        "<span id=\"changelog\" />\n",
        "\n",
        "## Registro de cambios\n",
        "\n",
        "* 2026-02-20: Aviso de obsolescencia: el campo `provider_job_ids` de metadatos quedará obsoleto en 30 días en la versión 0.13.0. Los usuarios pueden acceder al ID del trabajo a través `job_id()` del método del servicio de tiempo de ejecución.\n",
        "* 11/02/2026: Ahora ofrecemos compatibilidad con `ibm_miami`y hemos añadido metadatos de ejecución al `PubResult`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bb33258d",
      "metadata": {},
      "source": [
        "<span id=\"get-support\" />\n",
        "\n",
        "## Obtener soporte\n",
        "\n",
        "Para cualquier pregunta o problema, [póngase en contacto con Q-CTRL](https://form.typeform.com/to/iuujEAEI).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2fe4a6ea",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximos pasos\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendaciones\">\n",
        "  * Solicite acceso a [Q-CTRL Performance Management](/functions?id=q-ctrl-performance-management).\n",
        "  * Consulta la [referencia](/docs/api/functions/q-ctrl-performance-management) de la API de esta función de Qiskit.\n",
        "  * Prueba el [modelo de Ising de campo transversal con](/docs/tutorials/transverse-field-ising-model) el tutorial de gestión del rendimiento de Q-CTRL.\n",
        "  * Prueba la [estimación de fase cuántica con](/docs/tutorials/quantum-phase-estimation-qctrl) el tutorial « Qiskit Functions » (Estimación de fase cuántica) de Q-CTRL\n",
        "  * Reseña [Mundada P. S., et al. (2023). Evaluación comparativa experimental de un flujo de trabajo automatizado y determinista para la supresión de errores en algoritmos cuánticos. Physical Review Applied, 20, 2](https://quantum-journal.org/papers/q-2023-07-25-1067/).\n",
        "  * Revisión [Kanno, S., et al. (2025). Estimación de la diferencia de fase cuántica basada en tensores para demostraciones a gran escala. arXiv Preimpresión arXiv:2408.04946](https://arxiv.org/abs/2408.04946).\n",
        "  * Reseña [SoftBank Corp, Experimento de demostración de un sistema de diagnóstico de fallos en servicios de comunicación utilizando la computación cuántica ( Machine Learning ) (blog), 30 de agosto de 2024](https://www.softbank.jp/en/corp/technology/research/topics/102/).\n",
        "  * Revisión [Yamauchi, H., et al. (2024). Núcleos cuánticos parametrizados y energéticamente eficientes para el diagnóstico de fallos en servicios de red. arXiv Preimpresión arXiv:2405.09724v1](https://arxiv.org/abs/2405.09724v1).\n",
        "  * Revisión [Yamauchi, H., et al. (2025). Espectroscopia cuántica de la dinámica topológica mediante un hamiltoniano supersimétrico. arXiv Preimpresión arXiv:2511.23169v1](https://arxiv.org/abs/2511.23169v1).\n",
        "  * Revisión [Wang, Y., et al. (2025).  Δ-Motif: Isomorfismo de subgrafos a escala mediante paralelismo centrado en datos. arXiv Preimpresión arXiv:2508.21287](https://arxiv.org/abs/2508.21287).\n",
        "  * Revisión [Paterakis, N. G., et al. (2025).  La computación cuántica en el panorama computacional de la electrónica de potencia: visión y realidad. arXiv Preimpresión arXiv:2507.02577](https://arxiv.org/abs/2507.02577).\n",
        "  * Revisión [Gharibyan, H., et al. (2023).  Aprendizaje jerárquico para el aprendizaje automático cuántico: novedosa técnica de entrenamiento para circuitos cuánticos variacionales a gran escala. arXiv Preimpresión arXiv:2311.12929](https://arxiv.org/abs/2311.12929).\n",
        "  * Revise el [caso práctico de Mitsubishi Chemical Corp](https://q-ctrl.com/case-study/unlocking-new-performance-capability-in-quantum-chemistry).\n",
        "  * Revise el [caso práctico del banco Redacted](https://q-ctrl.com/case-study/reducing-quantum-compute-costs-2-500x-with-fire-opal).\n",
        "  * Revise el [caso práctico « BlueQubit](https://q-ctrl.com/case-study/enabling-data-loading-for-quantum-machine-learning-with-fire-opal) ».\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": 5
}