{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "72a56be1-db57-4364-acf3-57814453b64e",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"古典的なフィードフォワードと制御フロー（動的回路）\"\n",
        "description: \"古典的なフィードフォワードおよび制御フロー（別名：動的回路）にはQiskitを使用する\"\n",
        "---\n",
        "\n",
        "<span id=\"classical-feedforward-and-control-flow-dynamic-circuits\" />\n",
        "\n",
        "# 古典的なフィードフォワードと制御フロー（動的回路）\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=\"パッケージ・バージョン\">\n",
        "    このページのコードは、以下の要件に基づいて開発された。\n",
        "    これらのバージョンまたは新しいバージョンの使用をお勧めします。\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": [
        "動的回路は、量子回路の実行中に量子ビットを測定し、その結果に基づいて回路内で古典論理演算を実行できる強力なツールである。  このプロセスは*古典的フィードフォワードとも*呼ばれる。 動的回路をどのように活用するのが最善かを理解するのはまだ日が浅いが、量子研究コミュニティはすでに、以下のような多くのユースケースを特定している：\n",
        "\n",
        "* 効率的な量子状態生成（ [GHZ状態](https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.5.030339)、 [W状態](https://arxiv.org/abs/2403.07604) （W状態の詳細については [「フィードフォワードを用いた浅い回路による状態生成」](https://arxiv.org/abs/2307.14840) も参照）、および広範な[行列積状態](https://arxiv.org/abs/2404.16083)など）\n",
        "* 浅い回路を用いた同一チップ上の量子ビット間の[効率的な長距離エンタングルメント](https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.5.030339)\n",
        "* [IQPのような回路の効率的なサンプリング](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 は、従来のフィードフォワード向けに 4 つの制御フロー構文をサポートしており、それぞれが のメソッドとして実装されています。 これらの構造体と、それに対応するメソッドは以下の通りです：\n",
        "\n",
        "* if文 - [`QuantumCircuit.if_test`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#if_test)\n",
        "* switch文 - [`QuantumCircuit.switch`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#switch)\n",
        "* forループ - [`QuantumCircuit.for_loop`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#for_loop)\n",
        "* whileループ - [`QuantumCircuit.while_loop`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#while_loop)\n",
        "\n",
        "`with` これらの各メソッドは[コンテキストマネージャー](https://docs.python.org/3/reference/datamodel.html#with-statement-context-managers) を返し、通常は 文で使用されます。 このガイドの残りの部分では、これらの構文それぞれについて、その詳細と使用方法を解説します。\n",
        "\n",
        "<Admonition type=\"caution\">\n",
        "  量子ハードウェア上で、従来のフィードフォワード演算や制御フロー演算にはいくつかの制限があり、これらがプログラムに影響を与える可能性があります。 詳細については、 [「動的回路の実行」](/docs/guides/execute-dynamic-circuits) を参照してください。\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"if-statement\" />\n",
        "\n",
        "## `if` ステートメント\n",
        "\n",
        "`if` ステートメントは、古典的なビットやレジスタの値に基づいて条件付きで演算を実行するために使用される。\n",
        "\n",
        "以下の例では、量子ビットにハダマードゲートを適用し、それを測定する。 もし結果が1であれば、量子ビットにXゲートを適用し、0状態に反転させる。 その後、再び量子ビットを測定する。 その結果、測定結果は100％の確率で0になるはずである。\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": [
        "`with` 、その代入先を指定することができる。その代入先は、それ自体がコンテキスト・マネージャーであり、 `if` 、そのブロックの内容が実行さ*れない*ときはいつでも実行されるelseブロックを作成するために使用される。\n",
        "\n",
        "以下の例では、2つの量子ビットと2つの古典ビットでレジスタを初期化している。 最初の量子ビットにハダマードゲートを適用し、それを測定する。 もし結果が1であれば、2番目の量子ビットにハダマードゲートを適用し、そうでなければ2番目の量子ビットにXゲートを適用する。 最後に、2番目の量子ビットも測定する。\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": [
        "単一の古典的ビットに対する条件付けに加えて、複数のビットで構成される古典的レジスタの値に対する条件付けも可能である。\n",
        "\n",
        "以下の例では、2つの量子ビットにハダマードゲートを適用し、それらを測定します。 結果が `01`、すなわち最初の量子ビットが1で2番目の量子ビットが0である場合、3番目の量子ビットにXゲートを適用する。 最後に、3番目の量子ビットを測定します。 明確化のため、条件 `if` 式において第三の古典ビットの状態（0）を明示的に指定したことに留意されたい。 回路図において、条件付けの対象となる古典ビット上の丸印によってその状態が示される。 塗りつぶされた円は条件付き1を示し、輪郭線のみの円は条件付き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",
        "## switch ステートメント\n",
        "\n",
        "switch文は、特定のビットやレジスタの値に基づいて処理を選択するために使用されます。 if文と似ていますが、分岐ロジックに対してより多くのケースを指定することができます。 以下の例では、1つの量子ビットにアダマールゲートを適用し、その状態を測定します。 結果が0の場合は、その量子ビットにXゲートを適用し、結果が1の場合はZゲートを適用する。 その結果として得られる測定値は、100％の確率で1となるはずです。\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": [
        "上記の例では単一の古典的なビットを使用していたため、考えられるケースは2つしかなく、if-else文を使っても同じ結果を得ることができたでしょう。 switch文は、主に複数のビットで構成される従来のレジスタの値に基づいて分岐を行う場合に役立ちます。 次の例は、それ以前のケースのいずれも実行されなかった場合に実行されるデフォルトのケースを定義する方法を示しています。 switch文では、いずれかのブロックが1つだけ実行されることに注意してください。 フォールスルーは発生しません。\n",
        "\n",
        "以下の例では、2つの量子ビットにアダマールゲートを適用し、その状態を測定します。 結果が「00」または「11」のいずれかである場合、3番目の量子ビットにZゲートを適用する。 結果が 01 の場合は、Y ゲートを適用する。 前述のいずれのケースにも該当しない場合は、Xゲートを適用する。 最後に、3番目の量子ビットを測定します。\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 ループ\n",
        "\n",
        "forループは、一連の値に対して反復処理を行い、各反復ごとに何らかの操作を実行するために使用されます。\n",
        "\n",
        "次の例では、forループを使用して1つの量子ビットに5つのXゲートを適用し、その後、その量子ビットを測定しています。 奇数のXゲートが実行されるため、全体としてクビットが0状態から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",
        "## while ループ\n",
        "\n",
        "whileループは、ある条件が満たされている間、命令を繰り返すために使用されます。\n",
        "\n",
        "以下の例では、2つの量子ビットにアダマールゲートを適用し、その状態を測定します。 そして、測定結果が11である間、この処理を繰り返すwhileループを作成します。 したがって、最終的な測定値が11になることは決してなく、残りの可能性はほぼ同じ頻度で現れることになる。\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",
        "## 古典的表現\n",
        "\n",
        "Qiskitの古典式モジュール [`qiskit.circuit.classical`](/docs/api/qiskit/circuit_classical) には、回路の実行中に古典値に対して行われる実行時操作の探索的な表現が含まれています。\n",
        "\n",
        "次の例では、パリティの計算を利用して、動的回路を使ってn量子ビットのGHZ状態を作ることができることを示している。 まず、隣接する量子ビットに $n/2$ ベル・ペアを生成する。 次に、ペアとペアの間にCNOTゲートのレイヤーを使って、これらのペアを接着する。 次に、すべての先行するCNOTゲートのターゲット量子ビットを測定し、各測定量子ビットを状態 $\\vert 0 \\rangle$ にリセットする。先行するすべてのビットのパリティが奇数である未測定のすべてのサイトに $X$。 最後に、CNOTゲートが測定された量子ビットに適用され、測定で失われたエンタングルメントが再び確立される。\n",
        "\n",
        "パリティ計算において、構築された式の最初の要素は、 Python`mr[0]` オブジェクトをノードに昇格させることを含む（ `lift`[`Value`](/docs/api/qiskit/circuit_classical#value) は任意のオブジェクトを古典式に変換するために使用される）。 これは、および `mr[1]` それに続く可能性のある古典レジスタには不要である。これらはへの入力であり、必要なリフティングは `expr.bit_xor`これらのケースでは自動的に行われるためである。 このような表現はループやその他の構文で構築できる。\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",
        "その式を繰り返し使用する場合は、この [`store`](/docs/api/qiskit/circuit#store) 命令を使って通常の式の結果を保存することができます。 処理は自動的に並列化されるため、実行時のコードの効率が大幅に向上します。\n",
        "\n",
        "例えば、実行時には、 $(\\neg A[0]) \\oplus (\\neg A[1]) \\oplus (\\neg A[2]) \\ldots$ と書くよりも、 $B[0] \\oplus B[1] \\oplus B[2] \\ldots$ と書く方がより自然で効率的です（ここで、 $B = \\neg A$ ）。前者の場合、式の中で各否定演算を順次評価するのではなく、XORチェーンの前に単一の並列ステップで否定演算を計算します。\n",
        "\n",
        "完全な例：\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",
        "\n",
        "<Admonition type=\"tip\" title=\"推奨事項\">\n",
        "  * [ストレッチ](/docs/guides/stretch)を使用して正確な動的デカップリングを実装する方法を学びましょう。\n",
        "  * [回路スケジュールの可視化機能](/docs/guides/qiskit-runtime-circuit-timing)を活用して、動的回路のデバッグと最適化を行ってください。\n",
        "  * [動的回路を実行する](/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
}