{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "3e8391e9-be00-46b0-81a9-5474ae778663",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"量子テレポーテーション\"\n",
        "description: \"量子もつれの原理を用いて、量子テレポーテーションが量子状態をある場所から別の場所へ転送する仕組みを探る。\"\n",
        "---\n",
        "\n",
        "<span id=\"quantum-teleportation\" />\n",
        "\n",
        "# 量子テレポーテーション\n",
        "\n",
        "このQiskit in Classroomsモジュールでは、以下のパッケージがインストールされた Python 環境が必要です：\n",
        "\n",
        "* `qiskit` v2.1.0 または新しい\n",
        "* `qiskit-ibm-runtime` v0.40.1 または新しい\n",
        "* `qiskit-aer` v0.17.0 または新しい\n",
        "* `qiskit.visualization`\n",
        "* `numpy`\n",
        "* `pylatexenc`\n",
        "\n",
        "上記のパッケージをセットアップしてインストールするには、 [Qiskitのインストール](/docs/guides/install-qiskit)ガイドをご覧ください。\n",
        "実際の量子コンピュータでジョブを実行するには、 IBM Quantum® のアカウントを設定する必要があります。 [IBM Cloud アカウントの設定](/docs/guides/cloud-setup)ガイドの手順に従ってください。\n",
        "\n",
        "このモジュールはテストされ、14秒のQPU時間を使用した。 これはあくまでも目安である。 実際の使用方法は異なる場合があります。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "0df1108e-f1ac-4e75-96c2-3d8b5992504e",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Uncomment and modify this line as needed to install dependencies\n",
        "#!pip install 'qiskit>=2.1.0' 'qiskit-ibm-runtime>=0.40.1' 'qiskit-aer>=0.17.0' 'numpy' 'pylatexenc'"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "404ed202-a761-4e82-a480-ce59d4b04adf",
      "metadata": {},
      "source": [
        "ケイティ博士（ McCormick ）によるモジュールのウォークスルーを以下でご覧いただくか、 [こちらを](https://youtu.be/jxqnzltpDdE?si=UVL58hFOOWe2Q9qI)クリックして YouTube でご覧ください。\n",
        "\n",
        "***\n",
        "\n",
        "<IBMVideo id=\"134413680\" title=\"ケイティ McCormick、量子テレポーテーションを解明し、Qiskitを使ったいくつかの例を紹介する。\" />\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a200b899-0c56-4f69-a7ba-0ca4d83e47cd",
      "metadata": {},
      "source": [
        "<span id=\"introduction-and-background\" />\n",
        "\n",
        "## はじめにおよび背景\n",
        "\n",
        "量子テレポーテーションは量子物理学の技術で、粒子を物理的に移動させることなく、ある場所から別の場所へ量子情報を転送することができる。 テレポーテーションというSF的な概念とは異なり、このプロセスは物質の輸送を伴わない。 その代わりに、2つの粒子が距離に関係なくリンクする量子もつれの原理を利用する。 一連の精密な測定と古典的な通信によって、ある粒子の量子状態を離れた場所にある別の粒子に再現することができ、量子情報を効果的に「テレポート」することができる。 このモジュールでは、量子テレポーテーションが数学的にどのように機能するのかを見ていく。 量子情報の背景やテレポーテーションについての詳しい説明は、ジョン・ワトラスの[量子情報の基礎](/learning/courses/basics-of-quantum-information)、特に[テレポーテーションの](/learning/courses/basics-of-quantum-information/entanglement-in-action/quantum-teleportation)セクションを参照されたい\n",
        "\n",
        "古典的なビットは0または1の状態になる。 量子ビット（qubits）は、 $|0\\rangle$ と $|1\\rangle$ で示される量子状態のほか、 $|\\psi\\rangle = \\alpha_0|0\\rangle +\\alpha_1|1\\rangle$ のような「重ね合わせ（superpositions）」と呼ばれるこれらの状態の線形結合、 $\\alpha_0,\\alpha_1 \\in \\mathbb{C},$ と $|\\alpha_0|^2+|\\alpha_1|^2 = 1.$ のような状態にもなり得る。この重ね合わせの状態にも状態は存在できるが、状態を測定すると、 $|0\\rangle$ または $|1\\rangle$ のいずれかの状態に「崩壊」する。 パラメータ $a$ と $b$ は、次のように各測定結果の確率に関連している\n",
        "\n",
        "$$\n",
        "P_0 = |\\alpha_0|^2\n",
        "$$\n",
        "\n",
        "$$\n",
        "P_1 = |\\alpha_1|^2\n",
        "$$\n",
        "\n",
        "という制約がある。 $|\\alpha_0|^2+|\\alpha_1|^2 = 1.$\n",
        "\n",
        "もう一つの重要な特徴は、量子ビットが \"もつれ \"ることである。これは、ある量子ビットの測定が、別のもつれた量子ビットの測定結果に影響を与える可能性があることを意味する。 エンタングルメントが単純な古典的相関とどう違うのかを理解するのは少し難しい。 まず、表記法を説明しよう。 友人0(アリス)と友人1(ボブ)に属する2つの量子ビットを、それぞれ $|0\\rangle$\n",
        "\n",
        "$$\n",
        "|0\\rangle_B|0\\rangle_A\n",
        "$$\n",
        "\n",
        "または\n",
        "\n",
        "$$\n",
        "|0\\rangle_1|0\\rangle_0\n",
        "$$\n",
        "\n",
        "と略されることもある\n",
        "\n",
        "$$\n",
        "|00\\rangle\n",
        "$$\n",
        "\n",
        "一番番号の小さい（またはアルファベットの）量子ビットが一番右にあることに注意。 これは \"リトルエンディアン \"記法と呼ばれる慣習で、Qiskit全体で使用されています。\n",
        "もし友人たちの2量子ビットの状態が $|00\\rangle,$、彼らがそれぞれの量子ビットの状態を測定すれば、それぞれ0を見つけるだろう。 同様に、もし量子ビットが $|11\\rangle,$ の状態であれば、それぞれの測定結果は1になる。 それは古典的なケースと変わらない。 しかし、量子コンピューティングでは、これを重ね合わせることで、次のような状態を得ることができる\n",
        "\n",
        "$$\n",
        "\\frac{1}{\\sqrt{2}}(|00\\rangle+|11\\rangle)\n",
        "$$\n",
        "\n",
        "このような状態では、アリスとボブの量子ビットの状態が0か1かはまだわかっておらず、自然界でも決定されていない。 $|0\\rangle$ 例えば、ボブが彼の量子ビットを測定して $|0\\rangle,$。このようなことが起こる唯一の方法は、測定によって2量子ビットの状態が2つの可能な状態のうちの1つ、具体的には $|00\\rangle.$。\n",
        "\n",
        "このように量子ビットをエンタングルする場合、量子ビットが物理的に互いに接近している必要はない。 言い換えれば、量子ビットをもつれさせ、それを大きな距離で分離し、そのもつれを使って情報を送ることができる。 上記のようなもつれた状態は、もつれの基本単位であり、「eビット」（もつれの1ビット）と呼ばれることもある。 このeビットは、量子通信における資源と考えることができる。なぜなら、離れたパートナー間で共有される各eビットは、ここで概説するように、ある場所から別の場所へ情報を移動させるために使用できるからである。\n",
        "\n",
        "このことを初めて知った多くの人が最初に考えるのは、相対性理論に反するということだ。これを使えば、光よりも速く情報を送ることができるのだろうか？ しかし残念なことに、このモジュールを通して明らかになるであろう理由により、光よりも速く情報を送ることはできない。 ネタバレ》 驚くべきことに、それは崩壊の伝播速度によるものではなく、光よりも速く起こっているように見える [\\[1\\]](https://www.nature.com/articles/nature15759)。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4ce474e6-cea7-4327-9742-9e1a7dd468b0",
      "metadata": {},
      "source": [
        "アリスとボブは同じ場所にいて、同じ量子ビットを扱うことができる。 これらの協力者は、それぞれの量子ビットを絡ませる。 そして、それぞれの量子ビットを携えて、2つの異なる地理的な場所に移動する。 アリスは新しい量子ビットQの量子情報を得る。 Qの情報については何も仮定していない。 Qの状態はアリスにとって未知の秘密かもしれないし、すべての人にとって未知のものかもしれない。 しかし、アリスはQの情報をボブに伝える仕事を与えられている。 彼女は量子テレポーテーションを使ってこれを行う。\n",
        "\n",
        "そのためには、いくつかの量子操作や \"ゲート \"を知る必要がある。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "03fe38b1-66fe-4c50-8403-d8c64197b5c6",
      "metadata": {},
      "source": [
        "<span id=\"quantum-operators-gates\" />\n",
        "\n",
        "## 量子演算子（ゲート）\n",
        "\n",
        "量子ゲートについてすでにご存知の方は、このセクションは読み飛ばしていただいて結構です。 これらのゲートをより深く理解したい場合は、 IBM Quantum Learningにある [Basics of quantum information](/learning/courses/basics-of-quantum-information)、特に最初の2つのレッスンをチェックしてほしい。\n",
        "\n",
        "このテレポーテーション・プロトコルでは、主にハダマード・ゲートとCNOTゲートという2種類の量子ゲートを使用する。 $X$、 $Z$、SWAPゲートなどだ。\n",
        "\n",
        "このモジュールは、ごく限られた線形代数の知識で完成させることができるが、行列やベクトルを使って量子力学的ゲートを視覚化することが役に立つこともある。 そこで、ここでは量子ゲート／状態の行列／ベクトル形式も紹介する。\n",
        "\n",
        "すでに紹介した状態は、（部分的には慣例によって、部分的には制約によって）ベクトル形を持つように選ばれている：\n",
        "\n",
        "$$\n",
        "|0\\rangle = \\begin{pmatrix}1 \\\\ 0\\end{pmatrix}\n",
        "$$\n",
        "\n",
        "$$\n",
        "|1\\rangle = \\begin{pmatrix}0 \\\\ 1\\end{pmatrix}\n",
        "$$\n",
        "\n",
        "このようにして、任意の状態 $|\\psi\\rangle = a|0\\rangle+b|1\\rangle$ は次のように書くことができる\n",
        "\n",
        "$$\n",
        "|\\psi\\rangle =\\begin{pmatrix}a \\\\ b\\end{pmatrix}\n",
        "$$\n",
        "\n",
        "多重量子ビット状態に表記法を拡張する方法にはいくつかの選択肢があるが、以下の選択は極めて標準的である：\n",
        "\n",
        "$$\n",
        "|00\\rangle = \\begin{pmatrix}1 \\\\ 0 \\\\ 0 \\\\ 0\\end{pmatrix},|01\\rangle = \\begin{pmatrix}0 \\\\ 1 \\\\ 0 \\\\ 0\\end{pmatrix},\n",
        "|10\\rangle = \\begin{pmatrix}0 \\\\ 0 \\\\ 1 \\\\0\\end{pmatrix},|11\\rangle = \\begin{pmatrix}0 \\\\ 0 \\\\ 0 \\\\ 1\\end{pmatrix}.\n",
        "$$\n",
        "\n",
        "このベクトル表記法の選択を念頭に置いて、必要な量子ゲート、量子状態に対するその効果、およびその行列形式を紹介しよう。\n",
        "\n",
        "**H ハダマードゲート：** 重ね合わせ状態を作り出す。 単一量子ビットゲート。\n",
        "\n",
        "$$\n",
        "H|0\\rangle = \\frac{1}{\\sqrt{2}}\\left(|0\\rangle+|1\\rangle\\right),\n",
        "$$\n",
        "\n",
        "$$\n",
        "H|1\\rangle = \\frac{1}{\\sqrt{2}}\\left(|0\\rangle-|1\\rangle\\right)\n",
        "$$\n",
        "\n",
        "$$\n",
        "H=\\frac{1}{\\sqrt{2}}\\begin{pmatrix} 1 & 1 \\\\ 1 & -1 \\end{pmatrix}\n",
        "$$\n",
        "\n",
        "ハダマードゲートを使った回路は次のように作られる：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "a66b8ef2-6660-45b8-97bd-dbc98db49857",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/modules/computer-science/quantum-teleportation/extracted-outputs/a66b8ef2-6660-45b8-97bd-dbc98db49857-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "\n",
        "qc = QuantumCircuit(1)\n",
        "qc.h(0)\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "19b06d0f-0811-48aa-bf5d-a575f7b63876",
      "metadata": {},
      "source": [
        "**CNOT制御NOTゲート：** このゲートは、コントロールとターゲットの2つの量子ビットを使用する。 変更されていない制御量子ビットの状態をチェックする。 しかし、もし制御量子ビットが $|1\\rangle$ の状態であれば、ゲートはターゲット量子ビットの状態を変化させる。もし制御量子ビットが $|0\\rangle$ の状態であれば、変化は全く起こらない。 以下の表記では、 $A$ （一番右の量子ビット）がコントロールで、 $B$ （一番左の量子ビット）がターゲットであると仮定する。 以下では、次のように表記する。 $CNOT(q_{control},q_{target})|BA\\rangle.$\n",
        "\n",
        "$$\n",
        "CNOT(A,B)|00\\rangle = |00\\rangle, \\\\ CNOT(A,B)|01\\rangle = |11\\rangle, \\\\ CNOT(A,B)|10\\rangle = |10\\rangle, \\\\ CNOT(A,B)|11\\rangle = |01\\rangle\n",
        "$$\n",
        "\n",
        "時々、コントロールとターゲットの順番が単に暗示されているCNOTを見ることがある。 しかし、コードや回路図にはそのような曖昧さはない。\n",
        "\n",
        "$$\n",
        "CNOT=\\begin{pmatrix} 1 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 1 \\\\ 0 & 0 & 1 & 0 \\\\ 0 & 1 & 0 & 0\\end{pmatrix}\n",
        "$$\n",
        "\n",
        "CNOTゲートは、2つの量子ビットを必要とするので、回路的には少し違って見える。 これが実施方法だ：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "df5acfc1-feb8-4008-8e51-d9709352edde",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/modules/computer-science/quantum-teleportation/extracted-outputs/df5acfc1-feb8-4008-8e51-d9709352edde-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qc = QuantumCircuit(2)\n",
        "qc.cx(0, 1)\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "131d90c7-6ef3-4c32-a01b-52da9f8e0e83",
      "metadata": {},
      "source": [
        "<span id=\"check-your-understanding\" />\n",
        "\n",
        "#### 理解度チェック\n",
        "\n",
        "Qiskitにおけるほとんどのゲートは、他の場所と同様にマトリックス形式をとっています。 しかし、CNOTゲートは2つの量子ビットに作用するため、量子ビットの順序に関する規約が突然問題となってくる。 $|q_0,q_1,...\\rangle$ で量子ビットを並べるテキストでは、CNOTゲートについて異なる行列形式が表示されます。 上記のCNOT行列が状態 $|01\\rangle.$ に対して正しい作用を持つことを、明示的な行列乗算によって確認せよ\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"回答\">\n",
        "    $CNOT|01\\rangle =\\begin{pmatrix} 1 & 0 & 0 & 0 \\\\ 0 & 0 & 0 & 1 \\\\ 0 & 0 & 1 & 0 \\\\ 0 & 1 & 0 & 0\\end{pmatrix}\\begin{pmatrix}0 \\\\ 1 \\\\ 0 \\\\0\\end{pmatrix} = \\begin{pmatrix}0 \\\\ 0 \\\\ 0 \\\\1\\end{pmatrix} = |11\\rangle$\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2c1a61f3-770a-443e-8e01-26fc1106f92b",
      "metadata": {},
      "source": [
        "**$X$ ゲート** ：NOT演算に相当。 単一量子ビットゲート。\n",
        "\n",
        "$$\n",
        "X|0\\rangle = |1\\rangle,\\\\X|1\\rangle=|0\\rangle\n",
        "$$\n",
        "\n",
        "$$\n",
        "X=\\begin{pmatrix} 0 & 1 \\\\ 1 & 0 \\end{pmatrix}\n",
        "$$\n",
        "\n",
        "Qiskitでは、 $X$ ゲートで回路を作ると次のようになる：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "5a23a576-385b-4a7c-899d-67ef4bb0bfed",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/modules/computer-science/quantum-teleportation/extracted-outputs/5a23a576-385b-4a7c-899d-67ef4bb0bfed-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qc = QuantumCircuit(1)\n",
        "qc.x(0)\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "81eaa9dc-740a-4a99-8950-fc7724c6440b",
      "metadata": {},
      "source": [
        "**$Z$ ゲート** ：ゲート：状態に「位相」を加える（前因子。Z固有状態の場合、 $|0\\rangle$ と $|1\\rangle$ は、それぞれ1か -1 のいずれか）。 単一量子ビットゲート。\n",
        "\n",
        "$$\n",
        "Z|0\\rangle = |0\\rangle,\\\\Z|1\\rangle=-|1\\rangle\n",
        "$$\n",
        "\n",
        "$$\n",
        "Z=\\begin{pmatrix} 1 & 0 \\\\ 0 & -1 \\end{pmatrix}\n",
        "$$\n",
        "\n",
        "Qiskitでは、 $Z$ ゲートで回路を作ると次のようになる：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "653b2420-eaa8-41ef-8262-3a9efa638cd3",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/modules/computer-science/quantum-teleportation/extracted-outputs/653b2420-eaa8-41ef-8262-3a9efa638cd3-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qc = QuantumCircuit(1)\n",
        "qc.z(0)\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "476c82d2-4c58-4c25-8f0d-646cd4afb757",
      "metadata": {},
      "source": [
        "<span id=\"theory\" />\n",
        "\n",
        "## 理論\n",
        "\n",
        "量子テレポーテーションのプロトコルを数学で説明しよう。 そして次のセクションでは、量子コンピューターを使ってこの設定を実現する。\n",
        "\n",
        "**アリスとボブは量子ビットをエンタングルする：** 最初は、アリスの量子ビットとボブの量子ビットは、それぞれ別々に $|0\\rangle$ （良い仮定であり、 IBM® 量子コンピューターの正しい初期化でもある）状態である。 これを $|0\\rangle_B|0\\rangle_A$ と書くこともできるし、単に $|00\\rangle$ と書くこともできる。アリスとボブがアリスの量子ビットのハダマードゲートと、アリスの量子ビットをコントロール、ボブの量子ビットをターゲットとするCNOTゲートで行動したときに何が起こるかを計算してみましょう：\n",
        "\n",
        "$$\n",
        "\\begin{aligned}\n",
        "CNOT(A,B)H_A |0\\rangle_B|0\\rangle_A &= CNOT(A,B)|0\\rangle_B\\frac{1}{\\sqrt{2}}\\left(|0\\rangle_A+|1\\rangle_A\\right)\\\\\n",
        "&=\\frac{1}{\\sqrt{2}}\\left(CNOT(A,B)|0\\rangle_B|0\\rangle_A+CNOT(A,B)|0\\rangle_B|1\\rangle_A\\right)\\\\\n",
        "&=\\frac{1}{\\sqrt{2}}\\left(|0\\rangle_B|0\\rangle_A+|1\\rangle_B|1\\rangle_A\\right)\n",
        "\\end{aligned}\n",
        "$$\n",
        "\n",
        "今、アリスとボブの量子ビットはエンタングルされていることに注意。 両者の量子ビットが $|0\\rangle$ 状態か $|1\\rangle$ 状態かはまだ自然界では決定されていないが、両者の量子ビットが同じ状態にあることは知られている。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b51aed85-2976-4c46-a1d8-07dba8af78fe",
      "metadata": {},
      "source": [
        "**アリスとボブは別れる：** アリスとボブは別れる：2人の友人は、それぞれの量子ビットを新しい場所に移動する。 量子情報を乱すことなく移動させるのは簡単ではない。 しかし、それは動かすことができるし、実際、このモジュールでは動かすことになる。 しかし、注意点として、量子情報を大量に移動させる場合、何らかのエラーが発生することが予想されることを覚えておいてほしい。\n",
        "\n",
        "**Qが導入される：** 秘密状態は量子ビットQに準備される：\n",
        "\n",
        "$$\n",
        "|\\psi\\rangle_Q = \\alpha_0 |0\\rangle_Q + \\alpha_1 |1\\rangle_Q\n",
        "$$\n",
        "\n",
        "この時点でQは単にアリスの量子ビット（A）に隣接している。 エンタングルメントがないので、3つの量子ビットを合わせた量子状態は次のように書ける：\n",
        "\n",
        "$$\n",
        "|\\psi\\rangle_{AB}|\\psi\\rangle_Q = \\frac{1}{\\sqrt{2}}\\left(|0\\rangle_B|0\\rangle_A+|1\\rangle_B|1\\rangle_A\\right)\\left(\\alpha_0 |0\\rangle_Q + \\alpha_1 |1\\rangle_Q\\right).\n",
        "$$\n",
        "\n",
        "目標は、Qの情報をアリスの位置からボブの位置に移動させることだ。 現時点では、秘密保持や情報伝達のスピードについて、いかなる主張も要求もしていない。 私たちは単に、情報がアリスからボブに移動する方法を探っているに過ぎない。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cd8f8dab-601f-42b6-8b1e-027568f8726c",
      "metadata": {},
      "source": [
        "情報はQから始まるので、Qは量子ビット数で最も小さい番号に割り当てられると仮定する。リトルエンディアン表記では、Qは以下の数学で最も右の量子ビットになる。\n",
        "\n",
        "**アリスは**自分の量子ビットをコントロール、QをターゲットとしてCNOTゲートを操作し、Qにハダマードゲートを適用する。  その演算後の3量子ビットの状態を計算してみよう：\n",
        "\n",
        "$$\n",
        "\\begin{aligned}\n",
        "H_Q CNOT(A,Q)|\\psi\\rangle_{AB}|\\psi\\rangle_Q &= H_Q CNOT(A,Q)\\frac{1}{\\sqrt{2}}\\left(|0\\rangle_B|0\\rangle_A+|1\\rangle_B|1\\rangle_A\\right)\\left(\\alpha_0 |0\\rangle_Q + \\alpha_1 |1\\rangle_Q\\right)\\\\\n",
        "&= H_Q CNOT(A,Q)\\frac{1}{\\sqrt{2}}\\left(\\left(\\alpha_0 |0\\rangle_B|0\\rangle_A|0\\rangle_Q + \\alpha_1 |0\\rangle_B|0\\rangle_A|1\\rangle_Q\\right)+\\left(\\alpha_0 |1\\rangle_B|1\\rangle_A|0\\rangle_Q + \\alpha_1 |1\\rangle_B|1\\rangle_A|1\\rangle_Q\\right)\\right)\\\\\n",
        "&= H_Q \\frac{1}{\\sqrt{2}}\\left(\\alpha_0 |0\\rangle_B|0\\rangle_A|0\\rangle_Q + \\alpha_1 |0\\rangle_B|1\\rangle_A|1\\rangle_Q+\\alpha_0 |1\\rangle_B|1\\rangle_A|0\\rangle_Q + \\alpha_1 |1\\rangle_B|0\\rangle_A|1\\rangle_Q\\right)\\\\\n",
        "&= \\frac{1}{2}\\left(\\alpha_0 |0\\rangle_B|0\\rangle_A|0\\rangle_Q + \\alpha_0 |0\\rangle_B|0\\rangle_A|1\\rangle_Q + \\alpha_1 |0\\rangle_B|1\\rangle_A|0\\rangle_Q-\\alpha_1 |0\\rangle_B|1\\rangle_A|1\\rangle_Q\\right)\\\\\n",
        "&+\\frac{1}{2}\\left(\\alpha_0 |1\\rangle_B|1\\rangle_A|0\\rangle_Q + \\alpha_0 |1\\rangle_B|1\\rangle_A|1\\rangle_Q + \\alpha_1 |1\\rangle_B|0\\rangle_A|0\\rangle_Q - \\alpha_1 |1\\rangle_B|0\\rangle_A|1\\rangle_Q\\right)\n",
        "\\end{aligned}\n",
        "$$\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "78aaf4c7-2775-483e-91cd-11d400793776",
      "metadata": {},
      "source": [
        "AとQは同じ場所にあるので、量子ビットAとQの測定結果に従って上記の用語をグループ分けしよう：\n",
        "\n",
        "$$\n",
        "\\begin{aligned}\n",
        "|\\psi\\rangle = \\frac{1}{2}\\left((\\alpha_0 |0\\rangle_B+\\alpha_1 |1\\rangle_B)|0\\rangle_A|0\\rangle_Q +  (\\alpha_0 |0\\rangle_B-\\alpha_1 |1\\rangle_B)|0\\rangle_A|1\\rangle_Q + (\\alpha_1 |0\\rangle_B+\\alpha_0 |1\\rangle_B)|1\\rangle_A|0\\rangle_Q+ (-\\alpha_1 |0\\rangle_B+\\alpha_0 |1\\rangle_B)|1\\rangle_A|1\\rangle_Q \\right)\\\\\n",
        "\\end{aligned}\n",
        "$$\n",
        "\n",
        "<span id=\"check-your-understanding\" />\n",
        "\n",
        "#### 理解度チェック\n",
        "\n",
        "3つの量子ビットすべての状態を表す上記の式を踏まえると、量子ビットAとQを測定した際に $|0\\rangle_A|0\\rangle_Q?$ となる確率はどれくらいか\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"回答\">\n",
        "    25%. これを見るには、ボブの状態が正規化されていなければならないことを思い出してほしい。 $ |_A \\langle0|_Q\\langle0| \\frac{1}{2} |0\\rangle_A|0\\rangle_Q (\\alpha_0 |0\\rangle_B+\\alpha_1 |1\\rangle_B)|^2 = \\frac{1}{4}|(\\alpha_0 |0\\rangle_B+\\alpha_1 |1\\rangle_B)|^2 = \\frac{1}{4}$\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8df3034b-9807-487b-a046-e689061cb026",
      "metadata": {},
      "source": [
        "今、アリスは量子ビットAとQを測定することができる。 量子測定は確率的なものなので、彼女はその測定結果をコントロールすることはできない。 つまり、彼女が測定するとき、4つの可能性のある結果があり、4つとも等しく可能性がある。 $|0\\rangle_A|0\\rangle_Q,$ $|0\\rangle_A|1\\rangle_Q,$ $|1\\rangle_A|0\\rangle_Q,$ and $|1\\rangle_A|1\\rangle_Q.$ それぞれの結果は、ボブの量子ビットにとって異なる意味を持つことに注意。 例えば、アリスが自分の量子ビットが $|0\\rangle_A|0\\rangle_Q,$、3量子ビットの量子状態全体が $(\\alpha_0|0\\rangle_B+\\alpha_1|1\\rangle_B)|0\\rangle_A|0\\rangle_Q.$、崩壊していることを発見した場合、アリスの他の測定結果はボブに異なる状態をもたらす。 これらは以下の表にまとめられている。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "99e01c8f-e6e1-4679-8e48-1e33a1b78e63",
      "metadata": {},
      "source": [
        "| アリスの結果                               | ボブの状態                                                | ボブへの指示     | 結果                                                  |\n",
        "| ------------------------------------ | ---------------------------------------------------- | ---------- | --------------------------------------------------- |\n",
        "| $ \\vert 0\\rangle_A \\vert 0\\rangle_Q$ | $\\alpha_0\\vert 0\\rangle_B+\\alpha_1\\vert 1\\rangle_B$  | なし         | $\\alpha_0\\vert 0\\rangle_B+\\alpha_1\\vert 1\\rangle_B$ |\n",
        "| $ \\vert 0\\rangle_A \\vert 1\\rangle_Q$ | $\\alpha_0\\vert 0\\rangle_B-\\alpha_1\\vert 1\\rangle_B$  | $Z$        | $\\alpha_0\\vert 0\\rangle_B+\\alpha_1\\vert 1\\rangle_B$ |\n",
        "| $ \\vert 1\\rangle_A \\vert 0\\rangle_Q$ | $\\alpha_1\\vert 0\\rangle_B+\\alpha_0\\vert 1\\rangle_B$  | $X$        | $\\alpha_0\\vert 0\\rangle_B+\\alpha_1\\vert 1\\rangle_B$ |\n",
        "| $ \\vert 1\\rangle_A \\vert 1\\rangle_Q$ | $-\\alpha_1\\vert 0\\rangle_B+\\alpha_0\\vert 1\\rangle_B$ | $X$ では $Z$ | $\\alpha_0\\vert 0\\rangle_B+\\alpha_1\\vert 1\\rangle_B$ |\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ff32d084-31ea-4408-b3cb-b5bebb845a3b",
      "metadata": {},
      "source": [
        "アリスの量子ビットの全ての可能な測定結果に対して、ボブの量子ビットは、Qに元々あった秘密の状態に曖昧に似た状態で残される。 アリスが $|0\\rangle_C|0\\rangle_A$ （表の最初の行）を測定する場合、ボブの量子ビットはまさに秘密の状態のままである！ それ以外のケースでは、何か状態がおかしい。 係数（ $\\alpha$ 's）が入れ替わっているか、\"+\"記号があるべきところに\"-\"記号があるか、あるいはその両方である。 ボブの量子ビットを修正し、秘密の状態と正確に等しくするために、アリスはボブに電話をかけ（古典的な通信手段を使う）、ボブの量子ビットに追加操作を行うように伝えなければならない。 例えば、3行目では係数が入れ替わっている。 アリスがボブに電話し、彼の量子ビットに $X$ ゲートを適用するよう指示すると、 $|0\\rangle$ が $|1\\rangle$ に、その逆が に変化し、秘密の状態が出てくる。\n",
        "\n",
        "光よりも速い情報を送るのに、なぜこの設定が使えないのか、これではっきりしたはずだ。 運が良ければ、 $|0\\rangle_A|0\\rangle_Q,$、ボブは瞬時に秘密の状態を手に入れたことになる。 でもボブは、私たちが電話して \" $|0\\rangle_A|0\\rangle_Q$、だから何もしなくていいよ \"と言うまで、そのことを知らない\n",
        "\n",
        "思考実験では、量子ビットはしばしば物理的に分離され、新しい場所に運ばれる。 IBM® 量子コンピューターは、分離できないチップ上の固体量子ビットを使用する。 そこで、アリスとボブを別の場所に移動させる代わりに、ある量子ビットから別の量子ビットに情報を移動させる、いわゆる \"スワップ・ゲート \"を使ってチップ自体の情報を分離する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "efa0afed-97e7-42fd-a06d-7c095e703537",
      "metadata": {},
      "source": [
        "<span id=\"experiment-1-basic-teleportation\" />\n",
        "\n",
        "## 実験1：基本テレポーテーション\n",
        "\n",
        "IBM Quantumは、我々が「Qiskitパターン」と呼ぶフレームワークを使って量子コンピューティングの問題に取り組むことを推奨している。 以下のステップで構成される。\n",
        "\n",
        "* ステップ1：問題を量子回路にマップする\n",
        "* ステップ2：実際の量子ハードウェア上で動作するように回路を最適化する\n",
        "* ステップ 3： IBM Quantum のプリミティブを使用して、 IBM の量子コンピュータ上でジョブを実行する\n",
        "* ステップ4：結果の後処理\n",
        "\n",
        "<span id=\"step-1-map-your-problem-to-a-quantum-circuit\" />\n",
        "\n",
        "### ステップ1：問題を量子回路にマッピングする\n",
        "\n",
        "上記で行った計算はすべて、ステップ1の概要を説明したものだ。 これからQiskitを使って量子回路を作り、実装していく！ まず3つの量子ビットで量子回路を作り、アリスとボブの2つの量子ビットをエンタングルする。 これらを量子ビット1と量子ビット2とし、量子ビット0を秘密状態用に確保する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "6e3e0d07-b52f-4e17-9233-0a00065f2d77",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/modules/computer-science/quantum-teleportation/extracted-outputs/6e3e0d07-b52f-4e17-9233-0a00065f2d77-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Step 1: Map your problem to a quantum circuit\n",
        "\n",
        "# Import some general packages\n",
        "from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister\n",
        "import numpy as np\n",
        "\n",
        "# Define registers\n",
        "secret = QuantumRegister(1, \"Q\")\n",
        "Alice = QuantumRegister(1, \"A\")\n",
        "Bob = QuantumRegister(1, \"B\")\n",
        "\n",
        "cr = ClassicalRegister(3, \"c\")\n",
        "\n",
        "qc = QuantumCircuit(secret, Alice, Bob, cr)\n",
        "\n",
        "# We entangle Alice's and Bob's qubits as in our work above.\n",
        "# We apply a Hadamard gate and then a CNOT gate.\n",
        "# Note that the second argument in the CNOT gate is the target.\n",
        "qc.h(Alice)\n",
        "qc.cx(Alice, Bob)\n",
        "\n",
        "# Inserting a barrier changes nothing about the logic. It just allows us to\n",
        "# force gates to be positioned in \"layers\".\n",
        "qc.barrier()\n",
        "\n",
        "# Now we will use random variables to create the secret state.\n",
        "# Don't worry about the \"u\" gate and the details.\n",
        "np.random.seed(42)  # fixing seed for repeatability\n",
        "theta = np.random.uniform(0.0, 1.0) * np.pi  # from 0 to pi\n",
        "varphi = np.random.uniform(0.0, 2.0) * np.pi  # from 0 to 2*pi\n",
        "\n",
        "# Assign the secret state to the qubit on the other side of Alice's (qubit 0), labeled Q\n",
        "qc.u(theta, varphi, 0.0, secret)\n",
        "qc.barrier()\n",
        "\n",
        "# Now entangle Q and Alice's qubits as in the discussion above.\n",
        "qc.cx(secret, Alice)\n",
        "qc.h(secret)\n",
        "qc.barrier()\n",
        "\n",
        "# Now Alice measures her qubits, and stores the outcomes in the \"classical registers\" cr[]\n",
        "qc.measure(Alice, cr[1])\n",
        "qc.measure(secret, cr[0])\n",
        "\n",
        "# Now we insert some conditional logic. If Alice measures Q in a \"1\" we need a Z gate, and if Alice\n",
        "# measures A in a \"1\" we need an X gate (see the table).\n",
        "with qc.if_test((cr[1], 1)):\n",
        "    qc.x(Bob)\n",
        "with qc.if_test((cr[0], 1)):\n",
        "    qc.z(Bob)\n",
        "\n",
        "qc.draw(output=\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2802dfbf-e3cb-4bd8-80cd-83ec972c7bd9",
      "metadata": {},
      "source": [
        "アリスの状態をボブにテレポートさせるために必要なことはそれだけだ。 しかし、量子状態 $\\alpha_0 |0\\rangle+\\alpha_1|1\\rangle$ を測定するとき、 $|0\\rangle$ か $|1\\rangle.$ のどちらかを見つけることを思い出してほしい。つまり、結局のところ、ボブは間違いなくアリスの秘密の状態を持っているのだが、測定によってこれを簡単に検証することはできない。 測定が正しく行われたことを教えてくれるためには、あるトリックをしなければならない。 私たちは \"ユニタリー \"を意味する \"U \"というラベルの演算子を持っていて、アリスの秘密の状態を準備するのに使った。 Uの逆数を回路の最後に適用すればよい。 もしUがアリスの $|0\\rangle$ の状態を $\\alpha_0 |0\\rangle+\\alpha_1|1\\rangle$ にマップしたなら、Uの逆はボブの $\\alpha_0 |0\\rangle+\\alpha_1|1\\rangle$ を $|0\\rangle.$ にマップすることになる。もし量子情報を移動させることだけが目的なら、この最後の部分は必ずしも行われないだろう。 これは、私たち自身をチェックするために行われるだけだ。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "dac9d281-6c57-4e70-9a61-74efa5d4bdc2",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/modules/computer-science/quantum-teleportation/extracted-outputs/dac9d281-6c57-4e70-9a61-74efa5d4bdc2-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Add the inverse of U and measure Bob's qubit.\n",
        "qc.barrier()\n",
        "\n",
        "qc.u(theta, varphi, 0.0, Bob).inverse()  # inverse of u(theta,varphi,0.0)\n",
        "qc.measure(Bob, cr[2])  # add measurement gate\n",
        "\n",
        "qc.draw(output=\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bd6643de-e67f-44f6-b83d-d7ea9f314eb8",
      "metadata": {},
      "source": [
        "だから、もしこれが正しく行われたなら、ボブの量子ビットの測定は $|0\\rangle$。 もちろん、これらの測定は確率的なものだ。 したがって、ボブの量子ビットが $|1\\rangle$ の状態にあることを測定する可能性がわずかでもあれば、1回の測定で $|1\\rangle.$。 $|0\\rangle$ の確率がかなり高いことを保証するために、本当は何回も測定を行いたい。\n",
        "\n",
        "<span id=\"step-2-optimize-problem-for-quantum-execution\" />\n",
        "\n",
        "### ステップ2：量子実行のための問題最適化\n",
        "\n",
        "このステップでは、私たちが実行したいオペレーションを、特定の量子コンピュータの機能の観点から表現する。 また、我々の問題を量子コンピューターのレイアウトにマッピングすることもできる。\n",
        "\n",
        "まず、 IBM 量子コンピューターと通信するために必要なパッケージをいくつかロードする。 また、実行するバックエンドも選択しなければならない。 最も忙しくないバックエンドを選ぶか、プロパティがわかっている特定のバックエンドを選ぶことができる。\n",
        "\n",
        "初回使用時に認証情報を保存するためのコードが以下にあります。 ノートブックを自分の環境に保存した後、必ずこの情報をノートブックから削除してください。そうすれば、ノートブックを共有するときにあなたの認証情報が誤って共有されることはありません。 詳しいガイダンスについては、 [IBM Cloud アカウントの設定](/docs/guides/initialize-account)および[信頼できない環境でのサービスの初期](/docs/guides/cloud-setup-untrusted)化を参照してください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "8f24b6b9-db1b-4077-8660-e355e377807e",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "ibm_sherbrooke\n"
          ]
        }
      ],
      "source": [
        "# Load IBM Quantum Compute Service\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "# Load IBM Quantum Compute Service\n",
        "\n",
        "# Syntax for first saving your token.  Delete these lines after saving your credentials.\n",
        "# QiskitRuntimeService.save_account(channel='ibm_quantum_platform',\n",
        "# instance = '<YOUR_IBM_INSTANCE_CRN>', token='<YOUR-API_KEY>', overwrite=True, set_as_default=True)\n",
        "# service = QiskitRuntimeService(channel='ibm_quantum_platform')\n",
        "\n",
        "# Load saved credentials\n",
        "service = QiskitRuntimeService()\n",
        "\n",
        "# Use the least busy backend, or uncomment the loading of a specific backend like \"ibm_brisbane\".\n",
        "backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)\n",
        "# backend = service.backend(\"ibm_brisbane\")\n",
        "print(backend.name)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "35bb9c51-a573-4363-89ed-2159aaa1976f",
      "metadata": {},
      "source": [
        "我々は、測定値に関する論理を明示的に有効にしている。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "e238e397-33f2-4fa1-99b1-94c78dd966f1",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit import IfElseOp\n",
        "\n",
        "backend.target.add_instruction(IfElseOp, name=\"if_else\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6074a3b9-54c3-4c52-90ee-f308bd96de76",
      "metadata": {},
      "source": [
        "さて、量子回路を \"トランスパイル \"しなければならない。 これには多くのサブステップがあり、魅力的なトピックである。 サブステップの例を挙げると、すべての量子コンピュータがQiskitのすべての論理ゲートを直接実装できるわけではない。 量子コンピューターが実装できるゲートの観点から、回路のゲートを書かなければならない。 プリセット・パス・マネージャーを使えば、このプロセスやその他のプロセスを実行することができる。 `optimization = 3` （最高レベルの最適化）を設定することで、抽象的な量子回路から量子コンピューターに与えられる命令へのマッピングが、我々の前処理で可能な限り効率的なものになる。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "c533d4a7-c53c-4048-bf99-46e06ad9cb95",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Step 2: Transpile\n",
        "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
        "\n",
        "target = backend.target\n",
        "pm = generate_preset_pass_manager(target=target, optimization_level=3)\n",
        "qc_isa = pm.run(qc)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "85f3e53c-f910-4427-a977-f6e24798542c",
      "metadata": {},
      "source": [
        "「サンプラー」とは、量子回路の結果として生じうる状態をサンプリングし、どのような状態がどの程度の確率で測定されるかに関する統計情報を収集するために設計されたプリミティブである。 ここで、 IBM Quantum サンプラーをインポートします：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "d3292506-1486-48cd-bf1e-696135572eab",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Load the Runtime primitive and session\n",
        "from qiskit_ibm_runtime import SamplerV2 as Sampler\n",
        "\n",
        "sampler = Sampler(mode=backend)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5ea27bf8-2dbf-4d68-8375-e40e89b71341",
      "metadata": {},
      "source": [
        "量子コンピュータのすべての計算が古典コンピュータで合理的にシミュレートできるわけではない。 このような単純なテレポーテーションは確かにあり得るが、古典的にある場所に情報を保存できることはまったく驚くべきことではない。 これらの計算は、実際の IBM 量子コンピュータを使って行うことを強く推奨する。 しかし、毎月の無料使用分を使い果たした場合、あるいは授業中に終わらせなければならないことがあり、キューで待つことができない場合、このモジュールはシミュレーターを使って完了させることができる。 これを行うには、以下のセルを実行し、\"Execute \"ステップで関連する行のコメントを解除するだけです。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "2332b984-cff6-4022-b7fa-f100d35a2719",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Load the backend sampler\n",
        "from qiskit.primitives import BackendSamplerV2\n",
        "\n",
        "# Load the Aer simulator and generate a noise model based on the currently-selected backend.\n",
        "from qiskit_aer import AerSimulator\n",
        "from qiskit_aer.noise import NoiseModel\n",
        "\n",
        "\n",
        "noise_model = NoiseModel.from_backend(backend)\n",
        "\n",
        "# Define a simulator using Aer, and use it in Sampler.\n",
        "backend_sim = AerSimulator(noise_model=noise_model)\n",
        "sampler_sim = BackendSamplerV2(backend=backend_sim)\n",
        "\n",
        "# Alternatively, load a fake backend with generic properties and define a simulator.\n",
        "# backend_gen = GenericBackendV2(num_qubits=18)\n",
        "# sampler_gen = BackendSamplerV2(backend=backend_gen)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bff5bb04-fc2d-45f4-ab26-98fe9a5a0b5c",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute\" />\n",
        "\n",
        "### ステップ3: 実行\n",
        "\n",
        "サンプラーを使用して、回路を引数としてジョブを実行する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "cbf63f9a-5b93-4bbd-b527-f3892e2188bd",
      "metadata": {},
      "outputs": [],
      "source": [
        "job = sampler.run([qc_isa])\n",
        "# job = sampler_sim.run([qc_isa])\n",
        "res = job.result()\n",
        "counts = res[0].data.c.get_counts()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a6a68d85-486a-401a-8336-805713eafd57",
      "metadata": {},
      "source": [
        "<span id=\"step-4-post-processing-and-analysis\" />\n",
        "\n",
        "### ステップ4：後処理と分析\n",
        "\n",
        "結果をプロットし、解釈してみよう。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "47488ddf-9357-41e4-a0fb-45616bee307c",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/modules/computer-science/quantum-teleportation/extracted-outputs/47488ddf-9357-41e4-a0fb-45616bee307c-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 12,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# This required 5 s to run on a Heron r2 processor on 10-28-24\n",
        "from qiskit.visualization import plot_histogram\n",
        "\n",
        "plot_histogram(counts)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "12dcb4f6-d105-41f0-8800-87f291ce1aeb",
      "metadata": {},
      "source": [
        "<span id=\"check-your-understanding\" />\n",
        "\n",
        "#### 理解度チェック\n",
        "\n",
        "上記の状態のうち、どれがテレポーテーションの成功を示しているか、また、どのようにして判断できるか\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"回答\">\n",
        "    $|000\\rangle,$ $|001\\rangle,$ $|010\\rangle,$ $|011\\rangle$ の状態は、すべてテレポーテーションの成功と一致する。 これは、秘密状態の最初の準備を元に戻すゲートを追加したためだ。 もし秘密の状態がボブの量子ビットにテレポートされたなら、その追加ゲートはボブの量子ビットを $|0\\rangle$。 つまり、ボブの量子ビット（量子ビット0、古典的レジスタの0番目の成分として測定され、したがって最高/最右）が $|0\\rangle$、上記のどの状態も成功を意味する。\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n",
        "このプロットは、5,000回の試行（ショット）にわたる、3つの量子ビットのすべての測定結果を示している。 先ほど、アリスは量子ビットAとQのすべての可能な状態を等確率で測定することを指摘した。 回路の0-2量子ビットをQ、A、Bの順に割り当てた。 リトルエンディアン表記では、ボブの量子ビットが最左端／最下位となる。 つまり、左側の4本のバーは、ボブの量子ビットが $|0\\rangle$、他の2つの量子ビットがほぼ等しい確率ですべての可能な組み合わせにあることに対応している。 測定結果のほぼ全て（通常95％）がボブの量子ビットを $|0\\rangle$、セットアップが成功したことを意味する！ ボブの量子ビットが $|1\\rangle$。 それは論理的にあり得ないはずだ。 しかし、現代の量子コンピュータはすべて、古典コンピュータよりもはるかに大きなノイズとエラーに悩まされている。 量子エラー訂正はまだ新しい分野だ。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cd75b04b-2d2d-4d87-b6cc-b0fed440d912",
      "metadata": {},
      "source": [
        "<span id=\"experiment-2-teleporting-across-a-processor\" />\n",
        "\n",
        "## 実験2：プロセッサ間でのテレポーテーション\n",
        "\n",
        "量子テレポーテーションの最も興味深い点は、量子状態を長距離にわたって瞬時にテレポートできることだろう（ただし、余分なゲートの古典的通信は瞬時ではない）。 すでに述べたように、プロセッサーから量子ビットを取り外して移動させることはできない。 しかし、テレポーテーションに関係する量子ビットがプロセッサーの反対側に来るまで、ある量子ビットから別の量子ビットに情報を移動させることができる。 上のステップを繰り返すが、今度はプロセッサーに十分な数の量子ビットを持つ、より大きな回路を作ろう。\n",
        "\n",
        "<span id=\"step-1-map-your-problem-to-a-quantum-circuit\" />\n",
        "\n",
        "### ステップ1：問題を量子回路にマッピングする\n",
        "\n",
        "今度は、アリスとボブに対応する量子ビットが変わる。 だから、1つの量子ビットに \"A\"、もう1つの量子ビットに \"B \"という名前はつけない。 そうではなく、量子ビットに番号を付け、アリスとボブに属する量子ビットの情報の現在位置を表す変数を使う。 スワップゲート以外のすべてのステップは、前述の通りである。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "7d7742fa-e9a2-4ca0-9d9b-f29d73e07cd9",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/modules/computer-science/quantum-teleportation/extracted-outputs/7d7742fa-e9a2-4ca0-9d9b-f29d73e07cd9-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 13,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Step 1: Map\n",
        "\n",
        "# Define registers\n",
        "qr = QuantumRegister(13, \"q\")\n",
        "\n",
        "qc = QuantumCircuit(qr, cr)\n",
        "\n",
        "# Define registers\n",
        "secret = QuantumRegister(1, \"Q\")\n",
        "ebitsa = QuantumRegister(6, \"A\")\n",
        "ebitsb = QuantumRegister(6, \"B\")\n",
        "# q = ClassicalRegister(1, \"q meas\")\n",
        "# a = ClassicalRegister(1, \"a\")\n",
        "# b = ClassicalRegister(1, \"b\")\n",
        "cr = ClassicalRegister(3, \"c\")\n",
        "qc = QuantumCircuit(secret, ebitsa, ebitsb, cr)\n",
        "\n",
        "# We'll start Alice in the middle of the circuit, then move information outward in both directions.\n",
        "Alice = 5\n",
        "Bob = 0\n",
        "qc.h(ebitsa[Alice])\n",
        "qc.cx(ebitsa[Alice], ebitsb[Bob])\n",
        "\n",
        "# Starting with Bob and Alice in the center, we swap their information onto adjacent qubits,\n",
        "# until the information is on distant qubits.\n",
        "\n",
        "for n in range(Alice):\n",
        "    qc.swap(ebitsb[Bob], ebitsb[Bob + 1])\n",
        "    qc.swap(ebitsa[Alice], ebitsa[Alice - 1])\n",
        "    Alice = Alice - 1\n",
        "    Bob = Bob + 1\n",
        "\n",
        "qc.barrier()\n",
        "\n",
        "# Create a random state for Alice (qubit zero)\n",
        "np.random.seed(42)  # fixing seed for repeatability\n",
        "# theta = np.random.uniform(0.0, 1.0) * np.pi    #from 0 to pi\n",
        "theta = 0.3\n",
        "varphi = np.random.uniform(0.0, 2.0) * np.pi  # from 0 to 2*pi\n",
        "\n",
        "\n",
        "qc.u(theta, varphi, 0.0, secret)\n",
        "\n",
        "# Entangle Alice's two qubits\n",
        "qc.cx(secret, ebitsa[Alice])\n",
        "qc.h(secret)\n",
        "\n",
        "qc.barrier()\n",
        "\n",
        "# Make measurements of Alice's qubits and store the results in the classical register.\n",
        "qc.measure(ebitsa[Alice], cr[1])\n",
        "qc.measure(secret, cr[0])\n",
        "\n",
        "# Send instructions to Bob's qubits based on the outcome of Alice's measurements.\n",
        "with qc.if_test((cr[1], 1)):\n",
        "    qc.x(ebitsb[Bob])\n",
        "with qc.if_test((cr[0], 1)):\n",
        "    qc.z(ebitsb[Bob])\n",
        "\n",
        "qc.barrier()\n",
        "\n",
        "# Invert the preparation we did for Carl's qubit so we can check whether we did this correctly.\n",
        "qc.u(theta, varphi, 0.0, ebitsb[Bob]).inverse()  # inverse of u(theta,varphi,0.0)\n",
        "qc.measure(ebitsb[Bob], cr[2])  # add measurement gate\n",
        "\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5174ffeb-28d4-49d4-9693-5271e026b026",
      "metadata": {},
      "source": [
        "回路図を見ても、論理的なステップは同じであることがわかるだろう。 唯一の違いは、アリスの量子ビットの状態を、量子ビット6（ $A_5$ ）から量子ビット1（ $A_0$ ）、つまりQのすぐ隣に持ってくるためにスワップゲートを使ったことだ。 そして、スワップゲートを使って、ボブの初期状態を量子ビット7( $B_0$ )から量子ビット12( $B_5$ )に下ろした。量子ビット12の状態は、離れた量子ビット0と1の測定が行われるまではQの秘密状態とは無関係であり、条件付き $X$ と $Z$ ゲートが適用されるまでは、量子ビット12の状態は秘密状態と等しくないことに注意してください。\n",
        "\n",
        "<span id=\"step-2-optimize-your-circuit\" />\n",
        "\n",
        "### ステップ2: 回路を最適化する\n",
        "\n",
        "通常、パス・マネージャーを使ってトランスパイルし、回路を最適化する場合、回路を可能な限り効率的にしたいので、 `optimization_level = 3` を設定するのは理にかなっている。 この場合、量子ビット6と7から量子ビット1と12に状態を転送する計算上の理由はない。 あれはテレポーテーションを実証するためにやったことなんだ。 パス・マネジャーに回路の最適化を依頼すれば、これらのスワップ・ゲートには論理的な理由がないことに気づき、ゲートを削除して隣接する量子ビットのゲート演算を実行する。 そこで、この特別なケースでは、 `optimization_level = 0` を使用する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "d7865560-a8a6-4abb-af8d-6a86ecc76bff",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "105\n"
          ]
        }
      ],
      "source": [
        "# Step 2: Transpile\n",
        "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
        "\n",
        "target = backend.target\n",
        "pmzero = generate_preset_pass_manager(target=target, optimization_level=0)\n",
        "\n",
        "qc_isa_zero = pmzero.run(qc)\n",
        "\n",
        "print(qc_isa_zero.depth())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "38c1dc99-e5e0-4969-b7a0-cdc1e4e6bedd",
      "metadata": {},
      "source": [
        "`plot_circuit_layout` 、これらの量子ビットが量子プロセッサー上のどの位置にあるかを視覚化することができる。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6a74e5a5-d32f-41a5-adf8-29174a0d5e8a",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute\" />\n",
        "\n",
        "### ステップ3: 実行\n",
        "\n",
        "前回と同様、本物の IBM 量子コンピューターで実行することを推奨する。 毎月の無料使用量に達した場合は、シミュレーターで実行するためにシミュレーターセルのコメントを自由に解除してください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "5536d98a-480b-4193-8c63-2ef77d1aeda0",
      "metadata": {},
      "outputs": [],
      "source": [
        "# This required 5 s to run on a Heron r2 processor on 10-28-24\n",
        "job = sampler.run([qc_isa_zero])\n",
        "# job = sampler_sim.run([qc_isa_zero])\n",
        "counts = job.result()[0].data.c.get_counts()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "13b6375b-73c7-436d-bf1c-98de45ef4056",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/modules/computer-science/quantum-teleportation/extracted-outputs/13b6375b-73c7-436d-bf1c-98de45ef4056-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 16,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.visualization import plot_histogram\n",
        "\n",
        "plot_histogram(counts)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "49ed3ba0-3482-4ad5-84c3-f8fba80d8668",
      "metadata": {},
      "source": [
        "<span id=\"step-4-classical-post-processing\" />\n",
        "\n",
        "### ステップ4：古典的な後処理\n",
        "\n",
        "ここでもまた、アリスの量子ビットの可能な結果の確率はかなり均一であることがわかる。 秘密コードを反転させた後、 $|0\\rangle$、ボブの量子ビットを見つけることに強い優先順位がある。つまり、Qからボブ（量子ビット0から12）へ、プロセッサ全体で秘密状態を正しくテレポートした可能性が高い。 ただし、Bob の場合、 $|0\\rangle$ を測定*しない*可能性が高くなっていることに注意してください。 ゲートの数が多ければ多いほど、特にスワップゲートのような多量子ビットゲートが多ければ多いほど、ノイズやエラーが発生する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ede2724d-536b-472a-b4bd-b1276b5b851d",
      "metadata": {},
      "source": [
        "<span id=\"questions\" />\n",
        "\n",
        "## 質問\n",
        "\n",
        "指導者は、このノートがどのように使用されているかについての[簡単なアンケートに](https://ibm.biz/classrooms_instructor_key_request)答えることで、解答と一般的なカリキュラムにおける配置についてのガイダンスが付いたバージョンのノートを要求することができる。\n",
        "\n",
        "<span id=\"critical-concepts\" />\n",
        "\n",
        "### 重要な概念\n",
        "\n",
        "* つまり、ある量子ビットの測定が別の量子ビットの状態に影響を与えたり、あるいはその状態を決定したりする。\n",
        "* 例えば、量子ビットAとBは、 $\\alpha_0|00\\rangle+\\alpha_1|11\\rangle.$ のような状態の重ね合わせにある可能性がある。AまたはBの状態は自然界では決定されないが、それでもAとBは同じ状態にあることが保証される。\n",
        "* エンタングルメントと測定の組み合わせによって、ある量子ビットから別の量子ビットに状態（情報を記憶できる）を転送することができる。 これは量子テレポーテーションと呼ばれている。\n",
        "* 量子テレポーテーションは、確率的な量子測定に依存している。 したがって、テレポートされた状態を微調整するためには、古典的なコミュニケーションが必要になる。 このため、量子テレポーテーションが光よりも速く情報を移動させることはできない。 量子テレポーテーションは相対性理論にも因果関係にも反しない。\n",
        "* 現代の量子コンピューターは、古典的なコンピューターよりもノイズやエラーの影響を受けやすい。 数パーセントの誤差を見込んでほしい。\n",
        "* ゲートを順番に増やせば増やすほど（特に2量子ビットゲート）、エラーやノイズが増えることが予想される。\n",
        "\n",
        "<span id=\"true/false-questions\" />\n",
        "\n",
        "### 正誤問題\n",
        "\n",
        "1. T/F 量子テレポーテーションは、光よりも速く情報を送るために使うことができる。\n",
        "2. T/F 現代の証拠は、量子状態の崩壊が光よりも速く伝播することを示唆している。\n",
        "3. T/F Qiskitでは、量子ビットは、次のように、一番小さい番号の量子ビットが右側になるように並びます。 $|q_3,q_2,q_1, q_0\\rangle$\n",
        "\n",
        "<span id=\"mc-questions\" />\n",
        "\n",
        "### MCの質問\n",
        "\n",
        "1. キュービットAとBはエンタングルされ、その後大きな距離（ $d$ ）によって分離される。キュービットAが測定される。 量子ビットBの状態が影響を受ける速度について正しい記述はどれか？\n",
        "\n",
        "* a. Qubit Bは、これまでに行われた実験では、実験の許容範囲内で即座に影響を受けている。\n",
        "* b. キュービットBは、時間（ $d/c$ ）後に影響を受ける。これは、実験的な許容範囲内で、ほぼ光速で量子状態が「崩壊」することを意味する。\n",
        "* c. キュービットBは、古典的な通信が発生した後にのみ影響を受ける。つまり、 $d/c$ よりも長い時間で通信が発生する。\n",
        "* d. 上記のいずれでもない\n",
        "\n",
        "2. 測定確率が量子状態の振幅に関係していることを思い出してほしい。 例えば、ある量子ビットが初期状態（ $\\alpha_0|0\\rangle+\\alpha_1 |1\\rangle,$ ）にある場合、状態（ $|0\\rangle$ ）を測定する確率は $|\\alpha_0|^2.$。有限サンプリングのため、すべての測定セットがこれらの確率と完全に一致するわけではない。 下の測定ヒストグラムは、次の量子状態のどれに対応するか？ 最適なオプションを選択する。\n",
        "\n",
        "![entangled\\_teleportation](https://quantum.cloud.ibm.com/learning/images/modules/computer-science/quantum-teleportation/entangled_teleportation_fig.avif)\n",
        "\n",
        "* a. $|0\\rangle$\n",
        "* b. $\\frac{1}{\\sqrt{2}}\\left(|0\\rangle-|1\\rangle\\right)$\n",
        "* c. $\\frac{1}{\\sqrt{2}}\\left(|0\\rangle+|1\\rangle\\right)$\n",
        "* d. $\\frac{4}{5}|0\\rangle+\\frac{3}{5}|1\\rangle$\n",
        "* e. $\\frac{3}{5}|0\\rangle+\\frac{4}{5}|1\\rangle$\n",
        "\n",
        "3. 次のうち、量子ビットAとBがもつれた状態はどれか？ 該当するものをすべて選択します。\n",
        "\n",
        "* a. $\\frac{1}{\\sqrt{2}}\\left(|0\\rangle_B|0\\rangle_A+|1\\rangle_B|1\\rangle_A\\right)$\n",
        "* b. $\\frac{4}{5}|0\\rangle_B|0\\rangle_A+\\frac{3}{5}|1\\rangle_B|1\\rangle_A$\n",
        "* c. $\\frac{1}{\\sqrt{2}}\\left(|0\\rangle_B|1\\rangle_A-|1\\rangle_B|0\\rangle_A\\right)$\n",
        "* d. $\\frac{1}{\\sqrt{2}}\\left(|0\\rangle_B|0\\rangle_A+|1\\rangle_B|0\\rangle_A\\right)$\n",
        "* e. $|0\\rangle_B|0\\rangle_A$\n",
        "\n",
        "4. このモジュールでは、もつれ状態を用意した： $\\frac{1}{\\sqrt{2}}\\left(|0\\rangle_B|0\\rangle_A+|1\\rangle_B|1\\rangle_A\\right).$ しかし、同じようなプロトコルに使えるもつれ状態は他にもたくさんある。 次のような2量子ビットの測定ヒストグラムが得られる状態はどれか？ 最適な回答を選択してください。\n",
        "\n",
        "![entangled\\_teleportation\\_fig\\_0110](https://quantum.cloud.ibm.com/learning/images/modules/computer-science/quantum-teleportation/entangled_teleportation_fig_0110.avif)\n",
        "\n",
        "* a. $\\frac{1}{\\sqrt{2}}\\left(|0\\rangle_B|0\\rangle_A+|1\\rangle_B|1\\rangle_A\\right)$\n",
        "* b. $\\frac{4}{5}|0\\rangle_B|0\\rangle_A+\\frac{3}{5}|1\\rangle_B|1\\rangle_A$\n",
        "* c. $\\frac{1}{\\sqrt{2}}\\left(|0\\rangle_B|1\\rangle_A-|1\\rangle_B|0\\rangle_A\\right)$\n",
        "* d. $\\frac{4}{5}|0\\rangle_B|1\\rangle_A+\\frac{3}{5}|1\\rangle_B|0\\rangle_A$\n",
        "* e. $|0\\rangle_B|0\\rangle_A$\n",
        "\n",
        "<span id=\"discussion-questions\" />\n",
        "\n",
        "### 議論における疑問点:\n",
        "\n",
        "1. 量子テレポーテーションのプロトコルを、最初から最後まで、パートナーやグループに説明する。 何か付け加えることがあるか、質問があるかどうかを確認する。\n",
        "\n",
        "2. アリスとボブの間の最初のもつれ状態に何かユニークな点はありますか？ $\\frac{1}{\\sqrt{2}}\\left(|0\\rangle_B|0\\rangle_A+|1\\rangle_B|1\\rangle_A\\right)?$ もしそうなら、何がユニークなのですか？ もしそうでなければ、他にどのようなもつれ状態を使うことができただろうか？\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "in_page_toc_max_heading_level": 2,
    "in_page_toc_min_heading_level": 2,
    "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"
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "state": {},
        "version_major": 2,
        "version_minor": 0
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}