{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "72a56be1-db57-4364-acf3-57814453b64e",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Klassische Vorwärtskopplung und Kontrollfluss (dynamische Schaltungen)\"\n",
        "description: \"Verwenden Sie Qiskit für klassische Vorwärtskopplung und Kontrollfluss, auch als dynamische Schaltungen bezeichnet\"\n",
        "---\n",
        "\n",
        "<span id=\"classical-feedforward-and-control-flow-dynamic-circuits\" />\n",
        "\n",
        "# Klassische Vorwärtskopplung und Kontrollfluss (dynamische Schaltungen)\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=\"Paketversionen\">\n",
        "    Der Code auf dieser Seite wurde unter Berücksichtigung der folgenden Anforderungen entwickelt.\n",
        "    Wir empfehlen die Verwendung dieser oder neuerer Versionen.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.2\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ea7e102f-6e41-4bdd-95be-5dd13225952b",
      "metadata": {},
      "source": [
        "Dynamische Schaltkreise sind leistungsstarke Werkzeuge, mit denen man Qubits mitten in der Ausführung eines Quantenschaltkreises messen und dann klassische logische Operationen innerhalb des Schaltkreises durchführen kann, die auf dem Ergebnis dieser Messungen in der Mitte des Schaltkreises basieren.  Dieses Verfahren wird auch als *klassische Vorsteuerung* bezeichnet. Auch wenn wir noch am Anfang stehen, um zu verstehen, wie man die Vorteile dynamischer Schaltkreise am besten nutzen kann, hat die Quantenforschungsgemeinschaft bereits eine Reihe von Anwendungsfällen identifiziert, wie z. B. die folgenden:\n",
        "\n",
        "* Effiziente Quantenzustandsvorbereitung, wie [GHZ-Zustand](https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.5.030339), [W-Zustand](https://arxiv.org/abs/2403.07604) (weitere Informationen zum W-Zustand finden Sie auch unter [„Zustandsvorbereitung durch flache Schaltungen unter Verwendung von Feedforward“](https://arxiv.org/abs/2307.14840) ) und eine breite Klasse von [Matrixproduktzuständen](https://arxiv.org/abs/2404.16083)\n",
        "* [Effiziente Verschränkung über große Entfernungen](https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.5.030339) zwischen Qubits auf demselben Chip durch Verwendung flacher Schaltungen\n",
        "* Effiziente [Abtastung von IQP-ähnlichen Schaltungen](https://arxiv.org/pdf/2505.04705)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b2953dd4-218e-4daa-a753-0d2aa5e0a0bb",
      "metadata": {},
      "source": [
        "[`QuantumCircuit`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit)Qiskit unterstützt vier Kontrollflusskonstrukte für klassische Feedforward-Netzwerke, die jeweils als Methode auf implementiert sind. Die Konstrukte und die ihnen entsprechenden Methoden lauten wie folgt:\n",
        "\n",
        "* if-Anweisung – [`QuantumCircuit.if_test`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#if_test)\n",
        "* Switch-Anweisung – [`QuantumCircuit.switch`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#switch)\n",
        "* for-Schleife – [`QuantumCircuit.for_loop`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#for_loop)\n",
        "* While-Schleife – [`QuantumCircuit.while_loop`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#while_loop)\n",
        "\n",
        "Jede dieser Methoden gibt einen [Kontextmanager](https://docs.python.org/3/reference/datamodel.html#with-statement-context-managers) zurück und wird in der Regel in einer `with` -Anweisung verwendet. Im weiteren Verlauf dieses Leitfadens werden diese Konstrukte einzeln erläutert und ihre Verwendung erklärt.\n",
        "\n",
        "<Admonition type=\"caution\">\n",
        "  Es gibt einige Einschränkungen bei klassischen Feedforward- und Kontrollflussoperationen auf Quantenhardware, die sich möglicherweise auf Ihr Programm auswirken könnten. Weitere Informationen finden Sie unter „[Dynamische Schaltkreise ausführen](/docs/guides/execute-dynamic-circuits) “.\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"if-statement\" />\n",
        "\n",
        "## `if` Anweisung\n",
        "\n",
        "Die Anweisung `if` wird verwendet, um bedingte Operationen basierend auf dem Wert eines klassischen Bits oder Registers durchzuführen.\n",
        "\n",
        "Im folgenden Beispiel wenden wir ein Hadamard-Gatter auf ein Qubit an und messen es. Wenn das Ergebnis 1 ist, wenden wir ein X-Gatter auf das Qubit an, das es wieder in den Zustand 0 zurückversetzt. Dann messen wir das Qubit erneut. Das Ergebnis der Messung sollte mit 100 %iger Wahrscheinlichkeit 0 sein.\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": [
        "Die Anweisung `with` kann mit einem Zuweisungsziel versehen werden, das selbst ein Kontextmanager ist, der gespeichert und anschließend zur Erstellung eines else-Blocks verwendet werden kann, der immer dann ausgeführt wird, wenn der Inhalt des `if` -Blocks *nicht* ausgeführt wird.\n",
        "\n",
        "Im folgenden Beispiel werden Register mit zwei Qubits und zwei klassischen Bits initialisiert. Wir wenden ein Hadamard-Tor auf das erste Qubit an und messen es. Wenn das Ergebnis 1 ist, wenden wir ein Hadamard-Gatter auf das zweite Qubit an; andernfalls wenden wir ein X-Gatter auf das zweite Qubit an. Schließlich messen wir auch noch das zweite 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": [
        "Neben der Konditionierung auf ein einzelnes klassisches Bit ist auch die Konditionierung auf den Wert eines aus mehreren Bits bestehenden klassischen Registers möglich.\n",
        "\n",
        "Im folgenden Beispiel wenden wir Hadamard-Gatter auf zwei Qubits an und messen sie. Wenn das Ergebnis ist `01`, d. h. das erste Qubit ist 1 und das zweite Qubit ist 0, dann wenden wir ein X-Gatter auf ein drittes Qubit an. Schließlich messen wir das dritte Qubit. Beachten Sie, dass wir aus Gründen der Klarheit beschlossen haben, den Zustand des dritten klassischen Bits, der 0 ist, in der `if` Bedingung anzugeben. In der Schaltplanzeichnung wird die Bedingung durch die Kreise auf den klassischen Bits angezeigt, die konditioniert werden. Ein ausgefüllter Kreis steht für die Konditionierung auf 1, während ein umrandeter Kreis die Konditionierung auf 0 anzeigt.\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",
        "## Switch-Anweisung\n",
        "\n",
        "Die switch-Anweisung dient dazu, Aktionen anhand des Werts eines klassischen Bits oder Registers auszuwählen. Es ähnelt einer if-Anweisung, allerdings können Sie mehr Fälle für die Verzweigungslogik festlegen. Im folgenden Beispiel wird ein Hadamard-Gatter auf ein Qubit angewendet und dessen Zustand gemessen. Ist das Ergebnis 0, wende ein X-Gatter auf das Qubit an; ist das Ergebnis 1, wende ein Z-Gatter an. Das resultierende Messergebnis sollte mit einer Wahrscheinlichkeit von 100 % den Wert 1 ergeben.\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": [
        "Da im obigen Beispiel ein einzelnes klassisches Bit verwendet wurde, gab es nur zwei mögliche Fälle, sodass man das gleiche Ergebnis auch mit einer if-else-Anweisung hätte erzielen können. Der „switch“-Fall ist vor allem dann nützlich, wenn eine Verzweigung anhand des Werts eines klassischen Registers erfolgt, das aus mehreren Bits besteht. Das folgende Beispiel zeigt, wie man einen Standardfall erstellt, der ausgeführt wird, wenn keiner der vorhergehenden Fälle zutrifft. Beachten Sie, dass in einer switch-Anweisung immer nur einer der Blöcke ausgeführt wird. Es gibt keinen Fallthrough.\n",
        "\n",
        "Im folgenden Beispiel werden Hadamard-Gatter auf zwei Qubits angewendet und diese anschließend gemessen. Wenn das Ergebnis entweder 00 oder 11 ist, wende ein Z-Gatter auf das dritte Qubit an. Wenn das Ergebnis 01 ist, wende ein Y-Gatter an. Wenn keiner der vorangegangenen Fälle zutrifft, wende ein X-Gatter an. Messen Sie schließlich das dritte 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",
        "## For-Schleife\n",
        "\n",
        "Eine for-Schleife wird verwendet, um eine Folge klassischer Werte durchzugehen und bei jeder Iteration bestimmte Operationen auszuführen.\n",
        "\n",
        "Im folgenden Beispiel werden mithilfe einer for-Schleife 5 X-Gatter auf ein Qubit angewendet und anschließend dessen Zustand gemessen. Da dabei eine ungerade Anzahl von X-Gattern ausgeführt wird, führt dies insgesamt dazu, dass das Qubit vom 0-Zustand in den 1-Zustand wechselt.\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",
        "## While-Schleife\n",
        "\n",
        "Eine „while“-Schleife wird verwendet, um Anweisungen so lange zu wiederholen, wie eine bestimmte Bedingung erfüllt ist.\n",
        "\n",
        "Im folgenden Beispiel werden Hadamard-Gatter auf zwei Qubits angewendet und diese anschließend gemessen. Anschließend wird eine while-Schleife erstellt, die diesen Vorgang so lange wiederholt, wie das Messergebnis 11 beträgt. Daher sollte das Endergebnis niemals 11 betragen, wobei die übrigen Möglichkeiten mit annähernd gleicher Häufigkeit auftreten.\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",
        "## Klassische Ausdrücke\n",
        "\n",
        "Das Qiskit-Modul [`qiskit.circuit.classical`](/docs/api/qiskit/circuit_classical) für klassische Ausdrücke enthält eine explorative Darstellung der Laufzeitoperationen mit klassischen Werten während der Schaltungsausführung.\n",
        "\n",
        "Das folgende Beispiel zeigt, dass man die Berechnung der Parität nutzen kann, um einen n-Qubit-GHZ-Zustand mit Hilfe dynamischer Schaltungen zu erzeugen. Erzeugen Sie zunächst $n/2$ Bell-Paare auf benachbarten Qubits. Dann kleben Sie diese Paare zusammen, indem Sie eine Schicht von CNOT-Gattern zwischen die Paare legen. Dann misst man das Ziel-Qubit aller vorherigen CNOT-Tore und setzt jedes gemessene Qubit auf den Zustand $\\vert 0 \\rangle$ zurück. Sie wenden $X$ auf jede nicht gemessene Stelle an, bei der die Parität aller vorhergehenden Bits ungerade ist. Schließlich werden CNOT-Gatter auf die gemessenen Qubits angewendet, um die bei der Messung verlorene Verschränkung wiederherzustellen.\n",
        "\n",
        "Bei der Paritätsberechnung beinhaltet das erste Element des konstruierten Ausdrucks die Erhebung des Objekts Python`mr[0]` zu einem [`Value`](/docs/api/qiskit/circuit_classical#value) Knoten (`lift` wird verwendet, um beliebige Objekte in klassische Ausdrücke umzuwandeln). Dies ist für `mr[1]` und das mögliche nachfolgende klassische Register nicht erforderlich, da sie Eingaben für sind `expr.bit_xor` und in diesen Fällen alle erforderlichen Hebevorgänge automatisch durchgeführt werden. Solche Ausdrücke können in Schleifen und anderen Konstrukten aufgebaut werden.\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",
        "Sie können die [`store`](/docs/api/qiskit/circuit#store) Anweisung verwenden, um das Ergebnis eines klassischen Ausdrucks zu speichern, falls dieser Ausdruck wiederholt verwendet wird. Operationen werden automatisch parallelisiert, wodurch Ihr Code zur Laufzeit deutlich effizienter wird.\n",
        "\n",
        "Beispielsweise ist es natürlicher und zur Laufzeit effizienter, „ $B[0] \\oplus B[1] \\oplus B[2] \\ldots$ “ zu schreiben, wobei „ $B = \\neg A$ “ gilt, als „ $(\\neg A[0]) \\oplus (\\neg A[1]) \\oplus (\\neg A[2]) \\ldots$ “. Im ersten Fall wird die Negation in einem einzigen parallelen Schritt vor der XOR-Kette berechnet, anstatt jede Negation nacheinander innerhalb des Ausdrucks auszuwerten.\n",
        "\n",
        "Vollständiges Beispiel:\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",
        "## Nächste Schritte\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Empfehlungen\">\n",
        "  * Erfahren Sie, wie Sie mithilfe von [Stretch](/docs/guides/stretch) eine präzise dynamische Entkopplung implementieren können.\n",
        "  * Nutzen Sie [die Visualisierung von Schaltkreisen,](/docs/guides/qiskit-runtime-circuit-timing) um Ihre dynamischen Schaltkreise zu debuggen und zu optimieren.\n",
        "  * [Dynamische Schaltkreise ausführen](/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
}