{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "3b140909-ace6-4665-a0bf-f3bb9bd094c0",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Qiskit SDK プリミティブを用いた正確なシミュレーション\"\n",
        "description: \"Qiskitのプリミティブを用いて量子回路を正確にシミュレートする方法\"\n",
        "---\n",
        "\n",
        "<span id=\"exact-simulation-with-qiskit-sdk-primitives\" />\n",
        "\n",
        "# Qiskit SDK プリミティブを用いた正確なシミュレーション\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b820ca5f-60cc-41c7-98db-4b41df4534cc",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "{/*\n",
        "  DO NOT EDIT THIS CELL!!!\n",
        "  This cell's content is generated automatically by a script. Anything you add\n",
        "  here will be removed next time the notebook is run. To add new content, create\n",
        "  a new cell before or after this one.\n",
        "  */}\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"パッケージ・バージョン\">\n",
        "    このページのコードは、以下の要件に基づいて開発された。\n",
        "    これらのバージョンまたは新しいバージョンの使用をお勧めします。\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.1\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "867f73c6-dd57-4755-9bbd-55ffffe7e09e",
      "metadata": {},
      "source": [
        "Qiskit SDK に含まれる参照プリミティブは、局所的な状態ベクトルシミュレーションを実行します。 これらのシミュレーションでは、\n",
        "デバイスのノイズをモデル化することはできませんが、より高度なシミュレーション\n",
        "手法（ [Qiskit Aerの使用](/docs/guides/simulate-stabilizer-circuits) ）を検討したり、実デバイス上で実行したり（ [IBM Quantum プリミティブ](primitives) ）する前に、アルゴリズムの迅速なプロトタイピングを行う上で役立ちます。\n",
        "\n",
        "Estimatorプリミティブは回路の期待値を計算することができ、Samplerプリミティブは回路の出力分布からサンプリングすることができる。 プリミティブは回路の出力分布から\n",
        "\n",
        "以下のセクションでは、参照プリミティブを使用してワークフローをローカルで実行する方法を示します。\n",
        "\n",
        "<span id=\"use-the-reference-estimator\" />\n",
        "\n",
        "## 参照用見積もりツールを使用する\n",
        "\n",
        "`qiskit.primitives` 、ローカルの状態ベクトル・シミュレータ上で動作する `EstimatorV2` 。 シミュレータは [`StatevectorEstimator`](../api/qiskit/qiskit.primitives.StatevectorEstimator) クラスである。 回路、観測値、パラメータを入力とし、局所的に計算された期待値を返す。\n",
        "\n",
        "以下のコードは、これから紹介する例で使用する入力データを準備するものです。 オブザーバブルの\n",
        "期待される入力型は です [`qiskit.quantum_info.SparsePauliOp`](../api/qiskit/qiskit.quantum_info.SparsePauliOp)。 なお、\n",
        "この例の回路はパラメータ化されていますが、パラメータ化されていない回路に対してもEstimatorを実行することができます。\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Estimator に渡される回路には、 **測定値**を含め**ない**でください。\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "5b41a52d-8f15-4ce4-b3f6-effd91946d9c",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/simulate-with-qiskit-sdk-primitives/extracted-outputs/5b41a52d-8f15-4ce4-b3f6-effd91946d9c-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "from qiskit.circuit import Parameter\n",
        "\n",
        "# circuit for which you want to obtain the expected value\n",
        "circuit = QuantumCircuit(2)\n",
        "circuit.ry(Parameter(\"theta\"), 0)\n",
        "circuit.h(0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.draw(\"mpl\", style=\"iqp\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "18658518-304a-49a7-8958-82adef366de6",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.quantum_info import SparsePauliOp\n",
        "import numpy as np\n",
        "\n",
        "# observable(s) whose expected values you want to compute\n",
        "\n",
        "observable = SparsePauliOp([\"II\", \"XX\", \"YY\", \"ZZ\"], coeffs=[1, 1, -1, 1])\n",
        "\n",
        "# value(s) for the circuit parameter(s)\n",
        "parameter_values = [[0], [np.pi / 6], [np.pi / 2]]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4c39904c-d586-41b9-ade0-e6a508ef7c2e",
      "metadata": {},
      "source": [
        "<Admonition type=\"tip\" title=\"ISA回路とオブザーバブルへのトランスパイル\">\n",
        "  IBM Quantum プリミティブのワークフローでは、回路およびオブザーバブルを、QPUがサポートする命令のみを使用するように変換する必要があります（これを「 *命令セットアーキテクチャ（ISA）* 回路およびオブザーバブル」と呼びます）。 参照プリミティブは、ローカルな状態ベクトルのシミュレーションに依存しているため、依然として抽象的な命令を受け付けますが、回路のトランスパイルを行うことは、回路の最適化という観点からは依然として有益である可能性があります。\n",
        "\n",
        "  ```python\n",
        "  # Generate a pass manager without providing a backend\n",
        "  from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "  pm = generate_preset_pass_manager(optimization_level=1)\n",
        "  isa_circuit = pm.run(circuit)\n",
        "  isa_observable = observable.apply_layout(isa_circuit.layout)\n",
        "  ```\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"initialize-estimator\" />\n",
        "\n",
        "### 推定器を初期化する\n",
        "\n",
        "をインスタンス化する。 [`qiskit.primitives.StatevectorEstimator`](../api/qiskit/qiskit.primitives.StatevectorEstimator).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "56f39026-7874-4f14-8529-b97df373eaf5",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.primitives import StatevectorEstimator\n",
        "\n",
        "estimator = StatevectorEstimator()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9c4c81b1-8b87-450d-9a93-4f209364ee83",
      "metadata": {},
      "source": [
        "<span id=\"run-and-get-results\" />\n",
        "\n",
        "### 走って結果を出せ\n",
        "\n",
        "この例では [`QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit)と 観測可能です。\n",
        "\n",
        "を呼び出して推定を実行する。 [`StatevectorEstimator.run`](../api/qiskit/qiskit.primitives.StatevectorEstimator#run) オブジェクトのインスタンスを返す [`PrimitiveJob`](/docs/api/qiskit/qiskit.primitives.PrimitiveJob) オブジェクトのインスタンスを返します。 ジョブから（オブジェクトとして）結果を得ることができます。 [`qiskit.primitives.PrimitiveResult`](../api/qiskit/qiskit.primitives.PrimitiveResult) オブジェクトとして) オブジェクトとして [`qiskit.primitives.PrimitiveJob.result`](../api/qiskit/qiskit.primitives.PrimitiveJob#result) メソッドで取得できます。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "0c424291-abb3-420c-80e1-a09ecbd6c035",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            " > Result class: <class 'qiskit.primitives.containers.primitive_result.PrimitiveResult'>\n"
          ]
        }
      ],
      "source": [
        "job = estimator.run([(circuit, observable, parameter_values)])\n",
        "result = job.result()\n",
        "print(f\" > Result class: {type(result)}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "871ce7d6-402c-417f-8a83-805d92fa0298",
      "metadata": {},
      "source": [
        "<span id=\"get-the-expected-value-from-the-result\" />\n",
        "\n",
        "#### 結果から期待値を取得する\n",
        "\n",
        "プリミティブの結果はオブジェクト [`PubResult`](/docs/api/qiskit/qiskit.primitives.PubResult#pubresult) の配列を出力し、配列の各要素は PUB 内のすべての回路-観測可能な組み合わせに対応する評価の配列をデータに含むオブジェクト `PubResult` である。\n",
        "\n",
        "最初の（そしてこの場合は唯一の）回路評価の期待値とメタデータを取得するには、評価にアクセスする必要があります。 [`data`](/docs/api/qiskit/qiskit.primitives.PubResult#data) にアクセスする必要があります。 PUB 0：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "145b3f62-dfaf-4288-8764-f2ecb90e38a1",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            " > Expectation value: [4.         3.73205081 2.        ]\n",
            " > Metadata: {'target_precision': 0.0, 'circuit_metadata': {}}\n"
          ]
        }
      ],
      "source": [
        "print(f\" > Expectation value: {result[0].data.evs}\")\n",
        "print(f\" > Metadata: {result[0].metadata}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e29ec8cc-2c38-464a-a8b3-8f05b282c807",
      "metadata": {},
      "source": [
        "<span id=\"set-estimator-run-options\" />\n",
        "\n",
        "### セット推定器の実行オプションを設定する\n",
        "\n",
        "デフォルトでは、リファレンス・エスティメータは [`quantum_info.Statevector`](../api/qiskit/qiskit.quantum_info.Statevector) クラスを使用します。\n",
        "しかし、これはサンプリング・オーバーヘッド（「ショット・ノイズ」とも呼ばれる）の影響を導入するために修正することができる。\n",
        "\n",
        "Estimatorは `precision` 。 プリミティブの実装が期待値の推定に目標とすべきエラーバーを表します。  これはサンプリングのオーバーヘッドで、 `.run()` メソッドでのみ定義されている。 これにより、 PUB レベルまでオプションを微調整できる。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "04047e7a-23f4-431b-8e3a-11edf035e8fc",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Estimate expectation values for two PUBs, both with 0.05 precision.\n",
        "precise_job = estimator.run(\n",
        "    [(circuit, observable, parameter_values)], precision=0.05\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d54f110f-004a-4337-8b4d-7d4287f22be9",
      "metadata": {},
      "source": [
        "完全な例については、 [「Estimator」のサンプル](/docs/guides/estimator-examples)ページをご覧ください。\n",
        "\n",
        "<span id=\"use-the-reference-sampler\" />\n",
        "\n",
        "## 参照サンプラーを使用する\n",
        "\n",
        "`qiskit.primitives` における `SamplerV2` の参照実装は [`StatevectorSampler`](../api/qiskit/qiskit.primitives.StatevectorSampler) クラスである。 回路とパラメータを入力とし、出力確率分布からサンプリングした結果を出力状態の準確率分布として返す。\n",
        "\n",
        "以下のコードは、以降の例で使用される入力データを準備するものです。 なお、\n",
        "これらの例では単一のパラメータ化された回路を実行していますが、\n",
        "パラメータ化されていない回路でもSamplerを実行することができます。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "d4c0ac3b-8e5b-4cde-bb26-256324982c2c",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/simulate-with-qiskit-sdk-primitives/extracted-outputs/d4c0ac3b-8e5b-4cde-bb26-256324982c2c-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "\n",
        "circuit = QuantumCircuit(2)\n",
        "circuit.h(0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.measure_all()\n",
        "circuit.draw(\"mpl\", style=\"iqp\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b34ae490-9efb-45f5-937d-3ce86afa445f",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\">\n",
        "  サンプラーに渡される量子回路には、測定値が含まれて**いなければならない**。\n",
        "</Admonition>\n",
        "\n",
        "<Admonition type=\"tip\" title=\"ISA回路とオブザーバブルへのトランスパイル\">\n",
        "  IBM Quantum プリミティブのワークフローでは、回路を、QPUがサポートする命令のみを使用するように変換する必要があります（これを「ISA回路」と呼びます）。 参照プリミティブは、ローカルな状態ベクトルのシミュレーションに依存しているため、依然として抽象的な命令を受け付けますが、回路のトランスパイルを行うことは、回路の最適化という観点からは依然として有益である可能性があります。\n",
        "\n",
        "  ```python\n",
        "  # Generate a pass manager without providing a backend\n",
        "  from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "  pm = generate_preset_pass_manager(optimization_level=1)\n",
        "  isa_circuit = pm.run(qc)\n",
        "  ```\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"initialize-samplerv2\" />\n",
        "\n",
        "### 初期化 `SamplerV2`\n",
        "\n",
        "インスタンス [`qiskit.primitives.StatevectorSampler`](../api/qiskit/qiskit.primitives.StatevectorSampler):\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "626177e7-f06a-4216-89c8-daf703520457",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.primitives import StatevectorSampler\n",
        "\n",
        "sampler = StatevectorSampler()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "626fb8d6-75ae-47b2-ac0b-00acc4ce5afe",
      "metadata": {},
      "source": [
        "<span id=\"run-and-get-results\" />\n",
        "\n",
        "### 走って結果を出せ\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "19659756-a01d-42ec-8fa7-d7a1bf2303d5",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            " > Result class: <class 'qiskit.primitives.containers.sampler_pub_result.SamplerPubResult'>\n"
          ]
        }
      ],
      "source": [
        "# execute 1 circuit with Sampler\n",
        "job = sampler.run([circuit])\n",
        "pub_result = job.result()[0]\n",
        "print(f\" > Result class: {type(pub_result)}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ee6d88f3-0115-4ea9-a2c5-633906841d9f",
      "metadata": {},
      "source": [
        "プリミティブは複数のPUBを入力として受け入れ、 PUB、それぞれ独自の結果を得る。 したがって、さまざまなパラメータと観測値の組み合わせで異なる回路を実行し、 PUB ：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "fb91dbfc-0340-4ea6-8d33-95357d7907e3",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            " > Result class: <class 'qiskit.primitives.containers.sampler_pub_result.SamplerPubResult'>\n"
          ]
        }
      ],
      "source": [
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "# create two circuits\n",
        "circuit1 = circuit.copy()\n",
        "circuit2 = circuit.copy()\n",
        "\n",
        "# transpile circuits\n",
        "pm = generate_preset_pass_manager(optimization_level=1)\n",
        "isa_circuit1 = pm.run(circuit1)\n",
        "isa_circuit2 = pm.run(circuit2)\n",
        "# execute 2 circuits using Sampler\n",
        "job = sampler.run([(isa_circuit1), (isa_circuit2)])\n",
        "pub_result_1 = job.result()[0]\n",
        "pub_result_2 = job.result()[1]\n",
        "print(f\" > Result class: {type(pub_result)}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6e7b2199-3c00-477a-a248-824b442431b5",
      "metadata": {},
      "source": [
        "<span id=\"get-the-probability-distribution-or-measurement-outcome\" />\n",
        "\n",
        "### 確率分布または測定結果を取得する\n",
        "\n",
        "測定結果のサンプルは、 **ビット列**または**カウントとして**返される。 ビット列は、測定されたショット順を保ったまま、測定結果を示している。 サンプラーの結果オブジェクトは、ダイナミック回路との互換性を保つため、入力回路の古典的なレジスタ名でデータを整理する。\n",
        "\n",
        "<Admonition>\n",
        "  クラシック・レジスタの名前のデフォルトは `\"meas\"`。 この名前は、あとで計測ビット列にアクセスするときに使う。\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "1dc395b4-5716-44be-9622-7c99df95616b",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "        ┌───┐      ░ ┌─┐   \n",
              "   q_0: ┤ H ├──■───░─┤M├───\n",
              "        └───┘┌─┴─┐ ░ └╥┘┌─┐\n",
              "   q_1: ─────┤ X ├─░──╫─┤M├\n",
              "             └───┘ ░  ║ └╥┘\n",
              "meas: 2/══════════════╩══╩═\n",
              "                      0  1 "
            ]
          },
          "execution_count": 11,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Define quantum circuit with 2 qubits\n",
        "circuit = QuantumCircuit(2)\n",
        "circuit.h(0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.measure_all()\n",
        "circuit.draw()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "27a2847b-6553-4c73-9b8a-85ba28725ed8",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The number of bitstrings is: 1024\n",
            "The counts are: {'00': 538, '11': 486}\n"
          ]
        }
      ],
      "source": [
        "# Transpile circuit\n",
        "pm = generate_preset_pass_manager(optimization_level=1)\n",
        "isa_circuit = pm.run(circuit)\n",
        "# Run using Sampler\n",
        "result = sampler.run([circuit]).result()\n",
        "# Access result data for PUB 0\n",
        "data_pub = result[0].data\n",
        "# Access bitstring for the classical register \"meas\"\n",
        "bitstrings = data_pub.meas.get_bitstrings()\n",
        "print(f\"The number of bitstrings is: {len(bitstrings)}\")\n",
        "# Get counts for the classical register \"meas\"\n",
        "counts = data_pub.meas.get_counts()\n",
        "print(f\"The counts are: {counts}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "de705fab-e718-4924-a03f-f19bdf6578d8",
      "metadata": {},
      "source": [
        "<span id=\"change-run-options\" />\n",
        "\n",
        "### 実行オプションを変更する\n",
        "\n",
        "デフォルトでは、リファレンス・サンプラーは [`quantum_info.Statevector`](../api/qiskit/qiskit.quantum_info.Statevector) クラス。\n",
        "しかし、これはサンプリング・オーバーヘッド（「ショット・ノイズ」とも呼ばれる）の影響を導入するために修正することができる。 このオーバーヘッドを管理するために、サンプラーインターフェイスは PUB レベルで定義できる `shots` 引数を受け付ける。\n",
        "\n",
        "この例では、2つの回路を定義したと仮定しています。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "927faaab-60c0-4b73-bf53-72f7c4c9ad65",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<qiskit.primitives.primitive_job.PrimitiveJob at 0x7f94d59db010>"
            ]
          },
          "execution_count": 13,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Sample two circuits at 128 shots each.\n",
        "sampler.run([isa_circuit1, isa_circuit2], shots=128)\n",
        "# Sample two circuits at different amounts of shots. The \"None\"s are necessary\n",
        "# as placeholders\n",
        "# for the lack of parameter values in this example.\n",
        "sampler.run([(isa_circuit1, None, 123), (isa_circuit2, None, 456)])"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1c0e76fe-4b5d-4fd4-9eec-da5332d76cfb",
      "metadata": {},
      "source": [
        "完全な例については、 [「Sampler」のサンプル](/docs/guides/sampler-examples)ページをご覧ください。\n",
        "\n",
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 次のステップ\n",
        "\n",
        "<Admonition type=\"tip\" title=\"推奨事項\">\n",
        "  * より大規模な回路を扱える、より高性能なシミュレーションや、シミュレーションにノイズモデルを組み込むには、 [Qiskit Aerプリミティブによる正確でノイズの少ないシミュレーションを](simulate-with-qiskit-aer)参照してください。\n",
        "  * シミュレーションにQuantum Composerを使用する方法については、 [IBM Quantum Composer](/docs/guides/composer) ガイドを参照してください。\n",
        "  * [Qiskit Estimator API](/docs/api/qiskit/1.4/qiskit.primitives.Estimator) リファレンスをお読みください。\n",
        "  * [Qiskit Sampler API](/docs/api/qiskit/1.4/qiskit.primitives.Sampler) リファレンスをお読みください。\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}