{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "24576595",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"分数ゲートを用いた量子カーネル\"\n",
        "description: \"任意の角度の回転を直接実行するパラメータ化ゲートである「フラクショナルゲート」を用いて、量子カーネル回路の深さと実行時間を短縮する。\"\n",
        "---\n",
        "\n",
        "<span id=\"quantum-kernels-with-fractional-gates\" />\n",
        "\n",
        "# 分数ゲートを用いた量子カーネル\n",
        "\n",
        "*使用時間の見積もり：Heron r2 プロセッサーで30秒以下（注：これはあくまでも見積もりです。 実行時間は異なるかもしれない)。*\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "983da41e",
      "metadata": {},
      "source": [
        "<span id=\"learning-outcomes\" />\n",
        "\n",
        "## 学習成果\n",
        "\n",
        "このチュートリアルを学習し終える頃には、以下の点を理解できるようになるはずです：\n",
        "\n",
        "* IBM® QPUにおけるフラクショナルゲートとは何か、そしてそれが回路の深さと実行時間をどのように短縮するのか\n",
        "* 分数ゲートの使用に伴う制約（特に、RZZ角の範囲）\n",
        "* IBM Quantum Compute Service を使用して、分数ゲートを用いた量子カーネルワークフローを構築する方法\n",
        "* フラクショナルゲートの有無によるハードウェア実行メトリクス（深さ、所要時間、非局所ゲート数、忠実度）の比較方法\n",
        "* 標準的なQiskitパターンのワークフローを維持しつつ、分数RXゲートのみを使用する方法\n",
        "\n",
        "<span id=\"prerequisites\" />\n",
        "\n",
        "## 前提条件\n",
        "\n",
        "このチュートリアルを進める前に、以下のトピックについて理解しておいていただくことをお勧めします：\n",
        "\n",
        "* [Qiskit](/docs/guides/intro-to-patterns) のパターンワークフロー\n",
        "* [フラクショナル・ゲートの](/docs/guides/fractional-gates)ガイド\n",
        "* 「 [Quantumカーネルのトレーニング](/docs/tutorials/quantum-kernel-training)チュートリアル」および「Quantum機械学習コース」の「 [Quantumカーネル](/learning/courses/quantum-machine-learning/quantum-kernel-methods) 」のレッスン\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "155eab76",
      "metadata": {},
      "source": [
        "<span id=\"background\" />\n",
        "\n",
        "## 背景\n",
        "\n",
        "<span id=\"fractional-gates-on-ibm-qpus\" />\n",
        "\n",
        "### IBM 量子プロセッサ上のフラクショナルゲート\n",
        "\n",
        "分数ゲートとは、パラメータ化された量子ゲートの一種であり、（特定の範囲内であれば）任意の角度の回転を直接実行できるため、\n",
        "それらを複数の基本ゲートに分解する必要がなくなります。\n",
        "物理量子ビット間の固有の相互作用を活用することで、特定のユニタリー演算をハードウェア上でより効率的に実装することができます。\n",
        "\n",
        "IBM Quantum® Heron QPUは、以下の分数ゲートをサポートしています：\n",
        "\n",
        "* $R_{ZZ}(\\theta)$ にとって $0 < \\theta < \\pi / 2$\n",
        "* $R_X(\\theta)$ 任意の実数値に対して $\\theta$\n",
        "\n",
        "これらのゲートは、量子回路の深さと時間の両方を大幅に短縮することができる。\n",
        "ハミルトニアン・シミュレーションや量子カーネル法など、 $R_{ZZ}$ や $R_X$ を多用するアプリケーションでは特に有利である、 ハミルトニアン・シミュレーション、量子近似最適化アルゴリズム（QAOA）、量子カーネル法などである。\n",
        "このチュートリアルでは、実例として量子カーネルに焦点を当てる。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fe5675f3",
      "metadata": {},
      "source": [
        "<span id=\"limitations\" />\n",
        "\n",
        "### 制限\n",
        "\n",
        "フラクショナル・ゲートは現在実験的な機能で、いくつかの制約がある：\n",
        "\n",
        "* $R_{ZZ}$ は、 $0 < \\theta < \\pi / 2$ の範囲の角度に限定される。\n",
        "* 分数ゲートの使用は、 [ダイナミック回路](/docs/guides/classical-feedforward-and-control-flow)、 [パウリ・ツワーリング](/docs/guides/error-mitigation-and-suppression-techniques#pauli-twirling)、 [確率的エラー・キャンセル](/docs/guides/error-mitigation-and-suppression-techniques#probabilistic-error-cancellation-pec) （PEC）、および[ゼロ・ノイズ外挿](/docs/guides/error-mitigation-and-suppression-techniques#zero-noise-extrapolation-zne) （ZNE）（ [確率的エラー増幅](/docs/guides/error-mitigation-and-suppression-techniques#probabilistic-error-amplification-pea) （PEA）を使用）ではサポートされていません。\n",
        "\n",
        "フラクショナルゲートは、標準的なアプローチとは異なるワークフローを必要とする。\n",
        "このチュートリアルでは、実践的なアプリケーションを通して、分数ゲートの扱い方を説明します。\n",
        "\n",
        "分数ゲートの詳細については、以下を参照のこと。\n",
        "\n",
        "* [フラクショナル・ゲート](/docs/guides/fractional-gates)\n",
        "* [フラクショナルゲートを使用*すべきでない*場合](/docs/guides/fractional-gates#when-not-to-use)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a4bdab87",
      "metadata": {},
      "source": [
        "<span id=\"workflow-approaches-for-the-rzz-angle-constraint\" />\n",
        "\n",
        "### RZZ角の制約に対するワークフローの手法\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "db213506",
      "metadata": {},
      "source": [
        "フラクショナルゲートを使用するためのワークフローは、一般的に [Qiskitのパターン](/docs/guides/intro-to-patterns)ワークフローに従います。\n",
        "主な違いは、すべてのRZZ角が制約条件 $0 < \\theta \\leq \\pi/2$ を満たさなければならないという点です。\n",
        "この条件を満たすためには、以下で説明する2つのアプローチがあります。 ここでは2番目のアプローチをお勧めします。このチュートリアルでは、量子カーネル法に着想を得た例を用いて、その手法を解説します。\n",
        "量子カーネルがどのような場面で有用である可能性が高いかをより深く理解するためには、 [Liu、Arunachalam、およびTemme（2021）](https://www.nature.com/articles/s41567-021-01287-z) の論文を読むことをお勧めします。\n",
        "\n",
        "また、 IBM Quantum® Learning の「Quantum Machine Learning」コースにある 「[Quantumカーネルのトレーニング](/docs/tutorials/quantum-kernel-training)チュートリアル」や「 [Quantumカーネル](/learning/courses/quantum-machine-learning/quantum-kernel-methods) 」のレッスンも学習することができます。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5797ed7e",
      "metadata": {},
      "source": [
        "<span id=\"1-generate-parameter-values-that-satisfy-the-rzz-angle-constraint\" />\n",
        "\n",
        "#### 1. RZZ角の制約を満たすパラメータ値を生成する\n",
        "\n",
        "すべてのRZZ角度が有効範囲内にあることを確信している場合、標準的なQiskitパターンのワークフローに従うことができます。\n",
        "この場合、 PUB の一部としてパラメータ値を送信するだけです。 ワークフローは次のように進む。\n",
        "\n",
        "```python\n",
        "pm = generate_preset_pass_manager(backend=backend, ...)\n",
        "t_circuit = pm.run(circuit)\n",
        "t_observable = observable.apply_layout(t_circuit.layout)\n",
        "sampler.run([(t_circuit, parameter_values)])\n",
        "estimator.run([(t_circuit, t_observable, parameter_values)])\n",
        "```\n",
        "\n",
        "有効範囲外の角度を持つRZZゲートを含む PUB ：\n",
        "\n",
        "```\n",
        "'The instruction rzz is supported only for angles in the range [0, pi/2], but an angle (20.0) outside of this range has been requested; via parameter value(s) γ[0]=10.0, substituted in parameter expression 2.0*γ[0].'\n",
        "```\n",
        "\n",
        "このエラーを回避するには、以下で説明する2つ目の方法を使用してください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d3e00f37",
      "metadata": {},
      "source": [
        "<span id=\"2-assign-parameter-values-to-circuits-before-transpilation\" />\n",
        "\n",
        "#### 2. トランスパイル前に回路にパラメータ値を割り当てる\n",
        "\n",
        "[`FoldRzzAngle`](/docs/api/qiskit-ibm-runtime/transpiler-passes-fold-rzz-angle)この `qiskit-ibm-runtime` パッケージは、と呼ばれる専用のトランスパイラ・パスを提供します。\n",
        "このパスは、すべてのRZZ角度がRZZ角度の制約を満たすように、量子回路を変換します。\n",
        "`transpile`または に `generate_preset_pass_manager` バックエンドを指定すると、Qiskit は自動的に を量子回路に適用 `FoldRzzAngle` します。\n",
        "このアプローチでは、トランスパイレーションの前に量子回路にパラメータ値を割り当てる必要があります。\n",
        "ワークフローは次のように進行します。\n",
        "\n",
        "```python\n",
        "pm = generate_preset_pass_manager(backend=backend, ...)\n",
        "b_circuit = circuit.assign_parameters(parameter_values)\n",
        "t_circuit = pm.run(b_circuit)\n",
        "t_observable = observable.apply_layout(t_circuit.layout)\n",
        "sampler.run([(t_circuit,)])\n",
        "estimator.run([(t_circuit, t_observable)])\n",
        "```\n",
        "\n",
        "なお、このワークフローでは、量子回路にパラメータ値を割り当て、パラメータが紐付けられた回路をローカルに保存する必要があるため、最初のアプローチよりも計算コストが高くなる点に留意してください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b7cb1bd2",
      "metadata": {},
      "source": [
        "<Admonition type=\"caution\">\n",
        "  **既知の問題に注意してください `qiskit-ibm-runtime`v0.47.0** では、特定のシナリオにおいて、無効な角度を持つRZZゲートがトランスパイル後も回路内に残る可能性があります。\n",
        "\n",
        "  この問題の進捗状況については、 [qiskit-ibm-runtime#2441](https://github.com/Qiskit/qiskit-ibm-runtime/issues/2441) を参照してください。\n",
        "  この問題が解決されるまでの間、以下の回避策をお試しください。\n",
        "\n",
        "  ```python\n",
        "  pm = generate_preset_pass_manager(backend=backend, ...)\n",
        "  pm.post_optimization = PassManager(\n",
        "      [\n",
        "          FoldRzzAngle(),\n",
        "          Optimize1qGatesDecomposition(target=backend.target),\n",
        "          RemoveIdentityEquivalent(target=backend.target),\n",
        "      ]\n",
        "  )\n",
        "  ... = pm.run(...)\n",
        "  ```\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "aaa153e7",
      "metadata": {},
      "source": [
        "<span id=\"requirements\" />\n",
        "\n",
        "## 要件\n",
        "\n",
        "このチュートリアルを始める前に、以下のものがインストールされていることを確認してください：\n",
        "\n",
        "* Qiskit SDK v2.0 またはそれ以降、 [可視化](/docs/api/qiskit/visualization)サポート付き\n",
        "* Qiskit Runtime v0.41 またはそれ以降 (`pip install qiskit-ibm-runtime`)\n",
        "* Qiskit Aer v0.17 以降 (`pip install qiskit-aer`)\n",
        "* Qiskit Basis Constructor (`pip install qiskit_basis_constructor`)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5f43ce5d",
      "metadata": {},
      "source": [
        "<span id=\"setup\" />\n",
        "\n",
        "## セットアップ\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "a6a15694",
      "metadata": {},
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\n",
        "import numpy as np\n",
        "from qiskit import QuantumCircuit, generate_preset_pass_manager\n",
        "from qiskit.circuit import ParameterVector\n",
        "from qiskit.circuit.library import UGate, n_local, unitary_overlap\n",
        "from qiskit.transpiler import Target, PassManager\n",
        "from qiskit.transpiler.passes import (\n",
        "    Optimize1qGatesDecomposition,\n",
        "    RemoveIdentityEquivalent,\n",
        ")\n",
        "from qiskit_aer.primitives import SamplerV2 as AerSampler\n",
        "from qiskit_basis_constructor import DEFAULT_EQUIVALENCE_LIBRARY\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2\n",
        "from qiskit_ibm_runtime.transpiler.passes import FoldRzzAngle"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3e94382d",
      "metadata": {},
      "source": [
        "<span id=\"enable-fractional-gates-and-check-basis-gates\" />\n",
        "\n",
        "### 分数ゲートを有効化し、基底ゲートをチェックする\n",
        "\n",
        "分数ゲートを使用するには、 `use_fractional_gates=True` オプションを設定することで、分数ゲートをサポートするバックエンドを入手できる。\n",
        "バックエンドが分数ゲートをサポートしている場合、 `rzz` と `rx` がその基底ゲートのリストに表示される。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "fd577102",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Backend: ibm_marrakesh\n",
            "No fractional gates: ['cz', 'id', 'rz', 'sx', 'x']\n",
            "With fractional gates: ['cz', 'id', 'rx', 'rz', 'rzz', 'sx', 'x']\n"
          ]
        }
      ],
      "source": [
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(\n",
        "    operational=True, simulator=False, min_num_qubits=133\n",
        ")  # backend should be a heron device or later\n",
        "backend_name = backend.name\n",
        "backend_c = service.backend(backend_name)  # w/o fractional gates\n",
        "backend_f = service.backend(\n",
        "    backend_name, use_fractional_gates=True\n",
        ")  # w/ fractional gates\n",
        "print(f\"Backend: {backend_name}\")\n",
        "print(f\"No fractional gates: {backend_c.basis_gates}\")\n",
        "print(f\"With fractional gates: {backend_f.basis_gates}\")\n",
        "if \"rzz\" not in backend_f.basis_gates:\n",
        "    print(f\"Backend {backend_name} does not support fractional gates\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3f11c5a3",
      "metadata": {},
      "source": [
        "<span id=\"small-scale-simulator-example\" />\n",
        "\n",
        "## 小規模シミュレータの例\n",
        "\n",
        "このセクションでは、量子カーネル回路を実例として用い、シミュレータ上で [Qiskitパターンの](/docs/guides/intro-to-patterns)ワークフローの4つのステップを順を追って解説します。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7bfd6a97",
      "metadata": {},
      "source": [
        "<span id=\"step-1-map-classical-inputs-to-a-quantum-problem\" />\n",
        "\n",
        "### ステップ1：古典的な入力を量子問題に写像する\n",
        "\n",
        "<span id=\"quantum-kernel-circuit\" />\n",
        "\n",
        "#### 量子カーネル回路\n",
        "\n",
        "このセクションでは、RZZゲートを用いた量子カーネル回路を探求し、分数ゲートのワークフローを紹介する。\n",
        "\n",
        "まず、カーネル行列の各エントリーを計算する量子回路を構築する。\n",
        "これは、ZZ特徴マップ回路をユニタリーオーバーラップで組み合わせることによって行われる。\n",
        "カーネル関数は、特徴マップ空間のベクトルを受け取り、その内積をカーネル行列のエントリとして返す： $K(x, y) = \\langle \\Phi(x) | \\Phi(y) \\rangle,$ ここで、 $|\\Phi(x)\\rangle$ は特徴マップされた量子状態を表す。\n",
        "\n",
        "RZZゲートを用いて、ZZ特徴マップ回路を手動で構築する。\n",
        "`zz_feature_map`Qiskit には組み込みの機能が用意されていますが、Qiskit v2.4.1 の時点では、RZZ ゲートはサポートされていません（ [イシューを参照](https://github.com/Qiskit/qiskit/issues/14469) ）。\n",
        "\n",
        "次に、同一の入力に対するカーネル関数を計算する。例えば、 $K(x, x) = 1$。 ノイズの多い量子コンピュータでは、ノイズのためにこの値が1より小さくなることがある。\n",
        "結果が1に近いほど、実行時のノイズが少ないことを示す。\n",
        "このチュートリアルでは、この値を*忠実度と*呼び、次のように定義する。 $\\text{fidelity} = K(x, x).$\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "e7d5b52a",
      "metadata": {},
      "outputs": [],
      "source": [
        "optimization_level = 2\n",
        "shots = 2000\n",
        "reps = 3\n",
        "rng = np.random.default_rng(seed=123)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "2e9ab33d",
      "metadata": {},
      "outputs": [],
      "source": [
        "def my_zz_feature_map(num_qubits: int, reps: int = 1) -> QuantumCircuit:\n",
        "    x = ParameterVector(\"x\", num_qubits * reps)\n",
        "    qc = QuantumCircuit(num_qubits)\n",
        "    qc.h(range(num_qubits))\n",
        "    for k in range(reps):\n",
        "        K = k * num_qubits\n",
        "        for i in range(num_qubits):\n",
        "            qc.rz(x[i + K], i)\n",
        "        pairs = [(i, i + 1) for i in range(num_qubits - 1)]\n",
        "        for i, j in pairs[0::2] + pairs[1::2]:\n",
        "            qc.rzz((np.pi - x[i + K]) * (np.pi - x[j + K]), i, j)\n",
        "    return qc\n",
        "\n",
        "\n",
        "def quantum_kernel(num_qubits: int, reps: int = 1) -> QuantumCircuit:\n",
        "    qc = my_zz_feature_map(num_qubits, reps=reps)\n",
        "    inner_product = unitary_overlap(qc, qc, \"x\", \"y\", insert_barrier=True)\n",
        "    inner_product.measure_all()\n",
        "    return inner_product\n",
        "\n",
        "\n",
        "def random_parameters(inner_product: QuantumCircuit) -> np.ndarray:\n",
        "    return np.tile(rng.random(inner_product.num_parameters // 2), 2)\n",
        "\n",
        "\n",
        "def fidelity(result) -> float:\n",
        "    ba = result.data.meas\n",
        "    return ba.get_int_counts().get(0, 0) / ba.num_shots"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f676ff81",
      "metadata": {},
      "source": [
        "量子カーネル回路とそれに対応するパラメータ値を4～40量子ビットのシステムに対して生成し、その忠実度を評価する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "24116973",
      "metadata": {},
      "outputs": [],
      "source": [
        "qubits = list(range(4, 12, 2))\n",
        "circuits = [quantum_kernel(i, reps=reps) for i in qubits]\n",
        "params = [random_parameters(circ) for circ in circuits]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "30a7c442",
      "metadata": {},
      "source": [
        "この4量子ビット回路は以下のように視覚化されている。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "b3d6341a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/b3d6341a-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "circuits[0].draw(\"mpl\", fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "07f31cbe",
      "metadata": {},
      "source": [
        "標準的なQiskitパターンのワークフローでは、パラメータ値は通常、 PUB の一部としてSamplerまたはEstimatorプリミティブに渡されます。\n",
        "しかし、分数ゲートをサポートするバックエンドを使用する場合、これらのパラメータ値はトランスパイル前に量子回路に明示的に割り当てる必要がある。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "6c9c1977",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/6c9c1977-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "b_qc = [\n",
        "    circ.assign_parameters(param) for circ, param in zip(circuits, params)\n",
        "]\n",
        "b_qc[0].draw(\"mpl\", fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7513072b",
      "metadata": {},
      "source": [
        "<span id=\"step-2-optimize-problem-for-quantum-hardware-execution\" />\n",
        "\n",
        "### ステップ2：量子ハードウェア実行に向けた問題の最適化\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "804ba317",
      "metadata": {},
      "source": [
        "次に、標準的なQiskitのパターンに従って、パスマネージャーを使って回路をトランスパイルする。\n",
        "`generate_preset_pass_manager` に分数ゲートをサポートするバックエンドを提供することで、 `FoldRzzAngle` と呼ばれる特殊なパスが自動的に含まれる。\n",
        "このパスは、RZZの角度制約に準拠するように回路を修正する。\n",
        "その結果、先の図で負の値を持つRZZゲートが正の値に変換され、Xゲートがいくつか追加される。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "6054bdea",
      "metadata": {},
      "outputs": [],
      "source": [
        "backend_f = service.backend(name=backend_name, use_fractional_gates=True)\n",
        "# pm_f includes `FoldRzzAngle` pass\n",
        "pm_f = generate_preset_pass_manager(\n",
        "    optimization_level=optimization_level, backend=backend_f\n",
        ")\n",
        "pm_f.post_optimization = PassManager(\n",
        "    [\n",
        "        FoldRzzAngle(),\n",
        "        Optimize1qGatesDecomposition(target=backend_f.target),\n",
        "        RemoveIdentityEquivalent(target=backend_f.target),\n",
        "    ]\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "a18e5c70",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "OrderedDict({'rz': 35, 'rzz': 18, 'x': 13, 'rx': 9, 'measure': 4, 'barrier': 2})\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/a18e5c70-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "t_qc_f = pm_f.run(b_qc)\n",
        "print(t_qc_f[0].count_ops())\n",
        "t_qc_f[0].draw(\"mpl\", fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a4cd07d1",
      "metadata": {},
      "source": [
        "分数ゲートの影響を評価するために、非局所ゲート（このバックエンドではCZとRZZ）の数を評価する、 を評価し、回路の深さと持続時間と共に、これらのメトリクスを後で標準的なワークフローのものと比較する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "b5bcf9ad",
      "metadata": {},
      "outputs": [],
      "source": [
        "nnl_f = [qc.num_nonlocal_gates() for qc in t_qc_f]\n",
        "depth_f = [qc.depth() for qc in t_qc_f]\n",
        "duration_f = [\n",
        "    qc.estimate_duration(backend_f.target, unit=\"u\") for qc in t_qc_f\n",
        "]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "629406cc",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute-using-qiskit-primitives\" />\n",
        "\n",
        "### ステップ3: `Qiskit primitives`を使用して実行する\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "87926539",
      "metadata": {},
      "source": [
        "分数ゲートをサポートするバックエンドでトランスパイルド回路を実行する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "a68acf11",
      "metadata": {},
      "outputs": [],
      "source": [
        "sampler_f = AerSampler.from_backend(backend_f)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "a703b939",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "085ce928-767e-4200-93bf-3905e5411cfe\n"
          ]
        }
      ],
      "source": [
        "job = sampler_f.run(t_qc_f, shots=shots)\n",
        "print(job.job_id())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6c9fd10d",
      "metadata": {},
      "source": [
        "<span id=\"step-4-post-process-and-return-result-in-desired-classical-format\" />\n",
        "\n",
        "### ステップ4：後処理を行い、結果を希望の古典形式で返す\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7a865036",
      "metadata": {},
      "source": [
        "カーネル関数の値 $K(x, x)$ は、出力にゼロのビット列 `00...00` が含まれる確率を測定することで求めることができる。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "1f0d9c51",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[0.929, 0.882, 0.8645, 0.817]\n"
          ]
        }
      ],
      "source": [
        "result = job.result()\n",
        "fidelity_f = [fidelity(result=res) for res in result]\n",
        "print(fidelity_f)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a5bcd1a8",
      "metadata": {},
      "source": [
        "<span id=\"comparison-of-workflow-and-circuit-without-fractional-gates\" />\n",
        "\n",
        "### フラクショナルゲートなしのワークフローと回路の比較\n",
        "\n",
        "このセクションでは、分数ゲートをサポートしていないバックエンドを使用した、Qiskitの標準的なパターンワークフローについて紹介します。\n",
        "トランスパイルされた回路を比較してみると、（前のセクションで説明した）分数ゲートを使用したバージョンの方が、分数ゲートを使用しないバージョンよりもコンパクトであることがわかるでしょう。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "e97fd0d5",
      "metadata": {},
      "outputs": [],
      "source": [
        "# step 1: map classical inputs to quantum problem\n",
        "# `circuits` and `params` from the previous section are reused here"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "a10f2d95",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "OrderedDict({'rz': 130, 'sx': 80, 'cz': 36, 'measure': 4, 'barrier': 2})\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/a10f2d95-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 15,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# step 2: optimize circuits\n",
        "backend_c = service.backend(backend_name)  # w/o fractional gates\n",
        "pm_c = generate_preset_pass_manager(\n",
        "    optimization_level=optimization_level, backend=backend_c\n",
        ")\n",
        "t_qc_c = pm_c.run(circuits)\n",
        "print(t_qc_c[0].count_ops())\n",
        "t_qc_c[0].draw(\"mpl\", fold=-1)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "bb3475df",
      "metadata": {},
      "outputs": [],
      "source": [
        "nnl_c = [qc.num_nonlocal_gates() for qc in t_qc_c]\n",
        "depth_c = [qc.depth() for qc in t_qc_c]\n",
        "duration_c = [\n",
        "    qc.estimate_duration(backend_c.target, unit=\"u\") for qc in t_qc_c\n",
        "]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "e8d307c0",
      "metadata": {},
      "outputs": [],
      "source": [
        "# step 3: execute\n",
        "sampler_c = AerSampler.from_backend(backend_c)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "id": "983dd26f",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "f2cca29d-7263-4976-9e51-13a91b75c3ae\n"
          ]
        }
      ],
      "source": [
        "job = sampler_c.run(pubs=zip(t_qc_c, params), shots=shots)\n",
        "print(job.job_id())"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "id": "a6a6fa77",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[0.8625, 0.7605, 0.702, 0.671]\n"
          ]
        }
      ],
      "source": [
        "# step 4: post-processing\n",
        "result = job.result()\n",
        "fidelity_c = [fidelity(res) for res in result]\n",
        "print(fidelity_c)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "765a7980",
      "metadata": {},
      "source": [
        "<span id=\"comparison-of-depths-durations-and-fidelities\" />\n",
        "\n",
        "### 深度、持続時間、および忠実度の比較\n",
        "\n",
        "このセクションでは、分数ゲートを持つ回路と持たない回路の非局所ゲートの数と忠実度を比較する。\n",
        "これは、実行効率と品質という点で、分数ゲートを使用することの潜在的な利点を浮き彫りにしている。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "id": "ef343a53",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<matplotlib.legend.Legend at 0x116af3cb0>"
            ]
          },
          "execution_count": 20,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/ef343a53-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plt.plot(qubits, depth_c, \"-o\", label=\"no fractional gates\")\n",
        "plt.plot(qubits, depth_f, \"-o\", label=\"with fractional gates\")\n",
        "plt.xlabel(\"number of qubits\")\n",
        "plt.ylabel(\"depth\")\n",
        "plt.title(\"Comparison of depths\")\n",
        "plt.grid()\n",
        "plt.legend()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "id": "98bb2cd0",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<matplotlib.legend.Legend at 0x11ea4f4d0>"
            ]
          },
          "execution_count": 21,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/98bb2cd0-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plt.plot(qubits, duration_c, \"-o\", label=\"no fractional gates\")\n",
        "plt.plot(qubits, duration_f, \"-o\", label=\"with fractional gates\")\n",
        "plt.xlabel(\"number of qubits\")\n",
        "plt.ylabel(\"duration (µs)\")\n",
        "plt.title(\"Comparison of durations\")\n",
        "plt.grid()\n",
        "plt.legend()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "id": "1383b242",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<matplotlib.legend.Legend at 0x1247fc440>"
            ]
          },
          "execution_count": 22,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/1383b242-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plt.plot(qubits, nnl_c, \"-o\", label=\"no fractional gates\")\n",
        "plt.plot(qubits, nnl_f, \"-o\", label=\"with fractional gates\")\n",
        "plt.xlabel(\"number of qubits\")\n",
        "plt.ylabel(\"number of non-local gates\")\n",
        "plt.title(\"Comparison of numbers of non-local gates\")\n",
        "plt.grid()\n",
        "plt.legend()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "id": "8b4594f5",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<matplotlib.legend.Legend at 0x120b792b0>"
            ]
          },
          "execution_count": 23,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/8b4594f5-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plt.plot(qubits, fidelity_c, \"-o\", label=\"no fractional gates\")\n",
        "plt.plot(qubits, fidelity_f, \"-o\", label=\"with fractional gates\")\n",
        "plt.xlabel(\"number of qubits\")\n",
        "plt.ylabel(\"fidelity\")\n",
        "plt.title(\"Comparison of fidelities\")\n",
        "plt.grid()\n",
        "plt.legend()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9f17acd5",
      "metadata": {},
      "source": [
        "<span id=\"large-scale-hardware-example\" />\n",
        "\n",
        "## 大規模なハードウェアの例\n",
        "\n",
        "このセクションでは、最大40キュービットの量子ハードウェアを用いて、分数ゲートを用いた場合と用いない場合について、量子カーネルワークフローのベンチマーク評価を行う。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fd68378c",
      "metadata": {},
      "source": [
        "<span id=\"step-1-4-combined\" />\n",
        "\n",
        "### ステップ1～4をまとめて\n",
        "\n",
        "このワークフローは、小規模な例と同じ構成になっています。 分数のゲートを含む回路と含まない回路をすべてトランスパイルし、メトリクスを収集した上で、それらの回路を実際の量子ハードウェアに送信します。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "id": "4431bf56",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "job id (w/ fractional gates): d8uasitbh0os73eqnpig\n"
          ]
        }
      ],
      "source": [
        "# -------------------------Step 1-------------------------\n",
        "qubits = list(range(4, 44, 4))\n",
        "circuits = [quantum_kernel(i, reps=reps) for i in qubits]\n",
        "params = [random_parameters(circ) for circ in circuits]\n",
        "b_qc = [\n",
        "    circ.assign_parameters(param) for circ, param in zip(circuits, params)\n",
        "]\n",
        "\n",
        "\n",
        "def benchmark(b_qc, backend):\n",
        "    # -------------------------Step 2-------------------------\n",
        "    pm = generate_preset_pass_manager(optimization_level, backend=backend)\n",
        "    if \"rzz\" in backend.target.operation_names:\n",
        "        # workaround until https://github.com/Qiskit/qiskit-ibm-runtime/issues/2441 is resolved\n",
        "        pm.post_optimization = PassManager(\n",
        "            [\n",
        "                FoldRzzAngle(),\n",
        "                Optimize1qGatesDecomposition(target=backend.target),\n",
        "                RemoveIdentityEquivalent(target=backend.target),\n",
        "            ]\n",
        "        )\n",
        "    t_qc = pm.run(b_qc)\n",
        "    nnl = [qc.num_nonlocal_gates() for qc in t_qc]\n",
        "    depth = [qc.depth() for qc in t_qc]\n",
        "    duration = [\n",
        "        qc.estimate_duration(backend_f.target, unit=\"u\") for qc in t_qc\n",
        "    ]\n",
        "\n",
        "    # -------------------------Step 3-------------------------\n",
        "    sampler = SamplerV2(mode=backend)\n",
        "    sampler.options.dynamical_decoupling.enable = True\n",
        "    sampler.options.dynamical_decoupling.sequence_type = \"XY4\"\n",
        "    sampler.options.dynamical_decoupling.skip_reset_qubits = True\n",
        "    sampler.options.environment.job_tags = [\"TUT_FG\"]\n",
        "    job = sampler.run(t_qc, shots=shots)\n",
        "    job_id = job.job_id()\n",
        "    return nnl, depth, duration, job_id\n",
        "\n",
        "\n",
        "def postprocessing(job_id: str):\n",
        "    # -------------------------Step 4-------------------------\n",
        "    job = service.job(job_id)\n",
        "    result = job.result()\n",
        "    fidelities = [fidelity(result=res) for res in result]\n",
        "    usage = job.usage()\n",
        "    return fidelities, usage\n",
        "\n",
        "\n",
        "backend_f = service.backend(backend_name, use_fractional_gates=True)\n",
        "nnl_f, depth_f, duration_f, job_id_f = benchmark(\n",
        "    b_qc, backend_f\n",
        ")  # step 2 & 3\n",
        "print(\"job id (w/ fractional gates):\", job_id_f)\n",
        "fidelity_f, usage_f = postprocessing(job_id_f)  # step 4"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "id": "4a5d15a2",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "job id (w/o fractional gates): d8uav3lposuc738pruug\n"
          ]
        }
      ],
      "source": [
        "backend_c = service.backend(backend_name, use_fractional_gates=False)\n",
        "nnl_c, depth_c, duration_c, job_id_c = benchmark(b_qc, backend_c)\n",
        "print(\"job id (w/o fractional gates):\", job_id_c)\n",
        "fidelity_c, usage_c = postprocessing(job_id_c)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9f78441e",
      "metadata": {},
      "source": [
        "次に、各指標を比較します。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 26,
      "id": "b409e8d3",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<matplotlib.legend.Legend at 0x12461e660>"
            ]
          },
          "execution_count": 26,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/b409e8d3-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plt.plot(qubits, depth_c, \"-o\", label=\"no fractional gates\")\n",
        "plt.plot(qubits, depth_f, \"-o\", label=\"with fractional gates\")\n",
        "plt.xlabel(\"number of qubits\")\n",
        "plt.ylabel(\"depth\")\n",
        "plt.title(\"Comparison of depths\")\n",
        "plt.grid()\n",
        "plt.legend()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 27,
      "id": "09f91f0f",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<matplotlib.legend.Legend at 0x11f2ac980>"
            ]
          },
          "execution_count": 27,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/09f91f0f-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plt.plot(qubits, duration_c, \"-o\", label=\"no fractional gates\")\n",
        "plt.plot(qubits, duration_f, \"-o\", label=\"with fractional gates\")\n",
        "plt.xlabel(\"number of qubits\")\n",
        "plt.ylabel(\"duration (µs)\")\n",
        "plt.title(\"Comparison of durations\")\n",
        "plt.grid()\n",
        "plt.legend()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 28,
      "id": "c9308517",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<matplotlib.legend.Legend at 0x125c91be0>"
            ]
          },
          "execution_count": 28,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/c9308517-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plt.plot(qubits, nnl_c, \"-o\", label=\"no fractional gates\")\n",
        "plt.plot(qubits, nnl_f, \"-o\", label=\"with fractional gates\")\n",
        "plt.xlabel(\"number of qubits\")\n",
        "plt.ylabel(\"number of non-local gates\")\n",
        "plt.title(\"Comparison of numbers of non-local gates\")\n",
        "plt.grid()\n",
        "plt.legend()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 29,
      "id": "234731d4",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<matplotlib.legend.Legend at 0x11fcf6e40>"
            ]
          },
          "execution_count": 29,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/234731d4-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plt.plot(qubits, fidelity_c, \"-o\", label=\"no fractional gates\")\n",
        "plt.plot(qubits, fidelity_f, \"-o\", label=\"with fractional gates\")\n",
        "plt.xlabel(\"number of qubits\")\n",
        "plt.ylabel(\"fidelity\")\n",
        "plt.title(\"Comparison of fidelities\")\n",
        "plt.grid()\n",
        "plt.legend()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d38b9fe1",
      "metadata": {},
      "source": [
        "分数ゲートの有無によるQPUの使用時間を比較する。 次のセルの結果は、QPUの使用時間がほとんど同じであることを示している。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 30,
      "id": "793326ca",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "no fractional gates: 8 seconds\n",
            "fractional gates: 8 seconds\n"
          ]
        }
      ],
      "source": [
        "print(f\"no fractional gates: {usage_c} seconds\")\n",
        "print(f\"fractional gates: {usage_f} seconds\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "efe18f80",
      "metadata": {},
      "source": [
        "<span id=\"advanced-topic-using-only-fractional-rx-gates\" />\n",
        "\n",
        "## 上級トピック：分数のRXゲートのみを使用する\n",
        "\n",
        "分数ゲートを使用する際にワークフローを変更する必要があるのは、主にRZZゲート角度の制限に起因する。\n",
        "ただし、分数RXゲートのみを使用し、分数RZZゲートを除外する場合は、標準的なQiskitパターンのワークフローに従い続けることができます。\n",
        "このアプローチは、特に多数のRXゲートやUゲートを含む回路において、全体のゲート数を減らし、性能を向上させる可能性があるため、依然として有意義な利点を提供できる。\n",
        "このセクションでは、RZZゲートを省き、分数RXゲートだけを使用して回路を最適化する方法を示す。\n",
        "\n",
        "これをサポートするために、Targetオブジェクトの特定のベーシス・ゲートを無効にできるユーティリティ関数を提供しています。\n",
        "ここでは、RZZゲートを無効にするために使用する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 31,
      "id": "ab43ba23",
      "metadata": {},
      "outputs": [],
      "source": [
        "def remove_instruction_from_target(target: Target, gate_name: str) -> Target:\n",
        "    new_target = Target(\n",
        "        description=target.description,\n",
        "        num_qubits=target.num_qubits,\n",
        "        dt=target.dt,\n",
        "        granularity=target.granularity,\n",
        "        min_length=target.min_length,\n",
        "        pulse_alignment=target.pulse_alignment,\n",
        "        acquire_alignment=target.acquire_alignment,\n",
        "        qubit_properties=target.qubit_properties,\n",
        "        concurrent_measurements=target.concurrent_measurements,\n",
        "    )\n",
        "\n",
        "    for name, qarg_map in target.items():\n",
        "        if name == gate_name:\n",
        "            continue\n",
        "        instruction = target.operation_from_name(name)\n",
        "        if qarg_map == {None: None}:\n",
        "            qarg_map = None\n",
        "        new_target.add_instruction(instruction, qarg_map, name=name)\n",
        "    return new_target"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7f689a02",
      "metadata": {},
      "source": [
        "U、CZ、RZZゲートで構成される回路を例に挙げる。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 32,
      "id": "6b812497",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/6b812497-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 32,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qc = n_local(3, \"u\", \"cz\", \"linear\", reps=1)\n",
        "qc.rzz(1.1, 0, 1)\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fa9dc1c4",
      "metadata": {},
      "source": [
        "まず、分数ゲートをサポートしないバックエンド用に回路をトランスパイルする。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 33,
      "id": "9e8e0709",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "OrderedDict({'rz': 23, 'sx': 16, 'cz': 4})\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/9e8e0709-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 33,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "pm_c = generate_preset_pass_manager(\n",
        "    optimization_level=optimization_level, backend=backend_c\n",
        ")\n",
        "t_qc = pm_c.run(qc)\n",
        "print(t_qc.count_ops())\n",
        "t_qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bd0e24da",
      "metadata": {},
      "source": [
        "次に、RZZゲートを除き、分数RXゲートを用いて同じ回路をトランスパイルする。\n",
        "この結果、RXゲートの効率的な実装により、総ゲート数はわずかに減少した。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 34,
      "id": "db45feb0",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "OrderedDict({'rz': 22, 'sx': 14, 'cz': 4, 'rx': 1})\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/db45feb0-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 34,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "backend_f = service.backend(backend_name, use_fractional_gates=True)\n",
        "target = remove_instruction_from_target(backend_f.target, \"rzz\")\n",
        "pm_f = generate_preset_pass_manager(\n",
        "    optimization_level=optimization_level,\n",
        "    target=target,\n",
        ")\n",
        "t_qc = pm_f.run(qc)\n",
        "print(t_qc.count_ops())\n",
        "t_qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "15140636",
      "metadata": {},
      "source": [
        "<span id=\"optimize-u-gates-with-fractional-rx-gates\" />\n",
        "\n",
        "### 分数の受信ゲートを用いてUゲートを最適化する\n",
        "\n",
        "本節では、前節で紹介した回路をベースに、分数RXゲートを用いてUゲートを最適化する方法を示す。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3f73cbda",
      "metadata": {},
      "source": [
        "RZZゲートを除き、分数RXゲートのみを使用した回路をトランスパイルする。\n",
        "以下に示すように、カスタム分解ルールを導入することで、Uゲートの実装に必要な単一量子ビット・ゲートの数を減らすことができる、 Uゲートの実装に必要な1量子ビットゲートの数を減らすことができる。\n",
        "\n",
        "この機能については、現在[、 GitHub の](https://github.com/Qiskit/qiskit/issues/13455)このイシューで議論されています。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 35,
      "id": "0f0c6d87",
      "metadata": {},
      "outputs": [],
      "source": [
        "# special decomposition rule for UGate\n",
        "x = ParameterVector(\"x\", 3)\n",
        "zxz = QuantumCircuit(1)\n",
        "zxz.rz(x[2] - np.pi / 2, 0)\n",
        "zxz.rx(x[0], 0)\n",
        "zxz.rz(x[1] + np.pi / 2, 0)\n",
        "DEFAULT_EQUIVALENCE_LIBRARY.add_equivalence(UGate(x[0], x[1], x[2]), zxz)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "91c824d8",
      "metadata": {},
      "source": [
        "次に、この `qiskit-basis-constructor` パッケージが提供する変換機能を用いて `constructor-beta` 、トランスパイラーを適用します。\n",
        "その結果、前回のトランスパイレーションと比較して、ゲート総数が減少した。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 36,
      "id": "b19aae7c",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "OrderedDict({'rz': 16, 'rx': 9, 'cz': 4})\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/fractional-gates/extracted-outputs/b19aae7c-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 36,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "pm_f = generate_preset_pass_manager(\n",
        "    optimization_level=optimization_level,\n",
        "    target=target,\n",
        "    translation_method=\"constructor-beta\",\n",
        ")\n",
        "t_qc = pm_f.run(qc)\n",
        "print(t_qc.count_ops())\n",
        "t_qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "23ad4615",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 次のステップ\n",
        "\n",
        "<Admonition type=\"tip\" title=\"推奨事項\">\n",
        "  この作品に興味を持たれた方は、以下の資料もご参考になるかもしれません：\n",
        "\n",
        "  * [フラクショナル・ゲートの](/docs/guides/fractional-gates)ガイド\n",
        "  * [フラクショナルゲートを使用*すべきでない*場合](/docs/guides/fractional-gates#when-not-to-use)\n",
        "  * [`FoldRzzAngle`](/docs/api/qiskit-ibm-runtime/transpiler-passes-fold-rzz-angle) トランスパイラー・パスのAPIリファレンス\n",
        "  * [Quantum](/docs/tutorials/quantum-kernel-training) カーネルのトレーニングチュートリアル\n",
        "  * 「 [Quantum](/learning/courses/quantum-machine-learning/quantum-kernel-methods) Machine Learning」コースの「Quantumカーネル」のレッスン\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"
    },
    "hours": 1,
    "qpuSeconds": 30
  },
  "nbformat": 4,
  "nbformat_minor": 5
}