{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "frontmatter",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"クイック・スタート\"\n",
        "description: \"Shaded lightconesの最新バージョンのクイックスタート\"\n",
        "---\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "38de8ef2",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"クイック・スタート\"\n",
        "description: \"Shaded Lightcones Qiskit アドオン（qiskit-addon-slc）のクイックスタートガイド\"\n",
        "---\n",
        "\n",
        "<span id=\"quickstart\" />\n",
        "\n",
        "# クイック・スタート\n",
        "\n",
        "このガイドでは、この `qiskit-addon-slc` パッケージの最小限の動作例を紹介します。 確率的誤差相殺（PEC）のサンプリングコストを低減するため、陰影付きの光錐を計算する。\n",
        "\n",
        "PECは、逆ノイズチャネルの準確率分解からサンプリングを行うことで、ゲートノイズを低減する。 そのサンプリングコストは、軽減しなければならない誤差項が増えるごとに増加する。しかし、すべての誤差が観測量に等しく影響を与えるわけではない。 オブザーバブルの因果光錐の外側にある誤差は、測定された期待値にまったく影響を及ぼすことはなく、また、因果光錐の内側であっても、誤差によっては他のものよりも悪影響が大きいものがある。 陰影付きの光錐は、各パウリ誤差項が観測量に及ぼす影響を境界で囲むことで、これを定量的に表します。 影響が最も小さい誤差項を切り捨てることで、PECが軽減すべきノイズモデルが縮小され、わずかでかつ有限なバイアスを許容する代わりに、サンプリングコストが削減される。\n",
        "\n",
        "現実的なワークフローを構築し、量子ハードウェア上で実行する方法については、 IBM Quantum Platform の「 [シェーディングされたライトコーンを用いた確率的エラーキャンセル](/docs/tutorials/pec-with-shaded-lightcones) 」チュートリアルをご覧ください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "71bc0134",
      "metadata": {},
      "source": [
        "<span id=\"1-prepare-the-inputs-for-slc\" />\n",
        "\n",
        "## 1. SLC用の入力データを準備する\n",
        "\n",
        "ここでは、6量子ビットのトロッター化された横磁場イジング回路を構築し、中央の量子ビットに対して単一量子ビットの $Z$ 観測量を選択する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "0fff4e37",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Observable: IIZIII\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/addons/qiskit-addon-slc/guides/quickstart/extracted-outputs/0fff4e37-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "import numpy as np\n",
        "from qiskit import QuantumCircuit\n",
        "from qiskit.quantum_info import Pauli\n",
        "\n",
        "\n",
        "def trotter_ising_circuit(num_qubits, num_steps, rx_angle, rzz_angle):\n",
        "    \"\"\"Trotterized transverse-field Ising evolution on a 1D chain.\"\"\"\n",
        "    circuit = QuantumCircuit(num_qubits)\n",
        "    for _ in range(num_steps):\n",
        "        circuit.rx(rx_angle, range(num_qubits))\n",
        "        circuit.barrier()\n",
        "        for start in (0, 1):  # even then odd bonds\n",
        "            for i in range(start, num_qubits - 1, 2):\n",
        "                circuit.rzz(rzz_angle, i, i + 1)\n",
        "        circuit.barrier()\n",
        "    return circuit\n",
        "\n",
        "\n",
        "num_qubits = 6\n",
        "circuit = trotter_ising_circuit(\n",
        "    num_qubits, num_steps=2, rx_angle=np.pi / 16, rzz_angle=-np.pi / 2\n",
        ")\n",
        "\n",
        "# Measure <Z> on the middle qubit\n",
        "observable = Pauli(\"I\" * num_qubits).compose(\"Z\", [num_qubits // 2])\n",
        "\n",
        "print(f\"Observable: {observable}\")\n",
        "circuit.draw(\"mpl\", fold=-1, scale=0.7)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9a732427",
      "metadata": {},
      "source": [
        "SLCは、回路内のノイズの多い2量子ビットゲート層上で動作する。 ここでは、ゲートをアノテーション付きボックスにグループ `samplomatic` 化し、各2量子ビット層にノイズ注入のアノテーションを付与する。 `generate_noise_model_paulis` その後、ノイズを含む各層について、パウリ誤差項を列挙する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "3f4301ac",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Noisy layers: 2\n",
            "Pauli error terms across all layers: 102\n"
          ]
        }
      ],
      "source": [
        "from qiskit_addon_slc.utils import generate_noise_model_paulis\n",
        "from samplomatic.transpiler import generate_boxing_pass_manager\n",
        "from samplomatic.utils import find_unique_box_instructions\n",
        "\n",
        "# Group gates into boxes and annotate each two-qubit layer with a noise-injection point\n",
        "boxing_pass = generate_boxing_pass_manager(\n",
        "    inject_noise_targets=\"all\",\n",
        "    inject_noise_strategy=\"individual_modification\",\n",
        "    inject_noise_site=\"after\",\n",
        "    twirling_strategy=\"active\",\n",
        "    remove_barriers=\"never\",\n",
        ")\n",
        "boxed_circuit = boxing_pass.run(circuit)\n",
        "\n",
        "# Enumerate the 1- and 2-weight Pauli error terms of each unique noisy layer\n",
        "noise_model_paulis = generate_noise_model_paulis(\n",
        "    find_unique_box_instructions(boxed_circuit)\n",
        ")\n",
        "\n",
        "num_terms = sum(len(paulis) for paulis in noise_model_paulis.values())\n",
        "print(f\"Noisy layers: {len(noise_model_paulis)}\")\n",
        "print(f\"Pauli error terms across all layers: {num_terms}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "97101eed",
      "metadata": {},
      "source": [
        "<span id=\"2-compute-the-shaded-lightcone\" />\n",
        "\n",
        "## 2. 網掛けされた光錐を計算する\n",
        "\n",
        "陰影で示された光錐は、ノイズモデルにおける各パウリ誤差項が観測量の期待値に及ぼす影響の大きさに基づいて、各誤差項にスケールを割り当てることで構築される。 これらのスケールは、各誤差項の前方誤差限界および後方誤差限界（後述）に加え、その誤差率から導出される：\n",
        "\n",
        "* `compute_forward_bounds` 各誤差項を回路の末端まで*順方向に*展開し、そこで測定される観測量に対するその影響を制限する。\n",
        "* `compute_backward_bounds` 各誤差項を回路の始点まで*遡って*展開し、初期状態への影響を制限する。\n",
        "\n",
        "`merge_bounds` これら2つを組み合わせて、エラー項ごとに1つのバインドとする。 各項の誤差率に応じて、各スケールを統合する。 これらの率は通常、ノイズ学習実験（例： `NoiseLearnerV3`）から得られる； ここでは、簡便のため、ランダムなレートを用いる。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "82205ea3",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.quantum_info import PauliLindbladMap, QubitSparsePauliList\n",
        "from qiskit_addon_slc.bounds import (\n",
        "    compute_backward_bounds,\n",
        "    compute_forward_bounds,\n",
        "    merge_bounds,\n",
        ")\n",
        "\n",
        "forward_bounds = compute_forward_bounds(\n",
        "    boxed_circuit, noise_model_paulis, observable\n",
        ")\n",
        "backward_bounds = compute_backward_bounds(boxed_circuit, noise_model_paulis)\n",
        "\n",
        "# Stand-in for rates that would be measured by a noise-learning experiment on hardware\n",
        "rng = np.random.default_rng(42)\n",
        "noise_rates = {\n",
        "    layer_id: PauliLindbladMap.from_components(\n",
        "        rng.random(len(paulis)) * 5e-3,\n",
        "        QubitSparsePauliList.from_sparse_list(\n",
        "            paulis.to_sparse_list(), paulis.num_qubits\n",
        "        ),\n",
        "    )\n",
        "    for layer_id, paulis in noise_model_paulis.items()\n",
        "}\n",
        "\n",
        "merged_bounds = merge_bounds(\n",
        "    boxed_circuit, forward_bounds, backward_bounds, noise_rates\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c324ebd6",
      "metadata": {},
      "source": [
        "以下の陰影付きライトコーンの可視化図において、各ボックスは、その地点での誤差が観測量に与える影響の大きさに応じて陰影が付けられています。明るいボックスは許容範囲が最も広いことを示し、背景に溶け込むように薄くなっているボックスは、計算にほとんど影響を与えない誤差項を含んでいます。これらの誤差は、ノイズモデルから除外する候補として自然です。 以下の可視化図に示されている値は、その地点におけるすべてのパウリ誤差の誤差範囲の合計を表しています。そのため、一部の値が――単一のパウリ誤差に対する上限値―― `2.0` よりも大きくなっているのです。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "a2201cec",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/addons/qiskit-addon-slc/guides/quickstart/extracted-outputs/a2201cec-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit_addon_slc.visualization import draw_shaded_lightcone\n",
        "\n",
        "draw_shaded_lightcone(boxed_circuit, merged_bounds, noise_model_paulis)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "42483e78",
      "metadata": {},
      "source": [
        "<span id=\"3-reduce-the-sampling-cost\" />\n",
        "\n",
        "## 3. サンプリングコストを削減する\n",
        "\n",
        "`compute_local_scales` 陰影のついた光錐を具体的なPEC構成に変換します。 この手法は、観測量に対する影響が有限である誤差項を優先順位付けし、要求された値 `bias_tolerance` に達するまで、影響が最も小さいものを順次切り捨てていきます。 各エラー項について、緩和措置の際に無視すべき項 `0.0` と、緩和措置を講じるべき項の `-1.0` 重みをそれぞれ返します。 また、この関数は、結果として生じる**サンプリングコストの**オーバーヘッド（ $\\gamma^2$ ）と、切り捨てによって生じる**残留**バイアスの上限値も返します。\n",
        "\n",
        "この設定により、観測量の因果光錐内のすべての誤差項が緩和 `bias_tolerance=0.0` され、ベースラインとなるサンプリングコストが得られる。 わずかなバイアスを許容することで、SLCは影響の小さい項を省略し、そのコストをさらに削減できるようになります。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "31fe87d9",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Full PEC (bias_tolerance=0.0):  sampling cost 1.923, residual bias 0.000\n",
            "Shaded    (bias_tolerance=0.05): sampling cost 1.441, residual bias 0.044\n",
            "\n",
            "Sampling-cost reduction: 25% for <= 0.05 bias\n"
          ]
        }
      ],
      "source": [
        "from qiskit_addon_slc.bounds import compute_local_scales\n",
        "\n",
        "_, full_cost, full_bias = compute_local_scales(\n",
        "    boxed_circuit, merged_bounds, noise_rates, bias_tolerance=0.0\n",
        ")\n",
        "local_scales, reduced_cost, reduced_bias = compute_local_scales(\n",
        "    boxed_circuit, merged_bounds, noise_rates, bias_tolerance=0.05\n",
        ")\n",
        "\n",
        "print(\n",
        "    f\"Full PEC (bias_tolerance=0.0):  sampling cost {full_cost:.3f}, residual bias {full_bias:.3f}\"\n",
        ")\n",
        "print(\n",
        "    f\"Shaded    (bias_tolerance=0.05): sampling cost {reduced_cost:.3f}, residual bias {reduced_bias:.3f}\"\n",
        ")\n",
        "print(\n",
        "    f\"\\nSampling-cost reduction: {(1 - reduced_cost / full_cost):.0%} for <= 0.05 bias\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}