{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "72a56be1-db57-4364-acf3-57814453b64e",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Alimentación directa clásica y flujo de control (circuitos dinámicos)\"\n",
        "description: \"Utilice Qiskit para el flujo clásico de alimentación directa y control, también conocido como circuitos dinámicos\"\n",
        "---\n",
        "\n",
        "<span id=\"classical-feedforward-and-control-flow-dynamic-circuits\" />\n",
        "\n",
        "# Alimentación directa clásica y flujo de control (circuitos dinámicos)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7f636096-9a03-4f72-823b-4b9219d496f0",
      "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",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ea7e102f-6e41-4bdd-95be-5dd13225952b",
      "metadata": {},
      "source": [
        "Los circuitos dinámicos son potentes herramientas con las que se pueden medir qubits en mitad de la ejecución de un circuito cuántico y, a continuación, realizar operaciones lógicas clásicas dentro del circuito, basándose en el resultado de esas mediciones a mitad de circuito.  Este proceso también se conoce como *feedforward clásico*. Aunque aún es pronto para comprender cuál es la mejor manera de aprovechar los circuitos dinámicos, la comunidad de investigación cuántica ya ha identificado una serie de casos de uso, como los siguientes:\n",
        "\n",
        "* Preparación eficiente de estados cuánticos, como [el estado GHZ](https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.5.030339), [el estado W](https://arxiv.org/abs/2403.07604) (para obtener más información sobre el estado W, consulte también [«Preparación de estados mediante circuitos superficiales utilizando alimentación directa»](https://arxiv.org/abs/2307.14840) ) y una amplia clase de [estados de producto matricial](https://arxiv.org/abs/2404.16083)\n",
        "* [Entrelazamiento eficiente de largo alcance](https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.5.030339) entre qubits del mismo chip mediante circuitos poco profundos\n",
        "* [Muestreo eficiente de circuitos tipo IQP](https://arxiv.org/pdf/2505.04705)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b2953dd4-218e-4daa-a753-0d2aa5e0a0bb",
      "metadata": {},
      "source": [
        "Qiskit admite cuatro construcciones de flujo de control para la red clásica de propagación hacia adelante, cada una de ellas implementada como un método en [`QuantumCircuit`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit). Las estructuras y sus métodos correspondientes son:\n",
        "\n",
        "* Instrucción «if» - [`QuantumCircuit.if_test`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#if_test)\n",
        "* Instrucción «switch» - [`QuantumCircuit.switch`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#switch)\n",
        "* Bucle «for» - [`QuantumCircuit.for_loop`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#for_loop)\n",
        "* Bucle «while» - [`QuantumCircuit.while_loop`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#while_loop)\n",
        "\n",
        "Cada uno de estos métodos devuelve un [gestor de contexto](https://docs.python.org/3/reference/datamodel.html#with-statement-context-managers) y suele utilizarse en una `with` instrucción. En el resto de esta guía se explican cada uno de estos constructos y cómo utilizarlos.\n",
        "\n",
        "<Admonition type=\"caution\">\n",
        "  Existen algunas limitaciones en las operaciones clásicas de avance y de flujo de control en el hardware cuántico que podrían afectar a tu programa. Para obtener más información, consulta «[Ejecutar circuitos dinámicos](/docs/guides/execute-dynamic-circuits) ».\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"if-statement\" />\n",
        "\n",
        "## `if` sentencia\n",
        "\n",
        "La sentencia `if` se utiliza para realizar condicionalmente operaciones basadas en el valor de un bit o registro clásico.\n",
        "\n",
        "En el siguiente ejemplo, aplicamos una puerta Hadamard a un qubit y lo medimos. Si el resultado es 1, entonces aplicamos una puerta X en el qubit, que tiene el efecto de voltearlo de nuevo al estado 0. A continuación, volvemos a medir el qubit. El resultado de la medición debe ser 0 con una probabilidad del 100%.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "f0f191a7-d59d-415f-a11b-9f39e431269b",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/classical-feedforward-and-control-flow/extracted-outputs/f0f191a7-d59d-415f-a11b-9f39e431269b-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister\n",
        "\n",
        "qubits = QuantumRegister(1)\n",
        "clbits = ClassicalRegister(1)\n",
        "circuit = QuantumCircuit(qubits, clbits)\n",
        "(q0,) = qubits\n",
        "(c0,) = clbits\n",
        "\n",
        "circuit.h(q0)\n",
        "circuit.measure(q0, c0)\n",
        "with circuit.if_test((c0, 1)):\n",
        "    circuit.x(q0)\n",
        "circuit.measure(q0, c0)\n",
        "circuit.draw(\"mpl\")\n",
        "\n",
        "# example output counts: {'0': 1024}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "867d8f76-9cba-47fd-a341-ac40db6ee073",
      "metadata": {},
      "source": [
        "A la sentencia `with` se le puede dar un objetivo de asignación que es a su vez un gestor de contexto que puede ser almacenado y posteriormente utilizado para crear un bloque else, que se ejecuta siempre que *no* se ejecute el contenido del bloque `if` .\n",
        "\n",
        "En el siguiente ejemplo, inicializamos los registros con dos qubits y dos bits clásicos. Aplicamos una puerta Hadamard al primer qubit y lo medimos. Si el resultado es 1, aplicamos una puerta Hadamard en el segundo qubit; en caso contrario, aplicamos una puerta X en el segundo qubit. Por último, medimos también el segundo qubit.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "d40249f1-d951-49e4-9ee9-662d3568f32f",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/classical-feedforward-and-control-flow/extracted-outputs/d40249f1-d951-49e4-9ee9-662d3568f32f-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qubits = QuantumRegister(2)\n",
        "clbits = ClassicalRegister(2)\n",
        "circuit = QuantumCircuit(qubits, clbits)\n",
        "(q0, q1) = qubits\n",
        "(c0, c1) = clbits\n",
        "\n",
        "circuit.h(q0)\n",
        "circuit.measure(q0, c0)\n",
        "with circuit.if_test((c0, 1)) as else_:\n",
        "    circuit.h(q1)\n",
        "with else_:\n",
        "    circuit.x(q1)\n",
        "circuit.measure(q1, c1)\n",
        "\n",
        "circuit.draw(\"mpl\")\n",
        "\n",
        "# example output counts: {'01': 260, '11': 272, '10': 492}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ba7b688a-e961-4361-9edf-47b387704f9d",
      "metadata": {},
      "source": [
        "Además de condicionar sobre un único bit clásico, también es posible condicionar sobre el valor de un registro clásico compuesto por múltiples bits.\n",
        "\n",
        "En el ejemplo siguiente, aplicamos puertas Hadamard a dos qubits y los medimos. Si el resultado es `01`, es decir, el primer qubit es 1 y el segundo qubit es 0, entonces aplicamos una puerta X a un tercer qubit. Por último, medimos el tercer qubit. Tenga en cuenta que, para mayor claridad, hemos optado por especificar el estado del tercer bit clásico, que es 0, en la `if` condición. En el esquema del circuito, la condición se indica mediante los círculos sobre los bits clásicos que están siendo condicionados. Un círculo sólido indica condicionamiento en 1, mientras que un círculo delineado indica condicionamiento en 0.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "6ccfd81b-0bda-409e-bd9a-116848df631b",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/classical-feedforward-and-control-flow/extracted-outputs/6ccfd81b-0bda-409e-bd9a-116848df631b-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qubits = QuantumRegister(3)\n",
        "clbits = ClassicalRegister(3)\n",
        "circuit = QuantumCircuit(qubits, clbits)\n",
        "(q0, q1, q2) = qubits\n",
        "(c0, c1, c2) = clbits\n",
        "\n",
        "circuit.h([q0, q1])\n",
        "circuit.measure(q0, c0)\n",
        "circuit.measure(q1, c1)\n",
        "with circuit.if_test((clbits, 0b001)):\n",
        "    circuit.x(q2)\n",
        "circuit.measure(q2, c2)\n",
        "\n",
        "circuit.draw(\"mpl\")\n",
        "\n",
        "# example output counts: {'101': 269, '011': 260, '000': 252, '010': 243}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f85c34ed-bca6-40b9-9db2-e534f8c79010",
      "metadata": {},
      "source": [
        "<span id=\"switch-statement\" />\n",
        "\n",
        "## Instrucción «switch»\n",
        "\n",
        "La instrucción «switch» se utiliza para seleccionar acciones en función del valor de un bit o un registro clásico. Es similar a una instrucción «if», pero permite especificar más casos para la lógica de ramificación. En el ejemplo siguiente se aplica una puerta de Hadamard a un qubit y se mide este. Si el resultado es 0, aplica una puerta X al qubit, y si el resultado es 1, aplica una puerta Z. El resultado de la medición debería ser 1 con una probabilidad del 100 %.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "04b82e33-7c95-4042-a5e9-d00ff075ca02",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/classical-feedforward-and-control-flow/extracted-outputs/04b82e33-7c95-4042-a5e9-d00ff075ca02-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qubits = QuantumRegister(1)\n",
        "clbits = ClassicalRegister(1)\n",
        "circuit = QuantumCircuit(qubits, clbits)\n",
        "(q0,) = qubits\n",
        "(c0,) = clbits\n",
        "\n",
        "circuit.h(q0)\n",
        "circuit.measure(q0, c0)\n",
        "with circuit.switch(c0) as case:\n",
        "    with case(0):\n",
        "        circuit.x(q0)\n",
        "    with case(1):\n",
        "        circuit.z(q0)\n",
        "circuit.measure(q0, c0)\n",
        "\n",
        "circuit.draw(\"mpl\")\n",
        "\n",
        "# example output counts: {'1': 1024}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e0da6aa3-736e-4eb5-ad36-8626236f7604",
      "metadata": {},
      "source": [
        "Dado que en el ejemplo anterior se utilizaba un único bit clásico, solo había dos casos posibles, por lo que se habría podido obtener el mismo resultado utilizando una instrucción «if-else». La instrucción «switch case» resulta especialmente útil cuando se desea realizar una ramificación en función del valor de un registro clásico compuesto por varios bits. El siguiente ejemplo muestra cómo crear un caso por defecto, que se ejecuta si no se ejecuta ninguno de los casos anteriores. Ten en cuenta que, en una instrucción «switch», solo se ejecuta uno de los bloques. No hay caída.\n",
        "\n",
        "En el ejemplo siguiente se aplican puertas de Hadamard a dos qubits y se miden estos. Si el resultado es 00 o 11, aplica una puerta Z al tercer qubit. Si el resultado es 01, aplica una puerta «Y». Si ninguno de los casos anteriores coincide, aplica una puerta X. Por último, mide el tercer qubit.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "6aaba57e-7841-47d3-8f31-f922cb2b81f7",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/classical-feedforward-and-control-flow/extracted-outputs/6aaba57e-7841-47d3-8f31-f922cb2b81f7-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qubits = QuantumRegister(3)\n",
        "clbits = ClassicalRegister(3)\n",
        "circuit = QuantumCircuit(qubits, clbits)\n",
        "(q0, q1, q2) = qubits\n",
        "(c0, c1, c2) = clbits\n",
        "\n",
        "circuit.h([q0, q1])\n",
        "circuit.measure(q0, c0)\n",
        "circuit.measure(q1, c1)\n",
        "with circuit.switch(clbits) as case:\n",
        "    with case(0b000, 0b011):\n",
        "        circuit.z(q2)\n",
        "    with case(0b001):\n",
        "        circuit.y(q2)\n",
        "    with case(case.DEFAULT):\n",
        "        circuit.x(q2)\n",
        "circuit.measure(q2, c2)\n",
        "\n",
        "circuit.draw(\"mpl\")\n",
        "\n",
        "# example output counts: {'101': 267, '110': 249, '011': 265, '000': 243}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e5f1da75-abcc-42de-8aa6-6f2a6d450ddd",
      "metadata": {},
      "source": [
        "<span id=\"for-loop\" />\n",
        "\n",
        "## Bucle for\n",
        "\n",
        "Un bucle «for» se utiliza para recorrer una secuencia de valores clásicos y realizar ciertas operaciones en cada iteración.\n",
        "\n",
        "En el siguiente ejemplo se utiliza un bucle «for» para aplicar 5 puertas X a un qubit y, a continuación, se mide este. Dado que realiza un número impar de puertas X, el efecto global es invertir el estado del qubit, pasando del estado 0 al estado 1.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "c6c91715-7a98-46a8-885e-92d3d1f99557",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/classical-feedforward-and-control-flow/extracted-outputs/c6c91715-7a98-46a8-885e-92d3d1f99557-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qubits = QuantumRegister(1)\n",
        "clbits = ClassicalRegister(1)\n",
        "circuit = QuantumCircuit(qubits, clbits)\n",
        "(q0,) = qubits\n",
        "(c0,) = clbits\n",
        "\n",
        "with circuit.for_loop(range(5)) as _:\n",
        "    circuit.x(q0)\n",
        "circuit.measure(q0, c0)\n",
        "\n",
        "circuit.draw(\"mpl\")\n",
        "\n",
        "# example output counts: {'1': 1024}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "98e7b4f3-e73e-4caf-9326-11b45bd6cfcf",
      "metadata": {},
      "source": [
        "<span id=\"while-loop\" />\n",
        "\n",
        "## Bucle while\n",
        "\n",
        "El bucle «while» se utiliza para repetir instrucciones mientras se cumpla una determinada condición.\n",
        "\n",
        "En el ejemplo siguiente se aplican puertas de Hadamard a dos qubits y se miden estos. A continuación, crea un bucle «while» que repite este procedimiento mientras el resultado de la medición sea 11. Por lo tanto, el resultado final nunca debería ser 11, y las demás posibilidades deberían aparecer con una frecuencia aproximadamente igual.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "c26465ff-5d3e-4799-8c68-c327abff5694",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/classical-feedforward-and-control-flow/extracted-outputs/c26465ff-5d3e-4799-8c68-c327abff5694-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qubits = QuantumRegister(2)\n",
        "clbits = ClassicalRegister(2)\n",
        "circuit = QuantumCircuit(qubits, clbits)\n",
        "\n",
        "q0, q1 = qubits\n",
        "c0, c1 = clbits\n",
        "\n",
        "circuit.h([q0, q1])\n",
        "circuit.measure(q0, c0)\n",
        "circuit.measure(q1, c1)\n",
        "with circuit.while_loop((clbits, 0b11)):\n",
        "    circuit.h([q0, q1])\n",
        "    circuit.measure(q0, c0)\n",
        "    circuit.measure(q1, c1)\n",
        "\n",
        "circuit.draw(\"mpl\")\n",
        "\n",
        "# example output counts: {'01': 334, '10': 368, '00': 322}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "672080db-913d-4511-ab63-48ca48b60fa5",
      "metadata": {},
      "source": [
        "<span id=\"classical-expressions\" />\n",
        "\n",
        "## Expresiones clásicas\n",
        "\n",
        "El módulo [`qiskit.circuit.classical`](/docs/api/qiskit/circuit_classical) de expresiones clásicas de Qiskit contiene una representación exploratoria de las operaciones en tiempo de ejecución sobre valores clásicos durante la ejecución del circuito.\n",
        "\n",
        "El siguiente ejemplo muestra que se puede utilizar el cálculo de la paridad para crear un estado GHZ de n-qubit utilizando circuitos dinámicos. En primer lugar, generar $n/2$ pares de Bell en qubits adyacentes. A continuación, pegue estos pares utilizando una capa de puertas CNOT entre pares. A continuación, se mide el qubit objetivo de todas las puertas CNOT anteriores y se restablece cada qubit medido al estado $\\vert 0 \\rangle$. Aplicas $X$ a cada sitio no medido para el que la paridad de todos los bits precedentes sea impar. Por último, se aplican puertas CNOT a los qubits medidos para restablecer el entrelazamiento perdido en la medición.\n",
        "\n",
        "En el cálculo de paridad, el primer elemento de la expresión construida implica elevar el objeto Python`mr[0]` a un [`Value`](/docs/api/qiskit/circuit_classical#value) nodo (`lift` se utiliza para convertir objetos arbitrarios en expresiones clásicas). Esto no es necesario para `mr[1]` y el posible registro clásico siguiente, ya que son entradas a `expr.bit_xor`, y cualquier elevación necesaria se realiza automáticamente en estos casos. Estas expresiones se pueden construir en bucles y otras construcciones.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "8c8ad702-1097-411f-983d-b5654f75059f",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister\n",
        "from qiskit.circuit.classical import expr\n",
        "\n",
        "num_qubits = 8\n",
        "if num_qubits % 2 or num_qubits < 4:\n",
        "    raise ValueError(\"num_qubits must be an even integer ≥ 4\")\n",
        "meas_qubits = list(range(2, num_qubits, 2))  # qubits to measure and reset\n",
        "\n",
        "qr = QuantumRegister(num_qubits, \"qr\")\n",
        "mr = ClassicalRegister(len(meas_qubits), \"m\")\n",
        "qc = QuantumCircuit(qr, mr)\n",
        "\n",
        "# Create local Bell pairs\n",
        "qc.reset(qr)\n",
        "qc.h(qr[::2])\n",
        "for ctrl in range(0, num_qubits, 2):\n",
        "    qc.cx(qr[ctrl], qr[ctrl + 1])\n",
        "\n",
        "# Glue neighboring pairs\n",
        "for ctrl in range(1, num_qubits - 1, 2):\n",
        "    qc.cx(qr[ctrl], qr[ctrl + 1])\n",
        "\n",
        "# Measure boundary qubits between pairs,reset to 0\n",
        "for k, q in enumerate(meas_qubits):\n",
        "    qc.measure(qr[q], mr[k])\n",
        "    qc.reset(qr[q])\n",
        "\n",
        "# Parity-conditioned X corrections\n",
        "# Each non-measured qubit gets flipped iff the parity (XOR) of all\n",
        "# preceding measurement bits is 1\n",
        "for tgt in range(num_qubits):\n",
        "    if tgt in meas_qubits:  # skip measured qubits\n",
        "        continue\n",
        "    # all measurement registers whose physical qubit index < tgt\n",
        "    left_bits = [k for k, q in enumerate(meas_qubits) if q < tgt]\n",
        "    if not left_bits:  # skip if list empty\n",
        "        continue\n",
        "\n",
        "    # build XOR-parity expression\n",
        "    parity = expr.lift(\n",
        "        mr[left_bits[0]]\n",
        "    )  # lift the first bit to Value so it will be treated like a boolean.\n",
        "    for k in left_bits[1:]:\n",
        "        parity = expr.bit_xor(\n",
        "            mr[k], parity\n",
        "        )  # calculate parity with all other bits\n",
        "    with qc.if_test(parity):  # Add X if parity is 1\n",
        "        qc.x(qr[tgt])\n",
        "\n",
        "# Re-entangle measured qubits\n",
        "for ctrl in range(1, num_qubits - 1, 2):\n",
        "    qc.cx(qr[ctrl], qr[ctrl + 1])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "a5d808f5-d424-4133-a557-89d2f2a2c853",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/classical-feedforward-and-control-flow/extracted-outputs/a5d808f5-d424-4133-a557-89d2f2a2c853-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qc.draw(output=\"mpl\", style=\"iqp\", idle_wires=False, fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "62134a85-608f-4ad2-a76e-b0736bec9362",
      "metadata": {},
      "source": [
        "<span id=\"store\" />\n",
        "\n",
        "<span id=\"store\" />\n",
        "\n",
        "### `Store`\n",
        "\n",
        "Puedes utilizar la [`store`](/docs/api/qiskit/circuit#store) instrucción para guardar el resultado de una expresión clásica, si vas a utilizar esa expresión varias veces. Las operaciones se paralelizan automáticamente, lo que hace que tu código sea mucho más eficiente en tiempo de ejecución.\n",
        "\n",
        "Por ejemplo, resulta más natural y más eficiente en tiempo de ejecución escribir « $B[0] \\oplus B[1] \\oplus B[2] \\ldots$ », donde « $B = \\neg A$ », que « $(\\neg A[0]) \\oplus (\\neg A[1]) \\oplus (\\neg A[2]) \\ldots$ ». La primera opción calcula la negación en un único paso paralelo antes de la cadena XOR, en lugar de evaluar cada negación de forma secuencial dentro de la expresión.\n",
        "\n",
        "Ejemplo completo:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "953fa3ca-f542-47ea-9cf2-36a616ecb7f7",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/classical-feedforward-and-control-flow/extracted-outputs/953fa3ca-f542-47ea-9cf2-36a616ecb7f7-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister\n",
        "from qiskit.circuit.classical import expr\n",
        "\n",
        "qregs = QuantumRegister(4, \"q\")\n",
        "creg = ClassicalRegister(3, \"c\")\n",
        "# temp is a plain ClassicalRegister used as the store target\n",
        "temp = ClassicalRegister(3, \"temp\")\n",
        "qc = QuantumCircuit(qregs, creg, temp)\n",
        "\n",
        "qc.h([0, 1, 2])\n",
        "qc.measure([0, 1, 2], creg)\n",
        "\n",
        "# Store bit-NOT of the full 3-bit register into temp\n",
        "qc.store(temp, expr.bit_not(creg))\n",
        "\n",
        "# Compute parity of temp using bit-indexed XOR\n",
        "parity = expr.bit_xor(\n",
        "    expr.bit_xor(expr.index(temp, 0), expr.index(temp, 1)),\n",
        "    expr.index(temp, 2),\n",
        ")\n",
        "\n",
        "# Flip q3 if parity of ~creg is 1\n",
        "with qc.if_test(parity):\n",
        "    qc.x(3)\n",
        "\n",
        "qc.measure([0, 1, 2], creg)\n",
        "\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f1b55508-04e8-4f53-9b13-33302102711d",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximos pasos\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendaciones\">\n",
        "  * Aprenda a implementar un desacoplamiento dinámico preciso utilizando [el estiramiento](/docs/guides/stretch).\n",
        "  * Utiliza [la visualización del esquema del circuito](/docs/guides/qiskit-runtime-circuit-timing) para depurar y optimizar tus circuitos dinámicos.\n",
        "  * [Ejecutar circuitos dinámicos](/docs/guides/execute-dynamic-circuits).\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
}