{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "a1b2c3d4",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"ハミルトンシミュレーション回路のコンパイル手法\"\n",
        "description: \"Hamlibのハミルトニアンシミュレーション回路を用いて、SABRE、AIを活用したトランスパイラー、およびRustiqの各コンパイル手法を比較する。\"\n",
        "---\n",
        "\n",
        "<span id=\"compilation-methods-for-hamiltonian-simulation-circuits\" />\n",
        "\n",
        "# ハミルトンシミュレーション回路のコンパイル手法\n",
        "\n",
        "*推定実行時間： IBM のHeronプロセッサで1分未満（注：これはあくまで推定値です。 （実行時間は異なる場合があります。）*\n",
        "\n",
        "{/* cspell:ignore Rustiq, nshuffles, edgecolors, edgecolor, Hamlib, Benchpress, Brugiere, Goubault, Martiel, Dubal, Lishman, Ivrii, fontweight, fontsize, textprops, wedgeprops, startangle, autopct, Hellinger, iloc, ylabel, frameon, ylims, CMHSC */}\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b1c2d3e4",
      "metadata": {},
      "source": [
        "<span id=\"learning-outcomes\" />\n",
        "\n",
        "## 学習成果\n",
        "\n",
        "このチュートリアルを学習すると、以下のことが理解できるようになります：\n",
        "\n",
        "* SABRE を使用してレイアウトおよび配線最適化を行う際の Qiskit トランスパイラーの使い方\n",
        "* AIを活用したトランスパイラーを活用して、高度な回路最適化を行う方法\n",
        "* ハミルトニアンシミュレーション回路における演算を合成 `PauliEvolutionGate` するためのRustiqプラグインの使用方法\n",
        "* 2量子ビットの深さ、総ゲート数、および実行時間を用いて、コンパイル手法のベンチマークと比較を行う方法\n",
        "\n",
        "<span id=\"prerequisites\" />\n",
        "\n",
        "## 前提条件\n",
        "\n",
        "このチュートリアルを進める前に、以下のトピックについて理解しておいていただくことをお勧めします：\n",
        "\n",
        "* [トランスパイレーションの概念](/docs/guides/transpile)\n",
        "* [トランスパイラの各段階](/docs/guides/transpiler-stages)\n",
        "* [パス・マネージャーを使用したトランスパイル](/docs/guides/transpile-with-pass-managers)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c1d2e3f4",
      "metadata": {},
      "source": [
        "<span id=\"background\" />\n",
        "\n",
        "## 背景\n",
        "\n",
        "量子回路のコンパイルとは、高水準の量子アルゴリズムを、対象となるハードウェアの制約を満たす物理回路に変換するプロセスである。 効果的なコンパイルにより、回路の深さとゲート数を大幅に削減することができ、これらはいずれも、近い将来の量子デバイスにおける結果の品質に直接的な影響を与える。\n",
        "\n",
        "`PauliEvolutionGate`このチュートリアルでは、で構築されたハミルトニアンシミュレーション回路について、3つのコンパイル手法のベンチマークを行います。 これらの回路は、量子ビット間のペアごとの相互作用（ $ZZ$、 $XX$、 $YY$ 項など）をモデル化したものであり、量子化学、凝縮系物理学、材料科学の分野で広く用いられている。\n",
        "\n",
        "ベンチマーク回路は、 [Benchpress](https://github.com/Qiskit/benchpress) リポジトリを通じてアクセスできる [Hamlib](https://github.com/SRI-International/QC-App-Oriented-Benchmarks/tree/master/qedcbench/hamlib#hamlib-simulation---benchmark-program) コレクションに収録されています。 Hamlibは、代表的なハミルトニアンの標準化されたセットを提供しており、これにより、現実的なシミュレーションワークロードにおいてコンパイル戦略を比較することが可能になります。\n",
        "\n",
        "<span id=\"compilation-methods-overview\" />\n",
        "\n",
        "### コンパイル方法の概要\n",
        "\n",
        "<span id=\"qiskit-transpiler-with-sabre\" />\n",
        "\n",
        "#### SABRE 搭載の Qiskit トランスパイラー\n",
        "\n",
        "Qiskitのトランスパイラーは、SABRE（SWAPベースの BidiREctional ヒューリスティック探索）アルゴリズムを用いて、回路のレイアウトと配線を最適化します。 SABREは、ハードウェアの接続制約を満たしつつ、SWAPゲートの数を最小限に抑え、回路の深さへの影響を最小限に抑えることに重点を置いています。 これは、パフォーマンスとコンパイル時間のバランスが良好な汎用的な手法です。 詳細については、 [\\[1\\]](https://arxiv.org/abs/2409.08368) を参照のこと。 SABREの利点やパラメータの検討については、別の[チュートリアル](/docs/tutorials/transpilation-optimizations-with-sabre)で詳しく解説しています。\n",
        "\n",
        "<span id=\"ai-powered-transpiler\" />\n",
        "\n",
        "#### AIを活用したトランスパイラー\n",
        "\n",
        "このAI搭載のトランスパイラーは、機械学習を活用して、回路構造やハードウェアの制約条件におけるパターンを分析し、最適なトランスパイリング戦略を予測します。 また、強化学習に基づく合成手法を用いてパウリネットワーク回路を対象とする「pass」を `AIPauliNetworkSynthesis` 適用することも可能です。 詳細については、 [\\[2\\]](https://arxiv.org/abs/2405.13196) および [\\[3\\]](https://arxiv.org/abs/2503.14448) を参照してください。\n",
        "\n",
        "<span id=\"rustiq-plugin\" />\n",
        "\n",
        "#### Rustiq プラグイン\n",
        "\n",
        "Rustiqプラグインは、トロッター化力学で一般的に用いられるパウリ回転を表す演算に特 `PauliEvolutionGate` 化した、高度な合成手法を提供します。 これは、ハミルトニアンシミュレーションのワークロード向けに、低深度の回路分解を生成するように設計されています。 詳細については、 [\\[4\\]](https://arxiv.org/abs/2404.03280) を参照のこと。\n",
        "\n",
        "<span id=\"key-metrics\" />\n",
        "\n",
        "### 主要メトリック\n",
        "\n",
        "以下の評価指標について、3つの手法を比較します：\n",
        "\n",
        "* **2量子ビットの深さ** ：2量子ビットゲートのみをカウントした回路の深さ。 これは、実機での再現精度において、しばしばボトルネックとなります。\n",
        "* **回路サイズ（総ゲート数）** ：トランスパイルされた回路のゲート総数。\n",
        "* **実行時間** ：トランスパイルにかかる実時間。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d1e2f3a4",
      "metadata": {},
      "source": [
        "<span id=\"requirements\" />\n",
        "\n",
        "## 要件\n",
        "\n",
        "このチュートリアルを始める前に、以下のものがインストールされていることを確認してください：\n",
        "\n",
        "* Qiskit SDK v2.0 またはそれ以降のバージョンで、 [可視化](/docs/api/qiskit/visualization)機能をサポートしているもの\n",
        "* Qiskit Runtime v0.22 またはそれ以降 (`pip install qiskit-ibm-runtime`)\n",
        "* Qiskit Aer (`pip install qiskit-aer`)\n",
        "* Qiskit IBM トランスパイラー (`pip install qiskit-ibm-transpiler`)\n",
        "* Qiskit AI Transpiler ローカルモード (`pip install qiskit_ibm_ai_local_transpiler`)\n",
        "* Networkx (`pip install networkx`)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e1f2a3b4",
      "metadata": {},
      "source": [
        "<span id=\"setup\" />\n",
        "\n",
        "## セットアップ\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "f1a2b3c4",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit import QuantumCircuit\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2\n",
        "from qiskit.circuit.library import PauliEvolutionGate\n",
        "from qiskit_ibm_transpiler import generate_ai_pass_manager\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
        "from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig\n",
        "from qiskit_aer import AerSimulator\n",
        "from qiskit_aer.noise import NoiseModel, depolarizing_error\n",
        "from collections import Counter\n",
        "from statistics import mean, stdev\n",
        "from scipy.sparse import SparseEfficiencyWarning\n",
        "import time\n",
        "import warnings\n",
        "import matplotlib.pyplot as plt\n",
        "import matplotlib.ticker as ticker\n",
        "import numpy as np\n",
        "import json\n",
        "import requests\n",
        "import logging\n",
        "\n",
        "# Suppress noisy loggers and warnings\n",
        "logging.getLogger(\n",
        "    \"qiskit_ibm_transpiler.wrappers.ai_local_synthesis\"\n",
        ").setLevel(logging.ERROR)\n",
        "warnings.filterwarnings(\"ignore\", category=FutureWarning)\n",
        "warnings.filterwarnings(\"ignore\", category=SparseEfficiencyWarning)\n",
        "\n",
        "seed = 42  # Seed for reproducibility"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a2b3c4d5",
      "metadata": {},
      "source": [
        "<span id=\"connect-to-a-backend\" />\n",
        "\n",
        "### バックエンドに接続する\n",
        "\n",
        "小規模および大規模の例の両方で使用するバックエンドを選択してください。 バックエンドは、トランスパイラーが対象とする結合マップと基底ゲートを決定します。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "b2c3d4e5",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Using backend: ibm_pittsburgh\n"
          ]
        }
      ],
      "source": [
        "# QiskitRuntimeService.save_account(channel=\"ibm_quantum_platform\",\n",
        "# token=\"<YOUR-API-KEY>\", overwrite=True, set_as_default=True)\n",
        "service = QiskitRuntimeService(channel=\"ibm_quantum_platform\")\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "print(f\"Using backend: {backend.name}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c2d3e4f5",
      "metadata": {},
      "source": [
        "<span id=\"define-pass-managers\" />\n",
        "\n",
        "### パスマネージャーの定義\n",
        "\n",
        "3つのコンパイル方法を設定してください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "d2e3f4a5",
      "metadata": {},
      "outputs": [],
      "source": [
        "# SABRE pass manager (Qiskit default at optimization level 3)\n",
        "pm_sabre = generate_preset_pass_manager(\n",
        "    optimization_level=3, backend=backend, seed_transpiler=seed\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "e2f3a4b5",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "e14d6bb64d3e4a399a645a5437a4a1cb",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "Fetching 127 files:   0%|          | 0/127 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# AI transpiler pass manager (local mode)\n",
        "pm_ai = generate_ai_pass_manager(\n",
        "    backend=backend, optimization_level=3, ai_optimization_level=3\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "f2a3b4c5",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Rustiq pass manager for PauliEvolutionGate synthesis\n",
        "hls_config = HLSConfig(\n",
        "    PauliEvolution=[\n",
        "        (\n",
        "            \"rustiq\",\n",
        "            {\n",
        "                \"nshuffles\": 400,\n",
        "                \"upto_phase\": True,\n",
        "                \"fix_clifford\": True,\n",
        "                \"preserve_order\": False,\n",
        "                \"metric\": \"depth\",\n",
        "            },\n",
        "        )\n",
        "    ]\n",
        ")\n",
        "pm_rustiq = generate_preset_pass_manager(\n",
        "    optimization_level=3,\n",
        "    backend=backend,\n",
        "    hls_config=hls_config,\n",
        "    seed_transpiler=seed,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a3b4c5d6",
      "metadata": {},
      "source": [
        "<span id=\"define-helper-functions\" />\n",
        "\n",
        "### ヘルパー関数を定義する\n",
        "\n",
        "以下の関数は、指定されたパスマネージャーを使用して回路のリストをトランスパイルし、各回路の主要な指標（2量子ビット深度、回路サイズ、実行時間）を記録します。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "b3c4d5e6",
      "metadata": {},
      "outputs": [],
      "source": [
        "def capture_transpilation_metrics(\n",
        "    results, pass_manager, circuits, method_name\n",
        "):\n",
        "    \"\"\"\n",
        "    Transpile circuits and append one metrics record per circuit to\n",
        "    ``results``.\n",
        "\n",
        "    Args:\n",
        "        results (list): List of dicts to append the metrics records to.\n",
        "        pass_manager: Pass manager used for transpilation.\n",
        "        circuits (list): List of quantum circuits to transpile.\n",
        "        method_name (str): Name of the transpilation method.\n",
        "\n",
        "    Returns:\n",
        "        list: List of transpiled circuits.\n",
        "    \"\"\"\n",
        "    transpiled_circuits = []\n",
        "\n",
        "    for i, qc in enumerate(circuits):\n",
        "        start_time = time.time()\n",
        "        transpiled_qc = pass_manager.run(qc)\n",
        "        end_time = time.time()\n",
        "\n",
        "        # Decompose swaps for consistency across methods\n",
        "        transpiled_qc = transpiled_qc.decompose(gates_to_decompose=[\"swap\"])\n",
        "\n",
        "        transpilation_time = end_time - start_time\n",
        "        two_qubit_depth = transpiled_qc.depth(\n",
        "            lambda x: x.operation.num_qubits == 2\n",
        "        )\n",
        "        circuit_size = transpiled_qc.size()\n",
        "\n",
        "        results.append(\n",
        "            {\n",
        "                \"method\": method_name,\n",
        "                \"qc_name\": qc.name,\n",
        "                \"qc_index\": i,\n",
        "                \"num_qubits\": qc.num_qubits,\n",
        "                \"two_qubit_depth\": two_qubit_depth,\n",
        "                \"size\": circuit_size,\n",
        "                \"runtime\": transpilation_time,\n",
        "            }\n",
        "        )\n",
        "        transpiled_circuits.append(transpiled_qc)\n",
        "        print(\n",
        "            f\"[{method_name}] Circuit {i} ({qc.name}): \"\n",
        "            f\"2Q depth={two_qubit_depth}, size={circuit_size}, \"\n",
        "            f\"time={transpilation_time:.2f}s\"\n",
        "        )\n",
        "\n",
        "    return transpiled_circuits"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "summary_table_fn",
      "metadata": {},
      "outputs": [],
      "source": [
        "def _method_order(results):\n",
        "    \"\"\"Return the distinct method names in their first-seen order.\"\"\"\n",
        "    order = []\n",
        "    for r in results:\n",
        "        if r[\"method\"] not in order:\n",
        "            order.append(r[\"method\"])\n",
        "    return order\n",
        "\n",
        "\n",
        "def print_summary_table(results):\n",
        "    \"\"\"\n",
        "    Print the mean and standard deviation of each metric per compilation\n",
        "    method, followed by the mean percent improvement relative to SABRE.\n",
        "    \"\"\"\n",
        "    metrics = [\n",
        "        (\"two_qubit_depth\", \"2Q Depth\"),\n",
        "        (\"size\", \"Gate Count\"),\n",
        "        (\"runtime\", \"Runtime (s)\"),\n",
        "    ]\n",
        "    methods = _method_order(results)\n",
        "    by_method = {m: [r for r in results if r[\"method\"] == m] for m in methods}\n",
        "    sabre_by_index = {r[\"qc_index\"]: r for r in by_method.get(\"SABRE\", [])}\n",
        "\n",
        "    col_w = 22\n",
        "    name_w = max(len(m) for m in methods)\n",
        "    header = f\"{'Method':<{name_w}}\" + \"\".join(\n",
        "        f\"  {label:>{col_w}}\" for _, label in metrics\n",
        "    )\n",
        "\n",
        "    print(\"Mean +/- std per compilation method\")\n",
        "    print(header)\n",
        "    print(\"-\" * len(header))\n",
        "    for method in methods:\n",
        "        cells = []\n",
        "        for key, _ in metrics:\n",
        "            values = [r[key] for r in by_method[method]]\n",
        "            std = stdev(values) if len(values) > 1 else 0.0\n",
        "            cells.append(f\"{mean(values):,.1f} +/- {std:,.1f}\")\n",
        "        print(\n",
        "            f\"{method:<{name_w}}\" + \"\".join(f\"  {c:>{col_w}}\" for c in cells)\n",
        "        )\n",
        "\n",
        "    others = [m for m in methods if m != \"SABRE\"]\n",
        "    if others and sabre_by_index:\n",
        "        print()\n",
        "        print(\"Mean % improvement vs SABRE (positive = better than SABRE)\")\n",
        "        print(header)\n",
        "        print(\"-\" * len(header))\n",
        "        for method in others:\n",
        "            cells = []\n",
        "            for key, _ in metrics:\n",
        "                pct = [\n",
        "                    (sabre_by_index[r[\"qc_index\"]][key] - r[key])\n",
        "                    / sabre_by_index[r[\"qc_index\"]][key]\n",
        "                    * 100\n",
        "                    for r in by_method[method]\n",
        "                    if sabre_by_index.get(r[\"qc_index\"])\n",
        "                    and sabre_by_index[r[\"qc_index\"]][key]\n",
        "                ]\n",
        "                if pct:\n",
        "                    std = stdev(pct) if len(pct) > 1 else 0.0\n",
        "                    cells.append(f\"{mean(pct):+.1f}% +/- {std:.1f}%\")\n",
        "                else:\n",
        "                    cells.append(\"n/a\")\n",
        "            print(\n",
        "                f\"{method:<{name_w}}\"\n",
        "                + \"\".join(f\"  {c:>{col_w}}\" for c in cells)\n",
        "            )"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "per_circuit_table_fn",
      "metadata": {},
      "outputs": [],
      "source": [
        "def print_per_circuit_comparison(results, num_rows=5):\n",
        "    \"\"\"\n",
        "    Print a per-metric comparison of the compilation methods for the\n",
        "    first ``num_rows`` circuits (sorted by qubit count). The best\n",
        "    (lowest) value for each metric is marked with an asterisk.\n",
        "    \"\"\"\n",
        "    metrics = [\n",
        "        (\"two_qubit_depth\", \"2Q Depth\"),\n",
        "        (\"size\", \"Gate Count\"),\n",
        "        (\"runtime\", \"Runtime (s)\"),\n",
        "    ]\n",
        "    methods = _method_order(results)\n",
        "\n",
        "    by_index = {}\n",
        "    for r in results:\n",
        "        by_index.setdefault(r[\"qc_index\"], {})[r[\"method\"]] = r\n",
        "    ordered = sorted(\n",
        "        by_index.items(),\n",
        "        key=lambda kv: (next(iter(kv[1].values()))[\"num_qubits\"], kv[0]),\n",
        "    )[:num_rows]\n",
        "\n",
        "    for key, label in metrics:\n",
        "        print(f\"{label} (first {num_rows} circuits by qubit count); * = best\")\n",
        "        header = f\"{'Idx':>3}  {'Circuit':<16} {'Q':>3}\" + \"\".join(\n",
        "            f\"{m:>9}\" for m in methods\n",
        "        )\n",
        "        print(header)\n",
        "        print(\"-\" * len(header))\n",
        "        for idx, method_map in ordered:\n",
        "            any_record = next(iter(method_map.values()))\n",
        "            present = {\n",
        "                m: method_map[m][key] for m in methods if m in method_map\n",
        "            }\n",
        "            best = min(present.values())\n",
        "            line = (\n",
        "                f\"{idx:>3}  {any_record['qc_name'][:16]:<16} \"\n",
        "                f\"{any_record['num_qubits']:>3}\"\n",
        "            )\n",
        "            for m in methods:\n",
        "                value = method_map[m][key]\n",
        "                text = f\"{value:.2f}\" if key == \"runtime\" else f\"{int(value)}\"\n",
        "                if value == best:\n",
        "                    text += \"*\"\n",
        "                line += f\"{text:>9}\"\n",
        "            print(line)\n",
        "        print()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c3d4e5f6",
      "metadata": {},
      "source": [
        "<span id=\"load-hamiltonian-circuits-from-hamlib\" />\n",
        "\n",
        "### Hamlib からハミルトニアン回路を読み込む\n",
        "\n",
        "Benchpressリポジトリから代表的なハミルトニアンのセットを読み込み、回路を構築 `PauliEvolutionGate` する。 バックエンドの量子ビット数を超える回路は、また、分解後のサイズが1,500ゲートを超える回路も（トランスパイレーション時間を妥当な範囲に抑えるため）、削除されます。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "d3e4f5a6",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Total Hamiltonian circuits loaded: 42\n",
            "Qubit range: 2 to 112\n"
          ]
        }
      ],
      "source": [
        "# Obtain the Hamiltonian JSON from the benchpress repository\n",
        "url = (\n",
        "    \"https://raw.githubusercontent.com/Qiskit/benchpress/\"\n",
        "    \"e7b29ef7be4cc0d70237b8fdc03edbd698908eff/\"\n",
        "    \"benchpress/hamiltonian/hamlib/100_representative.json\"\n",
        ")\n",
        "response = requests.get(url)\n",
        "response.raise_for_status()\n",
        "ham_records = json.loads(response.text)\n",
        "\n",
        "# Remove circuits that are too large for the backend\n",
        "ham_records = [\n",
        "    h for h in ham_records if h[\"ham_qubits\"] <= backend.num_qubits\n",
        "]\n",
        "\n",
        "# Build PauliEvolutionGate circuits\n",
        "qc_ham_list = []\n",
        "for h in ham_records:\n",
        "    terms = h[\"ham_hamlib_hamiltonian_terms\"]\n",
        "    coeff = h[\"ham_hamlib_hamiltonian_coefficients\"]\n",
        "    num_qubits = h[\"ham_qubits\"]\n",
        "    name = h[\"ham_problem\"]\n",
        "\n",
        "    evo_gate = PauliEvolutionGate(SparsePauliOp(terms, coeff))\n",
        "    qc = QuantumCircuit(num_qubits)\n",
        "    qc.name = name\n",
        "    qc.append(evo_gate, range(num_qubits))\n",
        "    qc_ham_list.append(qc)\n",
        "\n",
        "# Remove circuits whose decomposed size exceeds 1500 gates so that\n",
        "# transpilation completes in a reasonable time frame\n",
        "qc_ham_list = [qc for qc in qc_ham_list if qc.decompose().size() <= 1500]\n",
        "\n",
        "print(f\"Total Hamiltonian circuits loaded: {len(qc_ham_list)}\")\n",
        "min_qubits = min(qc.num_qubits for qc in qc_ham_list)\n",
        "max_qubits = max(qc.num_qubits for qc in qc_ham_list)\n",
        "print(f\"Qubit range: {min_qubits} to {max_qubits}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e3f4a5b6",
      "metadata": {},
      "source": [
        "回路を、小規模（20キュービット未満）と大規模（20キュービット以上）のグループに分類する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "f3a4b5c6",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Small-scale circuits (<20 qubits): 20\n",
            "Large-scale circuits (>=20 qubits): 22\n"
          ]
        }
      ],
      "source": [
        "qc_small = [qc for qc in qc_ham_list if qc.num_qubits < 20]\n",
        "qc_large = [qc for qc in qc_ham_list if qc.num_qubits >= 20]\n",
        "\n",
        "print(f\"Small-scale circuits (<20 qubits): {len(qc_small)}\")\n",
        "print(f\"Large-scale circuits (>=20 qubits): {len(qc_large)}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a4b5c6d7",
      "metadata": {},
      "source": [
        "トランスパイレーションを行う前に、小規模なハミルトニアン回路の1つをプレビューします。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "b4c5d6e7",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/compilation-methods-for-hamiltonian-simulation-circuits/extracted-outputs/b4c5d6e7-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 11,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# We decompose the circuit here, otherwise it would just be a PauliEvolutionGate box,\n",
        "# which isn't very informative to look at!\n",
        "qc_small[0].decompose().draw(\"mpl\", fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "sec-small-scale",
      "metadata": {},
      "source": [
        "<span id=\"small-scale-example\" />\n",
        "\n",
        "## 小規模な例\n",
        "\n",
        "このセクションでは、20キュービット未満のハミルトニアン回路を用いて、3つのコンパイル手法のベンチマーク評価を行う。 これらの回路は素早くトランスパイルされ、中程度の複雑さの回路に対して各メソッドがどのように処理を行うかを明確に把握することができます。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c4d5e6f7",
      "metadata": {},
      "source": [
        "<span id=\"step-1-map-classical-inputs-to-a-quantum-problem\" />\n",
        "\n",
        "### ステップ1：古典的な入力を量子問題にマッピングする\n",
        "\n",
        "`PauliEvolutionGate` 各ハミルトニアンは回路として表現される。 これらの回路は、Hamlibベンチマークデータを用いて、セットアップセクションですでに構築されていました。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d4e5f6a7",
      "metadata": {},
      "source": [
        "<span id=\"step-2-optimize-problem-for-quantum-hardware-execution\" />\n",
        "\n",
        "### ステップ2：量子ハードウェア実行に向けた問題の最適化\n",
        "\n",
        "3つのパスマネージャーそれぞれを使用して、小規模な回路をすべてトランスパイルし、その後、メトリクスを収集します。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "e4f5a6b7",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[SABRE] Circuit 0 (all-vib-bh): 2Q depth=3, size=30, time=2.09s\n",
            "[SABRE] Circuit 1 (all-vib-c2h): 2Q depth=18, size=111, time=0.01s\n",
            "[SABRE] Circuit 2 (all-vib-o3): 2Q depth=6, size=58, time=0.00s\n",
            "[SABRE] Circuit 3 (all-vib-c2h): 2Q depth=2, size=37, time=0.01s\n",
            "[SABRE] Circuit 4 (graph-gnp_k-2): 2Q depth=24, size=126, time=0.01s\n",
            "[SABRE] Circuit 5 (LiH): 2Q depth=66, size=285, time=0.01s\n",
            "[SABRE] Circuit 6 (all-vib-fccf): 2Q depth=66, size=339, time=0.01s\n",
            "[SABRE] Circuit 7 (all-vib-ch2): 2Q depth=88, size=413, time=0.01s\n",
            "[SABRE] Circuit 8 (all-vib-f2): 2Q depth=180, size=1000, time=0.02s\n",
            "[SABRE] Circuit 9 (all-vib-bhf2): 2Q depth=18, size=223, time=0.03s\n",
            "[SABRE] Circuit 10 (graph-gnp_k-4): 2Q depth=122, size=675, time=0.02s\n",
            "[SABRE] Circuit 11 (Be2): 2Q depth=343, size=1628, time=0.03s\n",
            "[SABRE] Circuit 12 (all-vib-fccf): 2Q depth=14, size=134, time=0.00s\n",
            "[SABRE] Circuit 13 (uf20-ham): 2Q depth=50, size=341, time=0.01s\n",
            "[SABRE] Circuit 14 (TSP_Ncity-4): 2Q depth=118, size=615, time=0.01s\n",
            "[SABRE] Circuit 15 (graph-complete_bipart): 2Q depth=232, size=1420, time=0.03s\n",
            "[SABRE] Circuit 16 (all-vib-cyclo_propene): 2Q depth=18, size=354, time=0.93s\n",
            "[SABRE] Circuit 17 (all-vib-hno): 2Q depth=6, size=174, time=0.14s\n",
            "[SABRE] Circuit 18 (all-vib-fccf): 2Q depth=30, size=286, time=0.01s\n",
            "[SABRE] Circuit 19 (tfim): 2Q depth=31, size=232, time=0.03s\n",
            "[AI] Circuit 0 (all-vib-bh): 2Q depth=3, size=30, time=0.01s\n"
          ]
        },
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "cf50b939bf4141bcbc610275a514d6fd",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "Fetching 4 files:   0%|          | 0/4 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[AI] Circuit 1 (all-vib-c2h): 2Q depth=18, size=101, time=0.18s\n",
            "[AI] Circuit 2 (all-vib-o3): 2Q depth=6, size=58, time=0.01s\n",
            "[AI] Circuit 3 (all-vib-c2h): 2Q depth=2, size=37, time=0.01s\n",
            "[AI] Circuit 4 (graph-gnp_k-2): 2Q depth=24, size=133, time=0.07s\n",
            "[AI] Circuit 5 (LiH): 2Q depth=62, size=267, time=8.00s\n",
            "[AI] Circuit 6 (all-vib-fccf): 2Q depth=65, size=300, time=0.18s\n",
            "[AI] Circuit 7 (all-vib-ch2): 2Q depth=79, size=353, time=0.16s\n",
            "[AI] Circuit 8 (all-vib-f2): 2Q depth=176, size=998, time=0.43s\n",
            "[AI] Circuit 9 (all-vib-bhf2): 2Q depth=18, size=194, time=0.11s\n",
            "[AI] Circuit 10 (graph-gnp_k-4): 2Q depth=114, size=668, time=0.18s\n",
            "[AI] Circuit 11 (Be2): 2Q depth=292, size=1382, time=0.88s\n",
            "[AI] Circuit 12 (all-vib-fccf): 2Q depth=14, size=134, time=0.01s\n",
            "[AI] Circuit 13 (uf20-ham): 2Q depth=40, size=330, time=0.16s\n",
            "[AI] Circuit 14 (TSP_Ncity-4): 2Q depth=96, size=600, time=0.29s\n",
            "[AI] Circuit 15 (graph-complete_bipart): 2Q depth=231, size=1531, time=0.46s\n",
            "[AI] Circuit 16 (all-vib-cyclo_propene): 2Q depth=18, size=309, time=0.25s\n",
            "[AI] Circuit 17 (all-vib-hno): 2Q depth=10, size=198, time=0.15s\n",
            "[AI] Circuit 18 (all-vib-fccf): 2Q depth=34, size=402, time=0.02s\n",
            "[AI] Circuit 19 (tfim): 2Q depth=44, size=311, time=0.15s\n",
            "[Rustiq] Circuit 0 (all-vib-bh): 2Q depth=3, size=30, time=0.01s\n",
            "[Rustiq] Circuit 1 (all-vib-c2h): 2Q depth=13, size=69, time=0.00s\n",
            "[Rustiq] Circuit 2 (all-vib-o3): 2Q depth=13, size=82, time=0.01s\n",
            "[Rustiq] Circuit 3 (all-vib-c2h): 2Q depth=2, size=40, time=0.01s\n",
            "[Rustiq] Circuit 4 (graph-gnp_k-2): 2Q depth=31, size=132, time=0.01s\n",
            "[Rustiq] Circuit 5 (LiH): 2Q depth=59, size=285, time=0.01s\n",
            "[Rustiq] Circuit 6 (all-vib-fccf): 2Q depth=34, size=193, time=0.00s\n",
            "[Rustiq] Circuit 7 (all-vib-ch2): 2Q depth=49, size=302, time=0.01s\n",
            "[Rustiq] Circuit 8 (all-vib-f2): 2Q depth=141, size=807, time=0.02s\n",
            "[Rustiq] Circuit 9 (all-vib-bhf2): 2Q depth=13, size=146, time=0.02s\n",
            "[Rustiq] Circuit 10 (graph-gnp_k-4): 2Q depth=129, size=683, time=0.02s\n",
            "[Rustiq] Circuit 11 (Be2): 2Q depth=220, size=1101, time=0.02s\n",
            "[Rustiq] Circuit 12 (all-vib-fccf): 2Q depth=53, size=333, time=0.01s\n",
            "[Rustiq] Circuit 13 (uf20-ham): 2Q depth=63, size=425, time=0.01s\n",
            "[Rustiq] Circuit 14 (TSP_Ncity-4): 2Q depth=123, size=767, time=0.02s\n",
            "[Rustiq] Circuit 15 (graph-complete_bipart): 2Q depth=309, size=2107, time=0.05s\n",
            "[Rustiq] Circuit 16 (all-vib-cyclo_propene): 2Q depth=16, size=283, time=0.32s\n",
            "[Rustiq] Circuit 17 (all-vib-hno): 2Q depth=19, size=291, time=0.32s\n",
            "[Rustiq] Circuit 18 (all-vib-fccf): 2Q depth=44, size=546, time=0.02s\n",
            "[Rustiq] Circuit 19 (tfim): 2Q depth=24, size=416, time=0.01s\n"
          ]
        }
      ],
      "source": [
        "results_small = []\n",
        "\n",
        "tqc_sabre_small = capture_transpilation_metrics(\n",
        "    results_small, pm_sabre, qc_small, \"SABRE\"\n",
        ")\n",
        "tqc_ai_small = capture_transpilation_metrics(\n",
        "    results_small, pm_ai, qc_small, \"AI\"\n",
        ")\n",
        "tqc_rustiq_small = capture_transpilation_metrics(\n",
        "    results_small, pm_rustiq, qc_small, \"Rustiq\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f4a5b6c7",
      "metadata": {},
      "source": [
        "以下の表は、すべて的小規模回路における各指標の平均値と標準偏差、およびSABREに対する改善率をまとめたものです。 回路の規模には大きなばらつきがあるため、標準偏差は平均値を解釈する上で重要な手がかりとなる。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "a5b6c7d8",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Mean +/- std per compilation method\n",
            "Method                2Q Depth              Gate Count             Runtime (s)\n",
            "------------------------------------------------------------------------------\n",
            "SABRE            71.8 +/- 89.6         424.1 +/- 446.0             0.2 +/- 0.5\n",
            "AI               67.3 +/- 80.2         416.8 +/- 426.7             0.6 +/- 1.8\n",
            "Rustiq           67.9 +/- 80.0         451.9 +/- 484.7             0.0 +/- 0.1\n",
            "\n",
            "Mean % improvement vs SABRE (positive = better than SABRE)\n",
            "Method                2Q Depth              Gate Count             Runtime (s)\n",
            "------------------------------------------------------------------------------\n",
            "AI             -2.1% +/- 19.8%         -0.6% +/- 14.7%   -5635.1% +/- 20725.2%\n",
            "Rustiq        -25.3% +/- 85.4%        -16.3% +/- 50.4%         -7.0% +/- 60.6%\n"
          ]
        }
      ],
      "source": [
        "print_summary_table(results_small)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "per_circuit_small_md",
      "metadata": {},
      "source": [
        "「回路別」の表は、個々の回路において各手法がどのように比較されるかを示しています。 各指標において最も優れた値には、アスタリスクが付いています。 最も単純な回路の場合、これら3つの手法はいずれも同じ結果に収束することが多いことに注意してください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "per_circuit_small_code",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "2Q Depth (first 8 circuits by qubit count); * = best\n",
            "Idx  Circuit            Q    SABRE       AI   Rustiq\n",
            "----------------------------------------------------\n",
            "  0  all-vib-bh         2       3*       3*       3*\n",
            "  1  all-vib-c2h        3       18       18      13*\n",
            "  2  all-vib-o3         4       6*       6*       13\n",
            "  3  all-vib-c2h        4       2*       2*       2*\n",
            "  4  graph-gnp_k-2      4      24*      24*       31\n",
            "  5  LiH                4       66       62      59*\n",
            "  6  all-vib-fccf       4       66       65      34*\n",
            "  7  all-vib-ch2        4       88       79      49*\n",
            "\n",
            "Gate Count (first 8 circuits by qubit count); * = best\n",
            "Idx  Circuit            Q    SABRE       AI   Rustiq\n",
            "----------------------------------------------------\n",
            "  0  all-vib-bh         2      30*      30*      30*\n",
            "  1  all-vib-c2h        3      111      101      69*\n",
            "  2  all-vib-o3         4      58*      58*       82\n",
            "  3  all-vib-c2h        4      37*      37*       40\n",
            "  4  graph-gnp_k-2      4     126*      133      132\n",
            "  5  LiH                4      285     267*      285\n",
            "  6  all-vib-fccf       4      339      300     193*\n",
            "  7  all-vib-ch2        4      413      353     302*\n",
            "\n",
            "Runtime (s) (first 8 circuits by qubit count); * = best\n",
            "Idx  Circuit            Q    SABRE       AI   Rustiq\n",
            "----------------------------------------------------\n",
            "  0  all-vib-bh         2     2.09     0.01    0.01*\n",
            "  1  all-vib-c2h        3     0.01     0.18    0.00*\n",
            "  2  all-vib-o3         4    0.00*     0.01     0.01\n",
            "  3  all-vib-c2h        4     0.01     0.01    0.01*\n",
            "  4  graph-gnp_k-2      4    0.01*     0.07     0.01\n",
            "  5  LiH                4    0.01*     8.00     0.01\n",
            "  6  all-vib-fccf       4     0.01     0.18    0.00*\n",
            "  7  all-vib-ch2        4     0.01     0.16    0.01*\n",
            "\n"
          ]
        }
      ],
      "source": [
        "print_per_circuit_comparison(results_small, num_rows=8)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b5c6d7e8",
      "metadata": {},
      "source": [
        "<span id=\"visualize-results\" />\n",
        "\n",
        "#### 結果の可視化\n",
        "\n",
        "以下のグラフは、各指標について、3つの手法を回路ごとに比較したものです。 複数の回路が同じクビット数を共有する場合があるため、回路はクビット数順に並べられ、x軸上のインデックスでラベル付けされています。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "c5d6e7f8",
      "metadata": {},
      "outputs": [],
      "source": [
        "def plot_transpilation_comparison(results, title_prefix):\n",
        "    \"\"\"\n",
        "    Create a three-panel figure comparing compilation methods on\n",
        "    two-qubit depth, circuit size, and runtime.\n",
        "\n",
        "    Circuits are sorted by qubit count and plotted by circuit index.\n",
        "    \"\"\"\n",
        "    methods = _method_order(results)\n",
        "    palette = {\"SABRE\": \"#1f77b4\", \"AI\": \"#ff7f0e\", \"Rustiq\": \"#2ca02c\"}\n",
        "    markers = {\"SABRE\": \"o\", \"AI\": \"^\", \"Rustiq\": \"s\"}\n",
        "\n",
        "    # Order circuits by qubit count (then index) and map to plot positions\n",
        "    ref = sorted(\n",
        "        [r for r in results if r[\"method\"] == methods[0]],\n",
        "        key=lambda r: (r[\"num_qubits\"], r[\"qc_index\"]),\n",
        "    )\n",
        "    pos_map = {r[\"qc_index\"]: pos for pos, r in enumerate(ref)}\n",
        "    tick_positions = [pos_map[r[\"qc_index\"]] for r in ref]\n",
        "    tick_labels = [\n",
        "        f\"{pos_map[r['qc_index']]} ({r['num_qubits']}q)\" for r in ref\n",
        "    ]\n",
        "\n",
        "    metrics = [\n",
        "        (\"two_qubit_depth\", \"Two-Qubit Depth\"),\n",
        "        (\"size\", \"Total Gate Count (Circuit Size)\"),\n",
        "        (\"runtime\", \"Transpilation Runtime (s)\"),\n",
        "    ]\n",
        "\n",
        "    fig, axes = plt.subplots(1, 3, figsize=(20, 5.5))\n",
        "    fig.suptitle(title_prefix, fontsize=15, fontweight=\"bold\", y=1.02)\n",
        "\n",
        "    for ax, (metric, ylabel) in zip(axes, metrics):\n",
        "        for method in methods:\n",
        "            subset = sorted(\n",
        "                [r for r in results if r[\"method\"] == method],\n",
        "                key=lambda r: pos_map[r[\"qc_index\"]],\n",
        "            )\n",
        "            ax.plot(\n",
        "                [pos_map[r[\"qc_index\"]] for r in subset],\n",
        "                [r[metric] for r in subset],\n",
        "                marker=markers.get(method, \"o\"),\n",
        "                label=method,\n",
        "                color=palette.get(method, None),\n",
        "                linewidth=1.5,\n",
        "                markersize=6,\n",
        "                alpha=0.85,\n",
        "            )\n",
        "        ax.set_xlabel(\"Circuit Index (num qubits)\", fontsize=11)\n",
        "        ax.set_ylabel(ylabel, fontsize=11)\n",
        "        ax.legend(frameon=True, fontsize=9)\n",
        "        ax.grid(True, linestyle=\"--\", alpha=0.4)\n",
        "        step = max(1, len(tick_positions) // 15)\n",
        "        ax.set_xticks(tick_positions[::step])\n",
        "        ax.set_xticklabels(\n",
        "            [tick_labels[i] for i in range(0, len(tick_labels), step)],\n",
        "            fontsize=7,\n",
        "            rotation=45,\n",
        "            ha=\"right\",\n",
        "        )\n",
        "\n",
        "    plt.tight_layout()\n",
        "    plt.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "pct_improvement_plot_fn",
      "metadata": {},
      "outputs": [],
      "source": [
        "def plot_pct_improvement_vs_sabre(results, title_prefix):\n",
        "    \"\"\"\n",
        "    Plot the per-circuit percent improvement of each non-SABRE method\n",
        "    relative to SABRE, for each metric. A positive value means the\n",
        "    method improved on SABRE; negative means SABRE was better.\n",
        "    \"\"\"\n",
        "    metrics = [\n",
        "        (\"two_qubit_depth\", \"2Q Depth\"),\n",
        "        (\"size\", \"Gate Count\"),\n",
        "        (\"runtime\", \"Runtime\"),\n",
        "    ]\n",
        "    palette = {\"AI\": \"#ff7f0e\", \"Rustiq\": \"#2ca02c\"}\n",
        "    markers = {\"AI\": \"^\", \"Rustiq\": \"s\"}\n",
        "\n",
        "    methods = _method_order(results)\n",
        "    sabre = sorted(\n",
        "        [r for r in results if r[\"method\"] == \"SABRE\"],\n",
        "        key=lambda r: (r[\"num_qubits\"], r[\"qc_index\"]),\n",
        "    )\n",
        "    other_methods = [m for m in methods if m != \"SABRE\"]\n",
        "\n",
        "    tick_positions = list(range(len(sabre)))\n",
        "    tick_labels = [\n",
        "        f\"{i} ({sabre[i]['num_qubits']}q)\" for i in range(len(sabre))\n",
        "    ]\n",
        "\n",
        "    fig, axes = plt.subplots(1, 3, figsize=(20, 5.5))\n",
        "    fig.suptitle(\n",
        "        f\"{title_prefix}: % Improvement over SABRE\",\n",
        "        fontsize=15,\n",
        "        fontweight=\"bold\",\n",
        "        y=1.02,\n",
        "    )\n",
        "\n",
        "    for ax, (metric, label) in zip(axes, metrics):\n",
        "        ax.axhline(0, color=\"#1f77b4\", linewidth=2, label=\"SABRE (baseline)\")\n",
        "        for method in other_methods:\n",
        "            data = sorted(\n",
        "                [r for r in results if r[\"method\"] == method],\n",
        "                key=lambda r: (r[\"num_qubits\"], r[\"qc_index\"]),\n",
        "            )\n",
        "            pct = [\n",
        "                (sabre[i][metric] - data[i][metric]) / sabre[i][metric] * 100\n",
        "                for i in range(len(sabre))\n",
        "            ]\n",
        "            ax.plot(\n",
        "                tick_positions,\n",
        "                pct,\n",
        "                marker=markers.get(method, \"o\"),\n",
        "                label=method,\n",
        "                color=palette.get(method, None),\n",
        "                linewidth=1.5,\n",
        "                markersize=6,\n",
        "                alpha=0.85,\n",
        "            )\n",
        "        ax.set_xlabel(\"Circuit Index (num qubits)\", fontsize=11)\n",
        "        ax.set_ylabel(f\"% Improvement ({label})\", fontsize=11)\n",
        "        ax.legend(frameon=True, fontsize=9)\n",
        "        ax.grid(True, linestyle=\"--\", alpha=0.4)\n",
        "        step = max(1, len(tick_positions) // 15)\n",
        "        ax.set_xticks(tick_positions[::step])\n",
        "        ax.set_xticklabels(\n",
        "            [tick_labels[i] for i in range(0, len(tick_labels), step)],\n",
        "            fontsize=7,\n",
        "            rotation=45,\n",
        "            ha=\"right\",\n",
        "        )\n",
        "        ylims = ax.get_ylim()\n",
        "        ax.axhspan(0, max(ylims[1], 1), alpha=0.04, color=\"green\")\n",
        "        ax.axhspan(min(ylims[0], -1), 0, alpha=0.04, color=\"red\")\n",
        "\n",
        "    plt.tight_layout()\n",
        "    plt.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "d5e6f7a8",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/compilation-methods-for-hamiltonian-simulation-circuits/extracted-outputs/d5e6f7a8-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plot_transpilation_comparison(\n",
        "    results_small,\n",
        "    \"Small-Scale Hamiltonian Circuits: Compilation Comparison\",\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "id": "pct_improvement_small",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/compilation-methods-for-hamiltonian-simulation-circuits/extracted-outputs/pct_improvement_small-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plot_pct_improvement_vs_sabre(\n",
        "    results_small,\n",
        "    \"Small-Scale Hamiltonian Circuits\",\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d2a29d04",
      "metadata": {},
      "source": [
        "この規模では、3つのパス管理ツールはいずれも良好なパフォーマンスを示しており、その平均的な結果も互いに近いものとなっています。 これは主に、回路が小規模であるため、さらなる最適化の余地が限られていることから、各手法が類似した解に収束する傾向があるためである。\n",
        "\n",
        "この例では、Rustiqの結果が最もばらつきが大きく、2量子ビットの深度とゲート数の両方で最大の外れ値が見られます。 このばらつきにより、Rustiqが他の2つの手法に遅れをとることがある一方で、時折、それらよりも優れた解を見出すこともある。 このAIトランスパイラーは、SABREやRustiqと比較して結果の安定性が高く、ほとんどの回路において外れ値がほとんど見られず、それらにほぼ追随しています。\n",
        "\n",
        "実行速度に関しては、SABREとRustiqはいずれも高速ですが、AIを活用したトランスパイラは特定の回路において明らかに遅くなります。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e5f6a7b8",
      "metadata": {},
      "source": [
        "<span id=\"best-performing-method-by-metric\" />\n",
        "\n",
        "#### 各指標における最も優れた手法\n",
        "\n",
        "以下のグラフは、各指標について、各手法が最良（最低）の値を達成した頻度を示しています。 同値となる場合がある：より単純な回路の場合、複数の手法が同じ最適な2量子ビットの深さまたはゲート数に到達することがある。 同点となった場合、同点となったすべてのメソッドが評価対象となるため、特定の指標における割合の合計が100%を超えることがあります。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "id": "f5a6b7c8",
      "metadata": {},
      "outputs": [],
      "source": [
        "def plot_best_method_bars(results, metrics_list=None):\n",
        "    \"\"\"\n",
        "    Plot a grouped bar chart showing the percentage of circuits\n",
        "    where each method achieved the best (lowest) value for each metric.\n",
        "\n",
        "    Ties are counted for all tied methods, so percentages per metric\n",
        "    can sum to more than 100%.\n",
        "    \"\"\"\n",
        "    if metrics_list is None:\n",
        "        metrics_list = [\"two_qubit_depth\", \"size\", \"runtime\"]\n",
        "\n",
        "    labels = {\n",
        "        \"two_qubit_depth\": \"2Q Depth\",\n",
        "        \"size\": \"Gate Count\",\n",
        "        \"runtime\": \"Runtime\",\n",
        "    }\n",
        "    methods = _method_order(results)\n",
        "    palette = {\"SABRE\": \"#1f77b4\", \"AI\": \"#ff7f0e\", \"Rustiq\": \"#2ca02c\"}\n",
        "\n",
        "    by_index = {}\n",
        "    for r in results:\n",
        "        by_index.setdefault(r[\"qc_index\"], []).append(r)\n",
        "    n_circuits = len(by_index)\n",
        "\n",
        "    win_data = {m: [] for m in methods}\n",
        "    tie_counts = []\n",
        "    metric_labels = []\n",
        "\n",
        "    for metric in metrics_list:\n",
        "        metric_labels.append(\n",
        "            labels.get(metric, metric.replace(\"_\", \" \").title())\n",
        "        )\n",
        "        counts = Counter()\n",
        "        ties = 0\n",
        "        for group in by_index.values():\n",
        "            min_val = min(r[metric] for r in group)\n",
        "            best = [r[\"method\"] for r in group if r[metric] == min_val]\n",
        "            if len(best) > 1:\n",
        "                ties += 1\n",
        "            counts.update(best)\n",
        "        tie_counts.append(ties)\n",
        "        for m in methods:\n",
        "            win_data[m].append(counts.get(m, 0) / n_circuits * 100)\n",
        "\n",
        "    x = np.arange(len(metric_labels))\n",
        "    width = 0.22\n",
        "    fig, ax = plt.subplots(figsize=(8, 5))\n",
        "\n",
        "    for i, method in enumerate(methods):\n",
        "        bars = ax.bar(\n",
        "            x + i * width,\n",
        "            win_data[method],\n",
        "            width,\n",
        "            label=method,\n",
        "            color=palette.get(method, None),\n",
        "            edgecolor=\"black\",\n",
        "            linewidth=0.5,\n",
        "        )\n",
        "        for bar in bars:\n",
        "            height = bar.get_height()\n",
        "            if height > 0:\n",
        "                ax.text(\n",
        "                    bar.get_x() + bar.get_width() / 2,\n",
        "                    height + 1.5,\n",
        "                    f\"{height:.0f}%\",\n",
        "                    ha=\"center\",\n",
        "                    va=\"bottom\",\n",
        "                    fontsize=9,\n",
        "                )\n",
        "\n",
        "    # Annotate tie counts below each metric label\n",
        "    for j, ties in enumerate(tie_counts):\n",
        "        if ties > 0:\n",
        "            ax.text(\n",
        "                x[j] + width,\n",
        "                -8,\n",
        "                f\"({ties} tie{'s' if ties != 1 else ''})\",\n",
        "                ha=\"center\",\n",
        "                va=\"top\",\n",
        "                fontsize=8,\n",
        "                color=\"gray\",\n",
        "            )\n",
        "\n",
        "    ax.set_xticks(x + width)\n",
        "    ax.set_xticklabels(metric_labels, fontsize=11)\n",
        "    ax.set_ylabel(\"Circuits with best value (%)\", fontsize=11)\n",
        "    ax.set_title(\n",
        "        \"Best-Performing Method by Metric (ties counted for all tied methods)\",\n",
        "        fontsize=12,\n",
        "        fontweight=\"bold\",\n",
        "    )\n",
        "    ax.legend(frameon=True, fontsize=10)\n",
        "    ax.set_ylim(-12, 120)\n",
        "    ax.yaxis.set_major_formatter(ticker.PercentFormatter())\n",
        "    ax.grid(axis=\"y\", linestyle=\"--\", alpha=0.4)\n",
        "\n",
        "    plt.tight_layout()\n",
        "    plt.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "id": "a6b7c8d9",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/compilation-methods-for-hamiltonian-simulation-circuits/extracted-outputs/a6b7c8d9-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plot_best_method_bars(results_small)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "30687d7b",
      "metadata": {},
      "source": [
        "この例では、小規模な回路において、これら3つの手法の性能はほぼ同等です。 2量子ビットの深さとゲート数に関して、各手法が最適となる回路の割合は拮抗しており（およそ35～55％）、最も単純な回路では、複数の手法が単一の最適解を導き出すことが多いため、多くの回路で同率となる。 最も明らかな違いは実行時間です。SABREとRustiqは、それぞれ約半数の回路において最速ですが、AIを活用したトランスパイラーが最速となることはほとんどありません。 これら3つの指標を総合的に見ると、Rustiqが全体的にわずかに優位であり、2量子ビットの深度では最も高い勝率を誇り、ゲート数や実行時間においても競争力を維持している。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b6c7d8e9",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute-using-qiskit-primitives\" />\n",
        "\n",
        "### ステップ3: `Qiskit primitives`を使用して実行する\n",
        "\n",
        "トランスパイレーションの品質がノイズ下での実行にどのような影響を与えるかを評価するために、 **ミラー回路**の手法を用いる。 トランスパイルされた各回路 $U$ に対して、その逆回路 $U^\\dagger$ を付加することで、結合された回路 $U^\\dagger U$ は理論上、恒等回路となる。 $|0\\rangle$ という状態から開始した場合、完全な（ノイズのない）実行では、確率1で全ビットが0のビット列が返される。\n",
        "\n",
        "実際には、ゲートエラーが回路全体に蓄積されるため、 $|0\\rangle^{\\otimes n}$ を復元できる確率は低下します。 ゲート数が少なく、回路の深さが浅くなるような集積化手法を採用すれば、ノイズの蓄積も少なくなります。\n",
        "\n",
        "ミラー回路の手法は、期待される出力が常に $|0\\rangle^{\\otimes n}$ となるため、理想的な状態の古典的なシミュレーションを必要とせず、非常にシンプルで、どのような回路規模にも拡張可能であるという点で魅力的である。 ただし、以下の点に留意してください。ミラー回路は実際の回路の代用であり（回路そのものではありません）、ゲート数が2倍になる（これによりノイズの影響が誇張される）ほか、ミラー境界を挟んでノイズが対称的に打ち消し合う場合、特定のエラーを過小評価してしまう可能性があります。\n",
        "\n",
        "小規模なセットから回路インデックス6を選び、単純な偏光消去ノイズモデルを用いて、Aerシミュレータ上でミラー回路を実行する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "id": "c6d7e8f9",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Test circuit: all-vib-fccf, 4 qubits\n",
            "\n",
            "Transpilation metrics for circuit index 6:\n",
            "  SABRE     2Q depth=   66  size=   339\n",
            "  AI        2Q depth=   65  size=   300\n",
            "  Rustiq    2Q depth=   34  size=   193\n"
          ]
        }
      ],
      "source": [
        "# Select circuit index 6 from the small-scale transpiled circuits\n",
        "test_idx = 6\n",
        "test_circuit = qc_small[test_idx]\n",
        "print(f\"Test circuit: {test_circuit.name}, {test_circuit.num_qubits} qubits\")\n",
        "\n",
        "# Get the transpiled versions\n",
        "tqc_methods_small = {\n",
        "    \"SABRE\": tqc_sabre_small[test_idx],\n",
        "    \"AI\": tqc_ai_small[test_idx],\n",
        "    \"Rustiq\": tqc_rustiq_small[test_idx],\n",
        "}\n",
        "\n",
        "# Show transpilation metrics for this circuit\n",
        "print(f\"\\nTranspilation metrics for circuit index {test_idx}:\")\n",
        "for method, tqc in tqc_methods_small.items():\n",
        "    depth_2q = tqc.depth(lambda x: x.operation.num_qubits == 2)\n",
        "    size = tqc.size()\n",
        "    print(f\"  {method:8s}  2Q depth={depth_2q:5d}  size={size:6d}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d6e7f8a9",
      "metadata": {},
      "source": [
        "ミラー回路を構築し（ $U^\\dagger$ を追加）、シミュレータがアクティブな量子ビットのみを処理するように連続した量子ビットインデックスに再マッピングし、ノイズのある Aer シミュレータ上で実行する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "id": "e6f7a8b9",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "SABRE     P(|00...0>) = 0.7796  (7796/10000)\n",
            "AI        P(|00...0>) = 0.8073  (8073/10000)\n",
            "Rustiq    P(|00...0>) = 0.8923  (8923/10000)\n"
          ]
        }
      ],
      "source": [
        "def remap_to_contiguous(tqc):\n",
        "    \"\"\"Remap a transpiled circuit to use contiguous qubit indices.\n",
        "\n",
        "    Transpiled circuits target specific physical qubits (e.g., qubit 45, 67)\n",
        "    on a large backend. This remaps them to 0, 1, 2, ... so Aer only\n",
        "    simulates the active qubits.\n",
        "    \"\"\"\n",
        "    active = sorted(\n",
        "        {tqc.find_bit(q).index for inst in tqc.data for q in inst.qubits}\n",
        "    )\n",
        "    qubit_map = {old: new for new, old in enumerate(active)}\n",
        "    new_qc = QuantumCircuit(len(active))\n",
        "    for inst in tqc.data:\n",
        "        old_indices = [tqc.find_bit(q).index for q in inst.qubits]\n",
        "        new_qc.append(inst.operation, [qubit_map[i] for i in old_indices])\n",
        "    return new_qc\n",
        "\n",
        "\n",
        "def build_mirror_circuit(tqc):\n",
        "    \"\"\"Build a mirror circuit: U followed by U-dagger, with measurements.\n",
        "\n",
        "    The combined circuit U-dagger @ U should be the identity, so measuring\n",
        "    all zeros indicates a noise-free execution.\n",
        "    \"\"\"\n",
        "    tqc_compact = remap_to_contiguous(tqc)\n",
        "    mirror = tqc_compact.compose(tqc_compact.inverse())\n",
        "    mirror.measure_all()\n",
        "    return mirror\n",
        "\n",
        "\n",
        "# Build a simple depolarizing noise model\n",
        "noise_model = NoiseModel()\n",
        "noise_model.add_all_qubit_quantum_error(\n",
        "    depolarizing_error(0.001, 1),\n",
        "    [\"sx\", \"x\", \"rz\"],  # ~0.1% per 1Q gate\n",
        ")\n",
        "noise_model.add_all_qubit_quantum_error(\n",
        "    depolarizing_error(0.01, 2),\n",
        "    [\"cx\", \"ecr\"],  # ~1% per 2Q gate\n",
        ")\n",
        "\n",
        "aer_sim = AerSimulator(noise_model=noise_model)\n",
        "\n",
        "shots = 10000\n",
        "fidelities = {}\n",
        "\n",
        "for method, tqc in tqc_methods_small.items():\n",
        "    mirror = build_mirror_circuit(tqc)\n",
        "\n",
        "    sampler = SamplerV2(mode=aer_sim)\n",
        "    job = sampler.run([mirror], shots=shots)\n",
        "    result = job.result()\n",
        "    counts = result[0].data.meas.get_counts()\n",
        "\n",
        "    # Fidelity = fraction of all-zeros (error-free) outcomes\n",
        "    n_qubits = mirror.num_qubits - mirror.num_clbits  # active qubits\n",
        "    all_zeros = \"0\" * mirror.num_qubits\n",
        "    fidelity = counts.get(all_zeros, 0) / shots\n",
        "    fidelities[method] = fidelity\n",
        "    print(\n",
        "        f\"{method:8s}  P(|00...0>) = {fidelity:.4f}  \"\n",
        "        f\"({counts.get(all_zeros, 0)}/{shots})\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "id": "small_step4_plot",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/compilation-methods-for-hamiltonian-simulation-circuits/extracted-outputs/small_step4_plot-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "def plot_mirror_results(tqc_methods, fidelities, circuit_name):\n",
        "    \"\"\"\n",
        "    Plot a three-panel comparison: fidelity, 2Q depth,\n",
        "    and gate count for each compilation method.\n",
        "    \"\"\"\n",
        "    methods = list(tqc_methods.keys())\n",
        "    palette = {\"SABRE\": \"#1f77b4\", \"AI\": \"#ff7f0e\", \"Rustiq\": \"#2ca02c\"}\n",
        "    colors = [palette.get(m, \"gray\") for m in methods]\n",
        "\n",
        "    fidelity_vals = [fidelities[m] for m in methods]\n",
        "    depth_vals = [\n",
        "        tqc_methods[m].depth(lambda x: x.operation.num_qubits == 2)\n",
        "        for m in methods\n",
        "    ]\n",
        "    size_vals = [tqc_methods[m].size() for m in methods]\n",
        "\n",
        "    fig, axes = plt.subplots(1, 3, figsize=(16, 5))\n",
        "    fig.suptitle(\n",
        "        f\"Mirror Circuit Results: {circuit_name}\",\n",
        "        fontsize=14,\n",
        "        fontweight=\"bold\",\n",
        "        y=1.02,\n",
        "    )\n",
        "\n",
        "    def _annotate_bars(ax, bars, values, fmt=\"{}\"):\n",
        "        ymax = ax.get_ylim()[1]\n",
        "        for bar, val in zip(bars, values):\n",
        "            label = fmt.format(val)\n",
        "            y = val + ymax * 0.03\n",
        "            ax.text(\n",
        "                bar.get_x() + bar.get_width() / 2,\n",
        "                y,\n",
        "                label,\n",
        "                ha=\"center\",\n",
        "                va=\"bottom\",\n",
        "                fontsize=10,\n",
        "                fontweight=\"bold\",\n",
        "            )\n",
        "\n",
        "    # Panel 1: Survival Probability\n",
        "    bars = axes[0].bar(\n",
        "        methods, fidelity_vals, color=colors, edgecolor=\"black\", linewidth=0.5\n",
        "    )\n",
        "    axes[0].set_ylabel(\"Fidelity  P(|00...0>)\", fontsize=11)\n",
        "    axes[0].set_title(\"Fidelity (higher is better)\", fontsize=12)\n",
        "    axes[0].set_ylim(\n",
        "        0, max(fidelity_vals) * 1.18 if max(fidelity_vals) > 0 else 1.0\n",
        "    )\n",
        "    axes[0].grid(axis=\"y\", linestyle=\"--\", alpha=0.4)\n",
        "    _annotate_bars(axes[0], bars, fidelity_vals, fmt=\"{:.4f}\")\n",
        "\n",
        "    # Panel 2: Two-Qubit Depth\n",
        "    bars = axes[1].bar(\n",
        "        methods, depth_vals, color=colors, edgecolor=\"black\", linewidth=0.5\n",
        "    )\n",
        "    axes[1].set_ylabel(\"Two-Qubit Depth\", fontsize=11)\n",
        "    axes[1].set_title(\"2Q Depth (lower is better)\", fontsize=12)\n",
        "    axes[1].set_ylim(0, max(depth_vals) * 1.18)\n",
        "    axes[1].grid(axis=\"y\", linestyle=\"--\", alpha=0.4)\n",
        "    _annotate_bars(axes[1], bars, depth_vals)\n",
        "\n",
        "    # Panel 3: Gate Count\n",
        "    bars = axes[2].bar(\n",
        "        methods, size_vals, color=colors, edgecolor=\"black\", linewidth=0.5\n",
        "    )\n",
        "    axes[2].set_ylabel(\"Total Gate Count\", fontsize=11)\n",
        "    axes[2].set_title(\"Gate Count (lower is better)\", fontsize=12)\n",
        "    axes[2].set_ylim(0, max(size_vals) * 1.18)\n",
        "    axes[2].grid(axis=\"y\", linestyle=\"--\", alpha=0.4)\n",
        "    _annotate_bars(axes[2], bars, size_vals)\n",
        "\n",
        "    plt.tight_layout()\n",
        "    plt.show()\n",
        "\n",
        "\n",
        "plot_mirror_results(tqc_methods_small, fidelities, test_circuit.name)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "small_mirror_commentary",
      "metadata": {},
      "source": [
        "<span id=\"observations\" />\n",
        "\n",
        "#### 観察\n",
        "\n",
        "2量子ビットの深さが最も浅く、ゲート数が最も少ない手法が、最も高い忠実度を達成している。これは、回路が短いほどノイズの蓄積が少ないという予想と一致している。 脱分極ノイズモデルの下では、深さやゲート数のわずかな違いでさえ、忠実度に測定可能な差として現れる。\n",
        "\n",
        "これらの結果は単一の回路に関するものであることに留意してください。 各手法の相対的な順位は、ハミルトニアンの構造に応じて回路ごとに変化する可能性がある。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "sec-large-scale",
      "metadata": {},
      "source": [
        "<span id=\"large-scale-hardware-example\" />\n",
        "\n",
        "## 大規模なハードウェアの例\n",
        "\n",
        "このセクションでは、20個以上の量子ビットからなるハミルトニアン回路を用いて、これら3つのコンパイル手法のベンチマーク評価を行う。 これらの回路は、実用的なハミルトニアンシミュレーションのワークロードをよりよく反映しており、回路の品質やコンパイル時間という観点から、各手法のスケーラビリティを検証するものです。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f6a7b8c9",
      "metadata": {},
      "source": [
        "<span id=\"steps-1-4-combined\" />\n",
        "\n",
        "### 手順1～4をまとめて\n",
        "\n",
        "このワークフローは、小規模な例と同じ構成になっています。 各手法を用いて大規模な回路をすべてトランスパイルし、メトリクスを収集した上で、ミラー回路を実際の量子ハードウェアに送信する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "id": "a7b8c9d0",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[SABRE] Circuit 0 (all-vib-hc3h2cn): 2Q depth=2, size=258, time=0.16s\n",
            "[SABRE] Circuit 1 (ham-graph-gnp_k-5): 2Q depth=345, size=4036, time=0.08s\n",
            "[SABRE] Circuit 2 (TSP_Ncity-5): 2Q depth=187, size=2045, time=0.04s\n",
            "[SABRE] Circuit 3 (tfim): 2Q depth=100, size=489, time=0.21s\n",
            "[SABRE] Circuit 4 (all-vib-h2co): 2Q depth=30, size=570, time=0.18s\n",
            "[SABRE] Circuit 5 (uuf100-ham): 2Q depth=414, size=4779, time=0.09s\n",
            "[SABRE] Circuit 6 (uuf100-ham): 2Q depth=523, size=5667, time=0.11s\n",
            "[SABRE] Circuit 7 (graph-gnp_k-4): 2Q depth=3028, size=24885, time=0.39s\n",
            "[SABRE] Circuit 8 (uf100-ham): 2Q depth=700, size=8271, time=0.15s\n",
            "[SABRE] Circuit 9 (uf100-ham): 2Q depth=698, size=8957, time=0.15s\n",
            "[SABRE] Circuit 10 (TSP_Ncity-7): 2Q depth=432, size=6353, time=0.12s\n",
            "[SABRE] Circuit 11 (all-vib-cyclo_propene): 2Q depth=30, size=1144, time=0.20s\n",
            "[SABRE] Circuit 12 (TSP_Ncity-8): 2Q depth=704, size=10287, time=0.18s\n",
            "[SABRE] Circuit 13 (uf100-ham): 2Q depth=2454, size=30195, time=0.46s\n",
            "[SABRE] Circuit 14 (tfim): 2Q depth=245, size=3670, time=0.08s\n",
            "[SABRE] Circuit 15 (flat100-ham): 2Q depth=154, size=3836, time=0.12s\n",
            "[SABRE] Circuit 16 (graph-regular_reg-4): 2Q depth=863, size=14063, time=0.22s\n",
            "[SABRE] Circuit 17 (tfim): 2Q depth=581, size=8810, time=0.15s\n",
            "[SABRE] Circuit 18 (FH_D-1): 2Q depth=1704, size=9528, time=0.35s\n",
            "[SABRE] Circuit 19 (TSP_Ncity-10): 2Q depth=1091, size=22041, time=0.38s\n",
            "[SABRE] Circuit 20 (TSP_Ncity-10): 2Q depth=1091, size=22005, time=0.38s\n",
            "[SABRE] Circuit 21 (ham-unary-color02-queen13_13_k-4): 2Q depth=224, size=8321, time=0.17s\n",
            "[AI] Circuit 0 (all-vib-hc3h2cn): 2Q depth=2, size=258, time=0.17s\n",
            "[AI] Circuit 1 (ham-graph-gnp_k-5): 2Q depth=323, size=4418, time=3.13s\n",
            "[AI] Circuit 2 (TSP_Ncity-5): 2Q depth=161, size=2229, time=1.47s\n",
            "[AI] Circuit 3 (tfim): 2Q depth=20, size=402, time=0.34s\n",
            "[AI] Circuit 4 (all-vib-h2co): 2Q depth=38, size=661, time=0.19s\n",
            "[AI] Circuit 5 (uuf100-ham): 2Q depth=391, size=5130, time=3.27s\n",
            "[AI] Circuit 6 (uuf100-ham): 2Q depth=463, size=6095, time=4.23s\n",
            "[AI] Circuit 7 (graph-gnp_k-4): 2Q depth=3207, size=25641, time=15.15s\n",
            "[AI] Circuit 8 (uf100-ham): 2Q depth=637, size=8267, time=5.87s\n",
            "[AI] Circuit 9 (uf100-ham): 2Q depth=632, size=9330, time=7.29s\n",
            "[AI] Circuit 10 (TSP_Ncity-7): 2Q depth=452, size=7418, time=6.02s\n",
            "[AI] Circuit 11 (all-vib-cyclo_propene): 2Q depth=38, size=1323, time=0.27s\n",
            "[AI] Circuit 12 (TSP_Ncity-8): 2Q depth=609, size=11131, time=10.07s\n",
            "[AI] Circuit 13 (uf100-ham): 2Q depth=2251, size=31128, time=38.77s\n",
            "[AI] Circuit 14 (tfim): 2Q depth=165, size=3460, time=1.64s\n",
            "[AI] Circuit 15 (flat100-ham): 2Q depth=91, size=3497, time=2.49s\n",
            "[AI] Circuit 16 (graph-regular_reg-4): 2Q depth=664, size=15256, time=12.35s\n",
            "[AI] Circuit 17 (tfim): 2Q depth=583, size=9157, time=6.28s\n",
            "[AI] Circuit 18 (FH_D-1): 2Q depth=1193, size=7754, time=4.54s\n",
            "[AI] Circuit 19 (TSP_Ncity-10): 2Q depth=1134, size=22577, time=25.64s\n",
            "[AI] Circuit 20 (TSP_Ncity-10): 2Q depth=1172, size=23851, time=28.97s\n",
            "[AI] Circuit 21 (ham-unary-color02-queen13_13_k-4): 2Q depth=219, size=8600, time=8.85s\n",
            "[Rustiq] Circuit 0 (all-vib-hc3h2cn): 2Q depth=2, size=257, time=0.16s\n",
            "[Rustiq] Circuit 1 (ham-graph-gnp_k-5): 2Q depth=640, size=5831, time=0.13s\n",
            "[Rustiq] Circuit 2 (TSP_Ncity-5): 2Q depth=408, size=3985, time=0.08s\n",
            "[Rustiq] Circuit 3 (tfim): 2Q depth=31, size=688, time=0.07s\n",
            "[Rustiq] Circuit 4 (all-vib-h2co): 2Q depth=65, size=1058, time=2.91s\n",
            "[Rustiq] Circuit 5 (uuf100-ham): 2Q depth=633, size=6757, time=0.14s\n",
            "[Rustiq] Circuit 6 (uuf100-ham): 2Q depth=795, size=8495, time=0.17s\n",
            "[Rustiq] Circuit 7 (graph-gnp_k-4): 2Q depth=13768, size=139793, time=2.92s\n",
            "[Rustiq] Circuit 8 (uf100-ham): 2Q depth=1099, size=11878, time=0.25s\n",
            "[Rustiq] Circuit 9 (uf100-ham): 2Q depth=911, size=11111, time=0.22s\n",
            "[Rustiq] Circuit 10 (TSP_Ncity-7): 2Q depth=1183, size=13197, time=0.27s\n",
            "[Rustiq] Circuit 11 (all-vib-cyclo_propene): 2Q depth=67, size=2491, time=13.56s\n",
            "[Rustiq] Circuit 12 (TSP_Ncity-8): 2Q depth=1615, size=21358, time=0.48s\n",
            "[Rustiq] Circuit 13 (uf100-ham): 2Q depth=2920, size=40465, time=0.91s\n",
            "[Rustiq] Circuit 14 (tfim): 2Q depth=489, size=6552, time=0.15s\n",
            "[Rustiq] Circuit 15 (flat100-ham): 2Q depth=378, size=5906, time=0.14s\n",
            "[Rustiq] Circuit 16 (graph-regular_reg-4): 2Q depth=12163, size=168679, time=2.94s\n",
            "[Rustiq] Circuit 17 (tfim): 2Q depth=1208, size=17042, time=0.36s\n",
            "[Rustiq] Circuit 18 (FH_D-1): 2Q depth=1061, size=24000, time=0.47s\n",
            "[Rustiq] Circuit 19 (TSP_Ncity-10): 2Q depth=2565, size=41340, time=1.38s\n",
            "[Rustiq] Circuit 20 (TSP_Ncity-10): 2Q depth=2565, size=41275, time=1.38s\n",
            "[Rustiq] Circuit 21 (ham-unary-color02-queen13_13_k-4): 2Q depth=808, size=17548, time=0.42s\n"
          ]
        }
      ],
      "source": [
        "results_large = []\n",
        "\n",
        "tqc_sabre_large = capture_transpilation_metrics(\n",
        "    results_large, pm_sabre, qc_large, \"SABRE\"\n",
        ")\n",
        "tqc_ai_large = capture_transpilation_metrics(\n",
        "    results_large, pm_ai, qc_large, \"AI\"\n",
        ")\n",
        "tqc_rustiq_large = capture_transpilation_metrics(\n",
        "    results_large, pm_rustiq, qc_large, \"Rustiq\"\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "id": "b7c8d9e0",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Mean +/- std per compilation method\n",
            "Method                2Q Depth              Gate Count             Runtime (s)\n",
            "------------------------------------------------------------------------------\n",
            "SABRE          709.1 +/- 783.8     9,100.5 +/- 8,493.1             0.2 +/- 0.1\n",
            "AI             656.6 +/- 777.5     9,435.6 +/- 8,853.0            8.5 +/- 10.2\n",
            "Rustiq     2,062.5 +/- 3,631.1   26,804.8 +/- 43,403.1             1.3 +/- 2.9\n",
            "\n",
            "Mean % improvement vs SABRE (positive = better than SABRE)\n",
            "Method                2Q Depth              Gate Count             Runtime (s)\n",
            "------------------------------------------------------------------------------\n",
            "AI             +9.6% +/- 22.8%          -3.4% +/- 9.4%    -3620.0% +/- 2405.5%\n",
            "Rustiq      -154.5% +/- 273.9%      -137.1% +/- 233.2%     -527.0% +/- 1405.5%\n"
          ]
        }
      ],
      "source": [
        "print_summary_table(results_large)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 26,
      "id": "per_circuit_large_code",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "2Q Depth (first 8 circuits by qubit count); * = best\n",
            "Idx  Circuit            Q    SABRE       AI   Rustiq\n",
            "----------------------------------------------------\n",
            "  0  all-vib-hc3h2cn   24       2*       2*       2*\n",
            "  1  ham-graph-gnp_k-  24      345     323*      640\n",
            "  2  TSP_Ncity-5       25      187     161*      408\n",
            "  3  tfim              26      100      20*       31\n",
            "  4  all-vib-h2co      32      30*       38       65\n",
            "  5  uuf100-ham        40      414     391*      633\n",
            "  6  uuf100-ham        40      523     463*      795\n",
            "  7  graph-gnp_k-4     40    3028*     3207    13768\n",
            "\n",
            "Gate Count (first 8 circuits by qubit count); * = best\n",
            "Idx  Circuit            Q    SABRE       AI   Rustiq\n",
            "----------------------------------------------------\n",
            "  0  all-vib-hc3h2cn   24      258      258     257*\n",
            "  1  ham-graph-gnp_k-  24    4036*     4418     5831\n",
            "  2  TSP_Ncity-5       25    2045*     2229     3985\n",
            "  3  tfim              26      489     402*      688\n",
            "  4  all-vib-h2co      32     570*      661     1058\n",
            "  5  uuf100-ham        40    4779*     5130     6757\n",
            "  6  uuf100-ham        40    5667*     6095     8495\n",
            "  7  graph-gnp_k-4     40   24885*    25641   139793\n",
            "\n",
            "Runtime (s) (first 8 circuits by qubit count); * = best\n",
            "Idx  Circuit            Q    SABRE       AI   Rustiq\n",
            "----------------------------------------------------\n",
            "  0  all-vib-hc3h2cn   24     0.16     0.17    0.16*\n",
            "  1  ham-graph-gnp_k-  24    0.08*     3.13     0.13\n",
            "  2  TSP_Ncity-5       25    0.04*     1.47     0.08\n",
            "  3  tfim              26     0.21     0.34    0.07*\n",
            "  4  all-vib-h2co      32    0.18*     0.19     2.91\n",
            "  5  uuf100-ham        40    0.09*     3.27     0.14\n",
            "  6  uuf100-ham        40    0.11*     4.23     0.17\n",
            "  7  graph-gnp_k-4     40    0.39*    15.15     2.92\n",
            "\n"
          ]
        }
      ],
      "source": [
        "print_per_circuit_comparison(results_large, num_rows=8)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 27,
      "id": "c7d8e9f0",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/compilation-methods-for-hamiltonian-simulation-circuits/extracted-outputs/c7d8e9f0-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plot_transpilation_comparison(\n",
        "    results_large,\n",
        "    \"Large-Scale Hamiltonian Circuits: Compilation Comparison\",\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 28,
      "id": "pct_improvement_large",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/compilation-methods-for-hamiltonian-simulation-circuits/extracted-outputs/pct_improvement_large-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plot_pct_improvement_vs_sabre(\n",
        "    results_large,\n",
        "    \"Large-Scale Hamiltonian Circuits\",\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 29,
      "id": "d7e8f9a0",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/compilation-methods-for-hamiltonian-simulation-circuits/extracted-outputs/d7e8f9a0-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plot_best_method_bars(results_large)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 30,
      "id": "f7a8b9c0",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Test circuit: tfim, 26 qubits\n",
            "\n",
            "Transpilation metrics for circuit index 3:\n",
            "  SABRE     2Q depth=  100  size=   489\n",
            "  AI        2Q depth=   20  size=   402\n",
            "  Rustiq    2Q depth=   31  size=   688\n"
          ]
        }
      ],
      "source": [
        "# Select circuit index 3 from the large-scale transpiled circuits\n",
        "test_idx_large = 3\n",
        "test_circuit_large = qc_large[test_idx_large]\n",
        "print(\n",
        "    f\"Test circuit: {test_circuit_large.name}, {test_circuit_large.num_qubits} qubits\"\n",
        ")\n",
        "\n",
        "tqc_methods_large = {\n",
        "    \"SABRE\": tqc_sabre_large[test_idx_large],\n",
        "    \"AI\": tqc_ai_large[test_idx_large],\n",
        "    \"Rustiq\": tqc_rustiq_large[test_idx_large],\n",
        "}\n",
        "\n",
        "print(f\"\\nTranspilation metrics for circuit index {test_idx_large}:\")\n",
        "for method, tqc in tqc_methods_large.items():\n",
        "    depth_2q = tqc.depth(lambda x: x.operation.num_qubits == 2)\n",
        "    size = tqc.size()\n",
        "    print(f\"  {method:8s}  2Q depth={depth_2q:5d}  size={size:6d}\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 31,
      "id": "3cd3afa2",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "SABRE transpiled circuit:\n",
            "OrderedDict({'sx': 211, 'rz': 163, 'cz': 104, 'x': 11})\n",
            "SABRE mirror circuit count ops:\n",
            "OrderedDict({'rz': 1170, 'sx': 422, 'cz': 208, 'measure': 156, 'x': 22, 'barrier': 1})\n",
            "\n",
            "AI transpiled circuit:\n",
            "OrderedDict({'sx': 165, 'rz': 162, 'cz': 68, 'x': 7})\n",
            "AI mirror circuit count ops:\n",
            "OrderedDict({'rz': 984, 'sx': 330, 'measure': 156, 'cz': 136, 'x': 14, 'barrier': 1})\n",
            "\n",
            "Rustiq transpiled circuit:\n",
            "OrderedDict({'sx': 316, 'rz': 225, 'cz': 140, 'x': 7})\n",
            "Rustiq mirror circuit count ops:\n",
            "OrderedDict({'rz': 1714, 'sx': 632, 'cz': 280, 'measure': 156, 'x': 14, 'barrier': 1})\n"
          ]
        }
      ],
      "source": [
        "pm_mirror = generate_preset_pass_manager(\n",
        "    optimization_level=0, backend=backend\n",
        ")\n",
        "\n",
        "for method, tqc in tqc_methods_large.items():\n",
        "    # print the count ops for each circuit\n",
        "    mirror = tqc.copy()\n",
        "    mirror.compose(tqc.inverse(), inplace=True)\n",
        "    mirror.measure_all()\n",
        "    mirror = pm_mirror.run(mirror)\n",
        "    print(f\"\\n{method} transpiled circuit:\")\n",
        "    print(tqc.count_ops())\n",
        "    print(f\"{method} mirror circuit count ops:\")\n",
        "    print(mirror.count_ops())"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 32,
      "id": "large_hw_submit",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "SABRE: submitted job d8gvgq66983c73dqe5og\n",
            "AI: submitted job d8gvgqe6983c73dqe5pg\n",
            "Rustiq: submitted job d8gvgqm6983c73dqe5q0\n"
          ]
        }
      ],
      "source": [
        "# Build mirror circuits and submit to real hardware\n",
        "# The inverse may introduce gates (e.g., sxdg) not in the backend's\n",
        "# basis gate set, so we re-transpile the mirror circuit.\n",
        "pm_mirror = generate_preset_pass_manager(\n",
        "    optimization_level=0, backend=backend\n",
        ")\n",
        "\n",
        "shots_hw = 10000\n",
        "hw_jobs = {}\n",
        "\n",
        "for method, tqc in tqc_methods_large.items():\n",
        "    mirror = tqc.copy()\n",
        "    mirror.compose(tqc.inverse(), inplace=True)\n",
        "    mirror.measure_all()\n",
        "\n",
        "    # Re-transpile at opt level 0 to decompose into basis gates\n",
        "    # without changing the layout or routing\n",
        "    mirror = pm_mirror.run(mirror)\n",
        "\n",
        "    sampler = SamplerV2(mode=backend)\n",
        "    sampler.options.environment.job_tags = [\"TUT_CMHSC\"]\n",
        "    job = sampler.run([mirror], shots=shots_hw)\n",
        "    hw_jobs[method] = job\n",
        "    print(f\"{method}: submitted job {job.job_id()}\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 33,
      "id": "large_hw_results",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "SABRE     P(|00...0>) = 0.0005  (5/10000)\n",
            "AI        P(|00...0>) = 0.3267  (3267/10000)\n",
            "Rustiq    P(|00...0>) = 0.1845  (1845/10000)\n"
          ]
        }
      ],
      "source": [
        "# Retrieve results and compute fidelities\n",
        "fidelities_large = {}\n",
        "\n",
        "for method, job in hw_jobs.items():\n",
        "    result = job.result()\n",
        "    counts = result[0].data.meas.get_counts()\n",
        "\n",
        "    n_qubits = backend.num_qubits\n",
        "    all_zeros = \"0\" * n_qubits\n",
        "    fidelity = counts.get(all_zeros, 0) / shots_hw\n",
        "    fidelities_large[method] = fidelity\n",
        "    print(\n",
        "        f\"{method:8s}  P(|00...0>) = {fidelity:.4f}  \"\n",
        "        f\"({counts.get(all_zeros, 0)}/{shots_hw})\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 34,
      "id": "large_hw_plot",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/compilation-methods-for-hamiltonian-simulation-circuits/extracted-outputs/large_hw_plot-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plot_mirror_results(\n",
        "    tqc_methods_large, fidelities_large, test_circuit_large.name\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "sec-analysis",
      "metadata": {},
      "source": [
        "<span id=\"analysis-of-compilation-results\" />\n",
        "\n",
        "## コンパイル結果の分析\n",
        "\n",
        "上記のベンチマークでは、AIを活用したトランスパイラーであるSABREとRustiqを、Hamlibコレクションに含まれるハミルトニアンシミュレーション回路を用いて、小規模および大規模の両方で比較しています。\n",
        "\n",
        "<span id=\"two-qubit-depth-and-gate-count\" />\n",
        "\n",
        "### 2量子ビットの深さとゲート数\n",
        "\n",
        "大規模な環境では、SABREとAIを活用したトランスパイラーが最も優れたパフォーマンスを発揮しており、それぞれ異なる評価指標でトップの座を占めています。 *メトリック*チャートが示すように、SABREは大多数の回路においてゲート数が最も少なく、ほぼすべての回路で最速のアルゴリズムとなっています。これは、挿入されるSWAPゲートを最小限に抑えるよう設計されたヒューリスティック手法や、レイアウトおよび配線に関する最近の最適化と一致しています。 このAI駆動のトランスパイラーは、ほとんどの回路において最も低い2量子ビット深度を実現しており、これは回路の深度を目標とする強化学習の目的と一致している。 要約表にも同様の傾向が表れています。SABREは平均ゲート数が少なく、AIトランスパイラーは平均2量子ビット深度が小さいという結果です。 どちらの方法も、あらゆる種類の回路において一貫性があり、信頼性が高い。\n",
        "\n",
        "合成専用 `PauliEvolutionGate` に設計されたRustiqは、大規模な回路のごく一部においてのみ、他を圧倒する最高の結果を生み出しています。 その平均指標は、ごく少数の著しい外れ値によって大きく歪められており、これはコンパイル比較プロット上の大きなスパイクとして確認できる。そこでは、Rustiqが他の手法に比べて、深度およびゲート数が大幅に多い結果を示している。 これらの外れ値がなければ、その平均的なパフォーマンスはSABREやAI搭載のトランスパイラーにかなり近いものとなるだろう。\n",
        "\n",
        "重要な点は、どの回路においても、特定の1つの手法が他を圧倒しているわけではないということである。 各手法は特定のケースにおいて他の手法よりも優れた性能を発揮するため、利用可能なツールをすべて試して、各回路ごとに最適な結果を選ぶ価値がある。\n",
        "\n",
        "<span id=\"runtime\" />\n",
        "\n",
        "### ランタイム\n",
        "\n",
        "SABREは常に最速の手法です。 Rustiqは通常、ほぼ同程度の速度で動作しますが、コンパイルに著しく時間がかかるような例外的なケースが発生することがあります。 これは特に大規模な実験結果において顕著であり、ごく少数の回路によってRustiqの実行時間が急増している。 これらの外れ値は平均実行時間に大きな影響を与えるため、Rustiqについては中央値の方がより代表的な指標となる可能性があります。 AIを活用したトランスパイラーは3つの中で最も処理速度が遅く、回路が大きくなったり複雑になったりすると、実行時間が著しく長くなります。\n",
        "\n",
        "<span id=\"mirror-circuit-results\" />\n",
        "\n",
        "### ミラー回路の結果\n",
        "\n",
        "ミラー回路を用いた実験により、予想された傾向が裏付けられた。すなわち、2量子ビットの深さが浅く、ゲート数が少ない手法ほど、ノイズ下でも高い忠実度を達成できることが確認された。 これは、ノイズの多いシミュレータ（小規模）と実際のハードウェア（大規模）の両方で当てはまります。\n",
        "\n",
        "各ミラー回路のプロットは、個々の回路を表しており、全体を表しているわけではないことに留意してください。 上記のハードウェアの例では、26キュー `tfim` ビットの回路が1つ使用されています。このケースでは、SABREがAI駆動のトランスパイラーやRustiqよりもはるかに高い2キュービット深度を実現しているため、それに応じて忠実度はかなり低くなっています。 これは全体的な結果を代表するものではありません。大規模回路の全セットにおいて、SABREの2量子ビット深度は通常、AIを活用したトランスパイラーのそれと同程度であり、2つの手法はそれぞれ異なる評価指標で優位性を示しています（2量子ビット深度ではAIを活用したトランスパイラーが、ゲート数と実行時間ではSABREが優れています）。 1回のミラー結果では、ワークロード全体ではなく、ある回路の2倍のバージョンがテストされるため、これを手法全体の品質に関する結論として解釈すべきではありません。\n",
        "\n",
        "<span id=\"recommendations\" />\n",
        "\n",
        "### 推奨事項\n",
        "\n",
        "すべての回路に通用する、唯一の最適なトランスパイレーション戦略というものはありません。 最適な選択は、回路構造、最適化の目標、および割り当てられるコンパイル時間の制約によって異なります：\n",
        "\n",
        "* **SABRE が**推奨されるデフォルト設定です。 高速かつ信頼性が高く、幅広い回路において優れた結果をもたらします。 さらに微調整を行うには、レイアウトおよび配線の試行回数を増やすことができます（ [SABREの最適化チュートリアル](/docs/tutorials/transpilation-optimizations-with-sabre)を参照してください）。\n",
        "* コンパイル時間が制約とならない場合、特に2量子ビットの深さを最小限に抑えることが優先される場合には、 **AIを活用したトランスパイラー** を試してみる価値がある。このベンチマークにおける大規模回路のほとんどで、このトランスパイラーが最も低い2量子ビットの深さを実現した。\n",
        "* **Rustiqは**回路設計専用に `PauliEvolutionGate` 開発されており、特に小規模な回路において、深さが非常に浅く、ゲート数が少ないソリューションを見出すことができます。 大規模な回路では、時折はるかに大きな結果をもたらすことがあるため、デフォルトとしてではなく、試すべきいくつかの手法の一つとして使用するのが最善です。\n",
        "\n",
        "実際には、利用可能なすべてのメソッドを実行し、各回路について最良の結果を選ぶのが最善のアプローチです。 複数の手法を試すことによるコンパイルのオーバーヘッドは、実際のハードウェア上での実行品質が向上する可能性に比べれば、ごくわずかである。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "sec-next-steps",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 次のステップ\n",
        "\n",
        "このチュートリアルが役に立ったという方は、以下の記事もご参考になるかもしれません：\n",
        "\n",
        "<Admonition type=\"tip\" title=\"推奨事項\">\n",
        "  * [SABRE によるトランスパイレーションの最適化](/docs/tutorials/transpilation-optimizations-with-sabre)\n",
        "  * [AIを活用したトランスパイラーが合格した](/docs/guides/ai-transpiler-passes)\n",
        "  * [トランスパイラプラグインを作成する](/docs/guides/create-transpiler-plugin)\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "sec-references",
      "metadata": {},
      "source": [
        "<span id=\"references\" />\n",
        "\n",
        "## 参照\n",
        "\n",
        "\\[1] \"\"LightSABRE: A Lightweight and Enhanced SABRE Algorithm\". H. Zou, M. Treinish, K. Hartman, A. Ivrii, J. Lishman et al. [https://arxiv.org/abs/2409.08368](https://arxiv.org/abs/2409.08368)\n",
        "\n",
        "\\[2] 「強化学習による実用的で効率的な量子回路合成とトランスパイリング 博士 Kremer, V. Villar, H. Paik, I. Duran, I. Faro, J. Cruz-Benito et al. [https://arxiv.org/abs/2405.13196](https://arxiv.org/abs/2405.13196)\n",
        "\n",
        "\\[3] 「強化学習を用いたパウリ・ネットワーク回路合成」。 A。 Dubal, D. Kremer, S. Martiel, V. Villar, D. Wang, J. Cruz-Benito ほか。 [https://arxiv.org/abs/2503.14448](https://arxiv.org/abs/2503.14448)\n",
        "\n",
        "\\[4] 「ハミルトニアンシミュレーション回路のより高速かつ簡略化された合成」。 T. Goubault de Brugiere、S. Martiel ほか [ https://arxiv.org/abs/2404.03280](https://arxiv.org/abs/2404.03280)\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"
    },
    "hours": 1,
    "qpuSeconds": 60
  },
  "nbformat": 4,
  "nbformat_minor": 5
}