{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "3a5616bf-6edb-4539-872a-03217649edcb",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"動的デカップリングのためのパス管理機能を構築する\"\n",
        "description: \"Qiskitにおける動的デカップリングのためのパス管理者の作成方法\"\n",
        "---\n",
        "\n",
        "<span id=\"create-a-pass-manager-for-dynamical-decoupling\" />\n",
        "\n",
        "# 動的デカップリングのためのパス管理機能を構築する\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a5662d8c-46f8-40a8-92b5-af63c32d303f",
      "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",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1ed6dc8d-b6f2-43dc-bb40-ceec0f311764",
      "metadata": {},
      "source": [
        "このページでは [`PadDynamicalDecoupling`](/docs/api/qiskit/qiskit.transpiler.passes.PadDynamicalDecoupling) パスを使用して、 *ダイナミック・デカップリングと*呼ばれるエラー抑制技術を回路に追加する方法を示します。\n",
        "\n",
        "ダイナミック・デカップリングは、アイドル量子ビットにパルス・シーケンス（ *ダイナミック・デカップリング・シーケンスとして*知られる）を加えてブロッホ球の周りを反転させることで機能する。 これらのパルスシーケンスは、核磁気共鳴で使用されるリフォーカスパルスに似ている。 詳細については、『 [A Quantum Engineer's Guide to Superconducting Qubits](https://arxiv.org/abs/1904.06560) 』を参照のこと。\n",
        "\n",
        "`PadDynamicalDecoupling` パスはスケジュールされた回路上でのみ動作し、ターゲットの基底ゲートとは限らないゲートを含むため、以下のものが必要となる。 [`ALAPScheduleAnalysis`](/docs/api/qiskit/qiskit.transpiler.passes.ALAPScheduleAnalysis) パスと [`BasisTranslator`](/docs/api/qiskit/qiskit.transpiler.passes.BasisTranslator) パスも必要です。\n",
        "\n",
        "から `target` 情報を取得し `backend` 、操作名をとして保存してください。 `basis_gates` これは、動的デカップリングで使用されるゲートのタイミング情報を追加するために、を修正する必要がある `target` ためです。\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  これらの例では の `FakeSherbrooke``qiskit_ibm_runtime` モックバックエンドを使用していますが、Qiskitと互換性のある実在のバックエンドや模擬バックエンドであれば、どれでも試すことができます。  実際の結果は異なる場合があります。\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "c55c6e3b-4016-4866-b2ec-19793e89d215",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.fake_provider import FakeSherbrooke\n",
        "\n",
        "backend = FakeSherbrooke()\n",
        "\n",
        "target = backend.target\n",
        "basis_gates = list(target.operation_names)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b8dfccd9-30c9-48dc-88bc-50af3256f187",
      "metadata": {},
      "source": [
        "例として `efficient_su2` 。 まず、回路をバックエンドにトランスパイルする。動的デカップリングパルスは、回路がトランスパイルされスケジューリングされた後に追加する必要があるからだ。 ダイナミック・デカップリングは、量子回路にアイドル時間が多い場合、つまり、他の量子ビットがアクティブである間に使われていない量子ビットがある場合に、最もうまく機能することが多い。 この回路では、2量子ビット `ecr` ゲートが順次適用されるため、このようになる。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "9479a60c-d5d0-45c7-a93e-a2a488ba8985",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/dynamical-decoupling-pass-manager/extracted-outputs/9479a60c-d5d0-45c7-a93e-a2a488ba8985-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.circuit.library import efficient_su2\n",
        "\n",
        "qc = efficient_su2(12, entanglement=\"circular\", reps=1)\n",
        "pm = generate_preset_pass_manager(1, target=target, seed_transpiler=12345)\n",
        "qc_t = pm.run(qc)\n",
        "qc_t.draw(\"mpl\", fold=-1, idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d3ab848d-2782-431c-b028-69a46cf94360",
      "metadata": {},
      "source": [
        "ダイナミカル・デカップリング・シーケンスとは、同一性を構成する一連のゲートのことで、時間的に一定の間隔をおいて配置されている。 例えば、4つのゲートからなる XY4 という単純なシーケンスを作ることから始めよう。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "368df772-aee7-4b59-b096-a47e5bc94577",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit.library import XGate, YGate\n",
        "\n",
        "X = XGate()\n",
        "Y = YGate()\n",
        "\n",
        "dd_sequence = [X, Y, X, Y]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d5eafd85-6fea-42ac-8bcb-0abf15635456",
      "metadata": {},
      "source": [
        "動的デカップリングシーケンスの定期的なタイミングのため、は基底ゲート*ではないが*、は `XGate``target` 基底ゲートであるため、に関する情報をに追加しなければならない `YGate` 。 我々は、 `XGate`がと同じ持続時間と誤差 `YGate` を持つことを*事前に*知っている。したがって、それらの特性をから取得 `target` し、オブジェクト `YGate` に追加すればよい。 これもまた、が別々に `basis_gates` 保存された理由である。なぜなら、はの実際の基底ゲートではない `ibm_fez`にもかかわらず、命令 `YGate``target` をに追加しているからである。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "cabac6ca-c845-4c05-8c7d-2940717b3120",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler import InstructionProperties\n",
        "\n",
        "y_gate_properties = {}\n",
        "for qubit in range(target.num_qubits):\n",
        "    y_gate_properties.update(\n",
        "        {\n",
        "            (qubit,): InstructionProperties(\n",
        "                duration=target[\"x\"][(qubit,)].duration,\n",
        "                error=target[\"x\"][(qubit,)].error,\n",
        "            )\n",
        "        }\n",
        "    )\n",
        "\n",
        "target.add_instruction(YGate(), y_gate_properties)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d33f64d6-c4e3-4881-a924-f30dfce35106",
      "metadata": {},
      "source": [
        "`efficient_su2` のようなアンサッツ回路はパラメータ化されているため、バックエンドに送信する前に値をバインドしておく必要がある。 ここで、ランダムなパラメーターを割り当てる。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "788839cc-9378-4c9d-95fd-df0ec6bc2d64",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "\n",
        "rng = np.random.default_rng(1234)\n",
        "qc_t.assign_parameters(\n",
        "    rng.uniform(-np.pi, np.pi, qc_t.num_parameters), inplace=True\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "36d54ded-1786-41c0-9c8a-75f339dbd160",
      "metadata": {},
      "source": [
        "次に、カスタムパスを実行する。 `ALAPScheduleAnalysis` と `PadDynamicalDecoupling` で `PassManager` をインスタンス化する。  `ALAPScheduleAnalysis` を最初に実行し、量子回路のタイミング情報を追加してから、規則的な間隔の動的デカップリングシーケンスを追加する。 これらのパスは `.run()` でサーキットを走る。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "334796e7-fb37-42fa-be54-4135b485246b",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler import PassManager\n",
        "from qiskit.transpiler.passes.scheduling import (\n",
        "    ALAPScheduleAnalysis,\n",
        "    PadDynamicalDecoupling,\n",
        ")\n",
        "\n",
        "dd_pm = PassManager(\n",
        "    [\n",
        "        ALAPScheduleAnalysis(target=target),\n",
        "        PadDynamicalDecoupling(target=target, dd_sequence=dd_sequence),\n",
        "    ]\n",
        ")\n",
        "qc_dd = dd_pm.run(qc_t)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b0f68880-066c-4586-a27c-5d0f90d674f7",
      "metadata": {},
      "source": [
        "可視化ツールを使用して回路のタイミングを確認し、回路内に等間隔に配置 `YGate``XGate` された [`timeline_drawer`](/docs/api/qiskit/qiskit.visualization.timeline_drawer) オブジェクトとオブジェクトのシーケンスが現れることを確認してください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "7a552621-a96f-4bb8-ae9b-4ab5a65bbb64",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/dynamical-decoupling-pass-manager/extracted-outputs/7a552621-a96f-4bb8-ae9b-4ab5a65bbb64-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.visualization import timeline_drawer\n",
        "\n",
        "timeline_drawer(qc_dd, idle_wires=False, target=target)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "836a4094-0e55-4028-9e2e-cdf561d27049",
      "metadata": {},
      "source": [
        "最後に、 `YGate` はバックエンドの実際のベースゲートではないので、 `BasisTranslator` パスを手動で適用する（これはデフォルトのパスだが、スケジューリングの前に実行されるので、再度適用する必要がある）。 セッション等価ライブラリーは、トランスパイラーが回路を基底ゲートに分解できるようにする回路等価のライブラリーであり、引数としても指定される。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "f0f4b29d-1c95-47d2-a7ad-8e130eaff74a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/dynamical-decoupling-pass-manager/extracted-outputs/f0f4b29d-1c95-47d2-a7ad-8e130eaff74a-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.equivalence_library import (\n",
        "    SessionEquivalenceLibrary as sel,\n",
        ")\n",
        "from qiskit.transpiler.passes import BasisTranslator\n",
        "\n",
        "qc_dd = BasisTranslator(sel, basis_gates)(qc_dd)\n",
        "qc_dd.draw(\"mpl\", fold=-1, idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fafca471-0042-41f8-964c-606b4ee0d5cd",
      "metadata": {},
      "source": [
        "現在、回路から `YGate` オブジェクトは排除され、明示的なタイミング情報がゲート `Delay` という形で存在している。 この動的デカップリングを備えたトランスパイル回路は、バックエンドへ送信する準備が整いました。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "95fee5f9-9e7d-47db-83c2-309ca03d357a",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 次のステップ\n",
        "\n",
        "<Admonition type=\"tip\" title=\"推奨事項\">\n",
        "  * 独自のパスを書く代わりに `generate_preset_passmanager` 関数を使う方法を学ぶには、 [Transpilation のデフォルト設定と構成オプションの](defaults-and-configuration-options)トピックから始めてください。\n",
        "  * [トランスパイラ設定の比較](/docs/guides/circuit-transpilation-settings#compare-transpiler-settings)ガイドをお試しください。\n",
        "  * [Transpile API ドキュメント](https://docs.quantum-computing.ibm.com/api/qiskit/transpiler)を参照してください。\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
}