{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "0ff6f833-f5fb-4e9e-a572-445f2ff9ad64",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"プリミティブな入出力\"\n",
        "description: \"Qiskit SDK プリミティブの入力および出力形式（プリミティブ統一ブロック（PUB）を含む）を理解する\"\n",
        "---\n",
        "\n",
        "<span id=\"primitive-inputs-and-outputs\" />\n",
        "\n",
        "# プリミティブな入出力\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "36a00905-1855-4fce-9686-20eb01ba72b6",
      "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": "203951dd-4da7-4e0d-93f7-3ed7e2cd624b",
      "metadata": {},
      "source": [
        "このページでは、 Qiskit SDK プリミティブの入力と出力の概要を説明します。 これらのプリミティブを使用することで、「 **プリミティブ統合ブロック（ PUB ）** 」と呼ばれるデータ構造を活用し、ベクトル化されたワークロードを効率的に定義することができます。 これらのPUBは、ワークロード実行における基本的な処理単位です。 これらは、Sampler および Estimator プリミティブのメソッド `run()` への入力として使用され、定義されたワークロードをジョブとして実行します。 その後、ジョブが完了すると、使用されたPUBや指定されたオプションに応じて、結果が所定の形式で返されます。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c7bc7444-eada-42ec-8f9a-6ec848c40014",
      "metadata": {},
      "source": [
        "<span id=\"pubs\" />\n",
        "\n",
        "<span id=\"overview-of-pubs\" />\n",
        "\n",
        "## パブの概要\n",
        "\n",
        "プリミティブ `run()` のメソッドを呼び出す際、必須の主な引数は、1つ以上のタプルから `list` なるリストです。このタプルは、プリミティブによって実行される各回路に対応します。 これらのタプルはそれぞれ PUB と見なされ、リスト内の各タプルに必要な要素は、使用されるプリミティブ型によって異なります。 これらのタプルに提供されるデータは、ブロードキャストによってさまざまな形式に配置することも可能であり、これによりワークロードの柔軟性を高めることができます。そのルールについては、 [次のセクション](#broadcasting-rules)で説明します。\n",
        "\n",
        "<span id=\"estimator-pub\" />\n",
        "\n",
        "### 見積もりツール PUB\n",
        "\n",
        "Estimatorプリミティブの場合、 PUB のフォーマットは最大4つの値を含むべきである：\n",
        "\n",
        "* 1つの `QuantumCircuit` には1つ以上のオブジェクトが含まれる。 [`Parameter`](/docs/api/qiskit/qiskit.circuit.Parameter) オブジェクト\n",
        "* 推定する期待値を指定する1つ以上の観測値を配列に並べたリスト（例えば、1つの観測値は0-d配列、観測値のリストは1-d配列、など）。 データは、 `Pauli`、 `SparsePauliOp`、 `PauliList`、 `str` のような `ObservablesArrayLike` フォーマットのいずれかである。\n",
        "  <Admonition type=\"note\">\n",
        "    異なるPUBに属するが同じ回路を持つ2つの通勤可能な観測可能量が存在する場合、それらは同じ測定値を用いて推定されることはない。 各 PUB は異なる測定基準を表すため、各 PUB ごとに個別の測定が必要となる。 通勤観測量が同一の測定値を用いて推定されることを保証するには、それらを同一の PUB 内にグループ化する必要がある。\n",
        "  </Admonition>\n",
        "* 回路をバインドするパラメータ値のコレクション。 これは、最後のインデックスが回路 `Parameter` オブジェクトの上にある1つの配列のようなオブジェクトとして指定することができ、回路に `Parameter` オブジェクトがない場合は省略される（または等価的に、 `None` に設定される）。\n",
        "* (オプション）推定する期待値の目標精度\n",
        "\n",
        "<span id=\"sampler-pub\" />\n",
        "\n",
        "### サンプラー PUB\n",
        "\n",
        "Samplerプリミティブの場合、 PUB タプルの形式には最大3つの値が含まれます：\n",
        "\n",
        "* 1つ以上の [`Parameter`](/docs/api/qiskit/qiskit.circuit.Parameter) オブジェクトを含む単一 `QuantumCircuit`の\n",
        "  *注：これらの回路には*、サンプリング対象となる各量子ビットに対する測定命令も含まれている必要があります。\n",
        "* $\\theta_k$ に対して回路をバインドするためのパラメータ値のコレクション（実行時にバインドする必要がある `Parameter` オブジェクトが使用されている場合にのみ必要）\n",
        "* (オプションで)回路を測定するためのショット数\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2bdb4618-e59f-4627-81b6-6828b40258f7",
      "metadata": {},
      "source": [
        "***\n",
        "\n",
        "以下のコードは、プリミティブ `Estimator` へのベクトル化された入力の例を示しています。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "e84f14f0-7190-4ab6-ba49-2746c515238c",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit import (\n",
        "    Parameter,\n",
        "    QuantumCircuit,\n",
        "    ClassicalRegister,\n",
        "    QuantumRegister,\n",
        ")\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit.primitives.containers import BitArray\n",
        "from qiskit.primitives import StatevectorEstimator\n",
        "\n",
        "\n",
        "import numpy as np\n",
        "\n",
        "# Define a circuit with two parameters.\n",
        "circuit = QuantumCircuit(2)\n",
        "circuit.h(0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.ry(Parameter(\"a\"), 0)\n",
        "circuit.rz(Parameter(\"b\"), 0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.h(0)\n",
        "\n",
        "# Transpile the circuit without providing a backend\n",
        "pm = generate_preset_pass_manager(optimization_level=1)\n",
        "transpiled_circuit = pm.run(circuit)\n",
        "layout = transpiled_circuit.layout\n",
        "\n",
        "# Now define a sweep over parameter values, the last axis of dimension 2 is\n",
        "# for the two parameters \"a\" and \"b\"\n",
        "params = np.vstack(\n",
        "    [\n",
        "        np.linspace(-np.pi, np.pi, 10),\n",
        "        np.linspace(-4 * np.pi, 4 * np.pi, 10),\n",
        "    ]\n",
        ").T\n",
        "\n",
        "# Define three observables. The inner length-1 lists cause this array of\n",
        "# observables to have shape (3, 1), rather than shape (3,) if they were\n",
        "# omitted.\n",
        "observables = [\n",
        "    [SparsePauliOp([\"XX\", \"IY\"], [0.5, 0.5])],\n",
        "    [SparsePauliOp(\"XX\")],\n",
        "    [SparsePauliOp(\"IY\")],\n",
        "]\n",
        "# Apply the same layout as the transpiled circuit.\n",
        "observables = [\n",
        "    [observable.apply_layout(layout) for observable in observable_set]\n",
        "    for observable_set in observables\n",
        "]\n",
        "\n",
        "# Estimate the expectation value for all 300 combinations of observables\n",
        "# and parameter values, where the pub result will have shape (3, 100).\n",
        "#\n",
        "# This shape is due to our array of parameter bindings having shape\n",
        "# (100, 2), combined with our array of observables having shape (3, 1).\n",
        "estimator = StatevectorEstimator()\n",
        "estimator_pub = (transpiled_circuit, observables, params)\n",
        "\n",
        "# Run the transpiled circuit\n",
        "# using the set of parameters and observables.\n",
        "\n",
        "job = estimator.run([estimator_pub])\n",
        "result = job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3acc54a9-ab50-4155-9c2d-c6a75dba816d",
      "metadata": {},
      "source": [
        "<span id=\"broadcasting\" />\n",
        "\n",
        "<span id=\"broadcasting-rules\" />\n",
        "\n",
        "### 放送規則\n",
        "\n",
        "PUBは、 NumPy と同じブロードキャストルールに従って、複数の配列（観測値とパラメータ値）から要素を集約する。 このセクションでは、それらのルールを簡単にまとめる。  詳細な説明については、 [NumPy 放送ルールのドキュメントを](https://numpy.org/doc/stable/user/basics.broadcasting.html)参照のこと。\n",
        "\n",
        "規則:\n",
        "\n",
        "* 入力配列は同じ次元数である必要はない。\n",
        "  * 結果として得られる配列は、最大次元の入力配列と同じ次元数になる。\n",
        "  * 各次元のサイズは、対応する次元の最大サイズである。\n",
        "  * 欠けている寸法は、サイズが1であると仮定される。\n",
        "* 形状の比較は、一番右の寸法から始まり、左へと続く。\n",
        "* 2つの次元は、その大きさが等しいか、どちらかが1であれば互換性がある。\n",
        "\n",
        "ブロードキャストする配列ペアの例：\n",
        "\n",
        "```text\n",
        "A1     (1d array):      1\n",
        "A2     (2d array):  3 x 5\n",
        "Result (2d array):  3 x 5\n",
        "\n",
        "\n",
        "A1     (3d array):  11 x 2 x 7\n",
        "A2     (3d array):  11 x 1 x 7\n",
        "Result (3d array):  11 x 2 x 7\n",
        "```\n",
        "\n",
        "ブロードキャストしない配列ペアの例：\n",
        "\n",
        "```text\n",
        "A1     (1d array):  5\n",
        "A2     (1d array):  3\n",
        "\n",
        "A1     (2d array):      2 x 1\n",
        "# The following would work if the middle dimension were 2,\n",
        "# instead of 5.\n",
        "A2     (3d array):  6 x 5 x 4\n",
        "```\n",
        "\n",
        "`Estimator` ブロードキャストされた形状の各要素に対して、1つの期待値の推定値を返します。\n",
        "\n",
        "以下は、配列放送で表現される一般的なパターンの例である。  それに伴う視覚的な表現を次の図に示す：\n",
        "\n",
        "パラメータ値セットはn×mの配列で表現され、観測可能配列は1つ以上の1列の配列で表現される。 前のコードの各例について、パラメータ値セットは、結果の期待値推定値を作成するために、それらの観測可能な配列と組み合わされる。\n",
        "\n",
        "* *例1* : (broadcast single observable)は 5x1 配列と 1x1 observables配列のパラメータ値セットを持っています。  observables配列の1つの項目は、パラメータ値セットの各項目と組み合わされ、各項目がパラメータ値セットの元の項目とobservables配列の項目の組み合わせである1つの 5x1 配列を作成する。\n",
        "\n",
        "* *例2* : (zip)は 5x1 パラメータ値セットと 5x1 observables配列を持っています。  出力は 5x1 の配列で、各項目はパラメータ値セットのn番目の項目とobservables配列のn番目の項目の組み合わせである。\n",
        "\n",
        "* *例3* : (outer/product)は 1x6 パラメータ値セットと 4x1 observables配列を持っています。  これらの組み合わせの結果、 4x6 配列が作成される。この配列は、パラメータ値セットの各項目とobservables配列の*各項目を*組み合わせることによって作成されるため、各パラメータ値は出力の列全体となる。\n",
        "\n",
        "* *例4* : (Standard ndの一般化)は、 3x6 パラメータ値セット配列と、 3x1 2つの観測値配列を持っています。  これらを組み合わせて、先の例と同様の方法で2つの 3x6 出力アレイを作成する。\n",
        "\n",
        "![この図は、配列のブロードキャスティングを視覚的に表したいくつかの例を示しています。ブロードキャスティングの](https://quantum.cloud.ibm.com/docs/images/guides/primitive-input-output/broadcasting.avif \"視覚的表現\")\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "37aa226f-d550-42fd-9ab0-60e27757722a",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Broadcast single observable\n",
        "parameter_values = np.random.uniform(size=(5,))  # shape (5,)\n",
        "observables = SparsePauliOp(\"ZZZ\")  # shape ()\n",
        "# >> pub result has shape (5,)\n",
        "\n",
        "# Zip\n",
        "parameter_values = np.random.uniform(size=(5,))  # shape (5,)\n",
        "observables = [\n",
        "    SparsePauliOp(pauli) for pauli in [\"III\", \"XXX\", \"YYY\", \"ZZZ\", \"XYZ\"]\n",
        "]  # shape (5,)\n",
        "# >> pub result has shape (5,)\n",
        "\n",
        "# Outer/Product\n",
        "parameter_values = np.random.uniform(size=(1, 6))  # shape (1, 6)\n",
        "observables = [\n",
        "    [SparsePauliOp(pauli)] for pauli in [\"III\", \"XXX\", \"YYY\", \"ZZZ\"]\n",
        "]  # shape (4, 1)\n",
        "# >> pub result has shape (4, 6)\n",
        "\n",
        "# Standard nd generalization\n",
        "parameter_values = np.random.uniform(size=(3, 6))  # shape (3, 6)\n",
        "observables = [\n",
        "    [\n",
        "        [SparsePauliOp([\"XII\"])],\n",
        "        [SparsePauliOp([\"IXI\"])],\n",
        "        [SparsePauliOp([\"IIX\"])],\n",
        "    ],\n",
        "    [\n",
        "        [SparsePauliOp([\"ZII\"])],\n",
        "        [SparsePauliOp([\"IZI\"])],\n",
        "        [SparsePauliOp([\"IIZ\"])],\n",
        "    ],\n",
        "]  # shape (2, 3, 1)\n",
        "# >> pub result has shape (2, 3, 6)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "408e47b0-24ca-45b5-b71b-080d8ccf30a6",
      "metadata": {},
      "source": [
        "<Admonition type=\"tip\" title=\"SparsePauliOp\">\n",
        "  この文脈では、 `SparsePauliOp` に含まれるパウリの数に関係なく、各 `SparsePauliOp` は1つの要素としてカウントされる。 したがって、この放送ルールでは、以下の要素はすべて同じ形状を持つ：\n",
        "\n",
        "  ```text\n",
        "  a = SparsePauliOp(\"Z\") # shape ()\n",
        "  b = SparsePauliOp(\"IIIIZXYIZ\") # shape ()\n",
        "  c = SparsePauliOp.from_list([\"XX\", \"XY\", \"IZ\"]) # shape ()\n",
        "  ```\n",
        "\n",
        "  以下の演算子のリストは、含まれる情報の点では同等だが、形状が異なる：\n",
        "\n",
        "  ```text\n",
        "  list1 = SparsePauliOp.from_list([\"XX\", \"XY\", \"IZ\"])\n",
        "      # list1 has shape ()\n",
        "  list2 = [SparsePauliOp(\"XX\"), SparsePauliOp(\"XY\"), SparsePauliOp(\"IZ\")]\n",
        "      # list2 has shape (3, )\n",
        "  ```\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f548b270-afa7-480c-a457-c5260791d55b",
      "metadata": {},
      "source": [
        "<span id=\"overview-of-primitive-outputs\" />\n",
        "\n",
        "## プリミティブ出力の概要\n",
        "\n",
        "1つ以上のPUBがQPUに送信されて実行され、ジョブが正常に完了すると、データはコンテナ [`PrimitiveResult`](/docs/api/qiskit/qiskit.primitives.PrimitiveResult) オブジェクトとして返されます。 には、各 `PrimitiveResult`PUB の実行結果を含む [`PubResult`](/docs/api/qiskit/qiskit.primitives.PubResult) オブジェクトの反復可能なリストが含まれています。 たとえば、20個のPUBを指定してジョブを実行すると、各 PUB に対応する20個のリストを含むオブジェクト `PrimitiveResult``PubResults` が返されます。\n",
        "\n",
        "これらの `PubResult` オブジェクトはそれぞれ、属性 `data` と、オプションの `metadata` 属性を持ちます。 この `data` 属性は、Estimatorの場合は期待値の推定値を、Samplerの場合は回路出力のサンプル値を含む、 [`DataBin`](/docs/api/qiskit/qiskit.primitives.DataBin) カスタマイズされたものです。\n",
        "\n",
        "この `data` 属性には、標準偏差など、実装固有のその他の情報も含まれる場合があります。 この `metadata` 属性には、関連する PUB の実行に関する、実装固有の追加情報を含めることができます。\n",
        "\n",
        "以下は、 `PrimitiveResult` データ構造の視覚的アウトラインである：\n",
        "\n",
        "<Tabs>\n",
        "  <TabItem value=\"estimator\" label=\"Estimator output\">\n",
        "    ```\n",
        "    └── PrimitiveResult\n",
        "        ├── PubResult[0]\n",
        "        │   ├── metadata\n",
        "        │   └── data  ## In the form of a DataBin object,\n",
        "        |       |     ## which includes data such as the following:\n",
        "        │       ├── evs\n",
        "        │       │   └── List of estimated expectation values in the shape\n",
        "        |       |         specified by the first pub\n",
        "        │       └── stds\n",
        "        │           └── List of calculated standard deviations in the\n",
        "        |                 same shape as above\n",
        "        ├── PubResult[1]\n",
        "        |   ├── metadata\n",
        "        |   └── data  ## In the form of a DataBin object,\n",
        "        |       |     ## which includes data such as the following:\n",
        "        |       ├── evs\n",
        "        |       │   └── List of estimated expectation values in the shape\n",
        "        |       |        specified by the second pub\n",
        "        |       └── stds\n",
        "        |           └── List of calculated standard deviations in the\n",
        "        |                same shape as above\n",
        "        ├── ...\n",
        "        ├── ...\n",
        "        └── ...\n",
        "    ```\n",
        "\n",
        "    <Admonition type=\"note\">\n",
        "      上記は、返される可能性のあるデータの例です。  実際に返されるデータは、実装によって異なります。\n",
        "    </Admonition>\n",
        "  </TabItem>\n",
        "\n",
        "  <TabItem value=\"sampler\" label=\"Sampler output\">\n",
        "    ```\n",
        "    └── PrimitiveResult\n",
        "        ├── PubResult[0]\n",
        "        │   ├── metadata\n",
        "        │   └── data  ## In the form of a DataBin object\n",
        "        │       ├── NAME_OF_CLASSICAL_REGISTER\n",
        "        │       │   └── BitArray of count data for first PUB (default is 'meas')\n",
        "        |       |\n",
        "        │       └── NAME_OF_ANOTHER_CLASSICAL_REGISTER\n",
        "        │           └── BitArray of count data (exists only if more than one\n",
        "        |                 ClassicalRegister was specified in the circuit)\n",
        "        ├── PubResult[1]\n",
        "        |   ├── metadata\n",
        "        |   └── data  ## In the form of a DataBin object\n",
        "        |       └── NAME_OF_CLASSICAL_REGISTER\n",
        "        |           └── BitArray of count data for second PUB\n",
        "        ├── ...\n",
        "        ├── ...\n",
        "        └── ...\n",
        "    ```\n",
        "  </TabItem>\n",
        "</Tabs>\n",
        "\n",
        "<span id=\"estimator-output\" />\n",
        "\n",
        "### 見積もり出力\n",
        "\n",
        "前述の通り、Estimatorプリミティブ `PubResult` で返されるデータは実装によって異なります。 たとえば、期待値の配列 (`PubResult.data.evs`) と、それに対応する標準偏差 (`PubResult.data.stds`) が含まれている場合があります。\n",
        "\n",
        "以下のコード・スニペットは、上記で作成したジョブの `PrimitiveResult` （および関連する `PubResult` ）フォーマットについて説明しています。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "7b3ac687-8197-4c50-831c-a349fd8e90a2",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The result of the submitted job had 1 PUB and has a value:\n",
            " PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(3, 10), dtype=float64>), stds=np.ndarray(<shape=(3, 10), dtype=float64>), shape=(3, 10)), metadata={'target_precision': 0.0, 'circuit_metadata': {}})], metadata={'version': 2})\n",
            "\n",
            "The associated PubResult of this job has the following data bins:\n",
            " DataBin(evs=np.ndarray(<shape=(3, 10), dtype=float64>), stds=np.ndarray(<shape=(3, 10), dtype=float64>), shape=(3, 10))\n",
            "\n",
            "And this DataBin has attributes: dict_keys(['evs', 'stds'])\n",
            "Recall that this shape is due to our array of parameter binding sets having shape (100, 2) -- where 2 is the number of parameters in the circuit -- combined with our array of observables having shape (3, 1).\n",
            "The expectation values measured from this PUB are: \n",
            "[[ 3.06161700e-16  4.52395120e-01  4.36594428e-01  2.16506351e-01\n",
            "   6.33718361e-01 -6.33718361e-01 -2.16506351e-01 -4.36594428e-01\n",
            "  -4.52395120e-01 -3.06161700e-16]\n",
            " [ 1.22464680e-16  6.42787610e-01  9.84807753e-01  8.66025404e-01\n",
            "   3.42020143e-01 -3.42020143e-01 -8.66025404e-01 -9.84807753e-01\n",
            "  -6.42787610e-01 -1.22464680e-16]\n",
            " [ 4.89858720e-16  2.62002630e-01 -1.11618897e-01 -4.33012702e-01\n",
            "   9.25416578e-01 -9.25416578e-01  4.33012702e-01  1.11618897e-01\n",
            "  -2.62002630e-01 -4.89858720e-16]]\n"
          ]
        }
      ],
      "source": [
        "print(\n",
        "    f\"The result of the submitted job had {len(result)} PUB and \"\n",
        "    f\"has a value:\\n {result}\\n\"\n",
        ")\n",
        "print(\n",
        "    f\"The associated PubResult of this job has the following data bins:\"\n",
        "    f\"\\n {result[0].data}\\n\"\n",
        ")\n",
        "print(f\"And this DataBin has attributes: {result[0].data.keys()}\")\n",
        "print(\n",
        "    \"Recall that this shape is due to our array of parameter binding sets \"\n",
        "    \"having shape (100, 2) -- where 2 is the number of parameters in the circuit -- \"\n",
        "    \"combined with our array of observables having shape (3, 1).\"\n",
        ")\n",
        "\n",
        "print(\n",
        "    f\"The expectation values measured from this PUB are: \\n{result[0].data.evs}\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "af092cd2-4388-4cb4-ba2a-a95b0d6b6c1e",
      "metadata": {},
      "source": [
        "<span id=\"sampler-output\" />\n",
        "\n",
        "### サンプラー出力\n",
        "\n",
        "サンプラージョブが正常に完了すると、返される [`PrimitiveResult`](/docs/api/qiskit/qiskit.primitives.PrimitiveResult) オブジェクトには、 PUB ごとに1つずつ、s [`SamplerPubResult`](/docs/api/qiskit/qiskit.primitives.SamplerPubResult)のリストが含まれます。 これらの `SamplerPubResult` オブジェクトのデータビンは辞書のようなオブジェクトであり、回路 `ClassicalRegister` 内の各要素に対して `BitArray` 1つずつ含まれています。\n",
        "\n",
        "`BitArray` クラスは、順番に並べられたショットデータのコンテナです。 より詳細には、サンプリングされたビット列をバイトとして2次元配列に格納する。 この配列の一番左の軸はオーダーされたショットを表し、一番右の軸はバイトを表す。\n",
        "\n",
        "最初の例として、次の10量子ビット回路を見てみよう：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "f2902d44-e97e-450f-9290-e9a8e1a5b287",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Databin: DataBin(meas=BitArray(<shape=(), num_shots=1024, num_bits=10>))\n",
            "\n",
            "BitArray: BitArray(<shape=(), num_shots=1024, num_bits=10>)\n",
            "\n",
            "The shape of register `meas` is (1024, 2).\n",
            "\n",
            "The bytes in register `alpha`, shot by shot:\n",
            "[[  3 255]\n",
            " [  0   0]\n",
            " [  0   0]\n",
            " ...\n",
            " [  0   0]\n",
            " [  0   0]\n",
            " [  0   0]]\n",
            "\n"
          ]
        }
      ],
      "source": [
        "from qiskit.primitives import StatevectorSampler\n",
        "\n",
        "# generate a ten-qubit GHZ circuit\n",
        "circuit = QuantumCircuit(10)\n",
        "circuit.h(0)\n",
        "circuit.cx(range(0, 9), range(1, 10))\n",
        "\n",
        "# append measurements with the `measure_all` method\n",
        "circuit.measure_all()\n",
        "\n",
        "# transpile the circuit\n",
        "transpiled_circuit = pm.run(circuit)\n",
        "\n",
        "sampler = StatevectorSampler()\n",
        "\n",
        "# run the Sampler job and retrieve the results\n",
        "\n",
        "job = sampler.run([transpiled_circuit])\n",
        "result = job.result()\n",
        "\n",
        "# the data bin contains one BitArray\n",
        "data = result[0].data\n",
        "print(f\"Databin: {data}\\n\")\n",
        "\n",
        "# to access the BitArray, use the key \"meas\", which is the default name of\n",
        "# the classical register when this is added by the `measure_all` method\n",
        "array = data.meas\n",
        "print(f\"BitArray: {array}\\n\")\n",
        "print(f\"The shape of register `meas` is {data.meas.array.shape}.\\n\")\n",
        "print(f\"The bytes in register `alpha`, shot by shot:\\n{data.meas.array}\\n\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8d7e1188-d7a9-4e1a-a783-25e49a5fa1a2",
      "metadata": {},
      "source": [
        "場合によっては、の `BitArray` バイト形式をビット列に変換すると便利なことがあります。 この `get_count` メソッドは、ビット列とその出現回数を対応付けした辞書を返します。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "0eb3a383-30cd-4a32-8d8d-740264587079",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Counts: {'1111111111': 517, '0000000000': 507}\n"
          ]
        }
      ],
      "source": [
        "# optionally convert the native BitArray format to a dictionary format\n",
        "counts = data.meas.get_counts()\n",
        "print(f\"Counts: {counts}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f02341ca-4d0f-421b-9817-47f7b339d057",
      "metadata": {},
      "source": [
        "回路に複数の古典レジスタが含まれる場合、結果は異なる `BitArray` オブジェクトに格納される。 以下の例は、従来のレジスタを2つの独立したレジスタに分割することで、前のスニペットを変更したものです：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "5b294da8-b6b2-4313-aa98-efa4a1903ba4",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "BitArray for register 'alpha': BitArray(<shape=(), num_shots=1024, num_bits=1>)\n",
            "BitArray for register 'beta': BitArray(<shape=(), num_shots=1024, num_bits=9>)\n"
          ]
        }
      ],
      "source": [
        "# generate a ten-qubit GHZ circuit with two classical registers\n",
        "circuit = QuantumCircuit(\n",
        "    qreg := QuantumRegister(10),\n",
        "    alpha := ClassicalRegister(1, \"alpha\"),\n",
        "    beta := ClassicalRegister(9, \"beta\"),\n",
        ")\n",
        "circuit.h(0)\n",
        "circuit.cx(range(0, 9), range(1, 10))\n",
        "\n",
        "# append measurements with the `measure_all` method\n",
        "circuit.measure([0], alpha)\n",
        "circuit.measure(range(1, 10), beta)\n",
        "\n",
        "# transpile the circuit\n",
        "transpiled_circuit = pm.run(circuit)\n",
        "\n",
        "# run the Sampler job and retrieve the results\n",
        "\n",
        "job = sampler.run([transpiled_circuit])\n",
        "result = job.result()\n",
        "\n",
        "# the data bin contains two BitArrays, one per register, and can be accessed\n",
        "# as attributes using the registers' names\n",
        "data = result[0].data\n",
        "print(f\"BitArray for register 'alpha': {data.alpha}\")\n",
        "print(f\"BitArray for register 'beta': {data.beta}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e384e005-24fe-4d7a-922a-39ae0d9089ab",
      "metadata": {},
      "source": [
        "<span id=\"leveraging-bitarray-objects-for-performant-post-processing\" />\n",
        "\n",
        "#### オブジェクト `BitArray` を活用した高性能な後処理\n",
        "\n",
        "配列は一般的に辞書よりも優れたパフォーマンスを提供するため、カウントの辞書ではなく、直接オブジェクト `BitArray` に対して後処理を実行することが推奨されます。 この `BitArray` クラスは、いくつかの一般的な後処理操作を実行するための様々なメソッドを提供します：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "44c7ee14-2b22-488e-bc58-164099855210",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The shape of register `alpha` is (1024, 1).\n",
            "The bytes in register `alpha`, shot by shot:\n",
            "[[1]\n",
            " [0]\n",
            " [1]\n",
            " ...\n",
            " [0]\n",
            " [1]\n",
            " [1]]\n",
            "\n",
            "The shape of register `beta` is (1024, 2).\n",
            "The bytes in register `beta`, shot by shot:\n",
            "[[  1 255]\n",
            " [  0   0]\n",
            " [  1 255]\n",
            " ...\n",
            " [  0   0]\n",
            " [  1 255]\n",
            " [  1 255]]\n",
            "\n",
            "The shape of `beta` after post-selection is (0, 2).\n",
            "The bytes in `beta` after post-selection:\n",
            "[]\n",
            "The shape of `beta` after bit-wise slicing is (1024, 1).\n",
            "The bytes in `beta` after bit-wise slicing:\n",
            "[[7]\n",
            " [0]\n",
            " [7]\n",
            " ...\n",
            " [0]\n",
            " [7]\n",
            " [7]]\n",
            "\n",
            "The shape of `beta` after shot-wise slicing is (5, 2).\n",
            "The bytes in `beta` after shot-wise slicing:\n",
            "[[  1 255]\n",
            " [  0   0]\n",
            " [  1 255]\n",
            " [  0   0]\n",
            " [  0   0]]\n",
            "\n",
            "Exp. val. for observable `SparsePauliOp(['ZZZZZZZZZ'],\n",
            "              coeffs=[1.+0.j])` is: 0.01171875\n",
            "Exp. val. for observable `SparsePauliOp(['IIIIIIIIZ'],\n",
            "              coeffs=[1.+0.j])` is: 0.01171875\n",
            "\n",
            "The shape of the merged results is (1024, 2).\n",
            "The bytes of the merged results:\n",
            "[[  3 255]\n",
            " [  0   0]\n",
            " [  3 255]\n",
            " ...\n",
            " [  0   0]\n",
            " [  3 255]\n",
            " [  3 255]]\n",
            "\n"
          ]
        }
      ],
      "source": [
        "print(f\"The shape of register `alpha` is {data.alpha.array.shape}.\")\n",
        "print(f\"The bytes in register `alpha`, shot by shot:\\n{data.alpha.array}\\n\")\n",
        "\n",
        "print(f\"The shape of register `beta` is {data.beta.array.shape}.\")\n",
        "print(f\"The bytes in register `beta`, shot by shot:\\n{data.beta.array}\\n\")\n",
        "\n",
        "# post-select the bitstrings of `beta` based on having sampled \"1\" in `alpha`\n",
        "mask = data.alpha.array == \"0b1\"\n",
        "ps_beta = data.beta[mask[:, 0]]\n",
        "print(f\"The shape of `beta` after post-selection is {ps_beta.array.shape}.\")\n",
        "print(f\"The bytes in `beta` after post-selection:\\n{ps_beta.array}\")\n",
        "\n",
        "# get a slice of `beta` to retrieve the first three bits\n",
        "beta_sl_bits = data.beta.slice_bits([0, 1, 2])\n",
        "print(\n",
        "    f\"The shape of `beta` after bit-wise slicing is {beta_sl_bits.array.shape}.\"\n",
        ")\n",
        "print(f\"The bytes in `beta` after bit-wise slicing:\\n{beta_sl_bits.array}\\n\")\n",
        "\n",
        "# get a slice of `beta` to retrieve the bytes of the first five shots\n",
        "beta_sl_shots = data.beta.slice_shots([0, 1, 2, 3, 4])\n",
        "print(\n",
        "    f\"The shape of `beta` after shot-wise slicing is {beta_sl_shots.array.shape}.\"\n",
        ")\n",
        "print(\n",
        "    f\"The bytes in `beta` after shot-wise slicing:\\n{beta_sl_shots.array}\\n\"\n",
        ")\n",
        "\n",
        "# calculate the expectation value of diagonal operators on `beta`\n",
        "ops = [SparsePauliOp(\"ZZZZZZZZZ\"), SparsePauliOp(\"IIIIIIIIZ\")]\n",
        "exp_vals = data.beta.expectation_values(ops)\n",
        "for o, e in zip(ops, exp_vals):\n",
        "    print(f\"Exp. val. for observable `{o}` is: {e}\")\n",
        "\n",
        "# concatenate the bitstrings in `alpha` and `beta` to \"merge\" the results\n",
        "# of the two registers\n",
        "merged_results = BitArray.concatenate_bits([data.alpha, data.beta])\n",
        "print(f\"\\nThe shape of the merged results is {merged_results.array.shape}.\")\n",
        "print(f\"The bytes of the merged results:\\n{merged_results.array}\\n\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6863da3a-77bd-4b7c-ac95-e5b4dd116180",
      "metadata": {},
      "source": [
        "<span id=\"result-metadata\" />\n",
        "\n",
        "## 結果メタデータ\n",
        "\n",
        "実行結果に加え、および `PubResult` オブジェクト `PrimitiveResult` には、送信されたジョブに関するオプションのメタデータ属性が含まれています。 返されるメタデータ（ある場合）は、実装に依存します。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "5c08eeaa-8857-4fb6-aa8d-c4916f7354e8",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The metadata of the PrimitiveResult is:\n",
            "'version' : 2,\n",
            "\n",
            "The metadata of the PubResult result is:\n",
            "'shots' : 1024,\n",
            "'circuit_metadata' : {},\n"
          ]
        }
      ],
      "source": [
        "# Print out the results metadata\n",
        "print(\"The metadata of the PrimitiveResult is:\")\n",
        "for key, val in result.metadata.items():\n",
        "    print(f\"'{key}' : {val},\")\n",
        "\n",
        "print(\"\\nThe metadata of the PubResult result is:\")\n",
        "for key, val in result[0].metadata.items():\n",
        "    print(f\"'{key}' : {val},\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "75c67c45-102e-41dd-aebc-9e139b71a02f",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 次のステップ\n",
        "\n",
        "<Admonition type=\"tip\" title=\"推奨事項\">\n",
        "  * [Qiskit SDK](/docs/api/qiskit/primitives) のプリミティブAPIを確認してください。\n",
        "  * [Qiskit Aer](https://qiskit.github.io/qiskit-aer/apidocs/aer_primitives.html) のプリミティブAPIを確認してください。\n",
        "  * [IBM Quantum](/docs/guides/qiskit-runtime-primitives) のプリミティブについて詳しくはこちらをご覧ください。\n",
        "  * [Estimator `qiskit-ibm-runtime`](/docs/api/qiskit-ibm-runtime/estimator-v2) API を確認してください。\n",
        "  * [`qiskit-ibm-runtime` Sampler](/docs/api/qiskit-ibm-runtime/sampler-v2) API を確認してください。\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "celltoolbar": "Raw Cell Format",
    "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
}