{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "72a56be1-db57-4364-acf3-57814453b64e",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Feedforward classique et flux de contrôle (circuits dynamiques)\"\n",
        "description: \"Utilisez Qiskit pour le flux classique d'alimentation et de contrôle, également appelé circuits dynamiques\"\n",
        "---\n",
        "\n",
        "<span id=\"classical-feedforward-and-control-flow-dynamic-circuits\" />\n",
        "\n",
        "# Feedforward classique et flux de contrôle (circuits dynamiques)\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=\"Versions de package\">\n",
        "    Le code de cette page a été développé en tenant compte des exigences suivantes.\n",
        "    Nous recommandons d'utiliser ces versions ou des versions plus récentes.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.1\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ea7e102f-6e41-4bdd-95be-5dd13225952b",
      "metadata": {},
      "source": [
        "Les circuits dynamiques sont des outils puissants qui permettent de mesurer des qubits au milieu de l'exécution d'un circuit quantique, puis d'effectuer des opérations logiques classiques au sein du circuit, sur la base des résultats de ces mesures effectuées au milieu du circuit.  Ce processus est également connu sous le nom de \" *feedforward\" classique*. Bien qu'il soit encore trop tôt pour comprendre comment tirer le meilleur parti des circuits dynamiques, la communauté de la recherche quantique a déjà identifié un certain nombre de cas d'utilisation, tels que les suivants :\n",
        "\n",
        "* Préparation efficace d'états quantiques, tels que [l'état GHZ](https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.5.030339), [l'état W](https://arxiv.org/abs/2403.07604) (pour plus d'informations sur l'état W, voir également [« Préparation d'états par circuits peu profonds utilisant une alimentation en avant »](https://arxiv.org/abs/2307.14840) ) et une large classe [d'états de produit](https://arxiv.org/abs/2404.16083) matriciel\n",
        "* [Intrication efficace à longue portée](https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.5.030339) entre qubits sur une même puce par l'utilisation de circuits peu profonds\n",
        "* [Échantillonnage efficace des circuits de type IQP](https://arxiv.org/pdf/2505.04705)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b2953dd4-218e-4daa-a753-0d2aa5e0a0bb",
      "metadata": {},
      "source": [
        "Qiskit prend en charge quatre constructions de flux de contrôle pour les réseaux classiques à propagation directe, chacune étant implémentée sous forme de méthode sur [`QuantumCircuit`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit). Les constructions et les méthodes correspondantes sont les suivantes :\n",
        "\n",
        "* Instruction « if » - [`QuantumCircuit.if_test`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#if_test)\n",
        "* Instruction « switch » - [`QuantumCircuit.switch`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#switch)\n",
        "* Boucle « for » - [`QuantumCircuit.for_loop`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#for_loop)\n",
        "* Boucle « while » - [`QuantumCircuit.while_loop`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#while_loop)\n",
        "\n",
        "Chacune de ces méthodes renvoie un [gestionnaire de contexte](https://docs.python.org/3/reference/datamodel.html#with-statement-context-managers) et est généralement utilisée dans une `with` instruction. La suite de ce guide explique chacune de ces structures et comment les utiliser.\n",
        "\n",
        "<Admonition type=\"caution\">\n",
        "  Les opérations classiques de transmission en aval et de contrôle de flux sur le matériel quantique présentent certaines limites susceptibles d'avoir une incidence sur votre programme. Pour plus d'informations, consultez [la section « Exécuter des circuits dynamiques](/docs/guides/execute-dynamic-circuits) ».\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"if-statement\" />\n",
        "\n",
        "## `if` instruction\n",
        "\n",
        "L'instruction `if` est utilisée pour effectuer des opérations conditionnelles basées sur la valeur d'un bit classique ou d'un registre.\n",
        "\n",
        "Dans l'exemple ci-dessous, nous appliquons une porte de Hadamard à un qubit et nous le mesurons. Si le résultat est 1, nous appliquons une porte X sur le qubit, ce qui a pour effet de le ramener à l'état 0. Nous mesurons ensuite à nouveau le qubit. Le résultat de la mesure doit être 0 avec une probabilité de 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": [
        "Le `with` L'instruction peut recevoir une cible d'affectation qui est elle-même un gestionnaire de contexte qui peut être stocké et utilisé ultérieurement pour créer un bloc else, qui est exécuté chaque fois que le contenu de l'instruction `if` les blocs ne sont *pas* exécutés.\n",
        "\n",
        "Dans l'exemple ci-dessous, nous initialisons les registres avec deux qubits et deux bits classiques. Nous appliquons une porte de Hadamard au premier qubit et le mesurons. Si le résultat est 1, nous appliquons une porte de Hadamard sur le deuxième qubit; sinon, nous appliquons une porte X sur le deuxième qubit. Enfin, nous mesurons également le deuxième 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": [
        "Outre le conditionnement sur un seul bit classique, il est également possible de conditionner la valeur d'un registre classique composé de plusieurs bits.\n",
        "\n",
        "Dans l'exemple ci-dessous, nous appliquons des portes Hadamard à deux qubits et les mesurons. Si le résultat est `01`, c'est-à-dire que le premier qubit est 1 et le deuxième qubit est 0, alors nous appliquons une porte X à un troisième qubit. Enfin, nous mesurons le troisième qubit. Notez que pour plus de clarté, nous avons choisi de spécifier l'état du troisième bit classique, qui est 0, dans la `if` condition. Dans le schéma du circuit, la condition est indiquée par les cercles sur les bits classiques qui sont conditionnés. Un cercle plein indique un conditionnement sur 1, tandis qu'un cercle en pointillés indique un conditionnement sur 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",
        "## Instruction « switch »\n",
        "\n",
        "L'instruction « switch » sert à sélectionner des actions en fonction de la valeur d'un bit ou d'un registre classique. Cela s'apparente à une instruction « if », mais vous pouvez définir davantage de cas pour la logique de branchement. L'exemple ci-dessous applique une porte de Hadamard à un qubit, puis le mesure. Si le résultat est 0, appliquez une porte X au qubit; si le résultat est 1, appliquez une porte Z. Le résultat de la mesure devrait être égal à 1 avec une probabilité de 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": [
        "Comme l'exemple ci-dessus utilisait un seul bit classique, il n'y avait que deux cas possibles; vous auriez donc pu obtenir le même résultat en utilisant une instruction « if-else ». L'instruction « switch » est particulièrement utile pour effectuer une branche en fonction de la valeur d'un registre classique composé de plusieurs bits. L'exemple suivant montre comment définir un cas par défaut, qui est exécuté si aucun des cas précédents ne l'est. Notez que dans une instruction « switch », un seul des blocs est exécuté. Il n'y a pas de « fallthrough ».\n",
        "\n",
        "L'exemple ci-dessous applique des portes d'Hadamard à deux qubits, puis les mesure. Si le résultat est soit 00, soit 11, appliquez une porte Z au troisième qubit. Si le résultat est 01, appliquez une porte « Y ». Si aucun des cas précédents ne correspond, appliquez une porte X. Enfin, mesurez le troisième 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",
        "## Boucle For\n",
        "\n",
        "Une boucle « for » sert à parcourir une séquence de valeurs classiques et à effectuer certaines opérations à chaque itération.\n",
        "\n",
        "L'exemple suivant utilise une boucle « for » pour appliquer 5 portes X à un qubit, puis mesure ce dernier. Comme il effectue un nombre impair de portes X, cela a pour effet global de faire basculer le qubit de l'état 0 à l'état 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",
        "## Boucle While\n",
        "\n",
        "Une boucle « while » sert à répéter des instructions tant qu'une condition est remplie.\n",
        "\n",
        "L'exemple ci-dessous applique des portes d'Hadamard à deux qubits, puis les mesure. Il crée ensuite une boucle « while » qui répète cette procédure tant que le résultat de la mesure est égal à 11. Par conséquent, la mesure finale ne devrait jamais être égale à 11, les autres possibilités se présentant avec une fréquence à peu près égale.\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",
        "## Expressions classiques\n",
        "\n",
        "Le module [`qiskit.circuit.classical`](/docs/api/qiskit/circuit_classical) d'expression classique de Qiskit contient une représentation exploratoire des opérations d'exécution sur les valeurs classiques au cours de l'exécution du circuit.\n",
        "\n",
        "L'exemple suivant montre que vous pouvez utiliser le calcul de la parité pour créer un état GHZ à n qubits à l'aide de circuits dynamiques. Tout d'abord, générer des paires de Bell $n/2$ sur des qubits adjacents. Ensuite, coller ces paires ensemble en utilisant une couche de barrières CNOT entre les paires. Vous mesurez ensuite le qubit cible de toutes les portes CNOT précédentes et réinitialisez chaque qubit mesuré à l'état $\\vert 0 \\rangle$. Vous appliquez $X$ à chaque site non mesuré pour lequel la parité de tous les bits précédents est impaire. Enfin, les portes CNOT sont appliquées aux qubits mesurés pour rétablir l'intrication perdue lors de la mesure.\n",
        "\n",
        "Dans le calcul de parité, le premier élément de l'expression construite consiste à élever l'objet Python`mr[0]` à un [`Value`](/docs/api/qiskit/circuit_classical#value) nœud (`lift` est utilisé pour transformer des objets arbitraires en expressions classiques). Ceci n'est pas nécessaire pour `mr[1]` et le registre classique suivant éventuel, car ils sont des entrées de `expr.bit_xor`, et tout levage nécessaire est effectué automatiquement dans ces cas. De telles expressions peuvent être construites dans des boucles et d'autres constructions.\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",
        "Vous pouvez utiliser l'instruction [`store`](/docs/api/qiskit/circuit#store) pour enregistrer le résultat d'une expression classique, si celle-ci doit être réutilisée à plusieurs reprises. Les opérations sont automatiquement parallélisées, ce qui rend votre code nettement plus efficace lors de l'exécution.\n",
        "\n",
        "Par exemple, il est plus naturel et plus efficace en exécution d'écrire $B[0] \\oplus B[1] \\oplus B[2] \\ldots$, où $B = \\neg A$, plutôt que $(\\neg A[0]) \\oplus (\\neg A[1]) \\oplus (\\neg A[2]) \\ldots$. La première expression calcule la négation en une seule étape parallèle avant la chaîne XOR, au lieu d'évaluer chaque négation de manière séquentielle à l'intérieur de l'expression.\n",
        "\n",
        "Exemple complet :\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",
        "## Etapes suivantes\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recommandations\">\n",
        "  * Apprenez à mettre en œuvre un découplage dynamique précis à l'aide de [l'étirement](/docs/guides/stretch).\n",
        "  * Utilisez [la visualisation du schéma de circuit](/docs/guides/qiskit-runtime-circuit-timing) pour déboguer et optimiser vos circuits dynamiques.\n",
        "  * [Exécuter des circuits dynamiques](/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
}