{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "4a4b88ed-d21f-4056-9264-0ee8c8ec4b39",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Simulación exacta y ruidosa con primitivas Qiskit Aer\"\n",
        "description: \"Aprenda a realizar simulaciones exactas y ruidosas de programas cuánticos con las primitivas Aer de Qiskit\"\n",
        "---\n",
        "\n",
        "<span id=\"exact-and-noisy-simulation-with-qiskit-aer-primitives\" />\n",
        "\n",
        "# Simulación exacta y ruidosa con primitivas Qiskit Aer\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "678b9055-9164-417c-9897-9fde615b97ae",
      "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-aer~=0.17\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6a0ae8b1-b413-44ac-9267-fd36345a02df",
      "metadata": {},
      "source": [
        "[Simulación exacta con Qiskit primitives](/docs/guides/simulate-with-qiskit-sdk-primitives) demuestra cómo utilizar las primitivas de referencia incluidas con Qiskit para realizar la simulación exacta de circuitos cuánticos. Los procesadores cuánticos actuales adolecen de errores, o ruido, por lo que los resultados de una simulación exacta no reflejan necesariamente los resultados que cabría esperar al ejecutar los circuitos en hardware real. Aunque las primitivas de referencia de Qiskit no admiten ruido de modelado, [Qiskit Aer](https://qiskit.org/ecosystem/aer/) incluye implementaciones de las primitivas que sí admiten ruido de modelado. Qiskit Aer es un simulador de circuitos cuánticos de alto rendimiento que puedes utilizar en lugar de las primitivas de referencia para obtener un mayor rendimiento y más funciones. Forma parte del [ecosistema Qiskit](https://qiskit.github.io/ecosystem/). En este artículo, demostramos el uso de las primitivas Qiskit Aer para la simulación exacta y ruidosa.\n",
        "\n",
        "<Admonition type=\"note\" title=\"Notas\">\n",
        "  * `qiskit-aer` v0.14 o posterior.\n",
        "  * Aunque las primitivas Qiskit Aer implementan las interfaces de las primitivas, no proporcionan las mismas opciones que las primitivas Qiskit Runtime. El nivel de resistencia, por ejemplo, no está disponible con las primitivas Qiskit Aer.\n",
        "  * Consulte la [documentación de AerSimulator](https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.AerSimulator) para obtener más información sobre las opciones de métodos de simulación que admite Aer.\n",
        "</Admonition>\n",
        "\n",
        "Para explorar la simulación exacta y ruidosa, crea un circuito de ejemplo con ocho qubits:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "df70b5fd-971d-4e7d-a23a-8df037c0fa47",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/simulate-with-qiskit-aer/extracted-outputs/df70b5fd-971d-4e7d-a23a-8df037c0fa47-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.library import efficient_su2\n",
        "\n",
        "n_qubits = 8\n",
        "circuit = efficient_su2(n_qubits)\n",
        "circuit.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2074eaf0-746e-4a36-91d9-db9228f96a0d",
      "metadata": {},
      "source": [
        "Este circuito contiene parámetros para representar los ángulos de rotación de las compuertas $R_y$ y $R_z$. Al simular este circuito, necesitamos especificar valores explícitos para estos parámetros. En la siguiente celda, especificamos algunos valores para estos parámetros y utilizamos la primitiva Estimator de Qiskit Aer para calcular el valor exacto de la expectativa del observable $ZZ \\cdots Z$.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "40270ca7-1084-4329-aac5-28c87edc3791",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "0.8870140234256602"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_aer import AerSimulator\n",
        "from qiskit_aer.primitives import EstimatorV2 as Estimator\n",
        "\n",
        "observable = SparsePauliOp(\"Z\" * n_qubits)\n",
        "params = [0.1] * circuit.num_parameters\n",
        "\n",
        "exact_estimator = Estimator()\n",
        "# The circuit needs to be transpiled to the AerSimulator target\n",
        "pass_manager = generate_preset_pass_manager(3, AerSimulator())\n",
        "isa_circuit = pass_manager.run(circuit)\n",
        "pub = (isa_circuit, observable, params)\n",
        "job = exact_estimator.run([pub])\n",
        "result = job.result()\n",
        "pub_result = result[0]\n",
        "exact_value = float(pub_result.data.evs)\n",
        "exact_value"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "134d97a2-8420-4931-85b4-324679655e24",
      "metadata": {},
      "source": [
        "Ahora, inicialicemos un modelo de ruido que incluya un error de despolarización del 2 % en cada puerta CX. En la práctica, los errores derivados de las puertas de dos qubits —en este caso, las puertas CX— son la principal fuente de error al ejecutar un circuito. Consulte [«Creación de modelos de ruido»](/docs/guides/build-noise-models) para obtener una descripción general sobre cómo construir modelos de ruido en Qiskit Aer.\n",
        "\n",
        "En la siguiente celda, construimos un Estimador que incorpora este modelo de ruido y lo utilizamos para calcular el valor de la expectativa del observable.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "82b2f19a-ba10-46a2-ba1b-89cd27bc0e63",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "0.7247404214143528"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit_aer.noise import NoiseModel, depolarizing_error\n",
        "\n",
        "noise_model = NoiseModel()\n",
        "cx_depolarizing_prob = 0.02\n",
        "noise_model.add_all_qubit_quantum_error(\n",
        "    depolarizing_error(cx_depolarizing_prob, 2), [\"cx\"]\n",
        ")\n",
        "\n",
        "noisy_estimator = Estimator(\n",
        "    options=dict(backend_options=dict(noise_model=noise_model))\n",
        ")\n",
        "job = noisy_estimator.run([pub])\n",
        "result = job.result()\n",
        "pub_result = result[0]\n",
        "noisy_value = float(pub_result.data.evs)\n",
        "noisy_value"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6495f179-3fe6-4971-b023-700b8b2c8cbb",
      "metadata": {},
      "source": [
        "Como se puede ver, el valor de la expectativa en presencia del ruido está bastante lejos del valor correcto. En la práctica, se pueden emplear diversas técnicas de mitigación de errores para contrarrestar los efectos del ruido, pero un análisis de estas técnicas queda fuera del alcance de este artículo.\n",
        "\n",
        "Para hacernos una idea muy aproximada de cómo afecta el ruido al resultado final, consideremos nuestro modelo de ruido, que añade un error de despolarización del 2% a cada puerta CX. El error despolarizante con probabilidad $p$ se define como un canal cuántico $E$ que tiene la siguiente acción sobre una matriz de densidad $\\rho$ :\n",
        "\n",
        "$$\n",
        "E(\\rho) = (1 - p) \\rho + p\\frac{I}{2^n}\n",
        "$$\n",
        "\n",
        "donde $n$ es el número de qubits, en este caso, 2. Es decir, con probabilidad $p$, el estado se sustituye por el estado completamente mezclado, y el estado se conserva con probabilidad $1 - p$. Después de $m$ aplicaciones del canal despolarizante, la probabilidad de que el estado se conserve sería $(1 - p)^m$. Por lo tanto, esperamos que la probabilidad de conservar el estado correcto al final de la simulación disminuya exponencialmente con el número de puertas CX de nuestro circuito.\n",
        "\n",
        "Contemos el número de puertas CX en nuestro circuito y calculemos $(1 - p)^m$. Llamamos a `count_ops` para obtener un diccionario que relaciona los nombres de las puertas con los recuentos, y recuperamos la entrada de la puerta CX.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "3c20f7bc-203a-4f40-bb84-7cf3d231d66e",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "0.6542558123199923"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "cx_count = circuit.count_ops()[\"cx\"]\n",
        "(1 - cx_depolarizing_prob) ** cx_count"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ef506e15-7480-46ba-bce7-aa8f2fa78377",
      "metadata": {},
      "source": [
        "Este valor, 65%, da una estimación aproximada de la probabilidad de que nuestro estado final sea correcto. Es una estimación conservadora porque no tiene en cuenta el estado inicial de la simulación.\n",
        "\n",
        "La siguiente celda de código muestra cómo utilizar la primitiva Sampler de Qiskit Aer para muestrear desde el circuito ruidoso. Tenemos que añadir medidas al circuito antes de ejecutarlo con la primitiva Sampler.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "76c43aee-d559-4e5b-8228-e5bba3b4499c",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{'00000011': 2,\n",
              " '00000000': 68,\n",
              " '00001100': 2,\n",
              " '00000101': 2,\n",
              " '01010000': 1,\n",
              " '00000010': 2,\n",
              " '01101010': 1,\n",
              " '10100000': 1,\n",
              " '00110000': 1,\n",
              " '11100000': 1,\n",
              " '00011110': 1,\n",
              " '10000000': 8,\n",
              " '00000001': 1,\n",
              " '11000000': 1,\n",
              " '01000011': 1,\n",
              " '00001010': 2,\n",
              " '00010000': 1,\n",
              " '01000000': 1,\n",
              " '00000110': 1,\n",
              " '11001010': 1,\n",
              " '00000111': 1}"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit_aer.primitives import SamplerV2 as Sampler\n",
        "\n",
        "measured_circuit = circuit.copy()\n",
        "measured_circuit.measure_all()\n",
        "\n",
        "noisy_sampler = Sampler(\n",
        "    options=dict(backend_options=dict(noise_model=noise_model))\n",
        ")\n",
        "# The circuit needs to be transpiled to the AerSimulator target\n",
        "pass_manager = generate_preset_pass_manager(3, AerSimulator())\n",
        "isa_circuit = pass_manager.run(measured_circuit)\n",
        "pub = (isa_circuit, params, 100)\n",
        "job = noisy_sampler.run([pub])\n",
        "result = job.result()\n",
        "pub_result = result[0]\n",
        "pub_result.data.meas.get_counts()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "46a8c6b7-3f7c-48e4-9b73-b04a5458ba33",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximos pasos\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendaciones\">\n",
        "  * Para simular circuitos pequeños y sencillos, consulte [Simulación exacta con Qiskit primitives](/docs/guides/simulate-with-qiskit-sdk-primitives).\n",
        "  * Revise la documentación [de Qiskit Aer](https://qiskit.github.io/qiskit-aer/).\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
}