{
  "cells": [
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "f5d21946",
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      },
      "source": [
        "---\n",
        "title: \"反復コード\"\n",
        "description: \"このチュートリアルでは、 IBM 動的回路を用いた基本的な反復コードの構築方法を示します。これは基本的な量子誤り訂正（QEC）の一例です。\"\n",
        "---\n",
        "\n",
        "<span id=\"repetition-codes\" />\n",
        "\n",
        "# 反復コード\n",
        "\n",
        "*使用時間の目安：Heronプロセッサーで1分未満（注：あくまでも目安です。 ランタイムは異なるかもしれない)。*\n",
        "\n",
        "<span id=\"background\" />\n",
        "\n",
        "## 背景\n",
        "\n",
        "リアルタイムの量子エラー訂正（QEC）を可能にするためには、量子プログラムの実行中に量子プログラムの流れを動的に制御し、測定結果に応じて量子ゲートを条件付けできるようにする必要がある。 このチュートリアルでは、QEC の非常に単純な形式である bit-flip コードを実行します。 符号化量子ビットを1回のビット反転エラーから保護できる動的量子回路を実証し、ビット反転符号の性能を評価する。\n",
        "\n",
        "さらにアンシラ量子ビットとエンタングルメントを利用すれば、符号化された量子情報を変換することなく*安定化装置を*測定することができる。 量子スタビライザーコードは、 $k$ 論理量子ビットを $n$ 物理量子ビットにエンコードする。 スタビライザー符号は、パウリ群 $\\Pi^n$ からの支持を得て、離散的な誤り集合を訂正することに重点を置いている。\n",
        "\n",
        "QECに関する詳細については、 [『初心者向け量子エラー訂正』](https://arxiv.org/abs/0905.2794) を参照してください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "88672bd6",
      "metadata": {},
      "source": [
        "<span id=\"requirements\" />\n",
        "\n",
        "## 要件\n",
        "\n",
        "このチュートリアルを始める前に、以下のものがインストールされていることを確認してください：\n",
        "\n",
        "* Qiskit SDK v2.0 またはそれ以降、 [可視化](/docs/api/qiskit/visualization)サポート付き\n",
        "* Qiskit Runtime v0.40 またはそれ以降 (`pip install qiskit-ibm-runtime`)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "14c29e8b",
      "metadata": {},
      "source": [
        "<span id=\"setup\" />\n",
        "\n",
        "## セットアップ\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "1b9fd8ad",
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      },
      "outputs": [],
      "source": [
        "# Qiskit imports\n",
        "from qiskit import (\n",
        "    QuantumCircuit,\n",
        "    QuantumRegister,\n",
        "    ClassicalRegister,\n",
        ")\n",
        "\n",
        "# qiskit-ibm-runtime\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler\n",
        "\n",
        "from qiskit_ibm_runtime.circuit import MidCircuitMeasure\n",
        "\n",
        "service = QiskitRuntimeService()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4d01e8d3",
      "metadata": {},
      "source": [
        "<span id=\"step-1-map-classical-inputs-to-a-quantum-problem\" />\n",
        "\n",
        "## ステップ 1. 古典的な入力を量子問題にマッピングする\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cdee0b18",
      "metadata": {},
      "source": [
        "<span id=\"build-a-bit-flip-stabilizer-circuit\" />\n",
        "\n",
        "### ビット反転安定化回路を構築する\n",
        "\n",
        "ビット反転符号は、スタビライザー符号の最も単純な例である。 これは、符号化量子ビットのいずれかが1つのビット反転（X）エラーから状態を保護する。 $|0\\rangle \\rightarrow |1\\rangle$ $\\epsilon = \\{E_0, E_1, E_2 \\} = \\{IIX, IXI, XII\\}$ と を任意の量子ビットにマップする、ビット反転エラー の作用を考える。このコードには5つの量子ビットが必要です。3つは保護された状態をエンコードするのに使われ、残りの2つはスタビライザー測定アンシラとして使われます。 $|1\\rangle \\rightarrow |0\\rangle$ $X$\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "b588703a",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Choose the least busy backend that supports `measure_2`.\n",
        "\n",
        "backend = service.least_busy(\n",
        "    filters=lambda b: \"measure_2\" in b.supported_instructions,\n",
        "    operational=True,\n",
        "    simulator=False,\n",
        "    dynamic_circuits=True,\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "606dff18",
      "metadata": {},
      "outputs": [],
      "source": [
        "qreg_data = QuantumRegister(3)\n",
        "qreg_measure = QuantumRegister(2)\n",
        "creg_data = ClassicalRegister(3, name=\"data\")\n",
        "creg_syndrome = ClassicalRegister(2, name=\"syndrome\")\n",
        "state_data = qreg_data[0]\n",
        "ancillas_data = qreg_data[1:]\n",
        "\n",
        "\n",
        "def build_qc():\n",
        "    \"\"\"Build a typical error correction circuit\"\"\"\n",
        "    return QuantumCircuit(qreg_data, qreg_measure, creg_data, creg_syndrome)\n",
        "\n",
        "\n",
        "def initialize_qubits(circuit: QuantumCircuit):\n",
        "    \"\"\"Initialize qubit to |1>\"\"\"\n",
        "    circuit.x(qreg_data[0])\n",
        "    circuit.barrier(qreg_data)\n",
        "    return circuit\n",
        "\n",
        "\n",
        "def encode_bit_flip(circuit, state, ancillas) -> QuantumCircuit:\n",
        "    \"\"\"Encode bit-flip. This is done by simply adding a cx\"\"\"\n",
        "    for ancilla in ancillas:\n",
        "        circuit.cx(state, ancilla)\n",
        "    circuit.barrier(state, *ancillas)\n",
        "    return circuit\n",
        "\n",
        "\n",
        "def measure_syndrome_bit(circuit, qreg_data, qreg_measure, creg_measure):\n",
        "    \"\"\"\n",
        "    Measure the syndrome by measuring the parity.\n",
        "    We reset our ancilla qubits after measuring the stabilizer\n",
        "    so we can reuse them for repeated stabilizer measurements.\n",
        "    Because we have already observed the state of the qubit,\n",
        "    we can write the conditional reset protocol directly to\n",
        "    avoid another round of qubit measurement if we used\n",
        "    the `reset` instruction.\n",
        "    \"\"\"\n",
        "    circuit.cx(qreg_data[0], qreg_measure[0])\n",
        "    circuit.cx(qreg_data[1], qreg_measure[0])\n",
        "    circuit.cx(qreg_data[0], qreg_measure[1])\n",
        "    circuit.cx(qreg_data[2], qreg_measure[1])\n",
        "    circuit.barrier(*qreg_data, *qreg_measure)\n",
        "    circuit.append(MidCircuitMeasure(), [qreg_measure[0]], [creg_measure[0]])\n",
        "    circuit.append(MidCircuitMeasure(), [qreg_measure[1]], [creg_measure[1]])\n",
        "\n",
        "    with circuit.if_test((creg_measure[0], 1)):\n",
        "        circuit.x(qreg_measure[0])\n",
        "    with circuit.if_test((creg_measure[1], 1)):\n",
        "        circuit.x(qreg_measure[1])\n",
        "    circuit.barrier(*qreg_data, *qreg_measure)\n",
        "    return circuit\n",
        "\n",
        "\n",
        "def apply_correction_bit(circuit, qreg_data, creg_syndrome):\n",
        "    \"\"\"We can detect where an error occurred and correct our state\"\"\"\n",
        "    with circuit.if_test((creg_syndrome, 3)):\n",
        "        circuit.x(qreg_data[0])\n",
        "    with circuit.if_test((creg_syndrome, 1)):\n",
        "        circuit.x(qreg_data[1])\n",
        "    with circuit.if_test((creg_syndrome, 2)):\n",
        "        circuit.x(qreg_data[2])\n",
        "    circuit.barrier(qreg_data)\n",
        "    return circuit\n",
        "\n",
        "\n",
        "def apply_final_readout(circuit, qreg_data, creg_data):\n",
        "    \"\"\"Read out the final measurements\"\"\"\n",
        "    circuit.barrier(qreg_data)\n",
        "    circuit.measure(qreg_data, creg_data)\n",
        "    return circuit"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "dbe02949",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/repetition-codes/extracted-outputs/dbe02949-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/repetition-codes/extracted-outputs/dbe02949-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "def build_error_correction_sequence(apply_correction: bool) -> QuantumCircuit:\n",
        "    circuit = build_qc()\n",
        "    circuit = initialize_qubits(circuit)\n",
        "    circuit = encode_bit_flip(circuit, state_data, ancillas_data)\n",
        "    circuit = measure_syndrome_bit(\n",
        "        circuit, qreg_data, qreg_measure, creg_syndrome\n",
        "    )\n",
        "\n",
        "    if apply_correction:\n",
        "        circuit = apply_correction_bit(circuit, qreg_data, creg_syndrome)\n",
        "\n",
        "    circuit = apply_final_readout(circuit, qreg_data, creg_data)\n",
        "    return circuit\n",
        "\n",
        "\n",
        "circuit = build_error_correction_sequence(apply_correction=True)\n",
        "circuit.draw(output=\"mpl\", style=\"iqp\", cregbundle=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "609c0c47",
      "metadata": {},
      "source": [
        "<span id=\"step-2-optimize-the-problem-for-quantum-execution\" />\n",
        "\n",
        "## ステップ 2. 量子実行向けに問題を最適化する\n",
        "\n",
        "ジョブの実行時間を短縮するため、 Qiskit primitives は、ターゲットシステムがサポートする命令および接続仕様に準拠した回路およびオブザーバブルのみを受け入れます（これらは命令セットアーキテクチャ（ISA）回路およびオブザーバブルと呼ばれます）。  [トランスパイレーションについて詳しく知る](/docs/guides/transpile)。\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "c8ea2716",
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      },
      "source": [
        "<span id=\"generate-isa-circuits\" />\n",
        "\n",
        "### ISA回路を生成する\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "67b55eef",
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/repetition-codes/extracted-outputs/67b55eef-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/repetition-codes/extracted-outputs/67b55eef-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "isa_circuit = pm.run(circuit)\n",
        "\n",
        "isa_circuit.draw(\"mpl\", style=\"iqp\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "67acea4f",
      "metadata": {},
      "outputs": [],
      "source": [
        "no_correction_circuit = build_error_correction_sequence(\n",
        "    apply_correction=False\n",
        ")\n",
        "\n",
        "isa_no_correction_circuit = pm.run(no_correction_circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bcd61a1f",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute-using-qiskit-primitives\" />\n",
        "\n",
        "## ステップ 3. Qiskit primitives を使用して実行する\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e68d10d2",
      "metadata": {},
      "source": [
        "補正を適用したバージョンと補正なしのバージョンを実行する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "d53319ba",
      "metadata": {},
      "outputs": [],
      "source": [
        "sampler_no_correction = Sampler(backend)\n",
        "job_no_correction = sampler_no_correction.run(\n",
        "    [isa_no_correction_circuit], shots=1000\n",
        ")\n",
        "result_no_correction = job_no_correction.result()[0]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "df7421d0",
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      },
      "outputs": [],
      "source": [
        "sampler_with_correction = Sampler(backend)\n",
        "\n",
        "job_with_correction = sampler_with_correction.run([isa_circuit], shots=1000)\n",
        "result_with_correction = job_with_correction.result()[0]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "1cba37f5",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Data (no correction):\n",
            "{'111': 878, '011': 42, '110': 35, '101': 40, '100': 1, '001': 2, '000': 2}\n",
            "Syndrome (no correction):\n",
            "{'00': 942, '10': 33, '01': 22, '11': 3}\n"
          ]
        }
      ],
      "source": [
        "print(f\"Data (no correction):\\n{result_no_correction.data.data.get_counts()}\")\n",
        "print(\n",
        "    f\"Syndrome (no correction):\\n{result_no_correction.data.syndrome.get_counts()}\"\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "7b7697f2",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Data (corrected):\n",
            "{'111': 889, '110': 25, '000': 11, '011': 45, '101': 17, '010': 10, '001': 2, '100': 1}\n",
            "Syndrome (corrected):\n",
            "{'00': 929, '01': 39, '10': 20, '11': 12}\n"
          ]
        }
      ],
      "source": [
        "print(f\"Data (corrected):\\n{result_with_correction.data.data.get_counts()}\")\n",
        "print(\n",
        "    f\"Syndrome (corrected):\\n{result_with_correction.data.syndrome.get_counts()}\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1b652319",
      "metadata": {},
      "source": [
        "<span id=\"step-4-post-process-return-result-in-classical-format\" />\n",
        "\n",
        "## ステップ 4. 後処理を行い、結果を従来の形式で返す\n",
        "\n",
        "ビット・フリップ・コードによって多くのエラーが検出され、修正された結果、全体的にエラーが少なくなっていることがわかる。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "fa59fb42",
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      },
      "outputs": [],
      "source": [
        "def decode_result(data_counts, syndrome_counts):\n",
        "    shots = sum(data_counts.values())\n",
        "    success_trials = data_counts.get(\"000\", 0) + data_counts.get(\"111\", 0)\n",
        "    failed_trials = shots - success_trials\n",
        "    error_correction_events = shots - syndrome_counts.get(\"00\", 0)\n",
        "    print(\n",
        "        f\"Bit flip errors were detected/corrected on \"\n",
        "        f\"{error_correction_events}/{shots} trials.\"\n",
        "    )\n",
        "    print(\n",
        "        f\"A final parity error was detected on \"\n",
        "        f\"{failed_trials}/{shots} trials.\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "5b1ff3a3",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Completed bit code experiment data measurement counts (no correction): {'111': 878, '011': 42, '110': 35, '101': 40, '100': 1, '001': 2, '000': 2}\n",
            "Completed bit code experiment syndrome measurement counts (no correction): {'00': 942, '10': 33, '01': 22, '11': 3}\n",
            "Bit flip errors were detected/corrected on 58/1000 trials.\n",
            "A final parity error was detected on 120/1000 trials.\n"
          ]
        }
      ],
      "source": [
        "# non-corrected marginalized results\n",
        "data_result = result_no_correction.data.data.get_counts()\n",
        "marginalized_syndrome_result = result_no_correction.data.syndrome.get_counts()\n",
        "\n",
        "print(\n",
        "    f\"Completed bit code experiment data measurement counts (no correction): \"\n",
        "    f\"{data_result}\"\n",
        ")\n",
        "print(\n",
        "    f\"Completed bit code experiment syndrome measurement counts (no correction): \"\n",
        "    f\"{marginalized_syndrome_result}\"\n",
        ")\n",
        "decode_result(data_result, marginalized_syndrome_result)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "7f1c2d48",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Completed bit code experiment data measurement counts (corrected): {'111': 889, '110': 25, '000': 11, '011': 45, '101': 17, '010': 10, '001': 2, '100': 1}\n",
            "Completed bit code experiment syndrome measurement counts (corrected): {'00': 929, '01': 39, '10': 20, '11': 12}\n",
            "Bit flip errors were detected/corrected on 71/1000 trials.\n",
            "A final parity error was detected on 100/1000 trials.\n"
          ]
        }
      ],
      "source": [
        "# corrected marginalized results\n",
        "corrected_data_result = result_with_correction.data.data.get_counts()\n",
        "corrected_syndrome_result = result_with_correction.data.syndrome.get_counts()\n",
        "\n",
        "print(\n",
        "    f\"Completed bit code experiment data measurement counts (corrected): \"\n",
        "    f\"{corrected_data_result}\"\n",
        ")\n",
        "print(\n",
        "    f\"Completed bit code experiment syndrome measurement counts (corrected): \"\n",
        "    f\"{corrected_syndrome_result}\"\n",
        ")\n",
        "decode_result(corrected_data_result, corrected_syndrome_result)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b66026c4",
      "metadata": {},
      "source": [
        "<span id=\"tutorial-survey\" />\n",
        "\n",
        "## チュートリアル調査\n",
        "\n",
        "このチュートリアルに関するご意見・ご感想をお寄せください。 あなたの洞察は、私たちのコンテンツの提供とユーザーエクスペリエンスを向上させるのに役立ちます。\n",
        "\n",
        "[アンケートへのリンク](https://your.feedback.ibm.com/jfe/form/SV_5onAlfA2Y7ac1FA)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "celltoolbar": "Slideshow",
    "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"
    },
    "hours": 1.5,
    "qpuSeconds": 60
  },
  "nbformat": 4,
  "nbformat_minor": 5
}