{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "116af785-a9b7-4eaf-8a86-b1eeb235da18",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Puertas fraccionarias\"\n",
        "description: \"Utiliza puertas fraccionarias para ejecutar rotaciones de uno y dos qubits\"\n",
        "---\n",
        "\n",
        "<span id=\"fractional-gates\" />\n",
        "\n",
        "# Puertas fraccionarias\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5d679872",
      "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.3.1\n",
        "    qiskit-ibm-runtime~=0.45.1\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f0d7fa16",
      "metadata": {},
      "source": [
        "En esta página se presentan dos nuevos tipos de puertas compatibles con la flota de QPUs Quantum® de IBM. Estas puertas *fraccionarias* se admiten en [las QPU Heron](/docs/guides/processor-types#heron) en forma de:\n",
        "\n",
        "* $R_{ZZ}(\\theta)$ para $0 \\lt \\theta \\leq \\pi/2$\n",
        "* $R_X(\\theta)$ para cualquier $\\theta$\n",
        "\n",
        "Esta página analiza los casos de uso en los que la implementación de puertas fraccionarias puede mejorar la eficiencia de sus flujos de trabajo, así como la forma de utilizar estas puertas en IBM Quantum QPUs.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ee241e99-d095-4cb5-9506-da3d92c32e1c",
      "metadata": {},
      "source": [
        "<span id=\"how-to-use-fractional-gates\" />\n",
        "\n",
        "## Cómo utilizar las puertas fraccionarias\n",
        "\n",
        "Internamente, estas puertas fraccionarias funcionan ejecutando directamente una rotación $R_{ZZ}(\\theta)$ y $R_X(\\theta)$ para un ángulo arbitrario. El uso de la puerta « $R_X(\\theta)$ » puede reducir la duración y el error de las rotaciones de un solo qubit de ángulo arbitrario hasta en un factor de dos. La ejecución directa de la rotación de puertas « $R_{ZZ}(\\theta)$ » evita la descomposición en múltiples `CZGate` objetos, lo que reduce de forma similar la duración y el error de un circuito. Esto resulta especialmente útil para circuitos que contienen muchas rotaciones de uno y dos qubits, como cuando se simula la dinámica de un sistema cuántico o cuando se utiliza un ansatz variacional con muchos parámetros.\n",
        "\n",
        "Aunque este tipo de puertas forman parte de la [biblioteca de puertas estándar](/docs/guides/circuit-library) de las que `QuantumCircuit` puede disponer un usuario, solo pueden utilizarse en determinadas QPU de IBM Quantum, y deben cargarse con el indicador `use_fractional_gates` activado `True` (como se muestra a continuación). Esta opción garantizará que las puertas fraccionarias se incluyan en el backend `Target` del transpilador.\n",
        "\n",
        "```python\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.backend('ibm_torino', use_fractional_gates=True)\n",
        "```\n",
        "\n",
        "Este ejemplo de código demuestra cómo utilizar puertas fraccionarias en el contexto de un flujo de trabajo que simula la dinámica de una cadena de Ising utilizando puertas fraccionarias. A continuación, se compara la duración del circuito con un backend que no utiliza puertas fraccionarias.\n",
        "\n",
        "<Admonition title=\"Nota sobre los porcentajes de error notificados\" type=\"note\">\n",
        "  El valor de error notificado en `Target` de un backend con puertas fraccionarias activadas es sólo una copia del homólogo de la puerta no fraccionaria (que puede no ser el mismo). Esto se debe a que aún no se admite la notificación de porcentajes de error en las puertas fraccionarias.\n",
        "\n",
        "  Sin embargo, dado que el tiempo de compuerta de las compuertas fraccionarias y no fraccionarias es el mismo, es razonable suponer que sus tasas de error son comparables, especialmente cuando la fuente dominante de error en un circuito se debe a la relajación.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "9cb7f696-dec0-4393-9320-fe945326c893",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/9cb7f696-dec0-4393-9320-fe945326c893-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "from qiskit.circuit import Parameter\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.visualization.timeline import draw as draw_timeline, IQXSimple\n",
        "\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "\n",
        "num_qubits = 5\n",
        "num_time_steps = 3\n",
        "rx_angle = 0.1\n",
        "rzz_angle = 0.1\n",
        "\n",
        "ising_circuit = QuantumCircuit(num_qubits)\n",
        "for i in range(num_time_steps):\n",
        "    # rx layer\n",
        "    for q in range(num_qubits):\n",
        "        ising_circuit.rx(rx_angle, q)\n",
        "    for q in range(1, num_qubits - 1, 2):\n",
        "        ising_circuit.rzz(rzz_angle, q, q + 1)\n",
        "    # 2nd rzz layer\n",
        "    for q in range(0, num_qubits - 1, 2):\n",
        "        ising_circuit.rzz(rzz_angle, q, q + 1)\n",
        "    ising_circuit.barrier()\n",
        "ising_circuit.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "983bbe11-fa20-4043-a146-66af18cae054",
      "metadata": {},
      "source": [
        "Especifique dos objetos backend: uno con las puertas fraccionarias activadas y otro con ellas desactivadas, y transpile ambos.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "09ef3ed0-7126-45a2-a876-35a4f540c949",
      "metadata": {},
      "outputs": [],
      "source": [
        "service = QiskitRuntimeService()\n",
        "backend_fractional = service.backend(\"ibm_torino\", use_fractional_gates=True)\n",
        "backend_conventional = service.backend(\n",
        "    \"ibm_torino\", use_fractional_gates=False\n",
        ")\n",
        "\n",
        "pm_fractional = generate_preset_pass_manager(\n",
        "    optimization_level=3, backend=backend_fractional, scheduling_method=\"alap\"\n",
        ")\n",
        "pm_conventional = generate_preset_pass_manager(\n",
        "    optimization_level=3,\n",
        "    backend=backend_conventional,\n",
        "    scheduling_method=\"alap\",\n",
        ")\n",
        "\n",
        "ising_circuit_fractional = pm_fractional.run(ising_circuit)\n",
        "ising_circuit_conventional = pm_conventional.run(ising_circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cf108858-b8ee-44a8-b252-3e7748b691f8",
      "metadata": {},
      "source": [
        "Visualiza la cronología del circuito utilizando los dos tipos de compuertas.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "0013f5fa-4072-4aa4-94fe-7e195435f828",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/0013f5fa-4072-4aa4-94fe-7e195435f828-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Draw timeline of circuit with conventional gates\n",
        "draw_timeline(\n",
        "    ising_circuit_conventional,\n",
        "    idle_wires=False,\n",
        "    target=backend_conventional.target,\n",
        "    time_range=(0, 500),\n",
        "    style=IQXSimple(),\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "08dd1cdf-8b34-47c2-8324-f3538c9d1ab6",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/08dd1cdf-8b34-47c2-8324-f3538c9d1ab6-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Draw timeline of circuit with fractional gates\n",
        "draw_timeline(\n",
        "    ising_circuit_fractional,\n",
        "    idle_wires=False,\n",
        "    target=backend_fractional.target,\n",
        "    time_range=(0, 500),\n",
        "    style=IQXSimple(),\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "76f9f94e-f402-4519-b991-708b74a4f88c",
      "metadata": {},
      "source": [
        "<span id=\"angle-constraints\" />\n",
        "\n",
        "### Restricciones angulares\n",
        "\n",
        "Para la puerta de dos qubits $R_{ZZ}(\\theta)$, sólo los ángulos entre $0$ y $\\pi/2$ pueden ejecutarse en el hardware IBM Quantum. Si un circuito contiene alguna compuerta $R_{ZZ}(\\theta)$ con un ángulo fuera de este rango, entonces el pipeline de transpilación estándar generalmente lo corregirá con una transformación de circuito apropiada (a través del [`FoldRzzAngle`](../api/qiskit-ibm-runtime/transpiler-passes-fold-rzz-angle) pass).  Sin embargo, para cualquier puerta $R_{ZZ}(\\theta)$ que contenga una o más [`Parameter`](../api/qiskit/qiskit.circuit.Parameter)s, el transpilador asumirá que a estos parámetros se les asignarán ángulos dentro de este rango en tiempo de ejecución. El trabajo fallará si alguno de los valores de los parámetros especificados en PUB enviados a Qiskit Runtime están fuera de este rango.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "48bad5e6-3c7a-4bd0-b050-e440c3257be2",
      "metadata": {},
      "source": [
        "<span id=\"where-to-use-fractional-gates\" />\n",
        "\n",
        "## Dónde utilizar puertas fraccionarias\n",
        "\n",
        "Históricamente, las puertas base disponibles en IBM Quantum QPUs han sido **`CZ`**, **`X`**, **`RZ`**, \\*\\*`SX`\\*\\*y \\*\\*`ID`\\*\\*que no pueden representar eficientemente circuitos con rotaciones de uno y dos qubits que no sean múltiplos de $\\pi / 2$. Por ejemplo, una puerta $R_X(\\theta)$, cuando se transpila, debe descomponerse en una serie de puertas $RZ$ y $\\sqrt{X}$, lo que crea un circuito con dos puertas de duración finita en lugar de una.\n",
        "\n",
        "Del mismo modo, cuando se transpilan rotaciones de dos qubits como una puerta $R_{ZZ}(\\theta)$, la descomposición requiere dos **`CZ`** puertas y varias puertas de un solo qubit, lo que aumenta la profundidad del circuito. Estas descomposiciones se muestran en el siguiente código.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "11b003ee-aa8e-4794-a84a-b6870d15fa11",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/11b003ee-aa8e-4794-a84a-b6870d15fa11-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qc = QuantumCircuit(1)\n",
        "param = Parameter(\"θ\")\n",
        "qc.rx(param, 0)\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "5da9bba4-9a3b-4569-9997-c5b9ccf87b6a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/5da9bba4-9a3b-4569-9997-c5b9ccf87b6a-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Decomposition of an RX(θ) gate using the IBM Quantum QPU basis\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.backend(\"ibm_torino\")\n",
        "optimization_level = 3\n",
        "pm = generate_preset_pass_manager(optimization_level, backend=backend)\n",
        "transpiled_circuit = pm.run(qc)\n",
        "transpiled_circuit.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "6b256201-0237-4f63-91ff-fde1bb884804",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/6b256201-0237-4f63-91ff-fde1bb884804-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "from qiskit.circuit import Parameter\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "qc = QuantumCircuit(2)\n",
        "param = Parameter(\"θ\")\n",
        "qc.rzz(param, 0, 1)\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "f07217b9-a6f0-4adf-b341-6da447535c33",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/f07217b9-a6f0-4adf-b341-6da447535c33-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Decomposition of an RZZ(θ) gate using the IBM Quantum QPU basis\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.backend(\"ibm_torino\")\n",
        "optimization_level = 3\n",
        "pm = generate_preset_pass_manager(optimization_level, backend=backend)\n",
        "transpiled_circuit = pm.run(qc)\n",
        "transpiled_circuit.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5bc4f276-80e4-49af-bd5c-d9dceedc9aa3",
      "metadata": {},
      "source": [
        "Para los flujos de trabajo que requieren muchas rotaciones de un solo qubit $R_X(\\theta)$ o de dos qubits (como en un ansatz variacional o al simular la evolución temporal de sistemas cuánticos), esta restricción hace que la profundidad del circuito crezca rápidamente. Sin embargo, las puertas fraccionarias eliminan este requisito, ya que las rotaciones de uno y dos qubits se ejecutan directamente, y crean un circuito cuántico más eficiente (y, por tanto, con supresión de errores).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c601cc20-be04-45b6-9917-e8fe2925d36b",
      "metadata": {},
      "source": [
        "<span id=\"when-not-to-use\" />\n",
        "\n",
        "<span id=\"when-not-to-use-fractional-gates\" />\n",
        "\n",
        "<span id=\"when-*not*-to-use-fractional-gates\" />\n",
        "\n",
        "## Cuándo *no* utilizar puertas fraccionarias\n",
        "\n",
        "Es importante señalar que las puertas fraccionales son una característica *experimental* y el comportamiento de la bandera `use_fractional_gates` puede cambiar en el futuro. Para más información, consulte [las notas de la](/docs/api/qiskit-ibm-runtime/release-notes) nueva versión de Qiskit Runtime. Consulte también la documentación de referencia de la API para [QiskitRuntimeService.backend](/docs/api/qiskit-ibm-runtime/qiskit-runtime-service#backend), que describe `use_fractional_gates`.\n",
        "\n",
        "Además, el transpilador Qiskit tiene una capacidad limitada para utilizar $R_{ZZ}(\\theta)$ en sus pases de optimización. Esto obliga a tener más cuidado a la hora de elaborar y optimizar los circuitos que contienen estas instrucciones.\n",
        "\n",
        "Por último, no se admite el uso de puertas fraccionarias para:\n",
        "\n",
        "* [Pauli twirling](/docs/guides/error-mitigation-and-suppression-techniques#pauli-twirling) - sin embargo, *se* admite [la medición twirling con TREX](/docs/guides/error-mitigation-and-suppression-techniques#twirled-readout-error-extinction-trex).\n",
        "* [Cancelación probabilística de errores](/docs/guides/error-mitigation-and-suppression-techniques#probabilistic-error-cancellation-pec)\n",
        "* [Extrapolación de ruido cero (mediante amplificación probabilística de errores)](/docs/guides/error-mitigation-and-suppression-techniques#probabilistic-error-amplification-pea)\n",
        "\n",
        "Lea la guía sobre [opciones primitivas](/docs/guides/runtime-options-overview) para obtener más información sobre la personalización de las técnicas de mitigación y supresión de errores para una carga de trabajo cuántica determinada.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "58fba520-5d6e-4647-8cb7-2c8790eb8127",
      "metadata": {},
      "source": [
        "<span id=\"which-backends-support-fractional-gates\" />\n",
        "\n",
        "## ¿Qué backends admiten puertas fraccionarias?\n",
        "\n",
        "No todos los backends admiten puertas fraccionarias. Corre `service.backends(use_fractional_gates=True)` para encontrar a los que sí lo hacen. Un backend falso solo admite puertas fraccionarias si el backend «real» correspondiente las admite.\n",
        "\n",
        "Ten en cuenta que los backends falsos no admiten puertas fraccionarias de forma predeterminada, ya que estas están desactivadas por defecto. Para habilitar las puertas fraccionarias en un backend simulado que las admita, actualiza su configuración.\n",
        "\n",
        "Ejemplo:\n",
        "\n",
        "```python\n",
        "service = QiskitRuntimeService()\n",
        "fake_backend = FakeBoston()\n",
        "fake_backend.refresh(service=service, use_fractional_gates=True)\n",
        "```\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bf0a38a6-60d1-4848-bbde-df19bb496510",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximos pasos\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendaciones\">\n",
        "  * Para obtener más información sobre la transpilación, consulte la página [de introducción a la transpilación](/docs/guides/transpile).\n",
        "  * Más información sobre cómo [escribir un pase de transpilador personalizado](/docs/guides/custom-transpiler-pass).\n",
        "  * Comprender cómo [configurar la mitigación de errores](/docs/guides/configure-error-mitigation) para Qiskit Runtime.\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": 2
}