{
  "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 ’의 ‘음영 [처리된 라이트콘을 이용한 확률적 오류 상쇄(Probabilistic error cancellation with shaded lightcones](/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-큐비트 트로터화(Trotterized) 횡자장 이징(transverse-field Ising) 회로를 구축하고, 중간 큐비트에 대한 단일 큐비트 이진-이진( $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` 이 두 가지를 결합하여 오차 항당 하나의 결합으로 만듭니다. 각 척도를 해당 항의 오차율에 따라 병합합니다. 이러한 비율은 대개 노이즈 학습 실험(예: `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
}