{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0cee3711-080c-4ab3-83fe-c982af539f0a",
   "metadata": {},
   "source": [
    "# Quantum Computation, part 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d45eee5d-04f4-43a6-ac6c-ba5a99dc6db6",
   "metadata": {},
   "source": [
    "Computational note for Quantum Computation course (MAT3420), spring 2026\n",
    "\n",
    "Part 1 covers up to lecture 11 and exercise session 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "7015bb14-5578-481d-aa92-4f55e05c9720",
   "metadata": {},
   "outputs": [],
   "source": [
    "# print options\n",
    "import sympy as sy\n",
    "sy.init_printing(use_unicode=True)\n",
    "import numpy as np\n",
    "np.set_printoptions(suppress=True, legacy='1.25')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0c58aa17-15c1-45a5-997c-1bd5e942a7f7",
   "metadata": {},
   "source": [
    "## Lecture 3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd4908c8-f270-457a-9dcd-9c3d600a294e",
   "metadata": {},
   "source": [
    "Exponential of transforms"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "5e18aa28-42f8-4053-bbbc-f47421afc0af",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sympy as sy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "9e64b3bb-ff9d-4652-93a8-ce6f9ff4e220",
   "metadata": {},
   "outputs": [],
   "source": [
    "θ = sy.Symbol('θ', real=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6096f953-0e0c-463a-bc88-2a7db933801c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left( \\left[\\begin{matrix}0 & i θ\\\\- i θ & 0\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\cos{\\left(θ \\right)} & - \\sin{\\left(θ \\right)}\\\\\\sin{\\left(θ \\right)} & \\cos{\\left(θ \\right)}\\end{matrix}\\right]\\right)$"
      ],
      "text/plain": [
       "⎛⎡ 0    ⅈ⋅θ⎤  ⎡cos(θ)  -sin(θ)⎤⎞\n",
       "⎜⎢         ⎥, ⎢               ⎥⎟\n",
       "⎝⎣-ⅈ⋅θ   0 ⎦  ⎣sin(θ)  cos(θ) ⎦⎠"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "S = sy.Matrix([[0, sy.I * θ],\n",
    "               [-sy.I * θ, 0]])\n",
    "S, sy.exp(sy.I * S)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d67c7382-3b5d-4e42-afc3-f3089f853325",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left( \\left[\\begin{matrix}0 & θ\\\\θ & 0\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{e^{i θ}}{2} + \\frac{e^{- i θ}}{2} & \\frac{e^{i θ}}{2} - \\frac{e^{- i θ}}{2}\\\\\\frac{e^{i θ}}{2} - \\frac{e^{- i θ}}{2} & \\frac{e^{i θ}}{2} + \\frac{e^{- i θ}}{2}\\end{matrix}\\right]\\right)$"
      ],
      "text/plain": [
       "⎛        ⎡ ⅈ⋅θ    -ⅈ⋅θ   ⅈ⋅θ    -ⅈ⋅θ⎤⎞\n",
       "⎜        ⎢ℯ      ℯ      ℯ      ℯ    ⎥⎟\n",
       "⎜        ⎢──── + ─────  ──── - ─────⎥⎟\n",
       "⎜⎡0  θ⎤  ⎢ 2       2     2       2  ⎥⎟\n",
       "⎜⎢    ⎥, ⎢                          ⎥⎟\n",
       "⎜⎣θ  0⎦  ⎢ ⅈ⋅θ    -ⅈ⋅θ   ⅈ⋅θ    -ⅈ⋅θ⎥⎟\n",
       "⎜        ⎢ℯ      ℯ      ℯ      ℯ    ⎥⎟\n",
       "⎜        ⎢──── - ─────  ──── + ─────⎥⎟\n",
       "⎝        ⎣ 2       2     2       2  ⎦⎠"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "T = sy.Matrix([[0, θ],\n",
    "               [θ, 0]])\n",
    "T, sy.exp(sy.I * T)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "51622e8a-f18c-4157-b65c-4db09538fc82",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}\\cos{\\left(θ \\right)} & i \\sin{\\left(θ \\right)}\\\\i \\sin{\\left(θ \\right)} & \\cos{\\left(θ \\right)}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡ cos(θ)   ⅈ⋅sin(θ)⎤\n",
       "⎢                  ⎥\n",
       "⎣ⅈ⋅sin(θ)   cos(θ) ⎦"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sy.simplify(sy.exp(sy.I * T))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "63c62ab1-c3bd-46c8-afe2-e47320d61c2b",
   "metadata": {},
   "source": [
    "## Lecture 4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2658192c-21ba-41aa-ae8f-d7580e13f568",
   "metadata": {},
   "source": [
    "Parametrize density operators on $\\mathbb{C}^2$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "c3f7e5af-2315-4244-95c6-e7702a66bc91",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Pauli matrices\n",
    "X = sy.Matrix([[0, 1],\n",
    "               [1, 0]])\n",
    "Y = sy.Matrix([[0, -sy.I],\n",
    "               [sy.I, 0]])\n",
    "Z = sy.Matrix([[1, 0],\n",
    "               [0, -1]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "1455d327-314b-474e-a76b-5206a9626df8",
   "metadata": {},
   "outputs": [],
   "source": [
    "x, y, z = sy.symbols('x y z', real=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "d5bb918d-b3c7-4557-942b-5a4b178fa4d1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 'evenly mixed' state represented by scalar matrix\n",
    "HlfI2 = sy.Matrix([[sy.Rational(1, 2), 0],\n",
    "                   [0, sy.Rational(1, 2)]])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9646b182-5ca8-4dff-a9af-f6becd036215",
   "metadata": {},
   "source": [
    "$2 \\times 2$ matrices which are selfadjoint and has trace $1$ can be written as linear combination of $I_2$, $X$, $Y$, $Z$, with coefficient $\\frac{1}{2}$ for $I_2$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "0c46368b-e06f-4366-a0da-77762ae4cd1e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}z + \\frac{1}{2} & x - i y\\\\x + i y & \\frac{1}{2} - z\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡z + 1/2  x - ⅈ⋅y⎤\n",
       "⎢                ⎥\n",
       "⎣x + ⅈ⋅y  1/2 - z⎦"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "T = HlfI2 + x * X + y * Y + z * Z\n",
    "T"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6c73523e-0c97-41b8-a4a8-21b9e8468ef4",
   "metadata": {},
   "source": [
    "given $T = T^\\dagger$ and $\\operatorname{tr}(T) = 1$, we expect the positivity of $T$ to be equivalent to the positivity of $T - T^2$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "acf5188b-4980-46cb-9fc6-c8924ac59cb1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}- x^{2} - y^{2} - z^{2} + \\frac{1}{4} & 0\\\\0 & - x^{2} - y^{2} - z^{2} + \\frac{1}{4}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡   2    2    2   1                    ⎤\n",
       "⎢- x  - y  - z  + ─          0         ⎥\n",
       "⎢                 4                    ⎥\n",
       "⎢                                      ⎥\n",
       "⎢                       2    2    2   1⎥\n",
       "⎢        0           - x  - y  - z  + ─⎥\n",
       "⎣                                     4⎦"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sy.simplify(T - T * T)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a19442fe-3efb-43ec-acb2-8c7d1c37670f",
   "metadata": {},
   "source": [
    "$T$ has determinant $0$ when $x^2 + y^2 + z^2 = \\frac{1}{4}$, meaning it has rank $1$ on the sphere defined by this equation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "4b9c5bc0-3980-471e-a9e4-7b48319cf7a0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAKYAAAArCAYAAADypvNxAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFL0lEQVR4Ae2b61HdMBCFDUMBQDq46QCSCnLTAYQKgA7C8I9/DOkAKIF0AKmARwl0EEIH5HxCMn5lcokfksLujK5k2UjHZ1erlSyWnp6eChNjIAYDR0dHG+r3QmlT5ccqhpXqhZWNgbEZkAGuqo9zpQelD0ozpZaYYbYosYoxGfCecZs+VP6qDK/ZkuVWjVUYAwkwYIaZgBIMQpsBM8w2J1aTAANmmAkowSC0GTDDbHNiNQkwYIaZgBIMQpsBM8w2J1aTAAOT72P6DdZD/+4zn+/6/a0EKOmGkCPuHDEH9ic3THV8IsL2AwCVT1W+VXof6hLNc8SdI2an/hhT+Z6McV4xvhOVZ6rr/AJQeS52MUfcqWN+55W63lRuDI+Jt7xpAsngOkfcSWKWE+LgBhIc1IXq7nV9qfyMG0uxTxcJCB5zS3nqUzl8lZIj7pwwx5jKq8pl+t5S2iwrMyhIwdnhzg1zNMMUUazI8Zats3gp22aOuIfCrHbmSntT6CdGjFl4og6Uf+Yl/TU5cUay4nFmhXtgzJylJI0ukxumJ4otIhQcVuIE6Qejv22PDnLEnSPmoKJBDFMEMIqCi/+o8q4SU/WOEnKtZ74/F92eJc+zd1mK7mOck0oFNwuvW127FSEg/L1z5e5QK/eVksDt8TGow+p2WzjvlOCc6Ta8R1KYwb2oDGKY6qzcyBUpnErm6DzGiFfEOxJLOsPU9ZrKqcihx8gCDMxBoeD7okS9k5RwCwsDBLxwy14g/N8pZz84DKRC5ZS4FrzFpbdh6uXxlBhekEcVUCheE1lXqt53lbF/hBuPc+1xEOvyPyhVoe6qWpFQGU4/6R3g2onKcBw497X5Zit6IUbfDyXyRcVNHf7hG7VRXbSw9cO04khTXo7gRRvvem4AnM1m79UmXgbBOx670svPvKPu5e6CpRFwF2qz5Nu3fwhWlUtDXRBe52NqB0/M+zeFAVHoflfYhc4H0TV9DL7BLnC/1C4kfaOD1EU4UcCl0prKYTDhTYnP2MoKxqvLtETYiCn5ODEJ1+qHmZBw4Z/6098t/L/ivafyqqrUMUrG84aFTqE6rskHGc20NbAwyksP79vmPR6FOWWjBGPNSOA6YZ4LYVvy/P4162WYEKEeWBkSfBOP4eJRaDnV6NotMJSnKnidKl5wphxfFuLXLcqUVxdr4GZBNNh0SoOxpJdhCjSjlsTqGyOtLSBUx72wwFAxScEoXewEOo8Z3F1xFI9EFeEjzAAbXp6cMISVOcb6Xxil3qNY4aeH4CUZtSgSpe4rcUKE4JkY7UHlclrnmQSFjX32K1nV/lQKh0lSXZHvCCsevVCOMeIlGVxwn2zoIXyvksEXP6/qPcGHpVwMdK48q4MlU1DpB0Itrh2r3+WxGs6hXYxQCc/uRGXCEfZlj59r7LfBAAtY0qAi3jeUmGVL6TuVlw1lWmAqrBLCtHgmklIPP6LQLV7GCm9YQNfCkLdumMSX6yKcz6jElqcjkq/mTZoMeO6b1b0XP60Gc6oQKeYZIypM/LPD0BkevOkYM6JOrOtnBthhaO7FujtmmGYiURjwU3g1vq/hMMOs0WEXUzAgo5ypn+YXwlrXZpg1OuxiIgb4GNA5hYf+zTADE5ZPwoAMkn3iP07hAYQZZmDC8tEZ8FM4J6Cah2ZafdsnyRYlVjEWAzJIzlR0HY7hQwfbRmzgc4D7wAxTTJjEZUCGyOHyK+Xl6SibyuPqxHp/ZmBVGakU85glFVaYmgF5SBZBMyV3bFI5X+L479pvvwHsdttLa8GdkQAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle - x^{2} - y^{2} - z^{2} + \\frac{1}{4}$"
      ],
      "text/plain": [
       "   2    2    2   1\n",
       "- x  - y  - z  + ─\n",
       "                 4"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "T.det()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dcccabf7-baed-4afc-ba43-03b031c3376e",
   "metadata": {},
   "source": [
    "## Exercisce 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "2594c0e0-ae73-45d7-9aed-a720f83b6f07",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sympy.physics.quantum import TensorProduct"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae6887a2-2a80-4493-8332-8d5d61361df1",
   "metadata": {},
   "source": [
    "### Exercise 1.1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "637ab57a-9031-40a3-bac6-b71583d1241f",
   "metadata": {},
   "source": [
    "Kronecker product and matrix product"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "1111cbae-cce3-43bd-8860-d37f471dd8c6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left( \\left[\\begin{matrix}A_{11} & A_{12}\\\\A_{21} & A_{22}\\end{matrix}\\right], \\  \\left[\\begin{matrix}B_{11} & B_{12}\\\\B_{21} & B_{22}\\end{matrix}\\right]\\right)$"
      ],
      "text/plain": [
       "⎛⎡A₁₁  A₁₂⎤  ⎡B₁₁  B₁₂⎤⎞\n",
       "⎜⎢        ⎥, ⎢        ⎥⎟\n",
       "⎝⎣A₂₁  A₂₂⎦  ⎣B₂₁  B₂₂⎦⎠"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A11, A12, A21, A22 = sy.symbols('A11 A12 A21 A22')\n",
    "A = sy.Matrix([[A11, A12],\n",
    "               [A21, A22]])\n",
    "B11, B12, B21, B22 = sy.symbols('B11 B12 B21 B22')\n",
    "B = sy.Matrix([[B11, B12],\n",
    "               [B21, B22]])\n",
    "A, B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "5e890431-8fc4-45f0-9025-1ea62b5566e4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}A_{11} B_{11} & A_{11} B_{12} & A_{12} B_{11} & A_{12} B_{12}\\\\A_{11} B_{21} & A_{11} B_{22} & A_{12} B_{21} & A_{12} B_{22}\\\\A_{21} B_{11} & A_{21} B_{12} & A_{22} B_{11} & A_{22} B_{12}\\\\A_{21} B_{21} & A_{21} B_{22} & A_{22} B_{21} & A_{22} B_{22}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡A₁₁⋅B₁₁  A₁₁⋅B₁₂  A₁₂⋅B₁₁  A₁₂⋅B₁₂⎤\n",
       "⎢                                  ⎥\n",
       "⎢A₁₁⋅B₂₁  A₁₁⋅B₂₂  A₁₂⋅B₂₁  A₁₂⋅B₂₂⎥\n",
       "⎢                                  ⎥\n",
       "⎢A₂₁⋅B₁₁  A₂₁⋅B₁₂  A₂₂⋅B₁₁  A₂₂⋅B₁₂⎥\n",
       "⎢                                  ⎥\n",
       "⎣A₂₁⋅B₂₁  A₂₁⋅B₂₂  A₂₂⋅B₂₁  A₂₂⋅B₂₂⎦"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "TensorProduct(A, B)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "e47898d5-d4d5-444a-8da7-d4da0515485f",
   "metadata": {},
   "outputs": [],
   "source": [
    "v1, v2, w1, w2 = sy.symbols('v1 v2 w1 w2')\n",
    "v = sy.Matrix([v1, v2])\n",
    "w = sy.Matrix([w1, w2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "4c9629a1-e8fb-4383-911d-473d3d29a8e4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}v_{1} w_{1}\\\\v_{1} w_{2}\\\\v_{2} w_{1}\\\\v_{2} w_{2}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡v₁⋅w₁⎤\n",
       "⎢     ⎥\n",
       "⎢v₁⋅w₂⎥\n",
       "⎢     ⎥\n",
       "⎢v₂⋅w₁⎥\n",
       "⎢     ⎥\n",
       "⎣v₂⋅w₂⎦"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "TensorProduct(v, w)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "1b88b531-ada3-4361-947c-292da463e136",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}A_{11} B_{11} v_{1} w_{1} + A_{11} B_{12} v_{1} w_{2} + A_{12} B_{11} v_{2} w_{1} + A_{12} B_{12} v_{2} w_{2}\\\\A_{11} B_{21} v_{1} w_{1} + A_{11} B_{22} v_{1} w_{2} + A_{12} B_{21} v_{2} w_{1} + A_{12} B_{22} v_{2} w_{2}\\\\A_{21} B_{11} v_{1} w_{1} + A_{21} B_{12} v_{1} w_{2} + A_{22} B_{11} v_{2} w_{1} + A_{22} B_{12} v_{2} w_{2}\\\\A_{21} B_{21} v_{1} w_{1} + A_{21} B_{22} v_{1} w_{2} + A_{22} B_{21} v_{2} w_{1} + A_{22} B_{22} v_{2} w_{2}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡A₁₁⋅B₁₁⋅v₁⋅w₁ + A₁₁⋅B₁₂⋅v₁⋅w₂ + A₁₂⋅B₁₁⋅v₂⋅w₁ + A₁₂⋅B₁₂⋅v₂⋅w₂⎤\n",
       "⎢                                                             ⎥\n",
       "⎢A₁₁⋅B₂₁⋅v₁⋅w₁ + A₁₁⋅B₂₂⋅v₁⋅w₂ + A₁₂⋅B₂₁⋅v₂⋅w₁ + A₁₂⋅B₂₂⋅v₂⋅w₂⎥\n",
       "⎢                                                             ⎥\n",
       "⎢A₂₁⋅B₁₁⋅v₁⋅w₁ + A₂₁⋅B₁₂⋅v₁⋅w₂ + A₂₂⋅B₁₁⋅v₂⋅w₁ + A₂₂⋅B₁₂⋅v₂⋅w₂⎥\n",
       "⎢                                                             ⎥\n",
       "⎣A₂₁⋅B₂₁⋅v₁⋅w₁ + A₂₁⋅B₂₂⋅v₁⋅w₂ + A₂₂⋅B₂₁⋅v₂⋅w₁ + A₂₂⋅B₂₂⋅v₂⋅w₂⎦"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "TensorProduct(A, B) * TensorProduct(v, w)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "618e3571-1216-4913-9a46-d367b4a2dd79",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}\\left(A_{11} v_{1} + A_{12} v_{2}\\right) \\left(B_{11} w_{1} + B_{12} w_{2}\\right)\\\\\\left(A_{11} v_{1} + A_{12} v_{2}\\right) \\left(B_{21} w_{1} + B_{22} w_{2}\\right)\\\\\\left(A_{21} v_{1} + A_{22} v_{2}\\right) \\left(B_{11} w_{1} + B_{12} w_{2}\\right)\\\\\\left(A_{21} v_{1} + A_{22} v_{2}\\right) \\left(B_{21} w_{1} + B_{22} w_{2}\\right)\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡(A₁₁⋅v₁ + A₁₂⋅v₂)⋅(B₁₁⋅w₁ + B₁₂⋅w₂)⎤\n",
       "⎢                                   ⎥\n",
       "⎢(A₁₁⋅v₁ + A₁₂⋅v₂)⋅(B₂₁⋅w₁ + B₂₂⋅w₂)⎥\n",
       "⎢                                   ⎥\n",
       "⎢(A₂₁⋅v₁ + A₂₂⋅v₂)⋅(B₁₁⋅w₁ + B₁₂⋅w₂)⎥\n",
       "⎢                                   ⎥\n",
       "⎣(A₂₁⋅v₁ + A₂₂⋅v₂)⋅(B₂₁⋅w₁ + B₂₂⋅w₂)⎦"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "TensorProduct(A * v, B * w)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "65482fe0-3966-4209-a70f-df2d29bd3779",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# naive comparison gives wrong answer\n",
    "# because symbolic manipulation is not through enough\n",
    "TensorProduct(A, B) * TensorProduct(v, w) == TensorProduct(A * v, B * w)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "076c63a5-efd6-45a7-8af9-7e06c137264c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# unfortunately, wrong answer even with the simplify command\n",
    "sy.simplify(TensorProduct(A, B) * TensorProduct(v, w)) == \\\n",
    "    sy.simplify(TensorProduct(A * v, B * w))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "a436afe3-493e-4405-833e-d3bc7acdbc55",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABoAAABkCAYAAACYYiB/AAAACXBIWXMAAA7EAAAOxAGVKw4bAAACvUlEQVRoBe1a221UQQzdIL5RRCQKWDrgUQFLB0AHQAn53P0NHYQWkg6ggyjpIBSARBRRAefczLnrO5mH97IfEHmkK3vssX3njNfrneRgvV6/WCwWl3hK43yz2bwvKXIZ1l1DtszlnEN38NgovoDnYjt+2EmHPyno30L2jnIb6BSRd3E88QvbrxMBJpBRdC8Qhc0BQ731Lyx8jucEMtfLPWp6Nko45DlegB7jIczHeL6BL56LMR1YVyA4+4TVh6DncgD+Fjznp5K1qCsQHDDzrgqOLiBbIehhQTcReQOtYHUzsbyb6Hyob45uIM/bIsLTZhQou4GME55JbewNuloAyY/E1KhnR6WzkT9Bxs9Vc3QDpTSmkxI8kikpqsG6gZLld9BlwYt2RH1zeAOdwcurgqeXkF2ZXReW3IlcgeCIBfMGdCiQNAVP2D7g+ch5b9jq3VvLt2cRfQ3Kwyd9g3mpYkA1He5AcHgL089Tc//MBZ3fXX1lBKpj09EEdB2A6uqAro5NR+MuQfSDMhQN5AioN+uigRwhE+OBTg0Iv/hqQ91QTe/qVKvGRuFqIJ8kA1FjP7B/00A+k7MudKlX4PoSPJK5GsjfKaqoXsLSuQ3kTznp7igtjAZSiI3UXb2jgRwxS4w363K7necRaGfIZEDoWKf4u6dVPLV+V8rSNfymYqAlHl4c6XsH7N7GCp6GS6mHlwzuEkQwo4G0KeVNhmggLWoD74FOH+T/p4G8t81M0KqB2m3cQGagbafRQG6xSJy7ekcDmWPnKUG5zax5BJoFG40Cun8fOncJ4laigbQH6k3vaCAtagPvgU4tVTSQE/i60KVegUa6bbQOJHPdQFrDGj/3BnL0191RWhkN5AiZGHf1jgZSkIl6s07rZ9OHF8hm3TUyK4dmL/8xSKcMpBvIPAjn3RpmjPSnUyPasn8AXZ4WsbjyHqgAAAAASUVORK5CYII=",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}0\\\\0\\\\0\\\\0\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡0⎤\n",
       "⎢ ⎥\n",
       "⎢0⎥\n",
       "⎢ ⎥\n",
       "⎢0⎥\n",
       "⎢ ⎥\n",
       "⎣0⎦"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# correct answer by taking the difference, then simplify\n",
    "sy.simplify(TensorProduct(A, B) * TensorProduct(v, w)\n",
    "            - TensorProduct(A * v, B * w))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9f023ece-3c7a-4c36-b3e9-097fe6db4865",
   "metadata": {},
   "source": [
    "### Exercise 1.2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56e861ce-c75c-4708-bce0-ea14947ab66e",
   "metadata": {},
   "source": [
    "tensor product of qubit states"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "0753971c-7045-4279-a8bc-0e5bf36c77d3",
   "metadata": {},
   "outputs": [],
   "source": [
    "zeroket = sy.Matrix([1, 0])\n",
    "oneket = sy.Matrix([0, 1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "875a8249-0f34-4714-b4b0-a414636e2a6a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "printing |00⟩, |01⟩, |10⟩, |11⟩\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAOwAAABkCAYAAACFMNyhAAAACXBIWXMAAA7EAAAOxAGVKw4bAAANd0lEQVR4Ae1dTW7cRhpVBGGWgeAAs0/nBnJ8grH3WcSTE8S5gYXsvDOSGzhzgiRezF7OCRTrBs4BBhhHGMxyAM97FB9NsovsVnf9kd9XAFVkkayq9756/KqK7NInHz58ONknvHjx4i2uu0T8JnQ90i+QzmtC4TXOPw2dGKfhundI24zTeYxzn4TSc6ahDqvHGQtja7Nq7RkLJ/I5CCPuYzu/wvYQ+7f7tOOzfS5CZq9w3R+Ig2Id5fEjjgmgH/7oH+zY/yFw/gnSvg6kl0yygPNYjLTPEux5LM6DMEJP1NRrcPQPbHs5tJ2CRYYUyt+xfY5tn/CKFdnnwtA1uPencTrSmFSbYC3gPAojjbYQex6F8xiMuJe91j+xPQvlQw77YVawyOAcF1P9zHQvl93PfG4f+bFr+Su2vbsDc/nVeA4Y9eT9N+r3BbYfkHbww8wxlmMgsS3pXa9Qxptd7eN0BwUUK932ltfbcV/wNPI5x/YrNnaxmXdwrBq8eWGJwMjx/DViPuzY5brERqOsBrMFjGx2qXEifw412TWmLmbDpGCRCT0gu6FsaFEC8rzF9hTbd8jw5yiZVpgJ8D1DtfhwohGagH32UPYySntL1ZEFjDRARpzU2WOUNzv0mxQsbqYHvEEG+0w04VIPPQbYxbnpHWv3Gjs0CocaSw8WMNJGWXCiTXCoRK1pGMWyt0JQsK3K6WGjedetkted8Bjw3gcgavzK80sPFjDSRjlxUm8b6O/5VOMIChYXf49t39c4U3mbTN/Tez5YMjkWMNI+uXGiPPbK6GWpv2DYEixuomfltnMAHMzREyXGuVn1pXeJLWBkSy6Bk7rj/EdwLLslWFwsdUeZGSZqD1sMfLaVsr4ECxhptag4IVRNVEqHg5YxECwu5pOfyub7oDkPMcjEDwYMhMauukBPbL6XXXKwgJH2KYWTor2ABi/GjWQgWJzkF00M3h2+4+Hef3sPulC3V2mafLp3/jXcYAEjeS6IU/r7ZmzvsWA5hc3gr3LueDj0L/nbBG6Wh10DvxYw0oTZceJBofbB9/mD0AkWF/Hpzylszg57d3hA070P+Mnll4G7HiKN77bXwK8FjDRhKZwULSefBt3iTrA4qe6wBr2sbMqgwbq8TsqysuYNkjlh9x5xN9OHfT4QyfG3WSuTqDALGEldQZxXrekG3eKznj35EzYGXXh3FPkvCOATi4HenIHfFnNMx+9s1zQzTW/Kj/0fIeYkE+O/4Zjv2tYSLGCkrUrgVLdYOmnaTF+wzQk0KF2YpFEhf42Tk+RfS6bAyW4vv5lebbCAkcYrgRNlcujE4jlbzK5xM4xqusRMwAlui569JDoPzsCKGFBvrJsP0RhWbtcFuyJrO5TFM/B7i6CbeJJgNX6VoheP1AE4AytggL+pZpA+TyRYudzru/P+1xlwBipgQB5W+uwEu2kr513iCqzkVXAGRnrk/FIT5GGV4IIVMx47A4UZ0Mwwq4H9Zhx7ih15VybeFq6jF+8MOANDBuREG53Sw2oGSieGl/uRM+AMlGRATrQTrDysTpSsnJftDDgDQwbkSJtPeelhmx3Ec7/9G2bhR86AM5CLAemycaz8NDG7h8VYWSvD8RvbVS6wLWsCK4cc/H56lQumW7FlQZzq+XaCPW8bl5SstpYkBnC+DH6JuPlVEGKW/xbxE2xy/0nKzpVpi4nLxJJTvkPTQzFXFbKUA5yrtyWJrARno9NT1OdBFuveAV/9AtvkEga+xbbqBdOBz4otS+NkL5Sh0SkFKw972ySn/cNf6twEiuAXVo/RCFSXwCWeVBkDVmxZGqd02Wgjq4elKLGFut7qCutHCJW1Ta9OgAErtqwKJwWrINer46jxnt4zW/c8KjhjmVmxZSU4Bw6uL1i53lTNT2KcK6dx+6kq4PlGY8CKLavDScHWJBK9E47WsjyjYgxYsWVqnAMH1/ewfznStJ+29yseZzdw7aOTepJNdcv/Orq+5KHwKY5Zl1pwCpviMcb344Te8S5b8lILOGNh/J+4ZRe9L9j/6kSKGIXpSRHy6ErT5FOKKniekRiwYssaccYU7H/a9qA41Dy4wNsmcEJP5akF4P4VuKdUkvApjlmPWnAKm+IQxkNtybws4IyFcWCDvmBDRomdxk/0ul/P9zJ/iP21LLDdg7XqXSu2rApnVsGii7H6BbYDEtWkxIPAucUmWbFlbTjPCrQYetO1L7B9AkPzycygj0HWuGC6CVvChtXgzC5YNGROPq16gW2qFDhXv2C6IVtW02azdonZkD04A87A4Qy4YA/nzu90BrIz4ILNTrkX6AwczoAL9nDu/E5nIDsDLtjslHuBzsDhDLhgD+fO73QGsjPA1zr8mIEfKt8cWTq/A+brmrkPww8tgp/B1fIqyALOlBjZBmqxZ0qcsTCyjv8kaXyNRg/LNWu+wnaB7Ziwwc2vsKX4oocfHzDvGoIFnCkx0oa12DMlzlgYWUfq8ysIdvBrHRLpwRlwBipm4LTiukWpGp9KUTKqOBMLGEm/FZxzTY1j2OwBxGdZSLw18J+I+Usgfg+aNeTAWRojCUUdOJzit9PJFksvjRPlZ2mz5HMuZPewAM7Fp68RX2L7EfuX2K6wz7561IA8b5EhB+3n2M/qaVFeFpylMJJPbPxBA+cWuGh6dPshzy6UwskKoOwstuzAzuxkFSyAZ1+UGWXyX4HwoZAt5MZZCGP2xdIL4czeZucaalbBoiKlFmV+BGPT2+YKJXDmxpiLy3E5uXGWsOUYc3ecW7Cc6g69p2W3lYHnowYIlV3hqcXdopbVyywrzkIYe3Dz7BbCmdWWu5jMJtiW7F31SfEO9xnK5lg5SyiEMyvGLESGC8mKs5Atw8jb1GyCRXkS41zXNPrEUE6xtpxmx1kA42yjSnWyAM7sttzFXU7B7qoLz3+2z0UruMYKzhWYaieErLbMKdjQ2FVs6EmWe6yp8mPGVnDG5KzWvKqzZV+wc13VowlFd0b5h7q9StPk09HllcrACs5S/OYst0Zb9gUr0aTk5JjFp1PWK3beVnDG5q3G/KqyZV+wOciqalHmhICt4ExIYTVZV2NLenwKVl1VjSOTMYUCTSwkbgVnr6Fo4iV5G+qVmWW3AlsOOD3LgnpYyEMcrn4hcWBcPU40ZnofBn3wssbF0omvGltSsJwJyzF+JfATGJkevZbVI5o6pfhjAScwrn6xdLaNmmzZ7xJnE20KgXiezsBKGZAu6ehOKFi9a9I4ZKW4HZYzsEgGNIZtdOoedpE29EobYmDSw0rJhrhwqM5A9Qyo5+setnpTeQWdgY8Tws1XgOwSv2tZcQ/rzcMZqI+BTVulRqcUrL7f1Yn6quw1cgbsMiBH2nlYCVaDW7vUOHJnoD4G5EjvBIuXwhIsXxDrZH3V9ho5AzYZkCPtPCxpkGhdsDYbhaOukIGeA+UKlc2HE/qW+Ab1pVizCBaFV7Eoc2obWcBpAaPaCbBeYJ/fTydbMF1ltbH0KId6IsFe44KvWZHRDdEPAZqLMr9E/JqZI6bLf4v4CbauYjy35AAsq8dpBCPbJxdK53vQL7FJRNhNHviAYOBvcptw2sb0sAysULIAA1e1KHMqoBZwWsDI9gGc2RdM77XLR+0+HWoTJNjf22Mpuj2MHlW1KHN0dB8ztIDTAsaPFi2zJz0OPSyfIqhP0x3FfkqXz99NNp9YjfCrK8zzawgWcFrAWKwtQofsilOL3YQTKyMPy/1mTIk4iWjaCrCcufBg7uQSzlnAaQFjBW1NOuy8K+vUF+xVW8kniSorMdKbTwU+VZYeLOC0gLF0O/ymrcDP/Yp0gsVTk0qmmDhbXCrolwmlys9VrgWcFjCmbC+Nh4Uu1fNtyuoE25b8C2NcdNEex4xCY1flrye2LyQuRuqOrdiyiBVa/bG3ORArKzMWrBbVkjuOVmFUQl3hULdXaZp8ilZu7ows4LSAMXe7GZWn8eugO8xrBoKFIdQt5vvSFIH5bwIZy8MOBtiB65aSZAGnBYyl2hsdJmeHd3pYVvAltnNcLJUzLVagBw99nMEvrG56T+5Y5ZXKxwJOCxiztx9ogMNRblzDeysMPCzP4gb9L9XoS5Eib19I/OTk2y0rLDDBii1HptFEmnqEo9NRDr9vc6Hj3ApnWyl3CRTtcxiFnlZjz4lL751Mb+oLid+btipvMGFLaEBzO+p1JlkwnXqDlfmW5vWU7qYES3U/x0a1X2KLFtqKRPfe0SoYKSMLOC1gZHMATn6GmSNo7mhSc1tdYtaqNQRvarxsjpp6Gc6AM9A4yJ+gv8m3JUHBkjjcxG4xb1SfmskenAFnIAED0Bt7tOwST3pXFjspWJ5EkJfd3B36X2fAGYjNAMRKoXJRh++wPztnNCtY3Mz3QJzZfYXNgzPgDKRhgD+QfwO9BV/l9IucFSwvRCacINog1oC4f7/vOwPOwBEMQFeceea218TW1CzxuArM7Ddk/gu2WZeN697hmvH9nKbeq0K4jgsmL6ELbgHnURjZCBZiz6NwHomRvdenyGOXrkjnyV6CRWb8ComC4wvjqYw5QTX1umZy1gv3jIMWaBun13JsAWcsjLRZzfaMhfMgjNDUOfjhuHXvT3L/D6yQaSPyLegCAAAAAElFTkSuQmCC",
      "text/latex": [
       "$\\displaystyle \\left( \\left[\\begin{matrix}1\\\\0\\\\0\\\\0\\end{matrix}\\right], \\  \\left[\\begin{matrix}0\\\\1\\\\0\\\\0\\end{matrix}\\right], \\  \\left[\\begin{matrix}0\\\\0\\\\1\\\\0\\end{matrix}\\right], \\  \\left[\\begin{matrix}0\\\\0\\\\0\\\\1\\end{matrix}\\right]\\right)$"
      ],
      "text/plain": [
       "⎛⎡1⎤  ⎡0⎤  ⎡0⎤  ⎡0⎤⎞\n",
       "⎜⎢ ⎥  ⎢ ⎥  ⎢ ⎥  ⎢ ⎥⎟\n",
       "⎜⎢0⎥  ⎢1⎥  ⎢0⎥  ⎢0⎥⎟\n",
       "⎜⎢ ⎥, ⎢ ⎥, ⎢ ⎥, ⎢ ⎥⎟\n",
       "⎜⎢0⎥  ⎢0⎥  ⎢1⎥  ⎢0⎥⎟\n",
       "⎜⎢ ⎥  ⎢ ⎥  ⎢ ⎥  ⎢ ⎥⎟\n",
       "⎝⎣0⎦  ⎣0⎦  ⎣0⎦  ⎣1⎦⎠"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# list the Kronecker product of computational basis vectors\n",
    "print(\"printing |00⟩, |01⟩, |10⟩, |11⟩\")\n",
    "TensorProduct(zeroket, zeroket), \\\n",
    "    TensorProduct(zeroket, oneket), \\\n",
    "    TensorProduct(oneket, zeroket), \\\n",
    "    TensorProduct(oneket, oneket)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "773ba2ff-2c6a-4ce8-95b1-09cbacb76334",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left( \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2}\\\\\\frac{\\sqrt{2}}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2}\\\\- \\frac{\\sqrt{2}}{2}\\end{matrix}\\right]\\right)$"
      ],
      "text/plain": [
       "⎛⎡√2⎤  ⎡ √2 ⎤⎞\n",
       "⎜⎢──⎥  ⎢ ── ⎥⎟\n",
       "⎜⎢2 ⎥  ⎢ 2  ⎥⎟\n",
       "⎜⎢  ⎥, ⎢    ⎥⎟\n",
       "⎜⎢√2⎥  ⎢-√2 ⎥⎟\n",
       "⎜⎢──⎥  ⎢────⎥⎟\n",
       "⎝⎣2 ⎦  ⎣ 2  ⎦⎠"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "plusket = sy.Matrix([1/sy.sqrt(2), 1/sy.sqrt(2)])\n",
    "minusket = sy.Matrix([1/sy.sqrt(2), -1/sy.sqrt(2)])\n",
    "plusket, minusket"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "876aa37f-b5a0-4b57-bcb9-cfc8233f8622",
   "metadata": {},
   "source": [
    "since the Kronecker product of computational basis vectors (i.e., $\\ket{00}$, $\\ket{01}$, $\\ket{10}$, $\\ket{11}$) become standard basis vectors, when `TensorProduct(plusket, plusket)` gives 4 componets we can treat them as coefficients of $\\ket{11}$ in terms of those vectors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "dbf21296-66e8-4afb-a505-1e16365d2bdb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAB0AAABlCAYAAACx4uijAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAC6UlEQVRoBe1awU3EMBDkEG+EeFDAIVEAVwJHB8AD3kAJJx5I9z06gAJ4UQpQABIUgARCFMAxk7Mjx2dfdhMgINZSYntt78TjXXtlpTedTpc0aTwer6H/AZ5TlAeasb7vCgZuo3LnBVF+g/Z9L3N9h65O8GRCv0c09FONaOutBA0XKLNzmJ7CCgbco36PfC+UJ8qThGwXsmJcCHoJZRWQxECRCHqu4o6QUVSALseNP1E30G9luRN6Q+utnR0skL53imeIp486XeMFOd1NnLSgdKmRWHumYyf0dgIqphfrVnsyoE8vw2hFrAEVKaxoz1R+N738aNDH4+zMTYDuw3QM+dusKHuL6XXqJgCgnxYJ5UsUeBZvziSyt5beEwANA9XcHLhJMBAQJy0oZ3kr1p7pqKIXM4oPZ37EE+SMKMRJO9NSsaOUkYA6OGsECsA+wLieA5RVlsuvVtHLAQ5whJyBlq8zF8dXKlAo5gzpJgT1Fst1VZ08KlAop09yg6jEyfiA0nfRVpu0oDvQOHRaGeGrNgX/NSpQgEiDba8/mTey3qQmhdBAFWTpu/4ferUuwx2JGwF91YLtWsvqxJC4pq94rvF8LPpEbIFtg+0Hh1Ocp+uoHOI5rwFtG2xvOZyjzuhdNMFKGyi2YNuHLhVmchXtmnI3smA7x+acXEtvoQBW3EfBgu05OmMB995VJ/R53Cestwm2N7wigr67is99WypvE2w/e4UEFScLtsVUuY6N/FQLEvc30JiRL61rXYZ7rgXb4iXoxHrFa/oFwXbJhAa0bbBdgv5uevmZoNiCbQu2S4sNC42tF0ZFSu1mO2RzrizekTgSlPJos5vtORpzAi29drOdYzIpb7w5JLUJhQYqJKpZN63LcEeyYFvMdSfWK15TnDBtb7ZLJjSgFmzbbySl4cQFrcvYzXbM4MK6lt5CmQtF/+7N9iNmENMS/8nMo6022Iae7J/MBOA2yB9daJWpFP8EI73ZJvXZ9AlQPkFQZgElAAAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}\\frac{1}{2}\\\\\\frac{1}{2}\\\\\\frac{1}{2}\\\\\\frac{1}{2}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡1/2⎤\n",
       "⎢   ⎥\n",
       "⎢1/2⎥\n",
       "⎢   ⎥\n",
       "⎢1/2⎥\n",
       "⎢   ⎥\n",
       "⎣1/2⎦"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "TensorProduct(plusket, plusket)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "5f32aaac-b8ae-4162-a35c-ea18093a45c0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAC0AAABlCAYAAADZEWqbAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAEEklEQVR4Ae2cQW4TMRSGCeoaQRccYJA4AL1CuEHLAtbQI1QskLItN2gPwIorcAPoAZDaAyCBIg5A+P/EY5lgj515fxwZxtLEHtvz5puXN288v6LMVqvVPWVZLBYPYe8FtnO0T5S2e1tHMPwMO1/6jq36I8bPtvqSu87W3E0g/KgCO7c4sIsdjLHZUTDwHm1ODstduJNrw+AN5tygPs3NzYxfRsafo29tN4S+wsl2gowYlnSB43rbEPrYtYa+vz3Ywv4EXetbmjxdy9Nh9jCfE3c4c+s5tjm2DvtMXd9RM53KihqaKfNCRpcwNMV0wjHybll4IG6zKy/MmSmuQAktASq5qCZjWuZpeghfP5ejb523mP5YXqN/uWlqPqXQQLoEIPP0uqB9hQbX6k82PZpPdXi8Aeg8QOPDhQ8ZvmjIihqaXv4so0sYkoYHPLq9eOdF3KGfbzSyova0B3MhwTcN+cvtXqAB3AGW8XyCtjRz0CvS8KBBB3yBmi+i/T5r2funFBpg9DDTHKH7jMG4lq78pNCAY07mA+YPHQUXEOZujpvEHCk04B4BKFmc9+duAuFHFSl0jgDQEjFnL9kjB28dn6CtHiw9fvJ0qaes85r0dO2U18HLfNAwV48Wc2pDS8ScJsOjSWiGxw9sH7D9whYtePxynfAJ2y7rhTP32F7bRNsq5nyFIXKu19PHqF9ie8eOWMEJl+g3vYHAhlXMeQoGcr5qNjxizt1LH7zN8DKLOVVTHoAlYk7t8JCIObWh+TQ0izlVwwMxLRFzanva3+C4AL6tjxJzDgIN4I43JbZRYk7V8KCbHbBJzKkK7YDNYg6hH9ADKH292Rv5CTA+QFJiTFbMGTjt436M0D/dTl/3YzvXAObNNXcH/rW4wvigmJM54bd+XBoegJKIMT1cqj5I9kjBlPZP0KWess6bPG31YOnxTXpanfI6eMssxuQ8roaWiDE56CbDo0loWXjgEW4VY3JR4ceV0FYxxkPlGv93eNA7CBGJGJPztCw83IkkYkwOWh0eEjGmNrREjMlBS8MDMS0RY3LQ6vDw58MFjBZjvJFEYy/QAO5wvtFiTILVd0vDg1YdsEmM8XSJhhTaAZvFmASr75ZCw2pWjMGFDYk5HmyoIYUG0KAYg/FBMWcINByTQoeGY21AS8ScvWSPGLCyb4JWenPI1uTpIe8ox5r0dO2U18HjZjGnNrREzGkyPJqELgoPt8g59C9rfAIqhV7iiEP/ssZD/7vh4S/R2HBhNv2yxujHosMlYk7tmJaIOUXZo8iHBZMQ0xIxp7an/aXhAkaLOQeBBnAH+tFiTtXwoJsdsEnMCaFvYZB2w7LTP6mEB8baDjgr5mAe/xyF30a0EJrLRd7VscIxZcmKOe5kDJ1k+Q0nYl+oJfySAQAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}\\frac{1}{2}\\\\- \\frac{1}{2}\\\\\\frac{1}{2}\\\\- \\frac{1}{2}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡1/2 ⎤\n",
       "⎢    ⎥\n",
       "⎢-1/2⎥\n",
       "⎢    ⎥\n",
       "⎢1/2 ⎥\n",
       "⎢    ⎥\n",
       "⎣-1/2⎦"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "TensorProduct(plusket, minusket)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "72f44688-25c8-4162-b845-518a143f617b",
   "metadata": {},
   "source": [
    "### Exercise 1.3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "6d37cc30-be92-4322-81a7-253afb46bf71",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Hadamard matrix\n",
    "H = sy.Matrix([[1, 1],\n",
    "               [1, -1]]) * (1/sy.sqrt(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "15f9cc87-9b5c-4a4f-930a-02a60cd124d3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left( \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2}\\\\\\frac{\\sqrt{2} i}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2}\\\\- \\frac{\\sqrt{2} i}{2}\\end{matrix}\\right]\\right)$"
      ],
      "text/plain": [
       "⎛⎡ √2 ⎤  ⎡  √2  ⎤⎞\n",
       "⎜⎢ ── ⎥  ⎢  ──  ⎥⎟\n",
       "⎜⎢ 2  ⎥  ⎢  2   ⎥⎟\n",
       "⎜⎢    ⎥, ⎢      ⎥⎟\n",
       "⎜⎢√2⋅ⅈ⎥  ⎢-√2⋅ⅈ ⎥⎟\n",
       "⎜⎢────⎥  ⎢──────⎥⎟\n",
       "⎝⎣ 2  ⎦  ⎣  2   ⎦⎠"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "eyeket = sy.Matrix([1/sy.sqrt(2), sy.I/sy.sqrt(2)])\n",
    "minuseyeket = sy.Matrix([1/sy.sqrt(2), -sy.I/sy.sqrt(2)])\n",
    "eyeket, minuseyeket"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "93828c16-c2bb-4e2a-a0e3-e9b672e0da7f",
   "metadata": {},
   "source": [
    "the transformation of $\\ket{0}$ by H gives $\\ket{+}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "187b5f53-2942-4765-942c-2f814daa1bf4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACkAAAA/CAYAAAB97+FwAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADWUlEQVRoBe2a0U0cMRCGjygFJJRw6QBaODoIJQAdgPJ09xZRAkkFkeggpAOSEigB0UHy/Xu2Yzlen73jRXlYS2bGXnvmv39s7+C7o+12u1mtVt+paXna7XYf0s652vj6ie2TjP3zt1HnWaRLfU7aczcvcHCcOBnICyD5JA/JAHMTm78PGWHMkcYgf6Vj6XtRXwCZDrC2cXCJjSvkF6ut2UAC7ByA6RKahHcWkIC7Bs2dEKG/Q3ySTlnvxeqC/iGUrl0Us4DE4xkgPIu36FceBbrAaydXnxxv/OReEhCBRWfzkr5NZP8WfU1f7riJhv1VuzKJY4U2ZlGexOKjlKmlGSRAtK42yNyu1doTU6Fkxgm0XhT/HDlhUqI0hRvDCpuc3KGLtVBc+wQ5et7yTCH+SD0NEyuUVpAPOLrBrljwO9a7EYN6li3MUwQ05hS9emfLWBNITXDlM/IaZwObTmozZENIvwDeILVeX9R2fd5eUU4CiYN7rD5RPZujLDowOna0RLQcFHIx/kytKs0bJ7IqR19x+g15jMyyyDOdiWJcMhTGa21XlckgcXJPFYM/qKMbgTHvq5AUBk0Kd2RPbGozKfSzlclMChHgtDZVZy3VIAF0MDecghS7Qz5ZmtsC8qCxkiPLM+uatPiunlvNZMkiIdMR489MHdwqTTnjfkr+bxeQmDbnjHl4+95e4TbnjK8BUm8PU85YAtkl3KzJNLcU6KacsQSyV7iDDwBPyhmDgYzSFSQAtbMn5YwZbKGrS7hlzQEccsaorX7ze70LSAdQOaNA+v8CtS5HM3V9kNrSBSTOzDljCXAXkLBnzhlnBznmAPAHMyfGHExcujCZA4nz5VYtR0xTHyyG+yB0c4Y0V7jj+yBzhtT1jSO6YxYd/eYMqSuTLrQxi8JpzpCaQQJE7+flVs0tkyCa1iQsLrdqgbpEaWLSz4XR5VbNk+Fl8+72E8UmdblV84RUMwlro2lX6Zl3NCaZ2y9VqzE2BsTaP2l3W522zq8Od8kwLJvTsZL9LiBxYE7HSiB7hducjr0GSHM6VgLZJdysyeXCqteaHKIFo2uU5cKqtHaLzxyDy4VVkaWahzD5OhdWOEqznP/lB3UrnZP61sD/hicmrvpL83iSQc/9oE7mHv8A92R2zXnZqnUAAAAASUVORK5CYII=",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2}\\\\\\frac{\\sqrt{2}}{2}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡√2⎤\n",
       "⎢──⎥\n",
       "⎢2 ⎥\n",
       "⎢  ⎥\n",
       "⎢√2⎥\n",
       "⎢──⎥\n",
       "⎣2 ⎦"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "H * zeroket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "ddd08ec6-4718-4733-bb7e-7355584ea1ce",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAADkAAAA/CAYAAABaQWCYAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADv0lEQVRoBd2b7XETMRCGHYYCICWYDpIWnA5ICUk6SIZf9r9MSghUwEw6IHQQKCElZNwBPK8taY5Dd2fQrk6gmYs+T9rHu9LdeuOj9Xq9WiwWX7j66Xmz2bzrN7ZaR9ZvyHaSke/8dafxrFNW8aVXb716gYDHPSF3ykuQfBKPvQHuVdb8MbUIY46mxqifcd/742jbqi1B9gd41xHgkjWuyD96rzUbJGDnAPa3iAvvLJDAXUNzLyLKb8g+qExa7rPFBe07Uwv1omwWSCQ+AyJq8Y7yVaSgLHidlGYn+6s4ea0ciKTFsOYlbavO+neUl7TlHgedYYcXq2oSwWWaXS1KUmnxSQWvZA4JiPbVijx3amrvSVMpZcYJWi8ivz0S0k1/WDA1VwST2UnIe8rSWkqhfkI++DymTyb6nus03WhQsIZ8RNAb5JIW4okZxZQG1ZdN3CcL0JhTymYnqxYzhdSEId2SXyPsTpsh12GSNUHaBXhDrv26VT20xfmKchdIBHxAqmeuqM1BLQYYPTZk4jJnmaw0/sJlkswPno5UEvQTQn8mPybPapE+PROlceUpMV572yS5QSLkA5c0+JVr8CBhzFsTkpFJXMy1s560qcNIpjtbctOkiIDT3tQ1azKDBGjSN/wbUuY9yJ8cm9sSsliYMUFL+rz3ZIlsZveaaXJMIkxOj4j4zNSDX8nUZ9xPmf9bBZKl3X3GPN6+tZa5uvuMLUDq7cXVZxyDrGKu7Mm+byloU59xDLKWuSYZAHbxGdMCmUJVSAB1srr4jBm21FTFXLVaANz5jJ262t3fa6tABkD5jIKM38JpXw5+U6APwipVgURYd59x7AOpAon23H3G2SHHBBjr48OZ9GwYM+kYVNHkGMhQH8KbRb2ahQTeLOrVJCRaTPESysUeTJOQaLEbLyn2YKq+8Qztv257V4uhvdiDaUqTwTS7WhRnsQdTHRIQvb9WjXpVNVcAV0EzVaNetSFniXpVhdQGC+mWvFrUaxZIzLZq1Kv6wRNVSV4t6jUbpLTJVSXqNYu59rTpHvWa1CSftt4dFWNUfmjSy/UvQVfqg27TWN/Ugtxb7moxyZaFBoOoU0LE/kOEiWOt87nN1ZonO9+kuWbvcmhE08Uu1ZBYzUAiYLFLNQTZkrkWu1T/AmSxSzUE2Yy5sifdgkItmWtSBMCmQaHmIAFcQmsaFGrGXKXGAGgeFGoGMgC6BIWagUSRbkGhZiDRpFtQKEGySN9L+F9+kLYQpP4rI/5Gg2JKZv9Um2b0LeR+kKYVn34Cov5+cB0fwCkAAAAASUVORK5CYII=",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2}\\\\- \\frac{\\sqrt{2}}{2}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡ √2 ⎤\n",
       "⎢ ── ⎥\n",
       "⎢ 2  ⎥\n",
       "⎢    ⎥\n",
       "⎢-√2 ⎥\n",
       "⎢────⎥\n",
       "⎣ 2  ⎦"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "H * oneket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "ecdb57a6-3881-4cb9-8d15-25b0fe0249fa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABYAAAAzCAYAAACT1fi+AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB5klEQVRYCe1Y7U3DMBBNEQNUsEHYgMIEdATKBtAN6M/kb9kAGCFsABtUdAPYgNIReK/xmcg+fwgpv/BJ17Mvfi/ni31xOmmaZlop0rbtXnF7LoxT8UcY+Q79dnTtMYQdnYMlVzdBxB9oLHHntzA2/wp47jB6wYhHkeNcVkRyjrGc9gztZP6jxCDgg3mG7qAX0BqaJSliRrYgE25yD8Oos2S0HBdim/+Sin+SilMzzxM730gjuqWJw1Zm4aHMe1N18H2i/Qr7ZHyeySE+1AoPmXCUdWwTVFJRUmEzYBujrYrklmYIqAlylvtC9wy6NvWCl1VJRgwCHho3sCvoA9orKAtQrTIaZ5QYYB7wprAvQoI2DzHsP4pPs1FiAFjZtgpwA98cN+ERTJUUMWswz22usB5TpEb3vcFvkDgWzQAffJsEiQEWEHMakj+nIkQofnkPSt/aWMRabgUos+G6ViVIbJYVQdp0xScP0SMPEpuR/OCpPdRv/oMfRClivvr5ieDKDI7tYFbu9SpKDCDPDTvYa0GizTTcQG/Fp9mcIsToWHQuYfmwaK/Q13YkLvWSJAbBHkOXAsi10VTkkmjjCrHNymipkFVRm/Vp72hWg+2HGi4O4w7bXSLma2b4Z4i8PEN8Qz93p4f9Ac3geM8qWTlXAAAAAElFTkSuQmCC",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}1\\\\0\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡1⎤\n",
       "⎢ ⎥\n",
       "⎣0⎦"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "H * plusket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "578fe639-5a0a-4a78-bb19-f15336ca3628",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABYAAAAzCAYAAACT1fi+AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB5ElEQVRYCe1Y7VHCQBANDgUw2kHsQLQCUwLYgdKB/Ez+YgdqCbED6YCRDrQDkBJ8L2TPkNv7gBn+3c7c7GZv92XzuNtcGJRlOcoUqapqp7gtF+LU/AtEfmH89sbCQnA76l4useoBKv6GMcOdl+7c+BngPCF6yorPIsMYVFQh1GwQf42xgO/HlxusGAD8DVbQc4wX2HOMT9j5ycBIJl8j6A8Bgc3VwutX8Wk6VPEUSWslcQVfgZuoS43xIeACMVsG9kT45bwqTmBfNR2ky459YDqBESVJvh14MhUHVSgXV4qvcfkq1rgVHHkarmtVnMDtsmKS9rjikx/RAncCt5HsH7mV9c+/s7+EgNm5bhXgMXzrzlNZIV5gJL4hYws9kUzYpOEB41F8mo5pQqyOTecOmj8W9T2utR2Jqb0EgQGwQ+hMEmK1l4pYEC0uARtWEhWJCsOAMYJbWiKxtW9gs9uN220uU6r2AgOAnewdg28Tts8cI0pCwGxAPFtkuMkzFKuOkrRBDE2JikSFYcAYx6wKOVnKgdCAaIZ3SzMBW5mNh1LsVVbDx8MgP3B4UlIlBrjpFWq2x3kMFR4YeyoBG07ORoWsihxLh68hI7jm2yMo/TwkNDhSMb+Lu3+GyNd+EBgBXOdW7h+r9njPVpljOAAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}0\\\\1\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡0⎤\n",
       "⎢ ⎥\n",
       "⎣1⎦"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "H * minusket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "edad7556-4470-429d-91e4-fcc49f14c3a3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEAAAAAzCAYAAAAn3w6xAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADf0lEQVRoBe2b723bMBDF5SIDpB7B3SBBN3A3iNsJmm7QoJ/sr+kGzQpdId2gzQbNBgGyQft7KmkorGwedTIkGzpA4B9R5LvHuyNNwrP1en1etchms3luqR51FZily5z0MQUa3qXV1Rk1v3gWyZs7yp+adaGD96onf9l8N6L8F7A88XxtwfSdumVSfz/DAn5TKaXuk5fbIu8uKMSP1fbN9uWRZtDhGugrWUBWaPxAowfSq2zjI2tgImDsOjExsk5Z6VvyqxK8r0oaj7EtCivwXZDK769C2Qz16AlA0znPHYrLPR9Ji1avQQkA7JJHwaiz8H1UWqvWt9KOBiUAsDJfPS6BBPWhOCBLUCwwy9AEmIFmGkp5rVIy/xf7l8x39UYo16ai40XoWAMtKN+SPpG2bTiy/R2ggfYwH8DzmVTYzHJmaUnH2lreWNoO0QZ8mvmi5S/iPBUXiPoUp1kLgN0/uV5pM9vXhveKznKfVLSEVbxv81v59N5Z5b0bm4WAvcqlGrWVdyhYUa+1WzGlUyzhOze2yQXaZiytg2mts/qpKdGKIPlIvYLPoOLFlnWBoN0tA239lLx8WucIY/hZ7MJmdYFrlG4GMa218t2iXVcgs+/Ehc1KgGb/Z9/Ie+rPhc3kAsy0jsiaokH1I0QHJR5RDHHFES82EwFNDYPZa/lynwvS185juOaY1nwXbFYXqDEwgFYA+f8ledfMWZWytuuKzWwBYYAb0ncCFcpK/zuCtoLuq13A0gmbiYAwgJY+DRIjv+LA4D+QvNhMBKCo1vzzkJL8EwYXCUOLC5uJABR9zSMCRncxImxxBsgXn1NYCZDZL8NAImKUAgHFLmklYLoYGeWUB1DMvKxTVjpdjEBGkYsWbYRGagVzcHW+GDHFgJEqXsNixuuNGKmWZO1ViuQULKAKZq84MF2MQELR5szkAjCsH0HqWCxPFyOQMCphgp4BtPcIfRfgk4gBu5Sz1GddAHbdlw8hSP0AUMkaveK7vSdOfWCzEOC+fACoTNR9gpTOKP26sU0ukLLaVoZpme50MRLJgZDpYgQypouRaBEDp9qgdb60ya4CUg6TP9TFiJs7L7biVYABdfDQy8WIW/ukgy7YighggAVjThcjIj6QofQkLkYU0V9sUylr91YLec38UV+MpPqhT61vDIJSTk+U9A8TrsuH2OmBUiu21j9M/AXsQ4ZaAWLYiQAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}\\frac{1}{2} + \\frac{i}{2}\\\\\\frac{1}{2} - \\frac{i}{2}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡1   ⅈ⎤\n",
       "⎢─ + ─⎥\n",
       "⎢2   2⎥\n",
       "⎢     ⎥\n",
       "⎢1   ⅈ⎥\n",
       "⎢─ - ─⎥\n",
       "⎣2   2⎦"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "H * eyeket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "b7269773-b373-444f-9204-158627f56ab5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# is it a scalar multiple of |i⟩? -- Not quite\n",
    "H * eyeket == eyeket * ((1 + sy.I)/sy.sqrt(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "7c50f17a-fb8b-43b9-a4c1-d00fc0159499",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# is it a scalar multiple of |-i⟩? -- True, but get false negative\n",
    "H * eyeket == minuseyeket * ((1 + sy.I)/sy.sqrt(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "d719ade0-d516-493f-9654-f8fbd585a7cd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABYAAAAzCAYAAACT1fi+AAAACXBIWXMAAA7EAAAOxAGVKw4bAAABqElEQVRYCe1Y0VECMRAFhwIY7eAoQa1AShA7EErg8+4XO9AWsAPtgIEOtAOREnjvvD3vkt0kA+OHM8lMZvc2+x6bvWQTbliW5XigtKqqDorZM8FPxV/Ac4v+7fSVx2Ab1g6WXOshIv6AssAvv9vY9BHwzOE9Y8R/0kYprIhCUvMF/wn6CrbPEDYaMQj4DjaQS/Qn6Ev0N+jFycQAM19jyFchgc7VwudnsWkyFvEMoJ0C3MA2xY+oS43+MeIpfPZ0dJrkl+NqM4lD0XSYLjt6TzWJ4SWg0A48ORW9KJSHK8VWm0IRa7kVHpkN17XaTOJmWRGkTVds8hI9cpO48WT9KDzUb/7N+hIjZuW6UYivYdt1ZuW5BIkBfAFiD3kvSOhMwwP6o9g0mVKEGB2Lzi0kXxblHZ61HYmhnxYlBsEBrgsBpMpgKlJJNL9M3GYlpyKnos1Aq0S3ND2xrfOFZZAvLPWqkSOehd5qclp74+cWoXxhaS+M+cKSLyze/rIN5+48k/n/EcuZV+Bc61Wq5vpqTlUGXBzsNY+kgv+Lux9D5PAUfEi6H0Jq7BGECZ1CyAbz+QAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}0\\\\0\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡0⎤\n",
       "⎢ ⎥\n",
       "⎣0⎦"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# simplfying the difference gives the expected answer\n",
    "sy.simplify(H * eyeket - minuseyeket * ((1 + sy.I)/sy.sqrt(2)))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2b54316-d5c3-43a2-9aee-7dd4f48f99ed",
   "metadata": {},
   "source": [
    "### Exercise 1.5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "46b92b00-3bf6-49b6-b094-1a55c3d78801",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[ \\left( -1, \\  1, \\  \\left[ \\left[\\begin{matrix}1 - \\sqrt{2}\\\\1\\end{matrix}\\right]\\right]\\right), \\  \\left( 1, \\  1, \\  \\left[ \\left[\\begin{matrix}1 + \\sqrt{2}\\\\1\\end{matrix}\\right]\\right]\\right)\\right]$"
      ],
      "text/plain": [
       "⎡⎛       ⎡⎡1 - √2⎤⎤⎞  ⎛      ⎡⎡1 + √2⎤⎤⎞⎤\n",
       "⎢⎜-1, 1, ⎢⎢      ⎥⎥⎟, ⎜1, 1, ⎢⎢      ⎥⎥⎟⎥\n",
       "⎣⎝       ⎣⎣  1   ⎦⎦⎠  ⎝      ⎣⎣  1   ⎦⎦⎠⎦"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# list the eigenvalue, multiplicity, eigenvector(s)\n",
    "H.eigenvects()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "10a8072f-55a6-41be-8916-b02f463ebde9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# eigenvector for eigenvalue 1\n",
    "v1 = sy.Matrix([1+sy.sqrt(2), 1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "aa5546ab-ee59-4953-bc27-e1cd313c3898",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}\\frac{\\sqrt{\\sqrt{2} + 2}}{2}\\\\\\frac{\\sqrt{2}}{2 \\sqrt{\\sqrt{2} + 2}}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡   ________ ⎤\n",
       "⎢ ╲╱ √2 + 2  ⎥\n",
       "⎢ ────────── ⎥\n",
       "⎢     2      ⎥\n",
       "⎢            ⎥\n",
       "⎢     √2     ⎥\n",
       "⎢────────────⎥\n",
       "⎢    ________⎥\n",
       "⎣2⋅╲╱ √2 + 2 ⎦"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# calculate the unit vector\n",
    "v1norm = sy.sqrt((v1.T * v1)[0])\n",
    "u1 = sy.simplify(v1 * (1/v1norm))\n",
    "u1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8713a5fb-88f5-4e75-b8a8-ae7981fa49cd",
   "metadata": {},
   "source": [
    "To get a vector halfway between $|0\\rangle$ and $|+\\rangle$, we should consider vector at angle $\\frac{\\pi}{8}$: $\\cos(\\frac{\\pi}{8}) |0\\rangle + \\sin(\\frac{\\pi}{8}) |1\\rangle$ "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "5dd19095-24f7-42f0-9f39-6c812b56d733",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}\\sqrt{\\frac{\\sqrt{2}}{4} + \\frac{1}{2}}\\\\\\sqrt{\\frac{1}{2} - \\frac{\\sqrt{2}}{4}}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡    ________⎤\n",
       "⎢   ╱ √2   1 ⎥\n",
       "⎢  ╱  ── + ─ ⎥\n",
       "⎢╲╱   4    2 ⎥\n",
       "⎢            ⎥\n",
       "⎢    ________⎥\n",
       "⎢   ╱ 1   √2 ⎥\n",
       "⎢  ╱  ─ - ── ⎥\n",
       "⎣╲╱   2   4  ⎦"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "u2 = sy.Matrix([sy.cos(sy.pi/8), sy.sin(sy.pi/8)])\n",
    "u2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "15aab956-11bd-4b76-ba4d-58cdccd67d9c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABYAAAAzCAYAAACT1fi+AAAACXBIWXMAAA7EAAAOxAGVKw4bAAABqElEQVRYCe1Y0VECMRAFhwIY7eAoQa1AShA7EErg8+4XO9AWsAPtgIEOtAOREnjvvD3vkt0kA+OHM8lMZvc2+x6bvWQTbliW5XigtKqqDorZM8FPxV/Ac4v+7fSVx2Ab1g6WXOshIv6AssAvv9vY9BHwzOE9Y8R/0kYprIhCUvMF/wn6CrbPEDYaMQj4DjaQS/Qn6Ev0N+jFycQAM19jyFchgc7VwudnsWkyFvEMoJ0C3MA2xY+oS43+MeIpfPZ0dJrkl+NqM4lD0XSYLjt6TzWJ4SWg0A48ORW9KJSHK8VWm0IRa7kVHpkN17XaTOJmWRGkTVds8hI9cpO48WT9KDzUb/7N+hIjZuW6UYivYdt1ZuW5BIkBfAFiD3kvSOhMwwP6o9g0mVKEGB2Lzi0kXxblHZ61HYmhnxYlBsEBrgsBpMpgKlJJNL9M3GYlpyKnos1Aq0S3ND2xrfOFZZAvLPWqkSOehd5qclp74+cWoXxhaS+M+cKSLyze/rIN5+48k/n/EcuZV+Bc61Wq5vpqTlUGXBzsNY+kgv+Lux9D5PAUfEi6H0Jq7BGECZ1CyAbz+QAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}0\\\\0\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡0⎤\n",
       "⎢ ⎥\n",
       "⎣0⎦"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# compare them\n",
    "sy.simplify(u1 - u2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69b4de9a-5634-4d37-81a3-7536f3af4c50",
   "metadata": {},
   "source": [
    "## Lecture 7"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a3be0544-f599-4eda-b49c-bb2850fec92f",
   "metadata": {},
   "source": [
    "Elitzur-Vaidman bomb experiment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "e9721018-4c1b-4c1f-bec8-9cdb5b0acf82",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "rng = np.random.default_rng()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "f347d361-8a9c-49f0-9b64-9e160b8e81c7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([1, 0]),\n",
       " array([0, 1]),\n",
       " array([0.70710678+0.j        , 0.        +0.70710678j]))"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def col_vec(components):\n",
    "    \"\"\"Return a column vector (as a NumPy array) with the given components.\n",
    "\n",
    "    In a matrix context, this should be treated as a column vector.\n",
    "    \"\"\"\n",
    "    return np.array(components)\n",
    "\n",
    "\n",
    "def col_vec_inn_prod(v1, v2):\n",
    "    \"\"\"Hilbert space inner product of column vectors.\"\"\"\n",
    "    return np.conjugate(v1).dot(v2)\n",
    "\n",
    "\n",
    "zeroket = col_vec([1, 0])\n",
    "oneket = col_vec([0, 1])\n",
    "plusket = col_vec([1, 1]) * 1/np.sqrt(2)\n",
    "minusket = col_vec([1, -1]) * 1/np.sqrt(2)\n",
    "eyeket = col_vec([1, 1j]) * 1/np.sqrt(2)\n",
    "zeroket, oneket, eyeket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "958d0209-78f0-4be0-bb71-2302ab2e8058",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((0.7071067811865475+0j),\n",
       " 0.7071067811865475j,\n",
       " (0.4999999999999999+0.4999999999999999j))"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "col_vec_inn_prod(zeroket, eyeket), col_vec_inn_prod(oneket, eyeket), \\\n",
    "    col_vec_inn_prod(plusket, eyeket)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5e30304-1d42-42ee-9ab4-235ae383d3fb",
   "metadata": {},
   "source": [
    "measurement of qubit state $v = (z, w)$ in \"computational basis\" should give the case 0 with probability $|z|^2$, and the case 1 with probability $|w|^2$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "f2745ccc-aa99-4712-84e1-307cca6f03a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "def measure_qubit(v):\n",
    "    \"\"\"\n",
    "    Measure a single-qubit state vector in the computational basis.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    v : numpy.ndarray\n",
    "        Length-2 complex NumPy array representing the qubit state vector.\n",
    "        The vector need not be normalized.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    int\n",
    "        Measurement outcome in the computational basis.\n",
    "\n",
    "    * 0 with probability |v0|^2, and\n",
    "    * 1 with probability |v1|^2 = 1 - |v0|^2.\n",
    "\n",
    "    Notes\n",
    "    -----\n",
    "    The state vector is allowed to be unnormalized. The probabilities are\n",
    "    computed using the normalized state implied by `v`.\n",
    "    \"\"\"\n",
    "    # Compute the threshold value |v0|^2 / ||v||^2\n",
    "    # Do not assume ||v|| == 1\n",
    "    # hence threshold = |v0|^2 / ||v||^2\n",
    "    norm_v_sq = np.real(col_vec_inn_prod(v, v))\n",
    "    v1_sq = np.abs(v[0])**2\n",
    "    threshold = v1_sq / norm_v_sq\n",
    "    rand_num = rng.random()\n",
    "    if rand_num < threshold:\n",
    "        return 0\n",
    "    else:\n",
    "        return 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "cc709f13-047f-4db6-a7fc-64cbc2c1082f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACcAAAAOCAYAAACsAAXLAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABXElEQVRIDa2V/W3CQAzFCRNQukG7QSkb0A2abtAyRvIfYoTCBAg2oBtUZQQ2KMoG4ffgHB0hSIdkS4599sv55T7irK7rnklZli/4a3SEX1k8tsTnYfyPfUbnxPYxRr4HLiuKYsBcS/SAvqIi+MDkV+SI/ZGbYTfYHlbvKvaG3xDEd8H1mahCc3RKkRXaKeS/SAywJ2IC4esDNP7WWELMDdc/T5n0zEHtOpC/xCaQ0ipK3HD3kJtQWFvfFttO5SVuuCRy0aqcy3c/h964JHJwGQY+V5ck4qltdcWlkos43HQfb2YuE8m4VHJdZ81K2mrpv+eKSyLHWbLttBtpxGQttvfGJZELTH6wT8GPja2c8hI33D3k1NbUQdoyIrCLVs0N1yZnh9VWoyFC8QWDA/bdgvja0g/0M4q54TI1foroayX6gaqgOoF+rltyKnaSQEaNv0J1Acaoeq3wjXjhjq8rzaHgD8neAAAAAElFTkSuQmCC",
      "text/latex": [
       "$\\displaystyle 1000$"
      ],
      "text/plain": [
       "1000"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# if we measure |0⟩, expect the outcome 0 with probability 1\n",
    "[measure_qubit(zeroket) for _ in range(1000)].count(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "d5bffdc4-3715-49fd-898b-9e5b75731b72",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAOCAYAAAAWo42rAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAz0lEQVQoFXWS4Q2CMBCFhQkIbqAjqBvgBsoGOkf/GUbQFXQENjAyAhtA2AC/V3tGG2hyeXdfH71LSzKO48KWc64KeYeuiQrWiiVmBLyoL+hDG2iGiO3J2zTAM5qZKbAB1UdX1d6IHolGIFpP6kKnm7EA9JFJpZ8PLdIwy4TnD+U6MQ9IM82tb+s5g/GlTpyazQzWrdOM1lL3Fi9jn3tktyZWsYvaTqzteu7A7YRxA2vU1RtJboAePZiZXG1L4iT2+9ba0E8xEPopdoTe3r/YGx/SQ0OZAIYmAAAAAElFTkSuQmCC",
      "text/latex": [
       "$\\displaystyle 0$"
      ],
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# if we measure |1⟩, expect the outcome 1 with probability 1\n",
    "[measure_qubit(oneket) for _ in range(1000)].count(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "89b62fd0-22d4-4e58-92e3-dd0eba5e229d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAOCAYAAAA45qw5AAAACXBIWXMAAA7EAAAOxAGVKw4bAAABnklEQVQ4EY2V4VECQQyFD4cCGKwAShDtgBJ0rADpQP/eX+wALQFLoAPQEqAClA7O7+1sztzeyV5mlmRfXpLbXG4ZVFVVdElZljfgS/Qy9YOtHTbGXoCdHRbMS7xhSnb7DfaX2xckGrH/ZK2xX+VD6wGP6BnrELEs70rEVEjwnGJx/44e4w9FhWHr4fYs34Usr1WYRDqB2tZqHdg9K5wK7UXF58TqpJIsr1WYoEcSvIVw9+OSfjvYzFM0bvvyGoUJUot9yyxxgc86oGFK5ToC0768ujABU4LP6K5WWqEPDPFS0euRWKuzvLowQfp0Wi0O6f5+FjLhzQ3CtpkQZA+d5YXPieAngjpbbAWk4akjE8wVWgXV4l1c9UD14Q0hqXUjtD0t2/9FSfE2LhWwVYyoc+R4OrEK30HUheFFJ9KwCD+gX7wzscXdxmKJq7GteTrxVkENNxvwH+HoB/Nhq526HCbYYcrRGii98xkrSB+eHy6LM62EWl7UnfQ7Vkc0mLpETLK8QfonQQINmQJtcvVp7MDtbrb3aQ+1wdfVsYu8X/jjz2A3MEGaAAAAAElFTkSuQmCC",
      "text/latex": [
       "$\\displaystyle 499$"
      ],
      "text/plain": [
       "499"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# if we measure |+⟩, expect the outcome 0 with probability 0.5\n",
    "[measure_qubit(plusket) for _ in range(1000)].count(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "4a334a9d-20d2-4486-baf5-590dac9fd85f",
   "metadata": {},
   "outputs": [],
   "source": [
    "def bomb_machine(v):\n",
    "    \"\"\"\n",
    "    Implement the Elitzur–Vaidman bomb test for a single qubit.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    v : numpy.ndarray\n",
    "        Length-2 complex NumPy array representing the qubit state vector\n",
    "        (a single-qubit column vector). The vector need not be normalized.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    numpy.ndarray or str\n",
    "        If a projective measurement of `v` in the computational basis\n",
    "        yields 0, returns the state |0⟩.\n",
    "        If the measurement yields 1, returns the string \"💣\".\n",
    "    \"\"\"\n",
    "    if measure_qubit(v) == 0:\n",
    "        return zeroket\n",
    "    else:\n",
    "        return \"💣\"\n",
    "\n",
    "\n",
    "def empty_suitcase(v):\n",
    "    \"\"\"An empty suitcase returns the input unchanged.\"\"\"\n",
    "    return v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "745c489b-d715-4a37-9eac-58b7ed0b1b92",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[array([1, 0]),\n",
       " '💣',\n",
       " array([1, 0]),\n",
       " array([1, 0]),\n",
       " array([1, 0]),\n",
       " array([1, 0]),\n",
       " '💣',\n",
       " '💣',\n",
       " array([1, 0]),\n",
       " '💣']"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# with |+⟩ as input, expect the explosion half of the time, otherwise |0⟩\n",
    "[bomb_machine(plusket) for _ in range(10)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "8964de8a-4f85-4f27-9b20-e99e1fceb20d",
   "metadata": {},
   "outputs": [],
   "source": [
    "def EV_algo(ε, suitcase):\n",
    "    \"\"\"    Determine whether an Elitzur–Vaidman (EV) suitcase contains a bomb.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    ε : float\n",
    "        Control parameter (rotation angle), assumed to be small.\n",
    "    suitcase : collable\n",
    "        a function implementing the EV-bomb, or `empty_suitcase` function\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    str\n",
    "        A string describing the outcome:\n",
    "\n",
    "    * `\"we died\"` if the bomb explodes during any suitcase interaction\n",
    "    * `\"guess bomb\"` if the final measurement suggests a bomb is present\n",
    "    * `\"guess not bomb\"` if the final measurement suggests no bomb\n",
    "\n",
    "    \"\"\"\n",
    "    # work out the iteration count N and the rotation matrix\n",
    "    N = int(np.floor(np.pi / (2 * ε)))\n",
    "    R_ε = np.array([[np.cos(ε), -np.sin(ε)],\n",
    "                    [np.sin(ε), np.cos(ε)]])\n",
    "    # initial vector is |0⟩\n",
    "    w_vec = zeroket\n",
    "    for _ in range(N):\n",
    "        v = suitcase(w_vec)\n",
    "        if isinstance(v, str) and (v == \"💣\"):\n",
    "            return \"we died\"\n",
    "        # otherwise continue with the loop\n",
    "        w_vec = R_ε @ v\n",
    "    # if the suitcase did not explode, do measurement to decide our guess\n",
    "    last_qubit_meas = measure_qubit(w_vec)\n",
    "    if last_qubit_meas == 0:\n",
    "        return \"guess bomb\"\n",
    "    else:\n",
    "        return \"guess not bomb\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c44c534-8573-4fc3-9020-b08cf99eb7af",
   "metadata": {},
   "source": [
    "when the suitcase contains the EV-bomb, we expect explosion with probability $\\sim \\frac{\\pi}{2} \\epsilon$, and if we survive, get the correct guess with probability $\\sim 1 - \\epsilon^2$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "3e1bf0b1-fbee-4f96-9b2b-179e6f3f4c6d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left( 0.15707963267949, \\  0.99\\right)$"
      ],
      "text/plain": [
       "(0.15707963267948966, 0.99)"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ε = 0.1\n",
    "np.pi * ε / 2, 1 - ε**2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ff13367-4f9d-4a49-a2fe-d5e9641fcba4",
   "metadata": {},
   "source": [
    "with $\\epsilon = 0.1$, we expect to die 15% of the times, and otherwise expect the correct guess 99% of the times"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "d26cabff-ef41-4c93-97c3-85235455d732",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAF8AAAAVCAYAAAAgjzL/AAAACXBIWXMAAA7EAAAOxAGVKw4bAAADtklEQVRYCe2Z0VEbMRCGDyYFOKSCOB2EUEGgA+MOgA6SR/stQzogqSADHQQqSOIO7A5w6ID8n9BqZFm+kc+HHjLsjE7SaqXd+3e1OsvN4+NjE5fJZDKM+y/tVXy64pHDdb+JaDqdflL3fcR6afaHwNDjG1bcw5OQBkaqjlR/dozoId5V1D1Q+0y8h4jnmuJdet696ncql+ItPK/XqrIuAvJa5TD33rxYiT2SIbgfVH9jjgNfnYHad6oPYRp5/h/1r9T+Cl81htypYEgAVm3kvqi+Ud2oZk14J2oHOcZ2Ja337Lq8/d9l61Llgwrv/Vr8XNAV2+Nt/8g6lnaI2Di61XWE8gMJOuDhqD1T9VslyIt3rv5AtQNebeQwkn6Qg78r1dKF/SqnKhey+ccmuzvYAx4uQxj4Yy3itkKihFSUi1occKw5RDd0qgIvpV9ixHLpeJd+TV0l9m1lj8cZvAf7emQBjoBl26V07xlsR+hYJSdnjmO8L6qpq8TmLvaAy5jIP1G5TbUIfMttHLApvfEMTnCL/lQm7ufWiMeL2jV1lRi0gz3gfQL4RO98gzJy9jAzxuEDAbwBa85yA8mjxEHJlGy3pq6sAQmzqz3gPQR8gMmlDPSc8ZCHQ9pQG+ANaEsriLWR7ZQ2mb7GauoqsTlnD3gPX+mB9wzMlcUENCf+WzH5Xgd0FuIQpdhZsclxEgm7ws4IeLtQTV0ldna1h6AdAH4r4QAJ8LkVSDz7MbVgXIUxdlBKxivdIen8lX5NXSuKN3R2sMcFPGkH7xlIG9SssdkFtyj3IxwgubMBJdDagf7E7vSsqavEwC72gPcS8InKHHCNwB2p/FUJzvFtzoD4GoKf3vbZqWagQ7VmmmNOauK1gtR2jZq6SiwrtidajKBcAP5M5SgaiJs4Jc1rKLsQiMxzpDY/0JaqOQcceZDH6rhDG6bn4Ux+jnciza2mKzLQDk3byWGo1J4w4anhgnJPV52kkGstwkXYGolv+d2iH9m1NCIe48gS5RywOJS7nuAk9Rv17bN24yUVcm1US5f0EGgQO533413IFD81Fm4ESu3RPEeSB4MLd5cvB8xxQte76m3nSddIZbDtvC7yNXWV2Cd7hipzZEk7EBG78kXjuM/34OqaHVKDauoqeR/OSpdNHPh+C3FVQI5/VpIOtm9f3/2tttbU1WqIH/T4grNLWRb5DHM71+v1r9eZVudSHq6o08Ge+zV1lZgOviHDhH+ymOk9w+dlLXBKDP4vZIQp/2LdqA4/OP8BSOq+bE6tBOcAAAAASUVORK5CYII=",
      "text/latex": [
       "$\\displaystyle \\left( 90, \\  0, \\  10\\right)$"
      ],
      "text/plain": [
       "(90, 0, 10)"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_results = [EV_algo(0.1, bomb_machine) for _ in range(100)]\n",
    "test_results.count(\"guess bomb\"), test_results.count(\"guess not bomb\"), \\\n",
    "    test_results.count(\"we died\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "33410952-2c8b-451d-b5b9-7db6769f6c17",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left( 0.015707963267949, \\  0.9999\\right)$"
      ],
      "text/plain": [
       "(0.015707963267948967, 0.9999)"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ε = 0.01\n",
    "np.pi * ε / 2, 1 - ε**2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "261f3b21-4d15-457c-ae5a-6f637a232326",
   "metadata": {},
   "source": [
    "with $\\epsilon = 0.01$, we expect to die 1.5% of the times, and otherwise expect the correct guess 99.99% of the times"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "6d428309-8ff8-4205-900b-1a871ed1ae2b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAFUAAAAVCAYAAAA3raI2AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAEcklEQVRYCe2Y33EUMQyHjwwF3EAFHB0QqADSQUgHJB2E4Sl5Y6ADoAIGOgAqANJB0kFCOgjf57Ecr89HyN6f4QHNeG1pLcn+WbK9O7m6uprU5ejoaFbz/9tDfFo8enhtTSo6Pj4+hH1Uif43b0ZglnErPe+IvMSLXaon1C+ToHoge1ex92i/QHZZySbwU/hXlUz+E/KvlWxlTey+ycbOqR9S3iA7W5kDDGFvRhV4PKZ9IY/8hLoQvMF4Sf1eYQIVRgC+UW8rDMryn/DvaL9VTm0kf6Ns0y6ToG2fA/sEwX+i/ZH6c8hWUWPPMb0Ou9SOX9kO7TKmZXxhR0Cd007Yoe1CCqB+BsECr/+n1JeR/nauoxE20Qee9+iYAFVC21X6QSn9ke3Da7SlFwjq6G3f35rPvqbUZaFoX2JIvozp1obnFcSkDRKjVl8GS0v6TtkToO4xsBS6TU+3hN7KC+wzdIwQyfQrK5ok63s8x/Qg/bKr79T1mJYdwTMMnFZzDHtGqIs6C4E1vPiJ43SLRxc4X2ali1zX1Xlm3GckJ7SLzpdKT/miDPDdWHKyvTHF4vt+FSR4Z8zHyOxR4FO/cwx7d3kYYYP9wV4ao9j0YGrpfhak1aLfZwsyF+gXbdPE6BXkkqbwSxG2ehNpbfbG2/a5kceXGdEjz5QJ73vZIo47WzyMtlNKjwRkEOa5UzJMu0wyDyK2ECPUiOk5ziZGVQHYoujRaBnTKA9/UGKOzls84kbQ9hbHmaA6iF46qeBB46qUlMqGY1KRcvYxSpUboa6Yzt2TlG+SIovW4dMDyqwsB3fjRBwTqK5+gDTog7LyB5TntA8pRqBguYdKCVTknv5eM7zDuQ+5pUT6fICf2nkFtGjxNR1RHPv9Ctxdm2AOnu7OLeZ1/fK6JR5T99Q/EkYEtr1apKsD8ohUecEvhJ4ratSaEkb60nurY6FgqpvisXAxJvuthPBp0Hi1vOmGkwLU9Hf1Y0B/Owj3lq95kup6xRD8ASFzgoIZUTR4P5KJraVVDx9zh27b8TY8c3D7ekhdIpS2n6ZmbEticSGoTrzXYYKi1yRP8wJ6bht5abOGF0wjqGuDd+qWida2kI8h9zUP15b8GjzJ40nvlvWFvsHT+3QX6N5W5MKeCeqJipQeCVSr7KQOcKhekKvod34B3xfwpo3XqpSS+b2L1Pv6UuVGQtcbxgV1OQCz3T3k6WDVSJaN9oW+c3euZqGfq6Ugc/4GU0tpYe/w68rVEBD3vzlCHvtnANb9SUI/7fhJWi/CXF/6xfXNfwe9gc2NoRWg51gcl/oeTAaF/wLqhZ7Aj/aVdRdlnxkhgAPKOgfpXyrAngpu+69wXTy+dinTddmv7W7KF35mlFN9m/6Sqz444ZN0fQ/3qVFROmJIm/LlGZOyOoHKBN2nFp1oI+axWAVfpu5a7pKt1035wo/bhPilL8qIVMfjYbPKX2fa7NE+zhd9kfT6LyPblC9xK5le/vw78oy416hNTXoZwP4JXbDyp7UfOuWj4zd/TZoVjJLoNgAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left( 98, \\  0, \\  2\\right)$"
      ],
      "text/plain": [
       "(98, 0, 2)"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_results = [EV_algo(0.01, bomb_machine) for _ in range(100)]\n",
    "test_results.count(\"guess bomb\"), test_results.count(\"guess not bomb\"), \\\n",
    "    test_results.count(\"we died\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "08aabd79-e251-4901-a469-72e4f6aed098",
   "metadata": {},
   "source": [
    "when the suitcase does not contain the EV-bomb, we survive for sure, and get the correct guess with probability (at least) $\\sim 1 - \\epsilon^2$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "c85ab8e2-167e-49b7-9fcb-b12f39661fa8",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGAAAAAVCAYAAAC5d+tKAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADIklEQVRYCe2Z7XETMRCGnVRgoIOjg5hUQNyB4w5IOoCf9j8mdABUwCQdBCpgcAdOBxh3YN5HSBdxpyPrk7gkM9kZWdJqtftqVx+WbrTb7UZxWiwWVVx/Kv/tnxx/pHx7OIpouVy+VfUoYj0Vy3qg8j6utR4QUUgNM2XHyt85RvQj3oWv/lT+UulCvJtIpGhRupkEl0oTlbcp5VZMVrmUjX15FluSYZJvlX9CvwuAKmOVvymfwIxJvB+qv1d+BV85svCmKhcLgtf7WXo3Sq+UCMIz8VsBEM+EySonO9m0jy0v+1r5NmxBzPCPTRQSOBNvrNw5n3Y6KaPekqe9L6FX6VTpXDq+dOlRuwmTVa7Lzj78HrbwndtVQgDmUuKWRMPwqeqrBo/qd6UT9WE1DE1WTFa5Evj3suV9jc/Hh/ph7+/aSk7UxpbQpCBP+9BkxWSVK4G/jy18OGcFTJW+NlEYZ/fzZr//WbdissqVwJphC59PCQAH3joBJji3dQhGskNvQVZMVrloKL2LfW3h84oA4MTUNmNB9MIiNLCMFZNVrgT8lC187gJABFOz/F9BCVHnXjAkWTFZ5Upg72uLM2DMCkiS9rYQlNQ2E3jhME7qKM20YrLKlcCXYctNfAJABINDm5g4KKomU/WwAlqHd0K2NMuKySpXAl8fW/h8QwCYxSknA4znAA7pJk3EWEXRH6ncFcRm39y6FZNVrgR2s61o8EziGwKwUjqOGuqinMrlbKOcu4Ij7+i5Km88Kwzgl9p4IihB4dAKK63WKRtWTFY5Jk4WdiumehB/Cm4SH+iJ9Ej1Synhka1F4gOQa/NWiUOXYPE2ROBqUj38le18QKuFOwrSwUyCuNhgFxus0Gu11Td1la2YrHIlsJtsaSyOvL/O3bcABWFNIHLeuukrHTOlca6e++g/JHbZqpTWjJMtCGKG8wiWSzxnb3OV3FP/IbHz5H/7GOeXNx8Lug7jO32ivizBoe8Fd+KyCAyJ3fsYX7stNawAcPKil/PEfCalHywDfoAyQ2LHx/VuU38Rwyk+OrNH7MgHGNtbSPIrX8OulNcX2N8sb6/25QSlRwAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left( 0, \\  100, \\  0\\right)$"
      ],
      "text/plain": [
       "(0, 100, 0)"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_results = [EV_algo(0.1, empty_suitcase) for _ in range(100)]\n",
    "test_results.count(\"guess bomb\"), test_results.count(\"guess not bomb\"), \\\n",
    "    test_results.count(\"we died\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "31a9bf94-5847-4bcc-8b88-f78c3d1d3cbc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGAAAAAVCAYAAAC5d+tKAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADIklEQVRYCe2Z7XETMRCGnVRgoIOjg5hUQNyB4w5IOoCf9j8mdABUwCQdBCpgcAdOBxh3YN5HSBdxpyPrk7gkM9kZWdJqtftqVx+WbrTb7UZxWiwWVVx/Kv/tnxx/pHx7OIpouVy+VfUoYj0Vy3qg8j6utR4QUUgNM2XHyt85RvQj3oWv/lT+UulCvJtIpGhRupkEl0oTlbcp5VZMVrmUjX15FluSYZJvlX9CvwuAKmOVvymfwIxJvB+qv1d+BV85svCmKhcLgtf7WXo3Sq+UCMIz8VsBEM+EySonO9m0jy0v+1r5NmxBzPCPTRQSOBNvrNw5n3Y6KaPekqe9L6FX6VTpXDq+dOlRuwmTVa7Lzj78HrbwndtVQgDmUuKWRMPwqeqrBo/qd6UT9WE1DE1WTFa5Evj3suV9jc/Hh/ph7+/aSk7UxpbQpCBP+9BkxWSVK4G/jy18OGcFTJW+NlEYZ/fzZr//WbdissqVwJphC59PCQAH3joBJji3dQhGskNvQVZMVrloKL2LfW3h84oA4MTUNmNB9MIiNLCMFZNVrgT8lC187gJABFOz/F9BCVHnXjAkWTFZ5Upg72uLM2DMCkiS9rYQlNQ2E3jhME7qKM20YrLKlcCXYctNfAJABINDm5g4KKomU/WwAlqHd0K2NMuKySpXAl8fW/h8QwCYxSknA4znAA7pJk3EWEXRH6ncFcRm39y6FZNVrgR2s61o8EziGwKwUjqOGuqinMrlbKOcu4Ij7+i5Km88Kwzgl9p4IihB4dAKK63WKRtWTFY5Jk4WdiumehB/Cm4SH+iJ9Ej1Synhka1F4gOQa/NWiUOXYPE2ROBqUj38le18QKuFOwrSwUyCuNhgFxus0Gu11Td1la2YrHIlsJtsaSyOvL/O3bcABWFNIHLeuukrHTOlca6e++g/JHbZqpTWjJMtCGKG8wiWSzxnb3OV3FP/IbHz5H/7GOeXNx8Lug7jO32ivizBoe8Fd+KyCAyJ3fsYX7stNawAcPKil/PEfCalHywDfoAyQ2LHx/VuU38Rwyk+OrNH7MgHGNtbSPIrX8OulNcX2N8sb6/25QSlRwAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left( 0, \\  100, \\  0\\right)$"
      ],
      "text/plain": [
       "(0, 100, 0)"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_results = [EV_algo(0.01, empty_suitcase) for _ in range(100)]\n",
    "test_results.count(\"guess bomb\"), test_results.count(\"guess not bomb\"), \\\n",
    "    test_results.count(\"we died\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1fb87df5-997a-4b53-a118-14e7d89685c0",
   "metadata": {},
   "source": [
    "## Lecture 8"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "52017fb2-ce91-4cb2-9e79-d7760af8eada",
   "metadata": {},
   "source": [
    "Deutsch's algorithm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "2b063ee3-a067-448b-aefa-9ba45afef008",
   "metadata": {},
   "outputs": [],
   "source": [
    "# we work with symbolic computation, so use sympy\n",
    "zeroket = sy.Matrix([1, 0])\n",
    "oneket = sy.Matrix([0, 1])\n",
    "plusket = sy.Matrix([1/sy.sqrt(2), 1/sy.sqrt(2)])\n",
    "minusket = sy.Matrix([1/sy.sqrt(2), -1/sy.sqrt(2)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "f06ca64d-8ef7-436a-b173-df27fd10b406",
   "metadata": {},
   "outputs": [],
   "source": [
    "zerozeroket = TensorProduct(zeroket, zeroket)\n",
    "zerooneket = TensorProduct(zeroket, oneket)\n",
    "onezeroket = TensorProduct(oneket, zeroket)\n",
    "oneoneket = TensorProduct(oneket, oneket)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "25d9e90a-351d-4c8e-b72d-545671dfd169",
   "metadata": {},
   "source": [
    "Helper functions for two-qubit computational basis; see [Exercise 1.2](#Exercise-1.2) for the convention"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "7a6fe831-72c6-4402-b1b7-84d20cc08564",
   "metadata": {},
   "outputs": [],
   "source": [
    "def comp_basis_coeff(v, ij):\n",
    "    \"\"\"Return the coefficient of a two-qubit state in the computational basis.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    v : sympy.Matrix\n",
    "        SymPy vector with 4 components representing a two-qubit state in the\n",
    "        computational basis\n",
    "    ij : tuple of int\n",
    "        Pair of integers. Must be one of `(0, 0)`, `(0, 1)`,\n",
    "        `(1, 0)`, `(1, 1)`.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    sympy.Expr\n",
    "        Coefficient of `v` corresponding to the basis vector |ij⟩.\n",
    "    \"\"\"\n",
    "    if ij == (0, 0):\n",
    "        return v[0]\n",
    "    elif ij == (0, 1):\n",
    "        return v[1]\n",
    "    elif ij == (1, 0):\n",
    "        return v[2]\n",
    "    return v[3]\n",
    "\n",
    "\n",
    "def comp_basis_for_index(ij):\n",
    "    \"\"\"Return the two-qubit computational basis vector for a given index.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    ij : tuple of int\n",
    "        Pair of integers. Must be one of `(0, 0)`, `(0, 1)`,\n",
    "        `(1, 0)`, `(1, 1)`.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    sympy.Matrix\n",
    "        The corresponding computational basis vector |ij⟩.\n",
    "    \"\"\"\n",
    "    if ij == (0, 0):\n",
    "        return zerozeroket\n",
    "    elif ij == (0, 1):\n",
    "        return zerooneket\n",
    "    elif ij == (1, 0):\n",
    "        return onezeroket\n",
    "    return oneoneket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "id": "5aa6a9d7-7dad-400e-a628-870ef9e00c40",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACwAAABkCAYAAAD9j9IAAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFTElEQVR4Ae2c343cRgzG10GeA8MGUsCmA6eFdQeOO0jcQfx49xbYHTipwIg7cEqIrwO7gAAOFqkg329P0o1ojkitpPMdMATmNENyht984o4k5s+Di4uLJ7vd7oOaJ+8uLy9/8gxb6RTvo9bee+vL9uDbwvBafZxL+VQObqn/yonzVLpn6EvAb7SDrwFwhE8Yfh8pNJAO1QnwN/TukzTAW9+txvDWDJenRBhLv1bOR44dTpPPau/UnknPkXgrkk4JgToIEQ+Yl+rTAPlG7ZX6D3W9FUkB7gD9KUQALc9q+p+kO94KWgXJpgRp8FDA7KEO66TFSOTXP61Im8cavywdInvpa/sphjXpudpf5WQFJQ3I6fdG/4vGnwGpRtq813XwUX/SXq7l9UPACgAw2hC0W4hN7GQfbUQq2B10nf2gK5tDIvu1V+VvNiWYXuYuY15IrugIDM/5U19XNmd9j9I9kZ8udbtsdh7+I8kwTDAY6xnqAfJa+ne32lOBIRhgPflXykdqkd2bO9JlGead+A+B+lXXx2pv1WCYIw0dx9uUTIFlXmQf1k4BFihY9l7krQ4/T2CWOxDZvbkjXZgSI+9g0KUFoIb0KaZcRfbCt9pdFXAX5TddD31EgaTPp1b/g4rs/VT3mkoJd2ZFKWCv1chtji8eHD+o/dy7R/ber3ZdHTCBBGr0ZLPBI7v1L8dbpES5/ur9Bnh1Ss2CjWFDyOrDxvDqlJoFG8OGkNWHjeHVKTULznqX0DvAXvN5qeHNqxVSDJnuMMWwmOWLIV1IkT93AanVJViPr+4X8v0Rx6zwo/uuc+6v3lwApAopAjBZd5Cdj1d8AE3LyPe9U/aUgI2h1sBkBSYYOW3rFWxu8JUf/aEuoTGfShRY+i8QdfMC4P869/46mt0BA5wFxiZ2spfg2AC+FsxROpg9V/7pJ6ZyuHO2ILxCCmA96esSnm2WDoYnRQzCDizC3kmko9IDY7aQcu3w5d9HUtU286X3hCbLcLaQwuY8Aay9Q55fqEsB7li2RRMWH+nk19eKuRtXJrodG3NuGKZEbpmR16K6w2glZ5Bi2JlXVYnlqC4B+y/UDmp7+XMMUk/mqAtldcBEVPBqXUI2crlqjxBvkRJRzEX2BngRfYnJMExO8SPgaXRXhQcXGHcA3qtRQedpdFeFE+VU5W85vPUtagw3hg0DLSUMIasPZ7386MWFM5u3Kx42rZCSuR0phsUsnzhzCin4VwslWo+7hLiFlmuT/zf7oyNAtpDCx2m1UCKwk4UWH+aNNgs4XUgRoKhQwubLWgb9odByA83vhYC7dOAWh4UUP8SNVmvtNfK+oI/Sc2dCCQEXK9jP9FEhpQNTuLtdwHqSLrSEgAWE3S8tpHggS1260JI6JbRytpBSgvD6bN4TmLd30PPbpQB3LI+KJt1qns4NhFLrLC60hClRjX6+YVGhJcXwHGxikZOgWiiRfbLQEsXaAjC5OFkoEehJ+xTor5ESU3hCWwMcUrTQoTG8kMBwemM4pGihQ2N4IYHh9MZwSNFCh3vH8KyXn+5NrBVS5mRJimExyyfMmoUU1qsWWqY2kAKsBeYWUg5dUICNRJvnc75qHzk7gyzgWYUUxaGYcvqPTm1M6fmH5FW79bfj8JTo0gGmFhdSbPBzxiHgYlH7GX5OIaVY7rxuCFgMH7X01oWUNPpsDq9VSEkDqzmmAHcse0UTT1eLtYo+TIlVoqy4SIrhOfF0N/bynyqkTNqjWFsAniykaEOT9gjwvUuJewe4TImPul32jtyp/4MH4ABMTp3+bQ8URuzTzZg3GfKiVZX/AXGVMMoQFOQBAAAAAElFTkSuQmCC",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}a_{00}\\\\a_{01}\\\\a_{10}\\\\a_{11}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡a₀₀⎤\n",
       "⎢   ⎥\n",
       "⎢a₀₁⎥\n",
       "⎢   ⎥\n",
       "⎢a₁₀⎥\n",
       "⎢   ⎥\n",
       "⎣a₁₁⎦"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a, b, c, d = sy.symbols('a00 a01 a10 a11')\n",
    "test_vec = a * zerozeroket + b * zerooneket + c * onezeroket + d * oneoneket\n",
    "test_vec"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "ab4b0b9a-4fd6-47a3-b457-cf41255fb829",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAKoAAAAVCAYAAADW6nUiAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADcUlEQVRoBe2b723bMBDFlaIDGOkGzQYpuoGzQdwR4g2Sj/a3It2gXaHdwB2hzQjZIG02cN9PFlX9o0hZlEwDPOBMinek3p2ezxJtX2w2m/ssy9ZSZLXdbp8O3fSaMnC6DIiHNV5eiKiPgrOT4efpYKUzpwx0Z0C8zPn5ptucRlMG4spAImpc1yOhsWQgEdWSmDQcVwYSUeO6HgmNJQOJqJbEpOG4MvC2D46euN7LzlPXs/RF+kN6q/EvaqOTc8NLAhNmPxpZK6oSuNQSv6UP6qOQ86v0Uf2F2qjk3PCSvITZn0KdFbUg4nctA0GppkboP2vs1QzQ6piqi1B13+n4IT8qXlz2qu8xfa3PGyckXtb7JF1r7Q/HYHLNOQJzL6apc0w8E2DujamaQ1tFhXgLAftWdVafKsvHfynyudPBi1pTdfnyYGccXHbjN7INifdaWIiJJKJTyRDMvZhmyjF5CIm5N6Zm0m1EpZrUvqlSMrho3LOWJCwWA3zpKz/6S7X4Ii77wWvcazC8wv0k5Tan+kkyDl33bG/MHpjmyDFRBMPsEVMtay2iagFTSZqEBGQme5WUkBH/5kV91di1fHvt8hktIfGOBuO5wBDMriXnyDEYQmJ2xdRlbxG14tQk341s+Q9WBJonf0PCypSy+0e9Sykk7hJjL21FIsrjIzoh8A467UyYXZi8c8xCkWB2xdSyt4iqQKiGVE2ImIvGbtXhnuLXYSS70ViTGIUpb/pIikPNXiTvr1p2GQaJ5syBt4UpAswtTI2BWo6xnQHmRgj/D1tELUwrtR8V2L2U+x9ISUW9ZEwt21QIJOkS3uXMcdnzuVoTP/x5gGPuUAmF1/u8M2J2YfLKMYtEhNkVU8tu254ieC5+U2pjCtxsVVF9m79j5aGk115dXL5XUir3YNG8IHiHnngOzC5MwuCdY9aKAbMrpi67raJ2+drGPsvAtlUuSkS+hUUCiyGXvXDLG6q4rUJU/cb0h+DxOc8cmF04hsYUA2ZXTDV7kB9Oi1zcHiBs+F9J2VMtCeeyM1E+CzV3aif/erYPj2x8OqylvOG4LwcP+8QtXBqbBbMPJvn0XgPFkEssmH1iAnAR1y7jF/7S5X6/z06p/CXmlOc/5twJ8/ScMfw0FdXcG67E4Oa95uGtmF5TBmbMgHjIQzufbOxerP4BrDVMfbj2QjkAAAAASUVORK5CYII=",
      "text/latex": [
       "$\\displaystyle \\left[ a_{00}, \\  a_{01}, \\  a_{10}, \\  a_{11}\\right]$"
      ],
      "text/plain": [
       "[a₀₀, a₀₁, a₁₀, a₁₁]"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "index_list = [(0, 0), (0, 1), (1, 0), (1, 1)]\n",
    "[comp_basis_coeff(test_vec, index) for index in index_list]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "6b84fb21-1d51-4d60-9ad6-3b0607662e8f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGYAAAAVCAYAAAC0aZsNAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAC90lEQVRoBe2Z0VXbMBSGDRO47QbuBlAmKNkgZIPCBvQxeeuhG7SdoAc2ACbgNBuEDRqyQfp/iqTKjpwY2+glvufI0r2S7pX/X5JtOVuv11mYptNpEepDuYzPW+ARw/w4C2Q2m11LPQlMQzENAoXF3kc7YgYgqhgrO1P+1RiCi2w3Vv2r/KPSjWzPQZNei/LN5LhVOlV51avzwFnCOHvx01hYFCvlPxmiIUZKrvKj8lOMocj2R/o35XfYldMW20jl3sixfn/J71LpkxLkvJO9V2JSxdHYjSheY/xs28/cs9vKYPSH9eUzNbiUkis3pFBBJ2XoW+2pbyv4VbpQupKP32397OuXKg7jUKzX4gemZnU5YiZyYpZQ5cYupM8rNtQnpXP1YfUMUo/Aq/CzHMBFfqwLz5a6LelcdWwtVXHtqR+kHoE2+IHthBUzUnqo+m64Gt5X+w36BoEO+MHFCGJ40C427kpXB/quh++wlZUgKylt8YOLAmIAN7ZdlaLUKB9q7IO5GQIx/ODCEAOzsVWxiyw3G/iuGSSOQFv8eMbkrJioaI90ZMW2K2dzLwFRH4ds7ICfWSgQA7MO6CqWPIiKqlG6WzFbLw2RtodsaoMfXCwhhlkfAx9AORbh5aAqnBDMg1mRqVxHbrVvZz1VrB7iNMYvAIVJ/wwxc6WzoMIXNTA+OpfK+dYxYgc7kfLFmjJre1HO8UMf4h6KbmV6nz3HetM4Gmsj/PzNbQpm0h/pyPlE+q2ccDi5JRYIjglWSjzsIZGzMwj1It29crc+eJQPZhjChxkrkBis6HvV+ZOJrrFSxdG4M8XiPvbiR1tE7cHxyvyLETkLCOr6r0E+xkp5Vz9N+qeKlSoO96xYhdKCMlsZAqMcHnYVfhuwslJIqlip4oAZv1z+H2IKTLYJftbUvQTQaaeoL0s2yXdNqlip4gCsYoE9HJgt260Y6jgJ7XKUfymn33GUQFLFShUHyMDe71r+DyY1lrVxQoAJe/AivPl7eafcf7D/A8xfiLq6L9RLAAAAAElFTkSuQmCC",
      "text/latex": [
       "$\\displaystyle \\left( 0, \\  1, \\  1, \\  0\\right)$"
      ],
      "text/plain": [
       "(0, 1, 1, 0)"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# XOR operation is represented by the ^ operator\n",
    "0 ^ 0, 0 ^ 1, 1 ^ 0, 1 ^ 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "id": "aa966fd8-86d5-445f-b8ce-7ee816dbd8bd",
   "metadata": {},
   "outputs": [],
   "source": [
    "def U_f_gate(f, v):\n",
    "    \"\"\"Apply the Deutsch oracle gate $U_f$ to a two-qubit state.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    f : callable\n",
    "        Boolean function which takes input 0 or 1, returns 0 or 1.\n",
    "    v : sympy.Matrix\n",
    "        SymPy vector with 4 components.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    sympy.Matrix\n",
    "        The result of applying the linear transform\n",
    "        |ij⟩ → |ik⟩ with k = XOR(f(i), j) to v.\n",
    "    \"\"\"\n",
    "    ij_list = [(0, 0), (0, 1), (1, 0), (1, 1)]\n",
    "    a, b, c, d = [comp_basis_coeff(v, index) for index in ij_list]\n",
    "    ik_list = [(p[0], f(p[0]) ^ p[1]) for p in ij_list]\n",
    "    va, vb, vc, vd = [comp_basis_for_index(ik_pair) for ik_pair in ik_list]\n",
    "    return a * va + b * vb + c * vc + d * vd"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6652f980-f3f8-4647-b7f1-42c5fa67d0c1",
   "metadata": {},
   "source": [
    "with the constant function $f(i) = 0$, expect $U_f(v) = v$ from $\\mathrm{XOR}(0, j) = j$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "6cbae360-1de8-4cad-b17d-cbdd721cc6b9",
   "metadata": {},
   "outputs": [],
   "source": [
    "def f0(i):\n",
    "    return 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "0daa13cd-70b9-4518-88e1-30559a4f6c05",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACwAAABkCAYAAAD9j9IAAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFTElEQVR4Ae2c343cRgzG10GeA8MGUsCmA6eFdQeOO0jcQfx49xbYHTipwIg7cEqIrwO7gAAOFqkg329P0o1ojkitpPMdMATmNENyht984o4k5s+Di4uLJ7vd7oOaJ+8uLy9/8gxb6RTvo9bee+vL9uDbwvBafZxL+VQObqn/yonzVLpn6EvAb7SDrwFwhE8Yfh8pNJAO1QnwN/TukzTAW9+txvDWDJenRBhLv1bOR44dTpPPau/UnknPkXgrkk4JgToIEQ+Yl+rTAPlG7ZX6D3W9FUkB7gD9KUQALc9q+p+kO94KWgXJpgRp8FDA7KEO66TFSOTXP61Im8cavywdInvpa/sphjXpudpf5WQFJQ3I6fdG/4vGnwGpRtq813XwUX/SXq7l9UPACgAw2hC0W4hN7GQfbUQq2B10nf2gK5tDIvu1V+VvNiWYXuYuY15IrugIDM/5U19XNmd9j9I9kZ8udbtsdh7+I8kwTDAY6xnqAfJa+ne32lOBIRhgPflXykdqkd2bO9JlGead+A+B+lXXx2pv1WCYIw0dx9uUTIFlXmQf1k4BFihY9l7krQ4/T2CWOxDZvbkjXZgSI+9g0KUFoIb0KaZcRfbCt9pdFXAX5TddD31EgaTPp1b/g4rs/VT3mkoJd2ZFKWCv1chtji8eHD+o/dy7R/ber3ZdHTCBBGr0ZLPBI7v1L8dbpES5/ur9Bnh1Ss2CjWFDyOrDxvDqlJoFG8OGkNWHjeHVKTULznqX0DvAXvN5qeHNqxVSDJnuMMWwmOWLIV1IkT93AanVJViPr+4X8v0Rx6zwo/uuc+6v3lwApAopAjBZd5Cdj1d8AE3LyPe9U/aUgI2h1sBkBSYYOW3rFWxu8JUf/aEuoTGfShRY+i8QdfMC4P869/46mt0BA5wFxiZ2spfg2AC+FsxROpg9V/7pJ6ZyuHO2ILxCCmA96esSnm2WDoYnRQzCDizC3kmko9IDY7aQcu3w5d9HUtU286X3hCbLcLaQwuY8Aay9Q55fqEsB7li2RRMWH+nk19eKuRtXJrodG3NuGKZEbpmR16K6w2glZ5Bi2JlXVYnlqC4B+y/UDmp7+XMMUk/mqAtldcBEVPBqXUI2crlqjxBvkRJRzEX2BngRfYnJMExO8SPgaXRXhQcXGHcA3qtRQedpdFeFE+VU5W85vPUtagw3hg0DLSUMIasPZ7386MWFM5u3Kx42rZCSuR0phsUsnzhzCin4VwslWo+7hLiFlmuT/zf7oyNAtpDCx2m1UCKwk4UWH+aNNgs4XUgRoKhQwubLWgb9odByA83vhYC7dOAWh4UUP8SNVmvtNfK+oI/Sc2dCCQEXK9jP9FEhpQNTuLtdwHqSLrSEgAWE3S8tpHggS1260JI6JbRytpBSgvD6bN4TmLd30PPbpQB3LI+KJt1qns4NhFLrLC60hClRjX6+YVGhJcXwHGxikZOgWiiRfbLQEsXaAjC5OFkoEehJ+xTor5ESU3hCWwMcUrTQoTG8kMBwemM4pGihQ2N4IYHh9MZwSNFCh3vH8KyXn+5NrBVS5mRJimExyyfMmoUU1qsWWqY2kAKsBeYWUg5dUICNRJvnc75qHzk7gyzgWYUUxaGYcvqPTm1M6fmH5FW79bfj8JTo0gGmFhdSbPBzxiHgYlH7GX5OIaVY7rxuCFgMH7X01oWUNPpsDq9VSEkDqzmmAHcse0UTT1eLtYo+TIlVoqy4SIrhOfF0N/bynyqkTNqjWFsAniykaEOT9gjwvUuJewe4TImPul32jtyp/4MH4ABMTp3+bQ8URuzTzZg3GfKiVZX/AXGVMMoQFOQBAAAAAElFTkSuQmCC",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}a_{00}\\\\a_{01}\\\\a_{10}\\\\a_{11}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡a₀₀⎤\n",
       "⎢   ⎥\n",
       "⎢a₀₁⎥\n",
       "⎢   ⎥\n",
       "⎢a₁₀⎥\n",
       "⎢   ⎥\n",
       "⎣a₁₁⎦"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "U_f_gate(f0, test_vec)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45cba0ba-5c01-431d-820a-adc1590be42e",
   "metadata": {},
   "source": [
    "with the constant function $f(i) = 1$, expect flip on the second bit from $\\mathrm{XOR}(1, j) = \\mathrm{NOT}(j)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "904f95c7-0b5c-4644-8ce1-71c7364db8da",
   "metadata": {},
   "outputs": [],
   "source": [
    "def f1(i):\n",
    "    return 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "f83c7840-a1c9-407a-9b42-3fb1d8b4eff7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACwAAABkCAYAAAD9j9IAAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFLElEQVR4Ae2c0Y0UORCGB3TPJwTSBTCXwZLCkAF3GRxkAI+7bwgyACJARwZcCHdkAAEggVZEwP/1ulu213ZV37iXWcklee2uqi7//rvW3V30cuf8/Pxst9v9p1aS9xcXF3+UDFvpNN8nxd6X4st255fI8EpjnGP5HB/c0PhlYZ5H0j1GHwN+rRX8DIAJPmF4kyh0IB2qCfBdRrdJBuCtr9ZgeGuG413CnEu/reyPbDvsJl/V3qs9lp4t8UbEnRICdRAibjDPNaYB8rXaS43vqb8RcQEOgP4WIoDGezXjz9Jd3ghaTeJNCdLgnoDlmzqskxaJyG++W5E2D3T8PHbQMVfkT7WnGj+MbdbYxXAI/k8cLExKTn/I9E90/BWQaqTNB/WLj8Y8u+AD6NWpZALWBHPgZVJNhMDQTvZkIVLB7qIL9oN6Fof/RzUWEqcWJpd4U4Jg+QQ8kHzEIADc56exehaY+15KB7O5Xqp14mGYyWBsYojwASAA/uVY8kg6wAC2JN+kvF8yrNV5GeaZ+K1APVP/QO2dGgyzpaFje2sJYGuLaZ13zeYCLFCwXHqQz3X4lQSwR6cDgc2UKM1e04W0APSSPpHvnOORav2wK+Aw/Qv17M+TaBGMedXqwrArJcLcrk7AXqmR22xv3Dh+V/trPll62H+qxkL2s5961/NId8AA0+TJnQ3dLLLBdNU++9X6LVKiNlcX/QDchcZGkMFwg5wupsFwFxobQQbDDXK6mAbDXWhsBFn1LKHngL1i8VDD88AopDSIXUwuhsUsbwzuQor8uQpIrS7RtF+dWv7JL92vwTT3JU8mcBVSBNaqSzTtpcml+23We3cJahBLrYGTA+vkdF6vYHGLr/wYH9Tji1j2K6/KTwB/D7a5T1wDMFIiB8YidgHQdE4AVXrh5D3vzLJPQco/vsxqVw4H5/ydrFRIAWxJ5rqEZS+dm+hguCliBXa8hZRaLKsuYdmXuF6GvYUUFlcSmOUKWfbSuYnOBTiwnBdNCJTo5DfXivkFy+sQFAGb9gRZ5cBMicp5LbVVl7Dsrdg7F8PNCJlRLFp1iaY9C3ftsDtgZhDoZt3Bsl9DGSm2SIkofP/hANyf0zQiDLM/UpzjbnSqwo0LjFN9eK+eCjp3m1OVg4BNVf6Rw1tfosHwYDhjYKRERkj3w1UPP3poYc/mJXIUUryXwsWwmOUVZ00hBX/eqosfcIR4VXsLvAuwAqwppJzJn1spAvBEBLZpT5wLB17A7kKKAPEux/vb9K1kPqdlz/3zY3Nb0wSwRDMLKXnwLY5NwNGkzUKKFsYOsrmYgAXkUiiOLaR0W4g3h72FlG7AaoFcgAPLSdEkBCzpanN10Zsp0WWWjkFcDK+ZL/zy8f51ULv2AYdlt+baAjC7SbWQIsBNuwX41qXEAGxd0mPtg+FjGbTOHwxbDB1rHwwfy6B1/mDYYuhY+61jeNXDT3jSGoWUNWniYljM8tbcs5DCVUKKX6xcmco/vTm8tpBS/UsYLf7/fJGyoPcCXlVIEajWX8KweN7CJ5Ev4/iLlWApdybgkA5dCimKtRcMYuU1DkoJlLBMMQFHEfJJki9SApjIvTgEbEnmL1ZKtkRnAhYQVr91IYV/I6wtJgHs2iV0Rq9CCosvCWDzK1jy830vEVguFU1KuuJEKBXnJL9IqQIOhpP7IoWdoFVIOa0vUrjsAlwtpMCyfJp2fGpi7hK1E3+W/tYBjre1T7pUOXEn9T94AA7A5Nz0tQeKTFx7Y3bOsYfzk1wxzg+IwjM6UCXcrQAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}a_{01}\\\\a_{00}\\\\a_{11}\\\\a_{10}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡a₀₁⎤\n",
       "⎢   ⎥\n",
       "⎢a₀₀⎥\n",
       "⎢   ⎥\n",
       "⎢a₁₁⎥\n",
       "⎢   ⎥\n",
       "⎣a₁₀⎦"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "U_f_gate(f1, test_vec)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27972a0e-ed99-45b8-ad82-9f5bfdde703d",
   "metadata": {},
   "source": [
    "with the identity function $f(i) = i$, expect CNOT"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "07640168-b1d8-41fd-a447-ddd52415d929",
   "metadata": {},
   "outputs": [],
   "source": [
    "def f_id(i):\n",
    "    return i"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "c75716bd-f1cf-4059-8c1b-d28a48865a13",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACwAAABkCAYAAAD9j9IAAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFRElEQVR4Ae2c4Y0eNRCGvyB+oyiRKOCjg9DCpYNAB5AOyM+7f1HSQaCCiHQQSoDrICkAKehEBbzPd96NPbF3Zm+9x53kkXxrz4zt1+/O5/VOFh6cn58/ORwOf6nU5N3FxcUPNcNeOs33QWMfa+PL9uDrzPBadZxz+Zg3bqn+qjLPU+meoc8Bv9EK/g+ABT5h+LVQqCEdqhPgr6jdJxmA975bg+G9Gc53CXcu/VrZH9l22E0+qbxTeSY9W+KtSDgkBOpMiHjAvFCdAsg3Kq9Uf6jrrUgIcAL0uxABNN+rqX+U7upW0GqSaEgQBg8FzG7qsE5YFCK/6WlF2DxW+0Xu4NlzX1sPMaxOP6r8kXfWpIQBMf3e6H9W+xMgVQib97rOPqov2vOxanUXsCYAGGWeNA3EIg6yFwuRCnZnXbKf6criEM9+7dX4Gw0JuuexS5sDySUVgeE5f6rryuKs75V0T+SnS9sum+2HfyERhpkMxiaGJoAcS/9Moz0VGCYDbE3+kfKRimev9S10UYY5E/8mUL/o+ljlrQoMs6WhY3tbkiWw9PPs89ghwAIFy7WDvNXhVxOY5Q549lrfQueGROHtNFJYAGoOn6zLpWfPfJvVroDTLC91PZtmFEjqvGpNPyjPPnWtXkMhUe3ZUArYaxVim+2LB8d3Kj9N7p598mtduwNmIoEqnmx2cs9u/fP2HiGRj9+9PgB3p9QMOBg2hHRvDoa7U2oGHAwbQro3B8PdKTUDrjpL6AxwVH8ONZy8RiLFkFlthhgWs7wxhBMp8ucuIK28BOPx1v1cvt/jGBV+dN8k5+la6wuAUCJFABbzDrLz8ooPoCkR+XZyiu4SsDHnGuisiZmMmLb5ChY3+8qP+pyXUJtXJRIs0xuIqnEB8L/JfboWvRMwwFlgLOIgew6OBeBrwVxJB7M3lb+njqEYTs4WRC2RAtiaTHmJmm2VDoYXRQzCDizC3kmkI9MDYzaRcu3w5d9HUrUW86X3gibKcDSRwuJqAlh7h2p+ri4EOLFskyYMXujkN+WKuRuXZnbbNuZY0w2J2DCF16a8QzFSpRFiuNKvqRLLXl4C9p+rnKkc5c82SD6Zrc6V7oCZUZM38xKyEctNu4d4j5Dw5txkH4A30RfoDMPEFD8CnkZ3VXhwgfEA4KMKGXSeRndV2FFOWf4Rw3vfosHwYNgwMELCENK9uerwo4MLezanKx42I5ESuR0hhsUsrzhrEin4NxMlabymfQl4CLAGWJNI4eWURykC8EIEdtFeOFcaUcDhRIoA8e5GsuT0raSd07Nbf9t2tzVNAEsUN5FiB9+j7QLOJrWv6UUiRQtjB9ldXMACciUUWxMp3RYSjeFoIqUbsNZAIcCJ5SJpkgas6VpzddG7IdFllo6DhBheM1/68TUTJZ7dm2sPwIuJEgFetHuA711IDMDeLd1qHwxvZdDrPxj2GNpqHwxvZdDrPxj2GNpqv3cMrzr8pJPWSKSsCZMQw2KWt+aeiRTuElL9YuXaVP8bjeG1iZTmFyda/OIXK3WYn7VRwKsSKQK19MUJi88/CqE+f7HyGVq95gJO4dAlkaKxjoLBWDbHQSqBFJYrLuBsBDvJTRIpgK0J/0YY+mc3F7BYYfV7J1IA21pMscDQLqEevRIpLL4mgLV3sOZ3CAFOLNeSJjVddSKUGmfzFytuSDRnv7nhpbqeTd21COr5f0kzmarXEMPVng2lALATLCVSFr9YaQw7q/cA7CZKtKjxRcp8C+5aJQ+JD7pVFt+d+j94AA7AxNzpaw8URkJ7o+mztTmd5Krj/AfqLTDKDWryPAAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}a_{00}\\\\a_{01}\\\\a_{11}\\\\a_{10}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡a₀₀⎤\n",
       "⎢   ⎥\n",
       "⎢a₀₁⎥\n",
       "⎢   ⎥\n",
       "⎢a₁₁⎥\n",
       "⎢   ⎥\n",
       "⎣a₁₀⎦"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "U_f_gate(f_id, test_vec)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "id": "1d3e8d6b-cab7-4d2e-be54-3a9515515ddd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAC0AAABlCAYAAADZEWqbAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAEEklEQVR4Ae2cQW4TMRSGCeoaQRccYJA4AL1CuEHLAtbQI1QskLItN2gPwIorcAPoAZDaAyCBIg5A+P/EY5lgj515fxwZxtLEHtvz5puXN288v6LMVqvVPWVZLBYPYe8FtnO0T5S2e1tHMPwMO1/6jq36I8bPtvqSu87W3E0g/KgCO7c4sIsdjLHZUTDwHm1ODstduJNrw+AN5tygPs3NzYxfRsafo29tN4S+wsl2gowYlnSB43rbEPrYtYa+vz3Ywv4EXetbmjxdy9Nh9jCfE3c4c+s5tjm2DvtMXd9RM53KihqaKfNCRpcwNMV0wjHybll4IG6zKy/MmSmuQAktASq5qCZjWuZpeghfP5ejb523mP5YXqN/uWlqPqXQQLoEIPP0uqB9hQbX6k82PZpPdXi8Aeg8QOPDhQ8ZvmjIihqaXv4so0sYkoYHPLq9eOdF3KGfbzSyova0B3MhwTcN+cvtXqAB3AGW8XyCtjRz0CvS8KBBB3yBmi+i/T5r2funFBpg9DDTHKH7jMG4lq78pNCAY07mA+YPHQUXEOZujpvEHCk04B4BKFmc9+duAuFHFSl0jgDQEjFnL9kjB28dn6CtHiw9fvJ0qaes85r0dO2U18HLfNAwV48Wc2pDS8ScJsOjSWiGxw9sH7D9whYtePxynfAJ2y7rhTP32F7bRNsq5nyFIXKu19PHqF9ie8eOWMEJl+g3vYHAhlXMeQoGcr5qNjxizt1LH7zN8DKLOVVTHoAlYk7t8JCIObWh+TQ0izlVwwMxLRFzanva3+C4AL6tjxJzDgIN4I43JbZRYk7V8KCbHbBJzKkK7YDNYg6hH9ADKH292Rv5CTA+QFJiTFbMGTjt436M0D/dTl/3YzvXAObNNXcH/rW4wvigmJM54bd+XBoegJKIMT1cqj5I9kjBlPZP0KWess6bPG31YOnxTXpanfI6eMssxuQ8roaWiDE56CbDo0loWXjgEW4VY3JR4ceV0FYxxkPlGv93eNA7CBGJGJPztCw83IkkYkwOWh0eEjGmNrREjMlBS8MDMS0RY3LQ6vDw58MFjBZjvJFEYy/QAO5wvtFiTILVd0vDg1YdsEmM8XSJhhTaAZvFmASr75ZCw2pWjMGFDYk5HmyoIYUG0KAYg/FBMWcINByTQoeGY21AS8ScvWSPGLCyb4JWenPI1uTpIe8ox5r0dO2U18HjZjGnNrREzGkyPJqELgoPt8g59C9rfAIqhV7iiEP/ssZD/7vh4S/R2HBhNv2yxujHosMlYk7tmJaIOUXZo8iHBZMQ0xIxp7an/aXhAkaLOQeBBnAH+tFiTtXwoJsdsEnMCaFvYZB2w7LTP6mEB8baDjgr5mAe/xyF30a0EJrLRd7VscIxZcmKOe5kDJ1k+Q0nYl+oJfySAQAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}\\frac{1}{2}\\\\- \\frac{1}{2}\\\\\\frac{1}{2}\\\\- \\frac{1}{2}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡1/2 ⎤\n",
       "⎢    ⎥\n",
       "⎢-1/2⎥\n",
       "⎢    ⎥\n",
       "⎢1/2 ⎥\n",
       "⎢    ⎥\n",
       "⎣-1/2⎦"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# initial vector for Deutsch's algorithm\n",
    "plusminusket = TensorProduct(plusket, minusket)\n",
    "plusminusket"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e603fa52-a103-4551-a56a-79044aefd562",
   "metadata": {},
   "source": [
    "$U_f$ gate with $f_1$ on the input vector $v = |\\mathord{+-}\\rangle$ gives the output vector $-v$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "id": "e135baac-f548-43de-beab-87411bb0829c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAC0AAABlCAYAAADZEWqbAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAEL0lEQVR4Ae2c3W0UMRSFWZRnBDxQwCBRAGlh6YDwAM+QEiIekPIaOggF8EQLdAApACkpAAmEKIDlnI3Hmj//jH3GK8NYmvjf/ubO3Tveo1U2u93uTsl0fn5+H/u9wHWK8nHK3keY+BQTvzomf0L/iaNvdrPZa2smEn4yYdw1OpqpTvRtjjod71Hm4G666VZyy9jwCmtcIX8eWOtiov8Z2vbzutCXWEwKObFxVBM4PgwHoo1Ne+i7w84a6it0qae0WrqUpbvRY/E9EQEYe09xbXE1qDO0/UDOcBudSkMzpJ5F0zkGrj7tMIy8Oco94HM8J3zG5TwvTJCdYB5f2/uEcvBkhjGbdrwvj4X+hUWSTmTt5rFA7XhfXqVPR1nad9dz+mBtutdbM4fhj+k12vkko1NRaFBdAJBxep9QvkSBZ/nHty1xf0u7xxuAbjtofLnwJcMvItGpNDSt/CWazjGwqHvAosPDPW/iBu02NDo4e82lLW03Ny7BbyKzQ+lBoAHcAJb+fIzyrMjBuy7qHtzQAJ8h5xfVts48+vtpUWiA0cIMc4RuIwb9etbJTw4NGL5AXGIMYzL7ezoL5tjYjb5gkkIb623NroTrJfQ/6DUkVtTQsWJMIu7ttINEjyxiTF6hcy0YO3+1dKylcsdVaWl1yGtgRb4oGKuTxZjQk1BDS8SYEHSV7lElNN3jJ66PuP6EHouvH+cKmRjj2Ocb2sm5P08/RP4S1zs2pCZAR6lDqetj3hNc5HxVrXtk3Hx/KqzN42i2GNNfdVyThjwsLxFjxpj9FrV7SMSYPuK4pobm2zBbjBlj9luk7gGflogxfcRxTW1puwNugN+2k8QYu4ijsAg0gBvslyzGOFhts9Q9uKoBzhJjLJ2jIIU2wNlijIPVNhP6nqm1ue1MKATFGNyYT8zxbfmo7ST0b1Np87Zvdg4grxiDfn44t2bhkZgT2PB72y91j3ZRVw5oiZizSPRwQavaV2iVJUPrrJYOWUjVX6WlS4e8BtbOFnNKQ0vEnCrdo0roKPcwh5z1lzU54e/fdY8cq3TnGjfLFnOifLq7cWZZIuaUdg+JmFMaWiLmFHUP+LREzCltafuRwA0kizkHgQZwA/pkMaeoe9DMBjhLzCkKbYCzxRw5NMB8YkxQzLFO7ylIoQHsFWPQ7xVzPJy9LjW0RIzpEU5UDhI9JjhmNa3Qs8yVMXi1dIbxZk2t0tLqkNfAZNliTMjsamiJGBOCrtI9qoSWuQfOFUv/ssZ6jRJ66V/WWOj/2z1oBrjI+ssa6w+Dgto9JGLMgHFUVUNLxJgR5aBBFj24LnxaIsYMGEdVtaXtBriBZDHGLuIoLAIN4Ab7JYsxDlbbLHUPrmqAs8QYS+codKGvseFw2Kz/pGKAs8UYrMN/jsKnNZkIzeMkP/VTiX1zkkSMwYZ0LWf6C/1TX6gY/+4VAAAAAElFTkSuQmCC",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}- \\frac{1}{2}\\\\\\frac{1}{2}\\\\- \\frac{1}{2}\\\\\\frac{1}{2}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡-1/2⎤\n",
       "⎢    ⎥\n",
       "⎢1/2 ⎥\n",
       "⎢    ⎥\n",
       "⎢-1/2⎥\n",
       "⎢    ⎥\n",
       "⎣1/2 ⎦"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "U_f_gate(f1, plusminusket)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9eeeb4e1-97ef-4ca3-90fa-8f6f73f5a2dd",
   "metadata": {},
   "source": [
    "$U_f$ gate with $f_{\\mathrm{id}}$ on the input vector $|\\mathord{+-}\\rangle$ gives the output vector $|\\mathord{--}\\rangle$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "id": "eb6e7edd-4e29-4701-b319-c930b44e31c7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left( \\left[\\begin{matrix}\\frac{1}{2}\\\\- \\frac{1}{2}\\\\- \\frac{1}{2}\\\\\\frac{1}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{1}{2}\\\\- \\frac{1}{2}\\\\- \\frac{1}{2}\\\\\\frac{1}{2}\\end{matrix}\\right]\\right)$"
      ],
      "text/plain": [
       "⎛⎡1/2 ⎤  ⎡1/2 ⎤⎞\n",
       "⎜⎢    ⎥  ⎢    ⎥⎟\n",
       "⎜⎢-1/2⎥  ⎢-1/2⎥⎟\n",
       "⎜⎢    ⎥, ⎢    ⎥⎟\n",
       "⎜⎢-1/2⎥  ⎢-1/2⎥⎟\n",
       "⎜⎢    ⎥  ⎢    ⎥⎟\n",
       "⎝⎣1/2 ⎦  ⎣1/2 ⎦⎠"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "U_f_gate(f_id, plusminusket), TensorProduct(minusket, minusket)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "id": "56c90006-b74c-4772-b5a1-87400b998e51",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left( \\left[\\begin{matrix}\\frac{1}{2} & 0 & \\frac{1}{2} & 0\\\\0 & \\frac{1}{2} & 0 & \\frac{1}{2}\\\\\\frac{1}{2} & 0 & \\frac{1}{2} & 0\\\\0 & \\frac{1}{2} & 0 & \\frac{1}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{1}{2} & 0 & - \\frac{1}{2} & 0\\\\0 & \\frac{1}{2} & 0 & - \\frac{1}{2}\\\\- \\frac{1}{2} & 0 & \\frac{1}{2} & 0\\\\0 & - \\frac{1}{2} & 0 & \\frac{1}{2}\\end{matrix}\\right]\\right)$"
      ],
      "text/plain": [
       "⎛⎡1/2   0   1/2   0 ⎤  ⎡1/2    0    -1/2   0  ⎤⎞\n",
       "⎜⎢                  ⎥  ⎢                      ⎥⎟\n",
       "⎜⎢ 0   1/2   0   1/2⎥  ⎢ 0    1/2    0    -1/2⎥⎟\n",
       "⎜⎢                  ⎥, ⎢                      ⎥⎟\n",
       "⎜⎢1/2   0   1/2   0 ⎥  ⎢-1/2   0    1/2    0  ⎥⎟\n",
       "⎜⎢                  ⎥  ⎢                      ⎥⎟\n",
       "⎝⎣ 0   1/2   0   1/2⎦  ⎣ 0    -1/2   0    1/2 ⎦⎠"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "E_plus = TensorProduct(plusket * plusket.T, sy.eye(2))\n",
    "E_minus = TensorProduct(minusket * minusket.T, sy.eye(2))\n",
    "E_plus, E_minus"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "id": "fcb3452e-caaf-4be4-92a8-c2607d92e9d8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAYAAAAxFw7TAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA1klEQVQ4EWOsr69fzcDAYATEMODa0NBwD8bBRwPVlQHl05HUlDMCDTwLlDBGEiSLCTQjDaSRiSzdeDSx4JGDSwFtBwUJKGiMgewPcAksDJwGAjUKANXPBuJ3QGwCxEpATBDgMxDkklCQCUDDQYGPHHEgYayA6mE4aiDWcCZJcDQMSQourIqJDUNhqG4hrKYgCeLMeiA1wCwHKhBAwAVCMawGioHKyt1AehZUDIUiZCA4L6PoIMAh1ssEjEFIjxqICAtyWVQPQ3CyAaapu0guIrdeBiX6cgA2vC162/wUzAAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}1\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "[1]"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# apply U_f gate for the constant function f1 to the initial input\n",
    "v_prime = U_f_gate(f1, plusminusket)\n",
    "# then estimate the probability of observing the + case\n",
    "p_plus = v_prime.T * E_plus * v_prime\n",
    "p_plus"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "id": "f895b566-ef10-4652-addd-395306e4e65a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAYAAAAxFw7TAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABVElEQVQ4Ee2V300DMQzGU8QAFWxQNuDPBJQNgA2ADbjHu9eyAaxAN4ANqnYD2ICqI/DzcZZyOdvAiUciubZjf18cJ5dO6rp+TikdIzoumqZ5VyfS5N0Tv8tyqgmEawIn2eQoE45bAe6NQgeg/SDWhlh50eV8oI+QBXNuS8IKAa4hWKEr5AG7Ql6wZ2hzuISApCdT9FKR2Dts8R91rtQuIYlXyKYE4K+QOeRTIxYeyhzA1gBp/yQ+GGaF3uoF+qDwW9ckJKLJ0jNv/HrLHpHOH6qRa69Cq3eK0+rlXg6GSdhdD0m2tqVzejg9UpOwy3hFz3rZX45WKPHBiAjlFTodIFKSh2ST7aKX4hICeCJzi75UBLZs9xq50blSf/c4SDXyGJyh5RBEn+NbXxChlEJCgDty8ge0BUU/7pYjUBT7J4y687PYn/ewvTZcj7ds/bH/y/JJVp+03VHt8H+ZogAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}0\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "[0]"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# apply U_f gate for the identity function f_id to the initial input\n",
    "v_prime = U_f_gate(f_id, plusminusket)\n",
    "# then estimate the probability of observing the + case\n",
    "p_plus = v_prime.T * E_plus * v_prime\n",
    "p_plus"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0fedadf3-1fe8-4597-960d-9261000f117a",
   "metadata": {},
   "source": [
    "## Lecture 10"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e7e9144-2ae5-4ce3-a36e-827a4bf4da08",
   "metadata": {},
   "source": [
    "The BB84 key distribution protocol"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "id": "9105835d-5e0f-4e38-b8e7-f4de91e5f77b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "rng = np.random.default_rng()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "id": "2b7d7ce1-a405-4540-9fd7-bc53552131fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "# from Lecture 7\n",
    "def col_vec(components):\n",
    "    \"\"\"Return a column vector (as a NumPy array) with the given components.\n",
    "\n",
    "    In a matrix context, this should be treated as a column vector.\n",
    "    \"\"\"\n",
    "    return np.array(components)\n",
    "\n",
    "\n",
    "def col_vec_inn_prod(v1, v2):\n",
    "    \"\"\"Hilbert space inner product of column vectors.\"\"\"\n",
    "    return np.conjugate(v1).dot(v2)\n",
    "\n",
    "\n",
    "zeroket = col_vec([1, 0])\n",
    "oneket = col_vec([0, 1])\n",
    "plusket = col_vec([1, 1]) * 1/np.sqrt(2)\n",
    "minusket = col_vec([1, -1]) * 1/np.sqrt(2)\n",
    "eyeket = col_vec([1, 1j]) * 1/np.sqrt(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1bdb63d1-06ef-4185-a245-630b5013578b",
   "metadata": {},
   "source": [
    "### preparing strings and states"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10c01d21-8713-44f8-ad6b-2987a7154990",
   "metadata": {},
   "source": [
    "control parameter is an integer $n$, that Alice and Bob share;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "id": "117da652-7173-4cf1-b9da-9634a2b54da3",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = 5\n",
    "n = 20"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cfa27b6e-b2c6-4da7-b49a-284a3cedf29a",
   "metadata": {},
   "source": [
    "Alice chooses two strings $x = x_1 \\cdots x_n$ and $y = y_1 \\cdots y_n$ of $0$'s and $1$'s.\n",
    "This choice is random;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "id": "ddbe689f-e2c2-46b6-8717-d8e582a88c94",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1],\n",
       " [0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1])"
      ]
     },
     "execution_count": 81,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [rng.integers(2) for _ in range(n)]\n",
    "y = [rng.integers(2) for _ in range(n)]\n",
    "x, y"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b01e0b2-71d9-4030-a59a-eb20b1540ce0",
   "metadata": {},
   "source": [
    "she then prepares an $n$-qubits $v_1, \\ldots, v_n$ representing $x$ according to the following rule:\n",
    "- if $y_j = 0$, then $v_j = \\ket{0}$ or $\\ket{1}$ depending on $x_j = 0$ or not;\n",
    "- if $y_j = 1$, then $v_j = \\ket{+}$ or $\\ket{-}$ depending on $x_j = 0$ or not;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "id": "aac294ba-4a46-4f38-830b-caa19ce6bf5a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def v_enc(x_val, y_val):\n",
    "    if y_val == 0:\n",
    "        if x_val == 0:\n",
    "            return zeroket\n",
    "        else:\n",
    "            return oneket\n",
    "    else:\n",
    "        if x_val == 0:\n",
    "            return plusket\n",
    "    return minusket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "id": "f50a0149-ff4f-4e25-b7ca-af61a392bb9a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[array([1, 0]),\n",
       " array([0, 1]),\n",
       " array([ 0.70710678, -0.70710678]),\n",
       " array([0.70710678, 0.70710678]),\n",
       " array([ 0.70710678, -0.70710678]),\n",
       " array([0.70710678, 0.70710678]),\n",
       " array([1, 0]),\n",
       " array([ 0.70710678, -0.70710678]),\n",
       " array([0, 1]),\n",
       " array([ 0.70710678, -0.70710678]),\n",
       " array([0, 1]),\n",
       " array([ 0.70710678, -0.70710678]),\n",
       " array([1, 0]),\n",
       " array([0.70710678, 0.70710678]),\n",
       " array([1, 0]),\n",
       " array([0.70710678, 0.70710678]),\n",
       " array([0.70710678, 0.70710678]),\n",
       " array([1, 0]),\n",
       " array([ 0.70710678, -0.70710678]),\n",
       " array([ 0.70710678, -0.70710678])]"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v = [v_enc(x[i], y[i]) for i in range(n)]\n",
    "v"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0a6bbee-6e32-4006-8332-3cfca75b26ee",
   "metadata": {},
   "source": [
    "on Bob's side, he chooses a string $y' = y'_1 \\cdots y'_n$ of $0$'s and $1$'s, again in a random way."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "id": "84f53f4e-8ef9-475f-ba75-1bc8ba4c28ea",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1]"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "yp = [rng.integers(2) for _ in range(n)]\n",
    "yp"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a310b201-6a68-4a92-820e-4d8dbb89547f",
   "metadata": {},
   "source": [
    "### transmit states and strings, without eavesdropping"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2791dd56-47e3-47f8-8f0b-2b191e2ebf20",
   "metadata": {},
   "source": [
    "Alice sends the state $v$ to Bob;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "19e95cf7-f7dc-46a3-831d-625dd926c566",
   "metadata": {},
   "source": [
    "Bob makes the measurement of the factors $v_j$ by the following rule:\n",
    "- if $y'_j = 0$, the $j$-th qubit is measured in the computational basis, i.e., with the PVM $E_0 = \\ket{0} \\bra{0}$ and $E_1 = \\ket{1} \\bra{1}$;\n",
    "- if $y'_j = 1$, the $j$-th qubit is measured in the $(\\ket{+}, \\ket{-})$-basis, i.e., with $E_{+} = \\ket{+} \\bra{+}$ and $E_{-} = \\ket{-} \\bra{-}$.\n",
    "\n",
    "he records the result of measurement as the string $x' = x'_{1} \\cdots x'_{n}$ of $0$'s and $1$'s, where the case \"$+$\" corresponds to $0$ and the case \"$-$\" corresponds to $1$ in the case of $y'_j = 1$;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "id": "3ca314db-d735-4ded-a689-ae71c77e4f6d",
   "metadata": {},
   "outputs": [],
   "source": [
    "def measure_qubit(v, basis_choice):\n",
    "    \"\"\"Measure a single-qubit state vector in a specified basis.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    v : numpy.ndarray\n",
    "        Qubit state, a length-2 NumPy array (complex amplitudes).\n",
    "    basis_choice : int\n",
    "        0 for computational basis, 1 for the |+⟩ / |−⟩ basis\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    int\n",
    "        0 or 1, according to the measurement of v in the specified basis.\n",
    "        The case \"+\" corresponds to 0.\n",
    "    \"\"\"\n",
    "    # to be on the safe side, do not assume ||v|| = 1\n",
    "    # normalize the input vector\n",
    "    norm_v = np.sqrt(np.real(col_vec_inn_prod(v, v)))\n",
    "    v_normalized = v / norm_v\n",
    "    if basis_choice == 0:\n",
    "        # the case 0 happens with probability |v0|^2\n",
    "        threshold = np.real(np.conjugate(v_normalized[0]) * v_normalized[0])\n",
    "        rand_num = rng.random()\n",
    "        if rand_num < threshold:\n",
    "            return 0\n",
    "        else:\n",
    "            return 1\n",
    "    else:\n",
    "        # the case \"+\" happens with probability |⟨|+⟩,v⟩|^2\n",
    "        inn_prod_with_plus_ket = col_vec_inn_prod(plusket, v_normalized)\n",
    "        threshold = np.abs(inn_prod_with_plus_ket)**2\n",
    "        rand_num = rng.random()\n",
    "        if rand_num < threshold:\n",
    "            return 0\n",
    "        else:\n",
    "            return 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "id": "b26aac69-6f10-4595-8d12-12ba1575f9e2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAgoAAAAVCAYAAAAn3sYyAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAE4klEQVR4Ae2d3XHTQBSFHYYCMtBB6ICQDqADTAckHeQ1eWNCB0AFDHSQdMAkHUAHBJfAOY5kO/Yq1qykL9bm7sxG1t9+Oude23ckRd47Ozs7nUwmJ+pu0/Pz85u7l/E3HAgHwoFwIBwIB56aA6oD7tUFeyoULmTCpVZcPTUzQm84EA6EA+FAOBAOpB1QXTCvD56nV98trTbyzF/1V+oXWvbHC/puGve1xvyhfqjXs77HXx2PYIlhg90I7xBWaLoLaJe/RO75+EAOknulaqJ0ke/dEjVR/lEcx8hNvFbfu42Fgga41jifNP1ZDbiv6bXm36n3UixoHI/5Tf1W/Y36gfogDWYN7l1tknQhLIpjXRQL5CB5Lj0Ih8y9EjVVOY7FqrQ8Jz8jSNYux+lZ/aZfneqAjzW/r+m8SKjMmmnq+S+e76Np/Jm674vwPRLf+xizaQyKJQ7inXVSLIpTsCYkzxUnhAPHqThNlX+ILvi9W6Im5PN81+OULBSUyFP11E2Nv7T8rUS5Go6WdoD0jmJRHDtKsShOOkvGv7RE/0LTOPKSjBPFojhZEW4qFN5qNF8OWG/1JQevj5Z2gPSOYlEcO0qxKE46S8a/tET/QtM48pKME8WiOFkR3igUWp4teJFFK3wn0juKRXGcGhSL4pSa7iX6F5rGka1knCgWxekS4Y1CQYPVRYDvSWhqcekh7QzpHcWiOHaUYlGcdJaMf2mJ/oWmceQlGSeKRXGyI5wqFNoM9rLNRrFN0gHSO4pFcWwoxaI4ySQpYGGJ/oWmcSQmGSeKRXGSEU4VCql7E+qd68rHzwaItukA6R3Fojh2k2JRnM0MKWNJif6FpnHkJhknikVxsiO8USjoekl9ySF1eaFeVt/UmA0ucUfSO4pFcZwPFIvilJjjZJxI/0rMidDULYMo/yhOFzc2CoVqMD/O+SAxcH1GIR73nDDnEbyj4kRxbCHFojjNmTLuNSX6F5rGkZNknCgWxcmKcFOh4Ecp+0mJ6+1QC25WKqCJXtdnGda37XWe4vigO7JI7ygWxbH9FIviWFPr1jH3SM7O+deDdzunyQHtqCs0tX5XJDek/KM4SZHbFiYLBSXmV+14q+n7eoAqWT9o/uPasn9a58cId231zRr1WYvFeBW7L47HHYylY8W8o1gUx4GhWBTHmtbaYLlHch7Jv0G9eyRNDttgukLTpNP3BuUfxVn7jHgw91a3bfz1SB24zxT4B19m6r558Ujdv/1wo+miaf53NZP1Y07a35WUmx84YabH9z0Q/kVLf+nOW1eOB6FY4iDeVZoQVmiap2FWjsO5R76fqNwrThOcE0icCtaE+Ad/xrZ9T7kGuGwsFBz0tk0CfebhStNZ231ytqM4PjaKRXFCU07GLfeJOC29yHlF+Udx7EGJrNCUk93LfSj/QM68UEheeljKbv3qSAc+aJFQHQnFMY5iUZzQVCVR5iTilGlctRvlH8WxrBJZoSnyfMOBzoWCCgSflhn8uQoUxw5RLIoTmuxAfos45XvnPSn/KA6piWSV6F9ocgZ1b50LBR3CsYLxufuhbB2B4vhAKBbFCU1b0+vBDSJOD9qzdSXlH8Wx4BJZoWlrKj+4AeUfxVmIre9RqP+7Yaov/Xs3Ky62jBfhQDgQDoQD4UA4ULwDqgNOJfJE3f+FOP0PW/1tcoXwvcUAAAAASUVORK5CYII=",
      "text/latex": [
       "$\\displaystyle \\left[ 0, \\  1, \\  1, \\  0, \\  0, \\  0, \\  0, \\  0, \\  1, \\  1, \\  0, \\  1, \\  0, \\  1, \\  0, \\  1, \\  0, \\  0, \\  0, \\  1\\right]$"
      ],
      "text/plain": [
       "[0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1]"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xp = [measure_qubit(v[i], yp[i]) for i in range(n)]\n",
    "xp"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71d23cbc-28ce-4edf-8a49-3616c39b09ae",
   "metadata": {},
   "source": [
    "Alice and Bob exchange the strings $y$ and $y'$;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1efd040d-bf2b-4113-b174-e93cdeaf8156",
   "metadata": {},
   "source": [
    "now they know the $j$'s satisfying $y_j = y'_j$, call them $j_1, \\ldots, j_k$;\n",
    "now Alice's string $x_{j_1} \\cdots x_{j_k}$ and Bob's string $x'_{j_1} \\cdots x'_{j_k}$ are candidates of their shared secret."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "id": "ef2d9e6c-372e-40a3-a147-32ed150b9121",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 5, 6, 9, 11, 12, 14, 16, 17, 19],\n",
       " [1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1],\n",
       " [1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1])"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "matching_indices = [i for i in range(n) if y[i] == yp[i]]\n",
    "shared_secret_Alice = [x[i] for i in matching_indices]\n",
    "shared_secret_Bob = [xp[i] for i in matching_indices]\n",
    "matching_indices, shared_secret_Alice, shared_secret_Bob"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7e9ec22c-04b5-462b-aeaa-2d005a936317",
   "metadata": {},
   "source": [
    "### transmit states and strings, with eavesdropping"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cfd311a8-3db2-4ce7-b350-4ef215dd1900",
   "metadata": {},
   "source": [
    "Alice sends the state $v$ to Bob;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71ec26fd-4374-4827-8695-0c11fda3c086",
   "metadata": {},
   "source": [
    "Eve looks into the state, but needs to make guess about measurement schemes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "id": "47448ee9-2f25-40dd-b179-b3be594a7ff9",
   "metadata": {},
   "outputs": [],
   "source": [
    "y_eve = [rng.integers(2) for _ in range(n)]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "753ef346-2233-4b7c-b0f2-16e1586ba7ff",
   "metadata": {},
   "source": [
    "when she performs the measurement, the state changes according to the outcome"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "id": "1d8c632c-ebf0-45d6-8a01-7ed78c64f69c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[array([ 0.70710678, -0.70710678]),\n",
       " array([0, 1]),\n",
       " array([ 0.70710678, -0.70710678]),\n",
       " array([1, 0]),\n",
       " array([ 0.70710678, -0.70710678]),\n",
       " array([1, 0]),\n",
       " array([0.70710678, 0.70710678]),\n",
       " array([ 0.70710678, -0.70710678]),\n",
       " array([0, 1]),\n",
       " array([ 0.70710678, -0.70710678]),\n",
       " array([0.70710678, 0.70710678]),\n",
       " array([ 0.70710678, -0.70710678]),\n",
       " array([1, 0]),\n",
       " array([0.70710678, 0.70710678]),\n",
       " array([1, 0]),\n",
       " array([0.70710678, 0.70710678]),\n",
       " array([1, 0]),\n",
       " array([1, 0]),\n",
       " array([1, 0]),\n",
       " array([ 0.70710678, -0.70710678])]"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_eve = [measure_qubit(v[i], y_eve[i]) for i in range(n)]\n",
    "v = [v_enc(x_eve[i], y_eve[i]) for i in range(n)]\n",
    "v"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8952991a-5a80-4162-b992-f869261d6d47",
   "metadata": {},
   "source": [
    "Bob makes the measurement of the factors $v_j$ by the following rule:\n",
    "- if $y'_j = 0$, the $j$-th qubit is measured in the computational basis, i.e., with the PVM $E_0 = \\ket{0} \\bra{0}$ and $E_1 = \\ket{1} \\bra{1}$;\n",
    "- if $y'_j = 1$, the $j$-th qubit is measured in the $(\\ket{+}, \\ket{-})$-basis, i.e., with $E_{+} = \\ket{+} \\bra{+}$ and $E_{-} = \\ket{-} \\bra{-}$.\n",
    "\n",
    "he records the result of measurement as the string $x' = x'_{1} \\cdots x'_{n}$ of $0$'s and $1$'s, where the case \"$+$\" corresponds to $0$ and the case \"$-$\" corresponds to $1$ in the case of $y'_j = 1$;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "id": "636014d2-fc8d-4066-81d5-b4dba04e4e5f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAgoAAAAVCAYAAAAn3sYyAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAE+ElEQVR4Ae2d3XHUMBSFF4YCGOgAOuCnA+iA0AHQAa/JGwMdABUw0AF0wJAOoAMgJXDuYoE3cbKWrvzBbo5mFMu2pE/3XNm+u3a8Vw4PD5+vVqtnypEOjo6Ojn8X/dcKWAErYAWsgBW4bAooDtiIC64oUHgpET5qx6fLJobttQJWwApYAStgBaYVUFywjg+uTe/+u1UV72jtvfJdlU/+7ulbojgxaoIlRggc6bvybeWX2vYtNvROMIuaD6R+tqlxUnruNQo3NKP0ozhFDfEWP6ZImygWxan102SgoMFeV0dvlX8o31O+pdw9UZwYOMz6IuQLMT+M2F+0/lC5a7Cg/hZniYHMh9Aqkm36rUPtX/upVrGz9Ym5V6gUC+Rg5wnKpvAVxQI51X66WibteKkBnyjH8wrx7MK78b6eZYoTY6ZY4jwV7rqW6yChsLWM9dex3itRLEq70MU2tc8O+6ldO3LukSzqeBpsoq4b+3iOJW2q9tNkoJA73C596wMpMPVA6Gdtf6ADN6K5Xolk9Rrztn5s0zaF/o/99lPOD5R+FCenRl1r0iaKRXHqlB5qO1Boku3CRg+0N27ZnE7llkPs75VIVq8xb+vHNm1T6P/Ybz/l/EDpR3FyatS1Jm2iWBSnTumhtgOFJtmmG838tuDGdOu6rSSrbmTttW1Tu3ZkS/sppzalH8XJqVHXmrSJYlGcOqU3aztQ2NQju1aCgJMLOup164FkXWBO1122qauci3VmP+WkpfSjODk16lqTNlEsilOn9Ki2A4WRGFDxJsQJDMmizLJNlNI5jv20G/rZT/bTVgUcKGyVqKrC1LMJpYMSNcZ7FXokktVjvHP6sE1zVPr3deynnA8o/ShOTo261qRNFIvi1Ck9qu1AYSRGtqh7TeWWw9TthbKtPNSYwpGs1EArGtumCrH+YVX7KSc+pR/FyalR15q0iWJRnDqlN2s7UNjUo8davAr71kRH5RuFnq/KJlkTJi2yyTYtImv3Tu2nnKSUfhQnp0Zda9ImikVx6pQeaqcDBUVD5ZNy0wDmNqI4MZ4kK153HW+zPJ3uasOx+i7fOmQ50T/JOm3P5HpSO9u0O8eT597kETB7I6UfxZlteFRMnidImygWxanyU6k8J1AoD7uUT8SlbXH2Tzk9XiOcTRQnxrkYS1q8Uf8/tHxUBFE5gqnHyk9ObUtpR7LKuLVcTLtg2KZVak7YT+3nInLuUSyKM5p3pbjYeYK0iWJRnOKc0fJcP43qrM799UgNPCKcSPEiiLjQHSvH/fX4pcm4GK6Tyl+HYtOPRlGcGCPFEif0ih81im8P4uHF+8rx2w+h4Z+k9ZR20RHFEgeZD7YpNyfsp/Xh1XQuIuceyaLOEYNNyHkCtgk5n8M2zfVTXMc+nhsohNPnJhkYn54/aRkXxsUSxQkDKBbFsU25aWk/7YZ+++gnH7u7Mff20U86ntaBwpxbD3O8dF8dLhokDIOgOIGjWBTHNg2TqHFhPzUKNzSj9KM4YdY+smyT5/kZBdKBggKE+Fqm17sBzgywbKA4waNYFMc2lVnUtrSf2nQrrSj9KE7YtY8s21RmbNuS0o/ijFVIBwrq7KkG/mrc6UJlihPDp1gUxzblJqX9tBv67aOffOzuxtzbVz+t1S/PKJQn9A900d944C7nI7e2AlbAClgBK2AFdkkBxQHPNd5nyvHfjge/AIcFSCm8b5INAAAAAElFTkSuQmCC",
      "text/latex": [
       "$\\displaystyle \\left[ 1, \\  1, \\  1, \\  0, \\  0, \\  1, \\  0, \\  1, \\  0, \\  1, \\  0, \\  1, \\  0, \\  0, \\  0, \\  1, \\  0, \\  0, \\  0, \\  1\\right]$"
      ],
      "text/plain": [
       "[1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xp = [measure_qubit(v[i], yp[i]) for i in range(n)]\n",
    "xp"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6aa0cfd7-7158-4485-83e5-42711ee073f1",
   "metadata": {},
   "source": [
    "Alice and Bob exchange the strings $y$ and $y'$;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "129502b2-b80b-421a-924b-fcb9fff2c7cc",
   "metadata": {},
   "source": [
    "now they know the $j$'s satisfying $y_j = y'_j$, call them $j_1, \\ldots, j_k$;\n",
    "now Alice's string $x_{j_1} \\cdots x_{j_k}$ and Bob's string $x'_{j_1} \\cdots x'_{j_k}$ are candidates of their shared secret."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "id": "732a59fd-845d-4deb-8986-44756c1b9b09",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 5, 6, 9, 11, 12, 14, 16, 17, 19],\n",
       " [1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1],\n",
       " [1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1])"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "matching_indices = [i for i in range(n) if y[i] == yp[i]]\n",
    "shared_secret_Alice = [x[i] for i in matching_indices]\n",
    "shared_secret_Bob = [xp[i] for i in matching_indices]\n",
    "matching_indices, shared_secret_Alice, shared_secret_Bob"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "430aa1f4-1a30-4eae-aec1-0cb91abc26a4",
   "metadata": {},
   "source": [
    "### verify if there was eavesdropping or not"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "de1a5274-c402-4600-a08d-ae3a0f2b8240",
   "metadata": {},
   "source": [
    "Alice randomly chooses some $j_{a_1}, \\ldots, j_{a_m}$ among $j_1, \\ldots, j_k$;\n",
    "she sends the pairs $(j_{a_s}, z_{a_s})$ to Bob;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "id": "da620bcb-22e1-49d1-8f6c-c179b01bf263",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([11, 17, 19, 14,  9]), [1, 0, 1, 0, 1])"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sample_indices = rng.choice(matching_indices, m, replace=False)\n",
    "sample_secret_Alice = [x[i] for i in sample_indices]\n",
    "sample_indices, sample_secret_Alice"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33cbbaac-2bb6-4d37-b512-cdcd418e05aa",
   "metadata": {},
   "source": [
    "Bob checks these $z_{a_s}$ against the corresponding terms in his $z'$;\n",
    "if he sees any discrepancy, he reports it to Alice.\n",
    "(Then they know that the shared secret is bad and should be discarded.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "id": "2a8a66fc-3e4a-469e-b0c8-1984880dfa4b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 0, 1, 0, 1], True)"
      ]
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sample_secret_Bob = [xp[i] for i in sample_indices]\n",
    "sample_secret_Bob, sample_secret_Alice == sample_secret_Bob"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "edfefcf1-402a-4b31-9078-f678ac038848",
   "metadata": {},
   "source": [
    "otherwise they can keep the remaining terms of $z$ and $z'$ as valid shared secret which is not known to Eve."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "id": "5933f1f6-9b02-4a78-a207-6a583428974f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 1, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0])"
      ]
     },
     "execution_count": 94,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "remaining_secret_Alice = [x[i] for i in matching_indices\n",
    "                          if i not in sample_indices]\n",
    "remaining_secret_Bob = [xp[i] for i in matching_indices\n",
    "                        if i not in sample_indices]\n",
    "remaining_secret_Alice, remaining_secret_Bob"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51e6a524-e6ec-4cb7-83ba-003cc6d6978f",
   "metadata": {},
   "source": [
    "## Lecture 11"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b45b6bd-dd11-4578-a56e-08d4244be610",
   "metadata": {},
   "source": [
    "### superdense coding"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "id": "56cf41ca-ce1f-41cb-b861-fcb1204a3b14",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sympy as sy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "id": "f8e07216-3a6a-43bc-b613-0c650720629f",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sympy.physics.quantum import TensorProduct\n",
    "zeroket = sy.Matrix([1, 0])\n",
    "oneket = sy.Matrix([0, 1])\n",
    "EPR_state = (TensorProduct(zeroket, zeroket) +\n",
    "             TensorProduct(oneket, oneket)) * (1/sy.sqrt(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "id": "e90a0bf9-d0ba-4c8e-8f62-9599badd914c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# keep track of the state\n",
    "w = EPR_state"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68ce0ea9-7fb0-4874-889b-2699daa601a5",
   "metadata": {},
   "source": [
    "message is a string of two bits"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "id": "17b72f5b-700f-41e7-b482-94704048fd60",
   "metadata": {},
   "outputs": [],
   "source": [
    "s = [0, 1]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4f715a29-22ec-4e0f-b23f-2f9bf42fc58c",
   "metadata": {},
   "source": [
    "if $s_1 = 1$, Alice applies the Pauli $X$ transform on her part of $w$ (the $H_A$ factor)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "id": "45393a2e-ee17-46e6-a75e-79b7adb0d0e6",
   "metadata": {},
   "outputs": [],
   "source": [
    "X = sy.Matrix([[0, 1],\n",
    "               [1, 0]])\n",
    "# indexing starts with 0\n",
    "if s[0] == 1:\n",
    "    w = TensorProduct(X, sy.eye(2)) * w"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41f9a137-c31a-4de4-86cf-b0cf3484aea2",
   "metadata": {},
   "source": [
    "if $s_2 = 1$, she then applies the Pauli Z transform on her part of the state"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "id": "a979e0a2-7fd3-4908-bb70-ee88d31487a2",
   "metadata": {},
   "outputs": [],
   "source": [
    "Z = sy.Matrix([[1, 0],\n",
    "               [0, -1]])\n",
    "# indexing starts with 0\n",
    "if s[1] == 1:\n",
    "    w = TensorProduct(Z, sy.eye(2)) * w"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87dda18c-4d00-4656-be75-9dad63ab4a21",
   "metadata": {},
   "source": [
    "then she sends her part of the state to Bob; this means Bob now has access to the overall state in $H_A \\otimes H_B$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cddf8b86-9451-4f34-ad5f-cbcfe3604213",
   "metadata": {},
   "source": [
    "Bob does measurement for the projection-valued measure corresponding to the basis\n",
    "$$\n",
    "w_{00} = w_{\\mathrm{EPR}}, \\quad\n",
    "w_{10} = (X \\otimes I_2) w_{\\mathrm{EPR}}, \\quad\n",
    "w_{01} = (Z \\otimes I_2) w_{\\mathrm{EPR}}, \\quad \n",
    "w_{11} = (Z X \\otimes I_2) w_{\\mathrm{EPR}}\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "id": "ad949044-9bcd-43f0-9c16-b791d355c224",
   "metadata": {},
   "outputs": [],
   "source": [
    "w00 = EPR_state\n",
    "w10 = TensorProduct(X, sy.eye(2)) * w00\n",
    "w01 = TensorProduct(Z, sy.eye(2)) * w00\n",
    "w11 = TensorProduct(Z * X, sy.eye(2)) * w00"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f37c6219-cc62-4798-b6c2-77bd13b7f4fa",
   "metadata": {},
   "source": [
    "the (index of) result of the measurement is guaranteed to be $s_1 s_2$, what Alice wanted to send"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "id": "eb9c931e-4275-4b0c-9f32-8158e8e48a05",
   "metadata": {},
   "outputs": [],
   "source": [
    "def inn_prod_abs_sq(w1, w2):\n",
    "    \"\"\"Return the squared absolute value of the inner product ⟨w1, w2⟩.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    w1 : sympy.Matrix or sympy.ImmutableMatrix\n",
    "        SymPy column matrix representing a (possibly complex) vector.\n",
    "    w2 : sympy.Matrix or sympy.ImmutableMatrix\n",
    "        SymPy column matrix representing a (possibly complex) vector.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    sympy.Expr\n",
    "        The scalar |⟨w1, w2⟩|² as a SymPy expression.\n",
    "    \"\"\"\n",
    "    inn_prod = sy.conjugate(w1).T * w2\n",
    "    abs_sq = sy.conjugate(inn_prod) * inn_prod\n",
    "    return abs_sq[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "id": "8fe63c7b-8363-4f7a-8395-910d6e1267b9",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGYAAAAVCAYAAAC0aZsNAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADDUlEQVRoBe2Z23UTMRCGnVRgoAPTQUIqIO7AcQckHcCj/cYJHQAVcJIOgAo4uAOnA4w7MP8npEVea21FK88LmXO0kkaXfy4aaVc72Gw2gzjNZrNRXH8qb9vnGPZI2fx0ENF8Pn+r6lnEeiraWGDkbd+gnbACIDVMlF0of+cY0UO8W1/9pfyl0q14D1GXakVjLBbhndK5cNfVlGhNlKOT+hAUa+WfGO4co8pQ5e/Kz2HGJN5P1d8rv4evnL7wxipXdY7mOzqWl/+z5F8pvVLCOc/EP4pjHqOT7/saWcJWRkR8VNoidbgWY6jcOYVGBimjvtOf9lKywkJ+pSulG8n6pVTenHEFOmFTtzsFx0w1iQuhFuCV6osWj+oPpUuNIXpqkSVWLZkPzfMonbwP8MXwVA/Olq4t6VJthHybQn/aa5ElVi2ZD81TohO2nRIxY6VvbYTMaHjeHldSt8Qqka9kTA+d8MUYx3AALhPgwej7DsVaW5klVkLVo7BKdcIXIxyDcVPbVY60L3I6VepjiVVJ5IPTpHTCF84xeDYVFfucFVYD3zU1yBKrhrw5c5TqxBkzJGKSpD0yOCu1XQVeeAlIzpHLtMTKlalvvx46uUDBMXg2GLotDwfRqM1UPUTMzktDom8uyxIrV6a+/Up0whcrHMOqTxkfobiu4OWgTdwQLKJVMVC5y7ntsV11S6wuGbb4ljpFwCz6BxyzULqIGpqiBOOjc6Wcbx1HXtipKm88a+B5v5VzpVJEGmuGFQkYDt+wAzRNljo1oH8LbtGf6Mr5TPU7CcLl5A55AbkmWCtx2ONE7s5waEOqh1fu4gtBKyzhEJ0QH4BEOrqwc3xVW3MDYqmTsB15zBv3L0bOWeKgvv8aNMdEadh3npzxVlhWOOgsrJHSkjJbGUREcKnXl/htQGRZkBWWFQ4245fLv0tMH778rOl6CThoaI1lS6j1XbMXzwrLCgdlhYXt8YHbSkPE0MZNaJ+r/GtN+oGJDMgKywoHk2H7Ztdq/mDS4r02MTQwsP89yd78vbxX3nyw/wHEYanyCdaZ0gAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left( 0, \\  0, \\  1, \\  0\\right)$"
      ],
      "text/plain": [
       "(0, 0, 1, 0)"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# measurement probabilities are square of absolute value of inner product\n",
    "inn_prod_abs_sq(w00, w), inn_prod_abs_sq(w10, w), \\\n",
    "    inn_prod_abs_sq(w01, w), inn_prod_abs_sq(w11, w)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0bd84f85-039d-4fb1-9607-b65a9634c98c",
   "metadata": {},
   "source": [
    "check consistency of the above scheme; we want Bob's basis to be orthogonal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "id": "cd180020-a1b2-4658-88df-2c6897d28d1c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAJsAAAAVCAYAAABR25wkAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADNElEQVRoBe2a63HTQBSFnVTggQ5MBzGpgLgD4w5IOoCf9j8mdAAtJCVABQzuwOkgxh2Y8+3sisWWbL3mDAO6M/K+tPvpXh+tXjva7/ejfFsul5O8POT/jM8Qj3rxKNPR5Siz1Wr1XsWrrGrIDhFoG4FJ1FPR/4IzFVPDXMm10g+hIvtR3X0sPit9pe1edU/ZLr1lXSwXh8C4WC5OXZ90PExeO6Vf6BPEpsJY+W9Kp1TmprofKn9U+ki9UvalbqZ8r4LTeBaWixPj9V/7FGP9RukuXUaZuT4TnNy0w63KY6VBaLTRSQnlo/1pb2sulotDHFwsF6elT+gkXBmT2BY64DDVMWBmb5VfZ+WU/a7Mjfowy/VlLpaLQ1xcLBensU9RV+hrfKkf7tWqLoc3attCOLC0P+19mYvl4hAXF8vFaesTelkws820fWWU3GrOWi/yPm3zLpaLQxxcLBeno0/oa4bYXmvbMNiBJSFxj1ZlfV1GXSwXh3i5WC5OF5/Q1wSxIZiySyWDn7OX53bosd3FcnEIjYvl4lT5hL6C2DgzymavUwJMZ9Mzo/dgLpaLQ0hcLBeni0/cs42Z2UpN9wJJgGWXylSXHhRKx6hb6WK5OPjtYrk4HX0KExpi48xI4mHM3Lixm+QVMZ9mtqMHi5J961a5WC4OfrtYLk5bn9DXFrExO5UJioEftPEAcWhTVayzs4ozuUqwh32ryi6Wi4OfLpaL08in7I9mcnpCbGtt11lDkZWAeNG7Vcq7uGBRVAsV3sWqUaz7qZRPM61MfS0sF4cguFguThOfDkQQJqcLLQW5UsODDpgP7EememYsPjfstPFAgDD5VopIC1M5vT6ZKs++jc3FcnEIgIvl4jTxKQlAx4Y27sJaNglug+i6rtXSGHNt467j1OnvYrk4+OxiuTjRp4l4G/JcRjFmrruQ6/bDEqVWs1oLrIvl4hACF8vFwSeWrP3+EC+BcL/EYreqBwU6nTT15XLb13u3v4I1+HTybzjbGPWErsIijzSz0ZGVA12WDd1q0E9nj6CfHVwsF4eouFguDj6hp+KKWazUpSUqcW4UDdjB/sEISEOs0n1UWrz4/wUOL50S8siOEgAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left( 0, \\  0, \\  0, \\  0, \\  0, \\  0\\right)$"
      ],
      "text/plain": [
       "(0, 0, 0, 0, 0, 0)"
      ]
     },
     "execution_count": 104,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inn_prod_abs_sq(w00, w10), inn_prod_abs_sq(w00, w01), \\\n",
    "    inn_prod_abs_sq(w00, w11), inn_prod_abs_sq(w10, w01), \\\n",
    "    inn_prod_abs_sq(w10, w11), inn_prod_abs_sq(w01, w11)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56f230ec-5fd0-4a0c-9b46-fd01c4556e96",
   "metadata": {},
   "source": [
    "### quantum teleportation"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b9679fc9-a158-456b-9d79-f4e5745229c8",
   "metadata": {},
   "source": [
    "Alice wants to send a qubit state $v \\in H_{A1} = \\mathbb{C}^2$ to Bob"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "id": "cb0b674e-a748-4daa-b67e-ba2302fbd214",
   "metadata": {},
   "outputs": [],
   "source": [
    "α, β = sy.symbols(\"α β\")\n",
    "v = sy.Matrix([α, β])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8afc98be-a293-4987-b686-e0316eb7f0cb",
   "metadata": {},
   "source": [
    "we take $v \\otimes w_{\\mathrm{EPR}}$ in the composite system $H_{A1} \\otimes H_{A2} \\otimes H_B$;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "id": "bb259df8-e624-423b-845d-8edc838b3453",
   "metadata": {},
   "outputs": [],
   "source": [
    "tot_state = TensorProduct(v, EPR_state)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48c8c270-4568-4265-8fbb-8152b4c1be18",
   "metadata": {},
   "source": [
    "on her part of the system $H_{A1} \\otimes H_{A2}$, Alice first performs the CNOT transform;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "id": "2d673865-5795-494f-9e8f-cdc8a412edab",
   "metadata": {},
   "outputs": [],
   "source": [
    "CNOT = sy.Matrix([[1, 0, 0, 0],\n",
    "                  [0, 1, 0, 0],\n",
    "                  [0, 0, 0, 1],\n",
    "                  [0, 0, 1, 0]])\n",
    "tot_state = TensorProduct(CNOT, sy.eye(2)) * tot_state"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a0b2fe4-4a57-42eb-988c-94076519a05f",
   "metadata": {},
   "source": [
    "then she performs the Hadamard transform on the $H_{A1}$ part;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "id": "e176d2fb-3527-4714-a95b-c5c2ef58c21b",
   "metadata": {},
   "outputs": [],
   "source": [
    "H = sy.Matrix([[1, 1],\n",
    "               [1, -1]]) * (1/sy.sqrt(2))\n",
    "tot_state = TensorProduct(H, sy.eye(4)) * tot_state"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7f840bfc-97c0-4dcc-ace9-3f5438bf363e",
   "metadata": {},
   "source": [
    "Alice measures her part $H_{A1} \\otimes H_{A2}$ with PVM for the computational basis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "id": "e6a1d06a-6694-4074-951c-24bc8492239f",
   "metadata": {},
   "outputs": [],
   "source": [
    "zerozeroket = TensorProduct(zeroket, zeroket)\n",
    "onezeroket = TensorProduct(oneket, zeroket)\n",
    "zerooneket = TensorProduct(zeroket, oneket)\n",
    "oneoneket = TensorProduct(oneket, oneket)\n",
    "E00 = zerozeroket.reshape(4, 1) * zerozeroket.reshape(1, 4)\n",
    "E01 = zerooneket.reshape(4, 1) * zerooneket.reshape(1, 4)\n",
    "E10 = onezeroket.reshape(4, 1) * onezeroket.reshape(1, 4)\n",
    "E11 = oneoneket.reshape(4, 1) * oneoneket.reshape(1, 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "id": "4ef92d00-8b64-478a-9ca7-a58660bf0162",
   "metadata": {},
   "outputs": [],
   "source": [
    "def E(s):\n",
    "    \"\"\"Convenience function to get E_ij for s = ij.\"\"\"\n",
    "    if s == [0, 0]:\n",
    "        return E00\n",
    "    elif s == [0, 1]:\n",
    "        return E01\n",
    "    elif s == [1, 0]:\n",
    "        return E10\n",
    "    return E11"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "745f0f3d-5b5d-46c1-a7fa-2fffec8605a5",
   "metadata": {},
   "source": [
    "she sends the outcome $s_1 s_2$ to Bob;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "id": "f8ba0f91-5192-4dbb-8bdd-9ea171eaae29",
   "metadata": {},
   "outputs": [],
   "source": [
    "s = [1, 0]  # choose s\n",
    "# the factor of 2 is to get normalized vector\n",
    "new_state = TensorProduct(E(s), sy.eye(2)) * tot_state * 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f87e43e5-1d37-4b43-af74-a8b0b48549ae",
   "metadata": {},
   "source": [
    "Bob first looks at $s_1$, and if it is $1$, then he applies the Pauli $Z$ transform to his part of the state"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "id": "f4c8451f-85a0-49c9-934a-bfeb53d02aa7",
   "metadata": {},
   "outputs": [],
   "source": [
    "if s[0] == 1:\n",
    "    new_state = TensorProduct(sy.eye(4), Z) * new_state"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c1abcae-031c-49b8-a8cd-654d162c0bed",
   "metadata": {},
   "source": [
    "he next looks at $s_2$, and if it is $1$, then he applies the Pauli $X$ transform;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "id": "4842dd46-6939-420e-b0e5-5652736000b6",
   "metadata": {},
   "outputs": [],
   "source": [
    "if s[1] == 1:\n",
    "    new_state = TensorProduct(sy.eye(4), X) * new_state"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94176eca-057e-4199-ba0e-852c3321e676",
   "metadata": {},
   "source": [
    "now Bob's state is guaranteed to be $v$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "id": "a8519d6c-c5a5-41ea-9821-c876fe8e0824",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}0\\\\0\\\\0\\\\0\\\\α\\\\β\\\\0\\\\0\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡0⎤\n",
       "⎢ ⎥\n",
       "⎢0⎥\n",
       "⎢ ⎥\n",
       "⎢0⎥\n",
       "⎢ ⎥\n",
       "⎢0⎥\n",
       "⎢ ⎥\n",
       "⎢α⎥\n",
       "⎢ ⎥\n",
       "⎢β⎥\n",
       "⎢ ⎥\n",
       "⎢0⎥\n",
       "⎢ ⎥\n",
       "⎣0⎦"
      ]
     },
     "execution_count": 114,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_state"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec614f25-18e4-43a2-8b26-f6e4301bfb6f",
   "metadata": {},
   "source": [
    "## Exercise 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d8b07ead-71d8-46d0-8afe-4eade3f2b7ad",
   "metadata": {},
   "source": [
    "### Exercise 2.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "id": "5f04fdbb-c6aa-4819-9531-bc67462dc018",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sympy as sy\n",
    "from sympy.physics.quantum import TensorProduct"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "id": "a238a9ac-0c21-4caf-8a7d-30e26bc16719",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left( \\left[\\begin{matrix}1\\\\0\\\\0\\\\0\\end{matrix}\\right], \\  \\left[\\begin{matrix}0\\\\1\\\\0\\\\0\\end{matrix}\\right], \\  \\left[\\begin{matrix}0\\\\0\\\\1\\\\0\\end{matrix}\\right], \\  \\left[\\begin{matrix}0\\\\0\\\\0\\\\1\\end{matrix}\\right]\\right)$"
      ],
      "text/plain": [
       "⎛⎡1⎤  ⎡0⎤  ⎡0⎤  ⎡0⎤⎞\n",
       "⎜⎢ ⎥  ⎢ ⎥  ⎢ ⎥  ⎢ ⎥⎟\n",
       "⎜⎢0⎥  ⎢1⎥  ⎢0⎥  ⎢0⎥⎟\n",
       "⎜⎢ ⎥, ⎢ ⎥, ⎢ ⎥, ⎢ ⎥⎟\n",
       "⎜⎢0⎥  ⎢0⎥  ⎢1⎥  ⎢0⎥⎟\n",
       "⎜⎢ ⎥  ⎢ ⎥  ⎢ ⎥  ⎢ ⎥⎟\n",
       "⎝⎣0⎦  ⎣0⎦  ⎣0⎦  ⎣1⎦⎠"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "zeroket = sy.Matrix([1, 0])\n",
    "oneket = sy.Matrix([0, 1])\n",
    "zerozeroket = TensorProduct(zeroket, zeroket)\n",
    "zerooneket = TensorProduct(zeroket, oneket)\n",
    "onezeroket = TensorProduct(oneket, zeroket)\n",
    "oneoneket = TensorProduct(oneket, oneket)\n",
    "zerozeroket, zerooneket, onezeroket, oneoneket"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8334e711-24b9-47ae-9f20-d6caccc493c4",
   "metadata": {},
   "source": [
    "CNOT gate\n",
    "- if the first bit is 0, do nothing\n",
    "- if it is 1, flip the second bit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "id": "9b68ff61-b366-4eb5-b051-7996aef3c36d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAHkAAABkCAYAAACisp8MAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAKNElEQVR4Ae1dTY4UNxQeRijLaDSRsk/nBgOcILBnAeEEgRuA2LFD5AaQEwRYZD/kBIS5ARwgUsgoyjIS+T63v1K52nbVdLtsV7ctVbvKP8/vvc/v2a5yVV/78uXL0ZTw7NmzDyj3BPE7X3mknyGdZXzhLfLv+zKGaSj3EWmrYTqvkXfNl54zDTwUlRPtUzfnOG7g/HKK7NenFAKxlyj3CbEX4AGNn3FNoPrhU/9i5PyFJ/8O0u550ksmFZETGBCHtxD8FxyTDGcUZBCkcn/E8R2OKeElGZlS0FcGdV8N05HGpNpALiYn9EGP+jeOhzg29DXUXxRkEDhBBfYYEp3kGoYN+K5BS9b6F/K/x/ECaVt3DF8bNaTNLCet+BxtvBvT3fGIMggw3cNobxmh02WDFsft94jZcejynuAgs95xuKu4sJO55QR9Dp102xxKoyEIMohwgkEXSRCSBNB8CEIniMmcCTinh5jErK1SfZRRTmJzG+1Fh7IgyKhMK74AgSmTramKp4u58BR+jzQyy+FhH0IWOaEvDnHER8OfV3dekG3PoCUns2Lb+m3Enz2caDxm/j6EnHISoxUwexxSnBdkFH6KY+qSKUTbSZ9opadOpQVe5JYT7dEz0pqJmTdsgIxKtGAeowO6l2I4UQDGZun74K5LyEmsONfxjs0bIKOwekSyGXUY942cbzZS9jMhqZwAVxNZYedozQEZhWlJ7A1ce8UsziEy8cI3Fquqej/XzUsPpeQk0GfAjV7YCQ7IyOGdLYbUrvqo12l8LllpmoCtuVjgb0E5hdmDodqGIOteaMplU79N0l31E+y5LHmudj1NzpqUXU50LumO9yKc0IGMQrQmTv05q07tqtXoG5zc1EUvvoFzrsnnarfXVJbTUnISaE7AHJfdgYxMuWoN4sm1gcY5mfuMuJsF4pydi23/lLzBQgQLynluRXZc9vWeHvg4j0EF11fpf2m1fCBxCzEnWox/wDXXe/sUSsgpl+3cVOqDbDKgbBWcReGgT5f8aBbiFREtIScNBQe1wFk23bYZ/oy7ZgIyeCx+dksJDzzII3ZzH43JMu8G8vJ7yB9WhG7yJZA1HqsXLF/Uw5WAz+sZhOmRQJZp85FfC8vWgCxZmHYgr6xczV0vG2ByLww5xzJBlqwEFVB+ixemAc2oyTbOzbh8jBNZMRMvFyZTY9evARmrwZaWrFmYMvzVWuqSNCBj7UCWJStjScI0Xv0akMGa59a0ZHOCOPYc1E+qpdaqAWFpDJi3NYtYsp0U8GnN5Hd6atVoiC/IqF2UvEef8yUCeeUO5BPLpNAP8bxzOoRmW9zqy7a4jlMHw+l+BcjKmxLPEZunelb2D4jv4JA7nVtog+0xWjmduyXRh3CXOO7j4AOKX5W+bzHkK/0SAT0Hg8GWIMuSL01y+0mhgSyb6yOMCsv8lhxhat+y+MDHN/zJTeuBUBa5ackKMnFdt3gLDcBVyzPGas89RDodrA+yTDzGXMsb14AAjOlzSkcYb2liif6YPLFKK5ZAA7o3kYCUl4TTwfqW/JW3+PTEr21RxdNrjpf8drxIthKST/Gw4c/DhN61rDw0NKaS8z+1yeGjD/K/ymjx9hqAUmVFPpesNE3Atm/oCjVTgvyPbVfxFdgYLfrnaIl8BSSfYl/L3Ay58mSc2rTQZslUcjq89UH28NSSttRAqc31XnZLgqzJh3q3l8ElJsJlV/USAR9QZA1QAHs5g24IvEEaxyh+HKbE67KGmRl+boBmFS8RlABZL9XNoNd6SKLDcgJWxUsEJd11PYjsOScN5D0HmOI1kBvIB6CBAxCxWXID+QA0cAAicgnFtSlvjF/sKC/XulwyxG7Qb9sEbwNWsRwBH0uQkzz+RmVzKUd3zf1Id3Gc4dglrFCZX6CZ4w4Wb5zo6za78Jii7hLkJI/E9C5Adp5CpVBAo1GhBmjJex3Yk/dawAnCZb+tSZ6g+Cybzi3A/Iw/v6XBe8lZQy45x4TKbskQnJvOs3y5Hm1doi1OQviRlKwWnVPOqkCG4Nk3naNNvp6S+rvdUb2WkDPGUG5LLrXp/BYUT6vOFUrJ6ZUvN8hcCvnW0XSpDMxPGgAu3XRo41zStnrEssvZa3vjNBvIVtkbDAwS5lhj87+T+K81WUJBOYPyZQMZHAjAmNtMPjnKCbDVchE5gwgjIyfIMT6Up31fut7XOKucOUH2jcUCUb0/99ip9lPG1cnZBznmRndWAtym6PtcstI0Adu5vVIEapSzD7IUPad+tt10PidPc9CuSs4+yHMIO6RZ1abzIXMJr6uRk56FIMuNalxMKKtLCg1Wtenc5S7dVQVyOliWeEBRzabzdLB6KVUjJ0HmbDDHeGw0YScmtezy8KKTIrEmOfvuOhvQKZTYaEQ1ICzNUEyQta7LukCPstgyd9WAxmSDbbPkXdVZZ/2gJQv9OtluXF1FA/LKzZKvorWFlZUlmzuIdNcfrQDNkheGZITdlc0z2BJk3S9WRqRuy1qIBmSwnSULZJn4QuRobEY0IINdg4xFu0A+wrkyI/Vb1gI0IIPtLJk8C+gG8gIQjLHYM1R+dvqSZXXv+gLnBDgLyGg8y+Z6Clg6QNYz8MCnUrm+0C8MZbgdyO/BxD0ygmPWAKG5ub70F93nlpHustQX+tmpGLoPwh2vr7vXVru/frPpSSMAnH1zfVIBJhKDnCW/0H/LsknDNUEg6//91AuUnzquatN5auEqoScMXUtmzwODxofjXD59Dp6r2nQ+h4AlaQI7DhPEr5t0kR9ZMs/Nv54gJhDJg2VgjO7pWIGWH9WAsOusmKX7IJ/b6t3/7kbJXT1TAJppfaA6e2IL22vgga3q/FNPBzIsjegTAM6ySwU9PSnV/tLbNZYMLOWVjTwdyFa614xRSIO3TU4SaXOCj5isfB821/vkmz3NYkZP6ADMhocgc9HOILNfXyX4BRNy0z6XrLRuAZ+gyUMjofHYcdVUggMygJDL5np2jkD6Kw9hWbIzYfCUa0lhDdAwOasetWSSeI7jBIXVM5iWKtBT+G648E4bv+sha0/V3kHQgd44vPLwfi/csWRqBBX0Lm/ybbOgfRCb66nHXtBkUt6ql5Xs9KmlRAPdCNc3UtYJBPoxQKFFp7YuWm0VX3QPyJ4kGXrT/EYecZYv9BMjMMwV0dsQViGQ2SMe42APSfpRFctIci8BPqsKkJO3cHMEzZ+COG24a3JlgWAlY805OG1tbK0BGuIrYBZcmXhBZnOoRJfNivL3TG6hIg0AI3pbuuugFZPdIMjMRJA1r9aX7bcWDQBggsvNF49wHp03RUFGZa65OCN+iaOFujTATQnvgJF32dRnNQoyC4IIJ0krxBrg+/XbeQENAAvO2HlMmtyFZtdD1knsdxB/jSPqGlDuI8oM63N6P4khlOOG8CUMDyXlpGe9PwELg8MkkEGMd6MIEhf0IZA5SQstjYIzP8OF+6NNfm5qPVdF5QQOHIs5Dk++Bfw/XJlEsdSOQY8AAAAASUVORK5CYII=",
      "text/latex": [
       "$\\displaystyle \\left( \\left[\\begin{matrix}0\\\\1\\\\0\\\\0\\end{matrix}\\right], \\  \\left[\\begin{matrix}0\\\\0\\\\0\\\\1\\end{matrix}\\right]\\right)$"
      ],
      "text/plain": [
       "⎛⎡0⎤  ⎡0⎤⎞\n",
       "⎜⎢ ⎥  ⎢ ⎥⎟\n",
       "⎜⎢1⎥  ⎢0⎥⎟\n",
       "⎜⎢ ⎥, ⎢ ⎥⎟\n",
       "⎜⎢0⎥  ⎢0⎥⎟\n",
       "⎜⎢ ⎥  ⎢ ⎥⎟\n",
       "⎝⎣0⎦  ⎣1⎦⎠"
      ]
     },
     "execution_count": 117,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "CNOT = sy.Matrix([[1, 0, 0, 0],\n",
    "                  [0, 1, 0, 0],\n",
    "                  [0, 0, 0, 1],\n",
    "                  [0, 0, 1, 0]])\n",
    "CNOT * zerooneket, CNOT * onezeroket"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2ced8cb-dd01-4e4d-ba91-af55e918bb43",
   "metadata": {},
   "source": [
    "reversed CNOT gate\n",
    "- if the second bit is 0, do nothing\n",
    "- if it is 1, flip the first bit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "id": "20ac6c1b-d650-47ac-9896-5185e8e7e0d6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}1 & 0 & 0 & 0\\\\0 & 0 & 0 & 1\\\\0 & 0 & 1 & 0\\\\0 & 1 & 0 & 0\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡1  0  0  0⎤\n",
       "⎢          ⎥\n",
       "⎢0  0  0  1⎥\n",
       "⎢          ⎥\n",
       "⎢0  0  1  0⎥\n",
       "⎢          ⎥\n",
       "⎣0  1  0  0⎦"
      ]
     },
     "execution_count": 118,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "revCNOT = zerozeroket * zerozeroket.reshape(1, 4)\n",
    "revCNOT += onezeroket * onezeroket.reshape(1, 4)\n",
    "revCNOT += zerooneket * oneoneket.reshape(1, 4)\n",
    "revCNOT += oneoneket * zerooneket.reshape(1, 4)\n",
    "revCNOT"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e7ffd8e1-c79b-4fa4-b85a-bfac32a9856f",
   "metadata": {},
   "source": [
    "matrix for the CNOT—reversed CNOT—CNOT circuit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "id": "477d7609-8b1b-4922-8e93-4c10527f0409",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}1 & 0 & 0 & 0\\\\0 & 0 & 1 & 0\\\\0 & 1 & 0 & 0\\\\0 & 0 & 0 & 1\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡1  0  0  0⎤\n",
       "⎢          ⎥\n",
       "⎢0  0  1  0⎥\n",
       "⎢          ⎥\n",
       "⎢0  1  0  0⎥\n",
       "⎢          ⎥\n",
       "⎣0  0  0  1⎦"
      ]
     },
     "execution_count": 119,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "compos = CNOT * revCNOT * CNOT\n",
    "compos"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04118901-5d28-4ae5-b2d5-1ee74f92dfd8",
   "metadata": {},
   "source": [
    "we see that $\\ket{ij}$ is transformed to $\\ket{ji}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "id": "177096b0-9fd1-4654-a1ac-d5122b3098e1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left( \\left[\\begin{matrix}1\\\\0\\\\0\\\\0\\end{matrix}\\right], \\  \\left[\\begin{matrix}0\\\\0\\\\1\\\\0\\end{matrix}\\right], \\  \\left[\\begin{matrix}0\\\\1\\\\0\\\\0\\end{matrix}\\right], \\  \\left[\\begin{matrix}0\\\\0\\\\0\\\\1\\end{matrix}\\right]\\right)$"
      ],
      "text/plain": [
       "⎛⎡1⎤  ⎡0⎤  ⎡0⎤  ⎡0⎤⎞\n",
       "⎜⎢ ⎥  ⎢ ⎥  ⎢ ⎥  ⎢ ⎥⎟\n",
       "⎜⎢0⎥  ⎢0⎥  ⎢1⎥  ⎢0⎥⎟\n",
       "⎜⎢ ⎥, ⎢ ⎥, ⎢ ⎥, ⎢ ⎥⎟\n",
       "⎜⎢0⎥  ⎢1⎥  ⎢0⎥  ⎢0⎥⎟\n",
       "⎜⎢ ⎥  ⎢ ⎥  ⎢ ⎥  ⎢ ⎥⎟\n",
       "⎝⎣0⎦  ⎣0⎦  ⎣0⎦  ⎣1⎦⎠"
      ]
     },
     "execution_count": 120,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "compos * zerozeroket, compos * zerooneket, \\\n",
    "    compos * onezeroket, compos * oneoneket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "id": "bc9be453-72dc-4b22-a69e-d5534e416145",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}v_{1} w_{1}\\\\v_{1} w_{2}\\\\v_{2} w_{1}\\\\v_{2} w_{2}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡v₁⋅w₁⎤\n",
       "⎢     ⎥\n",
       "⎢v₁⋅w₂⎥\n",
       "⎢     ⎥\n",
       "⎢v₂⋅w₁⎥\n",
       "⎢     ⎥\n",
       "⎣v₂⋅w₂⎦"
      ]
     },
     "execution_count": 121,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v1, v2, w1, w2 = sy.symbols(\"v1 v2 w1 w2\")\n",
    "v = sy.Matrix([v1, v2])\n",
    "w = sy.Matrix([w1, w2])\n",
    "vTw = TensorProduct(v, w)\n",
    "vTw"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e7289277-54aa-40cf-9843-59534696c388",
   "metadata": {},
   "source": [
    "the circuit transdforms $v \\otimes w$ to $w \\otimes v$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "id": "8ba27e32-f1c7-4366-a1f9-1646e3cd2cd0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}v_{1} w_{1}\\\\v_{2} w_{1}\\\\v_{1} w_{2}\\\\v_{2} w_{2}\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡v₁⋅w₁⎤\n",
       "⎢     ⎥\n",
       "⎢v₂⋅w₁⎥\n",
       "⎢     ⎥\n",
       "⎢v₁⋅w₂⎥\n",
       "⎢     ⎥\n",
       "⎣v₂⋅w₂⎦"
      ]
     },
     "execution_count": 122,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "compos*vTw"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "id": "75bc6f49-3b3c-4b63-b151-b5c7cf32eb62",
   "metadata": {},
   "outputs": [],
   "source": [
    "# record this matrix as \"flip\"\n",
    "flip = compos"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0b1291ca-ea1e-4467-91ff-b2afe1020b7d",
   "metadata": {},
   "source": [
    "### Exercise 2.2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "id": "46cbb386-2a33-426c-8079-79ecb6a0c52a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Hadamard matrix\n",
    "H = sy.Matrix([[1, 1],\n",
    "               [1, -1]]) * (1/sy.sqrt(2))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3835c998-ba5e-4165-9769-6039e03bbc25",
   "metadata": {},
   "source": [
    "three-qubit CNOT gate with\n",
    "- first (qu)bit as control\n",
    "- second qubit is passed through\n",
    "- third (qu)bit is target\n",
    "\n",
    "This can be constructed as $(\\mathrm{flip} \\otimes I_2) (I_2 \\otimes \\mathrm{CNOT}) (\\mathrm{flip} \\otimes I_2)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "id": "79bf4a1d-8f4f-426d-8c82-8fd731fd70de",
   "metadata": {},
   "outputs": [],
   "source": [
    "I2 = sy.eye(2)\n",
    "three_qubit_CNOT = TensorProduct(flip, I2) * TensorProduct(I2, CNOT) * \\\n",
    "                     TensorProduct(flip, I2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "id": "1748e78a-683c-41ff-add9-86162a0c9529",
   "metadata": {},
   "outputs": [],
   "source": [
    "circ = TensorProduct(I2, three_qubit_CNOT) * \\\n",
    "       TensorProduct(three_qubit_CNOT, I2) * \\\n",
    "       TensorProduct(sy.eye(4), CNOT * TensorProduct(H, I2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "id": "a793a635-4827-4042-a82e-330297cfd8a0",
   "metadata": {},
   "outputs": [],
   "source": [
    "EPR_state = (TensorProduct(zeroket, zeroket) +\n",
    "             TensorProduct(oneket, oneket)) * (1/sy.sqrt(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "id": "3233e335-1996-4e66-833e-4e4803450afb",
   "metadata": {},
   "outputs": [],
   "source": [
    "def eq_check(i, j):\n",
    "    qubit1 = zeroket if i == 0 else oneket\n",
    "    qubit2 = zeroket if j == 0 else oneket\n",
    "    input_state = TensorProduct(qubit1, TensorProduct(qubit2, zerozeroket))\n",
    "    circ_effect = circ * input_state\n",
    "    EPR_at_34 = TensorProduct(sy.eye(4), EPR_state)\n",
    "    test_34_with_EPR = EPR_at_34.T * circ_effect\n",
    "    return test_34_with_EPR"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "id": "0c98543e-18a0-482b-9285-4bca55c5f9b2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABoAAABkCAYAAACYYiB/AAAACXBIWXMAAA7EAAAOxAGVKw4bAAACvUlEQVRoBe1a221UQQzdIL5RRCQKWDrgUQFLB0AHQAn53P0NHYQWkg6ggyjpIBSARBRRAefczLnrO5mH97IfEHmkK3vssX3njNfrneRgvV6/WCwWl3hK43yz2bwvKXIZ1l1DtszlnEN38NgovoDnYjt+2EmHPyno30L2jnIb6BSRd3E88QvbrxMBJpBRdC8Qhc0BQ731Lyx8jucEMtfLPWp6Nko45DlegB7jIczHeL6BL56LMR1YVyA4+4TVh6DncgD+Fjznp5K1qCsQHDDzrgqOLiBbIehhQTcReQOtYHUzsbyb6Hyob45uIM/bIsLTZhQou4GME55JbewNuloAyY/E1KhnR6WzkT9Bxs9Vc3QDpTSmkxI8kikpqsG6gZLld9BlwYt2RH1zeAOdwcurgqeXkF2ZXReW3IlcgeCIBfMGdCiQNAVP2D7g+ch5b9jq3VvLt2cRfQ3Kwyd9g3mpYkA1He5AcHgL089Tc//MBZ3fXX1lBKpj09EEdB2A6uqAro5NR+MuQfSDMhQN5AioN+uigRwhE+OBTg0Iv/hqQ91QTe/qVKvGRuFqIJ8kA1FjP7B/00A+k7MudKlX4PoSPJK5GsjfKaqoXsLSuQ3kTznp7igtjAZSiI3UXb2jgRwxS4w363K7necRaGfIZEDoWKf4u6dVPLV+V8rSNfymYqAlHl4c6XsH7N7GCp6GS6mHlwzuEkQwo4G0KeVNhmggLWoD74FOH+T/p4G8t81M0KqB2m3cQGagbafRQG6xSJy7ekcDmWPnKUG5zax5BJoFG40Cun8fOncJ4laigbQH6k3vaCAtagPvgU4tVTSQE/i60KVegUa6bbQOJHPdQFrDGj/3BnL0191RWhkN5AiZGHf1jgZSkIl6s07rZ9OHF8hm3TUyK4dmL/8xSKcMpBvIPAjn3RpmjPSnUyPasn8AXZ4WsbjyHqgAAAAASUVORK5CYII=",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}0\\\\0\\\\0\\\\0\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡0⎤\n",
       "⎢ ⎥\n",
       "⎢0⎥\n",
       "⎢ ⎥\n",
       "⎢0⎥\n",
       "⎢ ⎥\n",
       "⎣0⎦"
      ]
     },
     "execution_count": 129,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "eq_check(1, 0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "072b0fec-1d99-4d16-9fdd-9f0e92d7c6eb",
   "metadata": {},
   "source": [
    "### Exercise 2.3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "id": "8b4c2af0-7e22-48f5-8502-c7214b47f223",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Pauli matrices\n",
    "X = sy.Matrix([[0, 1],\n",
    "               [1, 0]])\n",
    "Y = sy.Matrix([[0, -sy.I],\n",
    "               [sy.I, 0]])\n",
    "Z = sy.Matrix([[1, 0],\n",
    "               [0, -1]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "id": "9a260f14-3206-4444-a7b9-4763699eee2b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}0\\\\\\frac{\\sqrt{2}}{2}\\\\\\frac{\\sqrt{2}}{2}\\\\0\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡0 ⎤\n",
       "⎢  ⎥\n",
       "⎢√2⎥\n",
       "⎢──⎥\n",
       "⎢2 ⎥\n",
       "⎢  ⎥\n",
       "⎢√2⎥\n",
       "⎢──⎥\n",
       "⎢2 ⎥\n",
       "⎢  ⎥\n",
       "⎣0 ⎦"
      ]
     },
     "execution_count": 131,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w10 = TensorProduct(X, I2) * EPR_state\n",
    "w10"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "47049395-944e-4693-9036-a862edea30d0",
   "metadata": {},
   "source": [
    "## Libraries"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "934fdb4f-00de-4839-a828-b534cb9a1205",
   "metadata": {},
   "source": [
    "### SymPy"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1470b3be-5b8b-4f42-a8d4-4bd0be53a62b",
   "metadata": {},
   "source": [
    "[SymPy](https://www.sympy.org/en/index.html) is a library for symbolic mathematics.\n",
    "This is useful when we want to understand algebraic manipulations involved in (quantum) algorithms, like using variables to represent the components of state vectors."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "id": "5b3e6427-b047-4acd-a0c2-a8b2fff065e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%script false --no-raise-error # safeguard in case this is unintended - remove this line to install sympy\n",
    "%pip install sympy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 133,
   "id": "88fea616-7cb1-4f9b-bd81-c0d639b58f7d",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sympy as sy"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0b4f5698-6a37-4675-ab33-70962412563a",
   "metadata": {},
   "source": [
    "Vectors can be represented as \"matrices\" constructed from 1-dimensional arrays, while matrices are constructed from 2-dimensional arrays"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 134,
   "id": "7b8ecb24-40ef-4f96-b4e2-4156a908e7bd",
   "metadata": {},
   "outputs": [],
   "source": [
    "vec = sy.Matrix([1, 0])  # |0⟩\n",
    "Xmat = sy.Matrix([[0, 1],\n",
    "                  [1, 0]])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7adba28b-78a0-47de-8e5e-8d8f7200ecef",
   "metadata": {},
   "source": [
    "The matrix product can be represented by the usual `*` operator.\n",
    "This also takes care of converting 1-dim arrays to 2-dim column vectors."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "id": "ce98a4c7-6545-4d9b-bed5-cf533d42ff72",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABYAAAAzCAYAAACT1fi+AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB5ElEQVRYCe1Y7VHCQBANDgUw2kHsQLQCUwLYgdKB/Ez+YgdqCbED6YCRDrQDkBJ8L2TPkNv7gBn+3c7c7GZv92XzuNtcGJRlOcoUqapqp7gtF+LU/AtEfmH89sbCQnA76l4useoBKv6GMcOdl+7c+BngPCF6yorPIsMYVFQh1GwQf42xgO/HlxusGAD8DVbQc4wX2HOMT9j5ycBIJl8j6A8Bgc3VwutX8Wk6VPEUSWslcQVfgZuoS43xIeACMVsG9kT45bwqTmBfNR2ky459YDqBESVJvh14MhUHVSgXV4qvcfkq1rgVHHkarmtVnMDtsmKS9rjikx/RAncCt5HsH7mV9c+/s7+EgNm5bhXgMXzrzlNZIV5gJL4hYws9kUzYpOEB41F8mo5pQqyOTecOmj8W9T2utR2Jqb0EgQGwQ+hMEmK1l4pYEC0uARtWEhWJCsOAMYJbWiKxtW9gs9uN220uU6r2AgOAnewdg28Tts8cI0pCwGxAPFtkuMkzFKuOkrRBDE2JikSFYcAYx6wKOVnKgdCAaIZ3SzMBW5mNh1LsVVbDx8MgP3B4UlIlBrjpFWq2x3kMFR4YeyoBG07ORoWsihxLh68hI7jm2yMo/TwkNDhSMb+Lu3+GyNd+EBgBXOdW7h+r9njPVpljOAAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}0\\\\1\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡0⎤\n",
       "⎢ ⎥\n",
       "⎣1⎦"
      ]
     },
     "execution_count": 135,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Xmat * vec  # expect |1⟩"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd70cf90-1162-4ee4-96c3-e2546f20cd2f",
   "metadata": {},
   "source": [
    "To create formal variables, use `symbols` command."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 136,
   "id": "2fb544be-6c40-4540-9bd2-2a7c34c5ecbb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAADYAAAAzCAYAAADciPtuAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADi0lEQVRoBe2a71HcMBDFjwwFkEkHlw7yp4JAB5AOEjoIH+++MaSDQAXk6CB0EEIHoYOQ6yB5P43kkXWSrFxsxrrxzgjJ8ml3n95qbe+wt1gsDmYRWS6X68j06KbkZ9T/Z/L0h9rvoF2MDkHaoVXgO1hWe2LspwanQn6bXlvPHeH4KG9PYGwnZX/sqOwZItzeqD3q+mWJz6NnTEDWakcC86BWfFxGD8xj55XG37zr7LAKYGLs0KLYOcZMKBKWWZq8m0XJQwrnWsOzjTj/pXajdqz5z+qfQmDsXvY+WWNv1V/rGj+i0hmKWoxSHuJnGtMA80XtQuPoU1/3ehNrg/PF5l5a+x80XmnMXFSywKxSUi2AYMsJ4wfNFYeGW7hF787XO2fP9tg+TunLAtMiwu9Aii4DBRhLhkHw2/+95HwRhuEmEi0vUsq7gL3XwlYmkgEUEgLFqTdlvHCeTQx9cCx+T+lIArMAABECAOxM91vGUgZ6mGcTQwAnVm/ShyQwzyH/bDFtQoOBwJEZMTy0ND7IHpvN5vLivk4ZTgKzi9iRxnHNcVjJUHdW4ZHmGqN2ru+Os8x7ohOS2VfZDc+9u2/6/dbV5gWUX0kJzw8O6rUajJHqmSPtDy2kdnzg5Re2SPNZUDiUBSYFUO3imd87ic25e732GR+ydpKhmF1Vwc0JWAUktVycGGttRwUXE2MVkNRycWKstR0VXOwsY9lXqrESo9csXsSv1OZqvBCfhr7WCuxeQF4L0B/14feiwVhtKArUoWUp+rFZLTCB4vMpWVCqGRiMRdmCyX86Y6KfqhUFU4RvtTvNEe+DimyQJPyCLYBIIOcpw0XArGIOKfVFU3ZTz9czH5yExGAiOzBDOYBkYcoQ6l3CSDJWGoooupFCv5ZIQcUZ0LB/kT1TCpDmWME2VmtsnOhkTMphhlBo0a75542W4QZbF2xLGIOZWwHhTD21GNu+UcsiG52Nliwwq4RwyCrxDfc1ztgG7Ez3k+eL+13AHEuuZ00jUs7BHlrCuiXJymRi2U8WbLPArMfU8DbKbVJK/D/a3/TeST+bCSuEnRGAaFBUsC1JHpSSKZAChP8JQQjPc2vcTAz0hw3dqmDbCQyHBeBsIMezau3GbUSLFsXmWrpKQrG1oJaLCVgtTDk/J8bcTtTSu6w4VwYihTdiM1JzPdZB6Lf8NDhcKPKi6/8zJs+sWoRPmg3f/wIsKSOjgzd5KgAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}a & b\\\\c & d\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡a  b⎤\n",
       "⎢    ⎥\n",
       "⎣c  d⎦"
      ]
     },
     "execution_count": 136,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x1, x2, x3, x4 = sy.symbols('a b c d')\n",
    "test_mat = sy.Matrix([[x1, x2],\n",
    "                      [x3, x4]])\n",
    "test_mat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 137,
   "id": "3048eb80-1cf2-4df3-ab36-894b812003f3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABcAAAAzCAYAAAB8F5OAAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACFElEQVRYCe2Y7U3DMBCGW8QARWyQEZih3YAyAmxAf7b/qrIBMAFqN4ARChvQDfgYgec1cRVfbCepVCSknHSxc/E9vlwujtvhfD4fDSKyWCy+I+aoibFRxgmjX9Evo6soJW1cG3/x1kMif6dzw+wvad9uV2Bd4zFV5EeTHh5N7f9Ny2n0foyR0iowqfZ36Ae6QS+x39EmpTEtAMZ460Wb0ZcKeI+u6EffTK45ycJLZ719gipqL+rvsGWXiCwcgFIxAvLgqWWru1FqstIEv8I7WBbKuymwP2fJXEzCS4hyaiGacMD1YFLZrCThlYHVXMs8Qd/UYQJVjO4iKkk4TnpYim7vLBjnF+gWlUyw2cl/r3BsqvMpYx4B3NKeo0+oIlcZyqaSTEoWDkDRawIrMZsdk36gtZEHGJI5P4BVc+nhtZTI0KelT0s0A1FjXy1/n5bsem7DYX3XbkCbIonW+i0298lzFnNoBQdQ4KcPtfYvbktBq6+QPhr6MkWlbbUIvPHgkqRdgN0ZBJM0Rl5GqMiXVU/sZ9XzWL9N5IrwBZhy3EmycIAjaNLs7admbIL7aH0bcJh8HBjMSRZejtUmtLaVAKyy/DS84LTNA9VvVG2CBNNvVolStcQWvSM3gkMjXAOBzLxDl7ZNWrrwgrE9PEiHPzlqWny1FFSEymsvTWW2H0jH+mJyLB+5ls/qHzqq6S5i/8xx/j+uFZXAI1ERLAAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}a\\\\c\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡a⎤\n",
       "⎢ ⎥\n",
       "⎣c⎦"
      ]
     },
     "execution_count": 137,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_mat * vec  # product with |0⟩ would gives the first column"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "80bb4a91-f8bf-4c87-9c27-92ebe1af8628",
   "metadata": {},
   "source": [
    "The Kronecker product is `sympy.physics.quantum.TensorProduct`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 138,
   "id": "5a37466e-2f91-4ca6-84a5-af40b32b44c5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}0 & 0 & 1 & 0\\\\0 & 0 & 0 & 1\\\\1 & 0 & 0 & 0\\\\0 & 1 & 0 & 0\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡0  0  1  0⎤\n",
       "⎢          ⎥\n",
       "⎢0  0  0  1⎥\n",
       "⎢          ⎥\n",
       "⎢1  0  0  0⎥\n",
       "⎢          ⎥\n",
       "⎣0  1  0  0⎦"
      ]
     },
     "execution_count": 138,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy.physics.quantum import TensorProduct\n",
    "# block matrix whose blocks are I_2 or the 0 matrix\n",
    "TensorProduct(Xmat, sy.eye(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 139,
   "id": "fa4c7094-34f9-49ce-83ee-1545ccc619d6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}0 & 1 & 0 & 0\\\\1 & 0 & 0 & 0\\\\0 & 0 & 0 & 1\\\\0 & 0 & 1 & 0\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡0  1  0  0⎤\n",
       "⎢          ⎥\n",
       "⎢1  0  0  0⎥\n",
       "⎢          ⎥\n",
       "⎢0  0  0  1⎥\n",
       "⎢          ⎥\n",
       "⎣0  0  1  0⎦"
      ]
     },
     "execution_count": 139,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# block matrix whose blocks are X or the 0 matrix\n",
    "TensorProduct(sy.eye(2), Xmat)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d8e84ced-5e5b-407b-aa92-c370d8598abd",
   "metadata": {},
   "source": [
    "### NumPy"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b3ed3c09-44d8-4873-ba09-da965f88eb5a",
   "metadata": {},
   "source": [
    "[NumPy](https://numpy.org/doc/stable/index.html) is an extensive scientific computing library.\n",
    "This is useful when we want to simulate algorithms involving some numerics, like probabilistic algorithms."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 140,
   "id": "a8dd9557-8b4c-4e8f-9a9f-722e8d5f11fe",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0445d64f-1a7a-402b-b8ca-d9d5dc7158b7",
   "metadata": {},
   "source": [
    "Vectors can be represented by 1-dimensional arrays, while matrices are represented by 2-dimensional arrays."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 141,
   "id": "42602988-0649-4be6-a3eb-0c2c8878e08a",
   "metadata": {},
   "outputs": [],
   "source": [
    "vec = np.array([1, 0])  # |0⟩\n",
    "Xmat = np.array([[0, 1],\n",
    "                 [1, 0]])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5fb27e79-4f00-4a04-948f-e8cbbf22cd81",
   "metadata": {},
   "source": [
    "The matrix product can be represented by the `@` infix operator.\n",
    "This also takes care of converting 1-dim arrays to 2-dim column vectors."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "id": "a92de1c2-9c19-4be5-9a57-425b4d4a5c4a",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1])"
      ]
     },
     "execution_count": 142,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Xmat @ vec  # expect |1⟩"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b4805282-dd7a-4184-a037-e8dfb6c7ca37",
   "metadata": {},
   "source": [
    "The Kronecker product is `np.kron`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 143,
   "id": "d19b8f5b-3301-477d-b239-f6465124b4bc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0., 0., 1., 0.],\n",
       "       [0., 0., 0., 1.],\n",
       "       [1., 0., 0., 0.],\n",
       "       [0., 1., 0., 0.]])"
      ]
     },
     "execution_count": 143,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# block matrix whose blocks are I_2 or the 0 matrix\n",
    "np.kron(Xmat, np.identity(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 144,
   "id": "7b64c531-6f1d-4f1e-b7c5-09f7c13312ef",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0., 1., 0., 0.],\n",
       "       [1., 0., 0., 0.],\n",
       "       [0., 0., 0., 1.],\n",
       "       [0., 0., 1., 0.]])"
      ]
     },
     "execution_count": 144,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# block matrix whose blocks are X or the 0 matrix\n",
    "np.kron(np.identity(2), Xmat)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94307a98-15a4-4a14-881d-bd6f4fb579ca",
   "metadata": {},
   "source": [
    "#### SciPy"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38c2ca7b-366f-4c09-9e2f-2343854874fc",
   "metadata": {},
   "source": [
    "[SciPy](https://scipy.org/) is a science computing library providing additional tools beyond NumPy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "id": "f155e4c5-263d-4450-aa31-60f1d9a5830a",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%script false --no-raise-error # safeguard in case this is unintended - remove this line to install scipy\n",
    "%pip install scipy"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "67da9b3c-0574-4dfa-b36a-967efc4abd2c",
   "metadata": {},
   "source": [
    "### Qiskit"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc8b5753-9c5d-4628-a71e-4a97dc2db735",
   "metadata": {},
   "source": [
    "[Qiskit](https://quantum.cloud.ibm.com/docs/en/guides/quick-start) is a quantum computing library developed by IBM.\n",
    "It takes a bit of effort to set up, but you can get a good feeling of how a quantum computing service looks like.\n",
    "Besides the official documentation, the [tutorial](https://colab.research.google.com/github/Qiskit/qiskit-tutorials/blob/master/tutorials/circuits/01_circuit_basics.ipynb) hosted at google is also a good entry point."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96d8f586-afec-45b8-949e-1eca078deb79",
   "metadata": {},
   "source": [
    "Edit and evaluate the next four cells to install the library."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "id": "9ffc332e-546e-4d6d-a533-eb35810b0adf",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%script false --no-raise-error # safeguard in case this is unintended - remove this line to install qiskit\n",
    "%pip install qiskit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "id": "f42618ea-e006-460c-b536-51c116c5bacf",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%script false --no-raise-error # safeguard in case this is unintended - remove this line to install qiskit\n",
    "%pip install qiskit-ibm-runtime"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 148,
   "id": "ea50cfa1-aff3-40f3-ad86-665c40987156",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%script false --no-raise-error # safeguard in case this is unintended - remove this line to install qiskit\n",
    "%pip install pylatexenc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 149,
   "id": "bf48a8e5-98d1-4c49-bde5-2bff34ac5519",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%script false --no-raise-error # safeguard in case this is unintended - remove this line to install qiskit\n",
    "%pip install matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 150,
   "id": "5261e017-dcbb-4129-82d3-9b2fb13fba9e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import qiskit as qs"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d266b0e-c3fa-49de-ae67-8a73043afe6a",
   "metadata": {},
   "source": [
    "Construct a quantum circuit with one qubit input.\n",
    "It applies the Hadamard gate to the input qubit, then perform measurement with respect to the computational basis.\n",
    "The result of measurement is recorded in the \"classical register\" bit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "id": "d4c80653-3380-421a-9239-5272d3e0f935",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 269.064x200.667 with 1 Axes>"
      ]
     },
     "execution_count": 151,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# quantum circuit with one qubit and one classical bit\n",
    "circ = qs.QuantumCircuit(1, 1)\n",
    "circ.h(0)  # add the Hadamard gate to the qubit wire\n",
    "# add measurement apparatus, telling it to record the result on the 0-th\n",
    "# classical bit\n",
    "circ.measure(0, 0)\n",
    "# draw the circuit (cregbundle option to suppress unwanted labels)\n",
    "circ.draw(\"mpl\", cregbundle=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d7f83330-6596-4fa8-982a-4838905666fc",
   "metadata": {},
   "source": [
    "To run the circuit (in a simulation), we need the following code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 152,
   "id": "d1844a7a-4948-4e56-954a-4699db6880fb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'1': 517, '0': 507}"
      ]
     },
     "execution_count": 152,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from qiskit.providers.basic_provider import BasicProvider\n",
    "from qiskit.compiler import transpile\n",
    "simulator = BasicProvider().get_backend()\n",
    "circ_tr = transpile(circ, simulator)\n",
    "job = simulator.run(circ_tr)\n",
    "result = job.result()\n",
    "result.get_counts(circ)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "19c52167-594c-45ce-aa43-6f20508f82b1",
   "metadata": {},
   "source": [
    "The default input qubit state is $\\ket{0}$.\n",
    "So the above circuit first turns $\\ket{0}$ to $\\ket{+}$ by the Hadamard gate.\n",
    "If we measure this state in the computational basis, we expect the case 0 and the case 1 with both 50% probability."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22f13a0f-268e-4e51-8c54-735e78055e40",
   "metadata": {},
   "source": [
    "for quantum circuits without measurements, it is also possible to get its effect as a unitary get acting on the input vector (by deault $\\ket{0\\ldots0}$) as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 153,
   "id": "862c02e8-c7d1-4d3e-b8d7-08166cdba461",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$$\\frac{\\sqrt{2}}{2} |0\\rangle+\\frac{\\sqrt{2}}{2} |1\\rangle$$"
      ],
      "text/plain": [
       "<IPython.core.display.Latex object>"
      ]
     },
     "execution_count": 153,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from qiskit.quantum_info import Statevector\n",
    "\n",
    "circ = qs.QuantumCircuit(1)  # quantum circuit with one qubit\n",
    "circ.h(0)  # add the Hadamard gate to the qubit wire\n",
    "\n",
    "state = Statevector.from_circuit(circ)\n",
    "# draw using latex\n",
    "state.draw('latex')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6199eeb4-d46d-4703-9a47-63b79e7c6715",
   "metadata": {},
   "source": [
    "If we want a different initial state $v$ for the algorithm, we can either add some gates to transform the $\\ket{0}$ state into $v$, or use the `initialize` command of the circuit."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e1d57b5-f300-4a7f-873b-269953e9cbc2",
   "metadata": {},
   "source": [
    "Suppose we want to run the above circuit with initial state $\\ket{+}$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 154,
   "id": "c1485095-7859-4088-8744-231d17b3de61",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 405.357x200.667 with 1 Axes>"
      ]
     },
     "execution_count": 154,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circ = qs.QuantumCircuit(1, 1)  # same setup\n",
    "circ.h(0)  # to turn the default state |0⟩ into |+⟩\n",
    "# the rest is the same\n",
    "circ.h(0)\n",
    "circ.measure(0, 0)\n",
    "circ.draw(\"mpl\", initial_state=True, cregbundle=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 155,
   "id": "fca31b1c-ba48-4b3b-a9b9-453801d32300",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'0': 1024}"
      ]
     },
     "execution_count": 155,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# then run the circuit\n",
    "circ_tr = transpile(circ, simulator)\n",
    "job = simulator.run(circ_tr)\n",
    "result = job.result()\n",
    "result.get_counts(circ)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0df6d4d0-9aff-4c17-b5e1-c4f9403a93d8",
   "metadata": {},
   "source": [
    "If we apply the Hadamard gate to $\\ket{+}$, we get $\\ket{0}$.\n",
    "So the measurement would be the case 0 for 100% of times."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 156,
   "id": "37677202-922a-4ea9-b13a-319d3c580368",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 352.675x200.667 with 1 Axes>"
      ]
     },
     "execution_count": 156,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circ = qs.QuantumCircuit(1, 1)  # same setup\n",
    "circ.initialize(\"+\", [0])  # prepare the |+⟩ state on the 0-th qubit input\n",
    "# the rest is the same\n",
    "circ.h(0)\n",
    "circ.measure(0, 0)\n",
    "circ.draw(\"mpl\", cregbundle=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 157,
   "id": "639e6531-c0be-4e97-bb33-7e4adbc61c7b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'0': 1024}"
      ]
     },
     "execution_count": 157,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# then run the circuit\n",
    "circ_tr = transpile(circ, simulator)\n",
    "job = simulator.run(circ_tr)\n",
    "result = job.result()\n",
    "result.get_counts(circ)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "99548f5c-9b56-4332-9f02-a03cb72ce673",
   "metadata": {},
   "source": [
    "Qiskit comes with a collection of standard gates that you can add to the circuit by `circ.cx(control-qubit-index,target-qubit-index)` for the CNOT gate, `circ.y(qubit-index)` for the Pauli Y gate, etc.\n",
    "See the [document](https://quantum.cloud.ibm.com/docs/en/api/qiskit/qiskit.circuit.QuantumCircuit) for details."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5d8311ff-2232-4839-8a3e-9e6ebeae5411",
   "metadata": {},
   "source": [
    "To achieve a more flexible algorithm, you want to supply a unitary matrix representing the desired quantum gate.\n",
    "This can be added to the circuit by the `unitary()` as described in the [document](https://quantum.cloud.ibm.com/docs/en/api/qiskit/qiskit.circuit.QuantumCircuit#qiskit.circuit.QuantumCircuit.unitary)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 158,
   "id": "4e8fea1d-ac9c-417b-8389-ea6aa379faa9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 0, 0, 0],\n",
       "       [0, 1, 0, 0],\n",
       "       [0, 0, 0, 1],\n",
       "       [0, 0, 1, 0]])"
      ]
     },
     "execution_count": 158,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# construct the CNOT by hand\n",
    "# computational basis\n",
    "zeroket = np.array([1, 0])\n",
    "oneket = np.array([0, 1])\n",
    "zerozeroket = np.kron(zeroket, zeroket)\n",
    "zerooneket = np.kron(zeroket, oneket)\n",
    "onezeroket = np.kron(oneket, zeroket)\n",
    "oneoneket = np.kron(oneket, oneket)\n",
    "# CNOT trasforms 00 -> 00, 01 -> 01, 10 -> 11, 11 -> 10\n",
    "# use atleast_2d to force 2d-array interpretation\n",
    "CNOT_mat = np.atleast_2d(zerozeroket).T @ np.atleast_2d(zerozeroket)\n",
    "CNOT_mat += np.atleast_2d(zerooneket).T @ np.atleast_2d(zerooneket)\n",
    "CNOT_mat += np.atleast_2d(onezeroket).T @ np.atleast_2d(oneoneket)\n",
    "CNOT_mat += np.atleast_2d(oneoneket).T @ np.atleast_2d(onezeroket)\n",
    "CNOT_mat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 159,
   "id": "cd6146ad-df2b-46f0-bac7-fdf298092a36",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 538.128x367.889 with 1 Axes>"
      ]
     },
     "execution_count": 159,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circ = qs.QuantumCircuit(2, 2)  # two qubits, two classical registers\n",
    "# prepare the |11⟩ state on the 0-th and the 1-st qubits\n",
    "circ.initialize(\"11\", [0, 1])\n",
    "circ.unitary(CNOT_mat, [0, 1], label=\"CNOT\")\n",
    "circ.measure(0, 0)\n",
    "circ.measure(1, 1)\n",
    "circ.draw(\"mpl\", cregbundle=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 160,
   "id": "5587a2c5-e8af-4d62-8488-553858d7f421",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'10': 1024}"
      ]
     },
     "execution_count": 160,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circ_tr = transpile(circ, simulator)\n",
    "job = simulator.run(circ_tr)\n",
    "result = job.result()\n",
    "result.get_counts(circ)  # expect 10"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2fae22c-8fc3-4df5-ab62-01aed48634d0",
   "metadata": {},
   "source": [
    "[Qiskit bit convention](https://quantum.cloud.ibm.com/docs/en/guides/bit-ordering)\n",
    "\n",
    "Integers:\n",
    "When interpreting bits as a number, bit $0$ is the least significant bit, and bit $n−1$ the most significant. This is helpful when coding because each bit has the value $2^\\text{label}$ (label being the qubit's index in QuantumCircuit.qubits).\n",
    "\n",
    "Strings:\n",
    "When displaying or interpreting a list of bits (or qubits) as a string, bit $n−1$ is the leftmost bit, and bit $0$ is the rightmost bit. This is because we usually write numbers with the most significant digit on the left, and in Qiskit, bit $n−1$ is interpreted as the most significant bit.\n",
    "This occasionally causes confusion when interpreting a string of bits, as you might expect the leftmost bit to be bit $0$, whereas it usually represents bit $n−1$."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9393f7b1-57c9-4062-83ff-21592daf8b40",
   "metadata": {},
   "source": [
    "This means that the two-qubit states are represented by $v_1 \\otimes v_0$, while $v_0$ still goes to the top wire in the circuit diagram."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d17d6810-32eb-4f46-8990-6b429d1d7738",
   "metadata": {},
   "source": [
    "Let's check this with the effect of CNOT gate."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 161,
   "id": "6543bd48-d350-4ce6-83ce-199643c052b9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 203.683x200.667 with 1 Axes>"
      ]
     },
     "execution_count": 161,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circ = qs.QuantumCircuit(2)  # two qubits\n",
    "circ.cx(0, 1)\n",
    "circ.draw(\"mpl\", cregbundle=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d19167af-0ec5-463c-b256-79185c4971ab",
   "metadata": {},
   "source": [
    "If we give the input $|ij\\rangle = |i\\rangle \\otimes |j\\rangle$ to this circuit, the state $|j\\rangle$ will be used as the control."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 162,
   "id": "ea6f2904-2e50-4a33-a37d-8eeb531a8fe1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 454.517x367.889 with 1 Axes>"
      ]
     },
     "execution_count": 162,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circ = qs.QuantumCircuit(2, 2)  # two qubits, two classical registers\n",
    "# transform |00⟩ to |10⟩\n",
    "circ.x(1)\n",
    "# we could also use the following\n",
    "# circ.initialize(\"10\",[0,1])\n",
    "# prepare the |10⟩ state on the 0-th and the 1-st qubits\n",
    "circ.cx(0, 1)\n",
    "circ.measure(0, 0)\n",
    "circ.measure(1, 1)\n",
    "circ.draw(\"mpl\", cregbundle=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 163,
   "id": "babb6cc4-641c-429f-8933-8ac8b8233691",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'10': 1024}"
      ]
     },
     "execution_count": 163,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circ_tr = transpile(circ, simulator)\n",
    "job = simulator.run(circ_tr)\n",
    "result = job.result()\n",
    "result.get_counts(circ)\n",
    "# expect 10 because 0 for the control bit wouldn't change the target bit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 164,
   "id": "e6a25974-0b48-49fe-8c04-3824b22a5ee5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXEAAAEvCAYAAACzA/EjAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAJAtJREFUeJzt3Qd0lGXaPvArmfQGJEBCCoSS0EIvCiIdBAEpAYRFYV0V94hl92PFwvqhq+iKrq5lPaJ/C/tXkP3AAqigggakK0iH0EwgJLRgekib79xPvhnTmQmZzDzvXL9zcob3nfYyyVzzzP2U18NsNptBRERa8nT2ARARUf0xxImINMYQJyLSGEOciEhjDHEiIo0xxImINMYQJyLSGEOciEhjDHEiIo0xxImINMYQJyLSGEOciEhjDHEiIo0xxImINMYQJyLSGEOciEhjDHEiIo0xxImINMYQJyLSGEOciEhjDHEiIo0xxImINMYQJyLSGEOciEhjDHEiIo0xxImINMYQJyLSGEOciEhjDHEiIo0xxImINMYQJyLSGEOciEhjDHEiIo0xxImINMYQJyLSGEOciEhjDHEiIo15OfsAqDKz2YySgqvavixe/r7w8PBw9mEY4u+gtLQUOjGZTPzdOwFD3MVIgH/U/g7oatbJD+Ed4Ofsw9CeBPjq1auhk8TERHh5MVIaG8spREQaY4gTEWmMIU5EpDGGOBGRxhjiREQaY4gTEWmMIU5EpDGGOBGRxhjiREQaY4gTEWmMIU5ENikrK+Mr5YK40AGRwWVnZ+PUqVNITU1FQUGB2ufj44PIyEi0a9cOzZs3v+bCVXl5eXj++ecxatQoDBkypJGOnGzBECcyoF9//RXfffcdvv/+e5w/f77O24aEhGDgwIEqoKOiomoM8MWLF6sPgpMnT6rVCgcNGuTAoyd7GL6ccunSJSxYsAAdOnSAn58fYmJi8PDDD6s/zLvvvlu1QN544w1nHyY1gpKSMlz+tRB5+cVqqVcjys3NxVtvvYV58+Zh5cqV1wxwS0t9/fr1mD9/Pp577jmcO3euxgAXwcHBaNOmjUP/D2QfQ7fEf/75Z4wdOxYZGRkIDAxEly5d1B/oa6+9ploUmZmZ6nY9e/aENjw80OXeceh45ygERbdA4eVsnF67DT8vWan1OuSOUlZmxsad5/DmyiNY832q2hbtooPxx2md8IfJ8Qhraoylc3/88Ue88847yMrKsu6TRkp8fDzat2+Ptm3bokmTJmqfhHNKSooK58OHD6O4uFjdfv/+/Xj00Udx++23q7KJlFAsAS4t9ieffFI1hMh1eJgN2iSRFnivXr1w9uxZ1cJYtGiRakWIJUuWqD9UWftY1m2Wr57yB+oKivML61xPvP8zd6HLPeOQ8uVOnN20F03jotD5D2NxfucRbJj+NzmbAJzJldYTz8y6iil//hZJP2bUepsAPy8sf2EoJg5zrdZlSUmJzeuJy1tYWt2fffaZdV9AQIAqj4wYMQItW7a8Zus9KSlJtcYvXrxY6THy8/NtDnCuJ+4chm2JP/TQQyrAH3jgAbz00kuVrpPyyvLly7Fv3z7VOnGVAL+WpvHRKrB/+WIHvr/nt/9TTuoF3Lj4brSddBNOf/qDU4/RVeTmF2PU3K+w58jlOm+XX1iCKX/eiE9eGeFyQW5rgH/44Yf44osvrPuk8XLvvfciNDTUpscICgrCuHHjMHLkSHz88cf46quv1H5LgEvjhy1w12XImviRI0dUy0R63eXrYE369OmjLnv06FFp/+nTp3HbbbepP9xmzZph9uzZuHy57iBoLG0nD4KHpycOv/PbG1Yc/+hb1YJvnzjYacfmav76+k/XDHALKbHMeux7/JqtXzlqw4YNlQJ8zpw5qpFia4BX5Ovri6lTp6JVq1aV9kt/EksorsuQIb5ixQo1pnXWrFmqlVETf3//aiGek5ODYcOGqRa8PMbbb7+NLVu2YPz48S4xRrZ5zw4oKy3Fpb3HK+0vvVqMzIO/oHnP9k47NlciHZfvf55s330KSvDvtSegE+nf+eijj6zbc+fOVX1A9T3HqaUTMz09vdL+vXv3YteuXdd9vOQYhgzxTZs2qUsJ5NpIUFcNcQnttLQ0VVuU4J42bZoqu+zYsQNr1qyBswWEN8PVzByUFZVUuy4/IxN+YU3g6W3YCpnNVm44jezc8o46e7z1P0ehC2lULF261NohOWbMGAwfPrzej1d1FIqUGGfMmGG9/t1331WjWMj1GPIdL73uorahUNJptHXr1mohvm7dOjX+tXXr1tZ9AwYMUBMi1q5di0mTJtXrePr27atGyNjC2+yJRehf43Umf1+UFtUcTtIaF17+Pigqrh7yjSU+Lh7FHs791pLlfwvgP9Du+x05mYmo6Bh4wPl9/TIZp7ZSoKV1fOzYMfXv8PDwSoHbEAEuNfDo6GgcP34cP/30kxrxIh2f06dPr/VxZBRMUVFRvY/D3UVERKgRRvYyZIjLH6WwzE6rSurlMnpF6t7SsWkhQ62k9V1V165d1XX1JQEuLXxb+HiYgPCarystuArvwCY1Xmfy9VaXJQXOfROdSz+HInOpU48BkYVAebXMPh6eOHcuAzA770OwYn26Ll9//bX133feeaeaA9GQAW6pgd91113qA0Na/vINd8qUKbWe0V7KO1ev6tevoDsvo36iXblyBXv27FEt6Yqk3vfII4+of3fv3r1S/VDu07Rp02qPJ51EllZPfY/HVtISRy0N2fzzV9AkPhqePl7VSioBEaEovJyFMie2wkVkq0int8Sz/T2QU4/7eZivIjKylk9QJ7TEayMTeGRklWjRogV69+7tkAAXMjhAvklKTVyG4u7evbvae8pCpvGzJY5GyQnDh7gMlZIRKi+88IIaKytf84T8AUqrRVrhjTnJx56vSHWNE7/08wlEDe2J5r3icGHnkUqt8NCEWJzf8ds+Z0k+nuz0ceIHkjPRfeqndt9vzqQEvP9MeV+JK48TP3DggPXfUgf39PR0SIBbyFhzS8emTAaqLcSTk5NrbaWT4xiyY1OGWIWFheHMmTOqFNKtWzfExcWhf//+qr5t6QCqOrxQhhRKa6MqmdlZnyFbDe3059tgLitTMzYrips1UgXnqU82O+3YXEm3+FDc3Nv+FvX9t3eGDizBKzp37uzQABedOnWyfmOVIbjkWgwZ4tIhI0MDZQKD1Ap/+eUXFcLSmy9jaqXFUFOIyxuiptq37KvPm6Wh/Xo0FUffX4/YcTdi2LuPIO53I9B30Wz0f2oOMrYdwqlPONHH4m/z+sDLZPtQuykjYtEvoQV0IH/PQoI1NjbWoQFuqc9bFsaShhFLJq7FsN99JHRltElNU4zlTSBfQRMSEipdJ8MKn3jiCTX8UD4IxM6dO9U6Ky+++CJcwa7//gC5Zy4i/o6RiB7RG4WZ2Tjy3lfYu2Sl06fcu5Kh/Vrh34uHYPbCJJSU1v26DO/fCv//OX2WV5W+G8s3R3s6NOsT4BXr3fK+kGUqZD6FfNMl12DYEK/NoUOH1FRlqZPL2hAVyWSJ119/HRMnTsTTTz+NwsJCVZqRMozscwVSTjm0dK36obrNvLU9osMD8czbe/HN9t9W5rNo1SJALYL12N3d4eNt0ubllMaGBPK1RrBUJdPz67uYlbwHpDUuHa71HQlDjuF2IW7pFKpaSrH8YcswKlmqVsbdSieNvGFeeeWVenUekfPd3CcCXy8di+RfsvDZphQV6Ln5JQgN8UHK+tvh7a3f71XKhPUhM5jlW6gsI2HvWihcP9x1McSrkCU7ayrDkN7iY5tgwR+647Xlh1SI+/t5aRng10OWoFi4cKGauFPTyR9ITwxxIjcL8trWEyI9uV2IW9ZVISIyAvf6PklEZDAMcSIijTHE3cSY1U+rn/rqOHs05qT9B/4tq68tQ0TOwxAnm6Ru2K0uY0b35StG5EIY4mSTgvNXcGnfSbQeU/Na50TkHAxxslnq+t1odVMCvFzkbPZExBB3e+PXv4BJm/9pfR2GvjMfMw+/b92+YfHd+H36KviEBODM+l0w+fkgaljjLOFLRNfGlrgb8zB5oml8tDrJskVoQltkHk6psB2LnNTzKMrOx6/JZ5F9Kh2tx7KkQuQqGOJurEn7SHj5+yLzUHmIewf5I7h1S+u2aNa5TaWQlw7O6OG91AcAETkf34luTFrdIvNQ+UL/zbrGwsPTE5kHy7eD24TDJzjAum0Jcd9mwQi/sYuTjpqIKmKIu7FmXdqoS0tLO7RrbOXthP/brtAyN5eWnz+TLXEi1+B2a6fQbyS05eTLhZeyrNulhUX49Xj5eSabdSkP8csVWuKtx/RDUVaeOpMQOY7JZEJiYmKDPd6LS1ciJy8PwYGBeOS+26ttN9QxU+NjiLuxkHatkH8+07otLW8JcHNJqdqW2ndu2kXkn7tsvU3rW/rh7MY91tuQY8ip1xrypMNybqMyc/mlPG7VbdIXyyluzNNkgl+zYGt5pFl8jLWUEjmkB5r37IBTn2yx3r5JXBSadIiyzt4kIudjiLux9G2HEBTTEgOWzEXrsTeoMeBF2Xnoct94DH37v5B1Ig0HXvu0Uiu89Gox0jbtdepxE9Fv+D3Kje1+6gP4t2iCjneOVj+i630TUFJwFceXb8TP//gPinMLrLePuaUfMrYdrLSPiJyLIe7Grmbm4JuZz6qhhDc+f48qoXw94xlc2HVUtbgr8m/RFC16x2HH4//PacdLRNUxxAk5Kefh6e2lLtO3lJ9IuqqYW8pXL2Q9nMi1MMTJOpxQSiW1Ob5iE07853uUFZXwFSNyIQxxQkCrUPiFBlea1FOVTPKxTPQhItfBEHcT6xMX1XpdfnomPmg1tVGPh4gaBocYEhFpjCFORKQxhjgRkcYY4kREGmOIExFpjCFORKQxhjgRkcYY4gYmZ6mfuOkfiBreS20Ht43ArWsWY/IPr2H8V39XJ0m+lv7P/AFTd72pHsty5h+LW1Y9hZmH30eXe8c57P9ARHVjiBvcV5OetC4dO3DJfUj+8Bt8OughHHjjMwx69YFr3j/li+34cuJfkXvmQrXrNkx9Cme+/tEhx01EtmGIuwm/sBCE9WiPk6s3q+2UL3YgMDIMwbERdd7v/I4jakYnEbkmTrt3E4FRzVFw/kql9U9y0y6p/Tm/ZDj12IhqYjabUVqqz2kATSaTOq1eY2OIE5FLkgBfvXo1dJGYmOiU85WynOIm8tIuwT+8mTqXpkVQVHO1n4j0xRB3E4WXs5F54DTaJw5W223G3Yi89ExrKWXQaw+i9dj+Tj5KIrIXyyluZNuCpRj0z3no9tAUdZ7MH/70L+t1zXu0w5F3v6x2HzmJcvSIPvBv2RSjVvxV3e+TgQ828pETUW0Y4m4k++Q5fDlhYbX9vmEhagTK5X0nq123fcHbjXR0RFQfLKcYWMGFKxjzyd+sk31qc/VytjpBsr1ksk/4gC4ozr8KV5aVU4Tvdp3Du58cQ25++QmgCwpLcDwlC2VlZmcfHtF1YUvcwFb2uNehjy+TfVzV6bM5eOt/juCTjSk4kZpd7frM7CLET1iFJsE+uKlnS8yd2gnjB8fAVKHjl0gHDHEylCOnfsUjL+/Cl1vOwGy2rZX+5Zaz6qd1q0A8eld3/HF6Z3h6Nv54X6L6YLODDKG0tAxL3tuPXtM/wxebbQvwqlLT8zDvue0Yfs+XOHmmeuudyBUxxEl7OXlFGH3fejz6z924WnT9M/ySfsxA98RP8dWWMw1yfESOxBAn7QN81Nz12LQrvUEfN7+wBLc9/A3Wfp/aoI9L1NAY4qQtGVkybf4m7Dxw0SGPX1JixrS/bMIuBz0+Na6ioiJcunQJGRkZ6lK27ZGamooffvgBroYdm6StN1cewYZtaXbdZ/eK2xDRPAAZl/LRb+aaa95eyjNz/pqEvf+ZBD9fvl10UlxcjJ07d2L//v04ffo00tLSUFb22wJwnp6eiI6ORtu2bdGjRw/079+/1rVPJMCfeeYZ5ObmqscYPLh85rMrcIuWuHzqLliwAB06dICfnx9iYmLw8MMPIy8vD3fffbdaeeyNN95w9mGSHU6dzcajr+y2+zWTAI8OD1SXtjp6OguL3tzD348msrKysGLFCtx///3qfb1582acOXOmUoAL2ZZwTkpKwmuvvYZ58+Zh5cqVyM7OrjHAc3Jy1MqK33zzTbXHcibDNy1+/vlnjB07Vn2FCgwMRJcuXXDu3Dn1Szt58iQyM8vXyu7Zsyd00O3ByQjr1g5h3dshuE24OlnDqv73w91IqErdurH8498H8dDvuiIqPLDRnpPsYzabsX37drz//vsqcKsuEyut7oiICHh7e6tWenp6Os6ePWsNZAn/Tz/9FJs2bVKNO2mZVwxw0b59ezz++OOqFe8qvIzeAp8wYYIK8Pnz52PRokUIDg5W1y1ZsgSPPvqo+vokLfHu3btDB32emIXCzBxkHjgFnxDbW5NGcjGzAP/ZcLpRn7O01Ix3Vh/DU/f3btTnJdsUFRXhzTffxI4dOyoF9w033IARI0YgLi4OPj4+Nd7v2LFj2LhxI3bv3q2Wv5Uwf/nll9GrVy+cOHGiUoAvXLgQAQGu9b4zdIg/9NBD6pP2gQcewEsvvVTpOimvLF++HPv27VM1sZCQEOhg1Q33Ize1/FRpE797Gd6BfnA3732WjKLixv86+/bqY1h4b094e7tOK4yAwsJCvPDCCzhy5Ij15ZDw/v3vf49mzZrV+RJJsHfr1k39XL58WbXif/yx/JSDe/eWn9bQlQNcGPavUX6hUt9q3rw5nn/++Rpv06dPH3UpnRoWltCXr1K+vr5OOVNHXSwB7s7WJTln/Hb6xXzsPXrZKc9NNSstLVWtZkuAS5+X9Hf9+c9/vmaAVxUWFqa+sc+YMaPSfgluKaG4YoAbOsSlY0NqXbNmzUJQUFCNt/H3968W4vL1Sc4mIrWzfv36Ndrxku0zM50ZpD8d5kk0XMnatWvV6BMhIfvkk09iwIAB9X486QD94osvKu3Lz89XnZ+uyrAhLp0TYtiwYbXeRlrdVUNchg5Jh8eaNWswcuTIRjhSskdySjbyChqvQ7MqhrjrkMBdtWqV+rd8Y/7LX/6iyh71VbUTMzIy0nrdxx9/rAZEuCLDhnhKSoq6bNOmTY3Xl5SUYOvWrdVC3JV6nam61PRcp74sZ87nOfX56Tfvvfeeeh+L8ePHq5Fn9VXTKJRnn30WY8aMUdsymmXZsmUu+fIbtmNTxoCLgoKCGq+XermMXpHRKtKx6Uh9+/ZVI2Rs4W32xCLoe5q0+Lh4FHs4rtOxwLsjEPy7Oify1CWiub/18sw3lWufFdU2Gej7pK2Ijr4Hupl8158QGBSC9Ix0NdSu6rYrkk7H2vqzpJFmqYNHRERg2rRpDRrglk5MqY9LR6dkhQyCkNZ4xRZ6RfHx8XbPAq1I/h+WTlV7GDbE5QW5cuUK9uzZU61GJuWSRx55RP1bhhY6uvNSAlxmi9nCx8MEhENb59LPoch8/YtQ1SqoGVA+SrTWiTy28DJ52nzbiooK823+XbqSstJS66WauVhl2xXJwILayIQbi7Fjx9Y4fPB6A9zSUSqt8Q8//ND6vHPmzKnxsSTgr15t/BOkGDbEpZ4tn9Qy9GjUqFHqU1LIWNA777xTfbI21iQf+UCxlbTE4TqTwewW2SrSoS3xIpM/LtbRer4WaYFLgJeUliHjUs3f0up6LH+fEoRGRUE3niaT9TIqKqratiuqLZhlwIJM6rGE7M033+yQALcYOnSo+uYuJZVt27Zh9uzZNTb8pIV+vS3x+jBsiFvGgUvnR9euXdGpUyc1nlRGn8gnd2xsLDZs2FCpHu4o9nxFKs4vxEft74Cuko8nwzvAcWPXZS2T4Bv/jeKS6h8UtqyFIiUUaYFLgMeM+tju5//b4/fgL79/Fbp57l8fITs3D60iWqkO/arbrkjq3TJSrKrz589by6Vdu3at19A/WwNcyOi2zp07q1EwMhFIxpPL0OWqkpOTa117xZEM24sndb4tW7Zg3Lhx6tP6l19+QWhoKJYuXaqGEMkLLhojxBtSu6mD0f1PierHLywE3sEB1m25zuh8fUxI6GDf+N+G1KdLmNOem8rJYlYW7dq1c2iAW1TsN6v4/K7AsC1xIZ+e69atq7ZfViKTUJeRKAkJCdBJ/MwRiBjYtdK+3o/OVJcZ2w7h1KrNMLph/Vs5Zax4oL8X+nat3gKjxlWxht+mltFnDRngQr65V3x+V5pDYugQr82hQ4fUYjlSJ6/pl2cZe3r48OFK2/KLlJEmzrQ+cRHc3dzEjnj53wcb/XnvGN8BwYH160CjhiPfrKWcITXq4P9bC8kWUjaqT4ALWZajSZMmavGsujpcncEtQ/zAgQN1llKqDleybEuv9AcffNAIR0h16di2KUbeGIlvdzTu5Iv7b+/cqM9HNZNF7eTHXk2bNlXhLyFu71ooUnuXUqwrYojXQFrp5Nr++75ejRrik0e0Qff40EZ7Pmp4QUFBKrhlwMMdd9zhsmuh2MuwHZvX0xIn13dznwg8+Lv6z9CzR2gTX7y5cGCjPBc5Psjnzp1rmAB325a4ZV0V0tvzD/XF+q1ncTyl8plY6mIZ/23LmHKLfz0xwK4zARE1JrcMcTKGwABvfPXmLRg0Z12dE3fsHUte0d/m9caMsfVfVInI0dyynELG0T4mBEnvjUNMRMOfNm3xg33w17l6nLaP3BdDnLQXH9sEu1dMVJ2PDSE8zB+fvToST9zb0+VOCkJUFUOcDEGCd/XLI7DihaHWlQrtJXl95/gOOPTpFEwc1jAfCESOxpo4GYa0mqV+PWVkLD7blII3Vx5B0o/XXgK4RTM/3DOlI+ZO7YjYKNsnjxC5AoY4GY6PtwnTb2mnfi7/Wog9Ry6rM/KcPJONgqul8PbyVMMGe3UKQ58uzRHfJgQmE7+Ukp4Y4mRoYU39MGpAlPohMiI2P4iINMYQJyLSGEOciEhjDHEiIo0xxImINMbRKS7Gy98Xs06Wn1lb1+MnaggmkwmJiYkN8lgvLl2JnLw8BAcG4pH7bq913/UerzMwxF1wwoojTzRMpNN7oaFOPGwGUGYuv7Q8Zk37dMRyChGRxhjiREQaY4gTEWmMIU5EpDGGOBGRxhjiREQaY4gTEWmMIU5EpDGGOBGRxhjiREQaY4gTEWmMIU5EpDGGOBGRxhjiREQaY4gTEWmMIU5EpDGGOBGRxhjiREQaY4gTEWmMIU5EpDGGOBGRxhjiREQaY4gTEWmMIU5EpDGGOBGRxrycfQBE1HCuXi3CZ99sRWlpaaX9BYWF1svln39bbbuiETf1QXjzZvy1aIIhTmQgvr4+KoDXJ+2q8friklLsP3qq1u2E+LZoGda0UY6VGgbLKUQGM7h/d8RGR9h9v6BAf0y+5WZ4eHg45LjIMRjiRAbj6emJ6eOGwsfH2677TR07BIEBfg47LnIMhjiRAYU2DcGEEQNsvv0NPTujU/vWDj0mcgyGOJFB9e3WEZ07tLnm7cKaheDWYTc2yjFRw2OIExmU1LYTxwyus0Qit7l93DD42ll6IdfBECcyMOmslCCvzbAbe6J1VHijHhM1LLcJ8bKyMqxatQqTJk1CZGQkfH191eXw4cPx6quvoqioyNmHSOQQXeJi0bd7x2r7o8KbqzHhpDe3CPELFy6osJ42bRo+//xzeHt7o2fPnuryu+++w+OPPw6TyeTswyRymAnDByC0SbB128vLhOnjh8FkcosIMDTD/wbz8vJw6623IikpCUOGDMG+ffuQkpKCnTt3qsuDBw/iscceY4iT4ScBSWhbRoCPGdKfszINwvAzNufPn4+ffvoJgwYNwtdffw0fH59K13ft2lX9EBmdTAAafEMPpGVcwsA+Cc4+HGogHmaz2QyDOnr0KBISEuDl5YXk5GS0bn3tcbCnT5/Gww8/rMoscr8JEybglVdeQVhYWL2P4/VlnyAnt6De9ydqKPJ2lx+ZEOROcvLy1f9bRuMEBwbUus+ZgoP88eCcKXbfz9At8eXLl6uFgGbPnm1TgOfk5GDYsGEIDQ3FihUrUFBQgAULFmD8+PHYunVrvf/wJcCzc/PqdV8iajhms7nae7GmfToxdIh/+2356mxSE7fF22+/jbS0NGzevNka+tHR0Rg4cCDWrFmjRrbU9xOWiJwnR5OWeH0YupwSExODs2fPqpp47969r3l7aYULKaVU1L59ewwdOhTvvvuuw46ViBznuX99pFrbIUGBeGLerFr36cjL6CNThJRFbHH48GE1DLEq6fiU6+qLNXEi58rJy7deSnjXts+ZWBOvpSV+5coVbNu2DTfddNM1X0S5bdOm1ddSlhr5sWPH6v3LYU2cyDWYWRPXy+TJk7F//34sXrwYPXr0wOjRo63XSe172bJlquUdFxfn0ONgTZzIuXJYE9dTbm6umuCzZ88etR0REaFa55mZmTh16pTq0MjOzkZgYKC6Pjw8XIX6G2+8UelxbrvtNly8eBHbt293yv+DiK7PcwauiRt6sGhQUBC2bNmCZ599VrXEs7Ky1AxNWUdFRppIS9wS4KJz58411r5ln1xHRORqDN2xKQICArBw4UL1cy0yHvyJJ55QI1pkaKGQ6fknT57Eiy++2AhHS0RkH0O3xO01d+5ctGrVChMnTsS6devUqoczZ85E//791T4iIlfDEK8gJCQEmzZtUkE+Y8YM3HPPPWqijwS6u01TJiI9GL6cYi+Z2COhTUSkAzYviYg0xhAnItIYQ5yISGMMcSIijTHEiYg0xhAnItIYQ5yISGMMcSIijTHEiYg0xhAnItIYQ5yISGMMcSIijTHEiYg0xhAnItIYQ5yISGMMcSIijTHEiYg0xhAnItIYQ5yISGMMcSIijTHEiYg0xhAnItIYQ5yISGMMcSIijTHEiYg0xhAnItIYQ5yISGMMcSIijTHEiYg0xhAnItIYQ5yISGMMcSIijTHEiYg0xhAnItIYQ5yISGMMcSIijTHEiYg0xhAnItIYQ5yISGNezj4AIqKGlJp2HoVFxZX2lZSWWi+TT5+tdZ/w9/VBTGRLbX4pHmaz2ezsgyAiaig/Hz6Bj9duqvf975g0Cgkd22rzC2E5hYgMpWeXDujeqV297ts7IV6rABcMcSIynEmjByEkKMCu+zQNCcJtIwdCNwxxIjKcAH8/TL11qM239wAwfdxQ+Pn6QDcMcSIypPi20RjQu6tNtx3UrzvatY6EjhjiRGRYY4fegBahTeq8TXjzZhg9uC90xRAnIsPy8fbC9PHD4OkhBZPqTJ6euH3CcHh76Tva2q1CvKysDKtWrcKkSZMQGRkJX19fdTl8+HC8+uqrKCoqcvYhElEDi2nVEsMH9q7xulE390VkyzCtX3O3GSd+4cIFTJ8+HUlJSWq7devWiIiIQEZGBlJTU+Hv74+cnByYTCZnHyoRNbDS0jK89dHnOJN+0bovNjoCc2eOh6en3m1ZvY/eRnl5ebj11ltVgA8ZMgT79u1DSkoKdu7cqS4PHjyIxx57jAFOZFAmk6cqq3h7lTfSfHy8MW3cUO0D3G1a4n/84x+xdOlSDBo0CBs3boSPj37DiIjo+m3fcwiff7MViWMGo1+PToZ4SQ0f4kePHkVCQgK8vLyQnJysyih1OXv2LP7+979j165dqsUudfLrfYleX/YJcnILrusxiOj6mc1mFBWXqA5Pj1o6O50lOMgfD86ZYvf99O2StdHy5ctRWlqK2bNnXzPAxYkTJ7B69Wr069dPtdi3bt163ccgAZ6dm3fdj0NEDeOqgQYxGD7Ev/32W3UpNXFbDB48GOnp6erfTz31VIOEuHzCEhE5IicMH+JnzpxRl+3a2bYgjiM6OurzFYmIyBZe7jAyRRQUOK8mzZo4EV0La+K1iImJwZUrV7Bt2zbcdNNNcAbWxInIUQzfEp88eTL279+PxYsXo0ePHhg9erT1urS0NCxbtgzTpk1DXFycw46BNXEiclROGH6IYW5urprgs2fPHrUtszSldZ6ZmYlTp06pYUbZ2dkIDAysdl/p2Hz66aeve4ghEZGj6D9d6RqCgoKwZcsWPPvss6olnpWVpWZoyjoqsoaKtMRrCnAiIh0YvpwiAgICsHDhQvVDRGQkbhHi9pKVDsXhw4crbcfGxqJvX33XHSYi4zF8Tbw+apuOO2fOHHzwwQeNfjxERLVhS7wG/FwjIl0YvmOTiMjIGOJERBpjiBMRaYwhTkSkMYY4EZHGGOJERBpjiBMRaYwhTkSkMYY4EZHGGOJERBpjiBMRaYwhTkSkMYY4EZHGGOJERBpjiBMRaYwhTkSkMYY4EZHGGOJERBpjiBMRaYwhTkSkMYY4EZHGGOJERBpjiBMRaYwhTkSkMYY4EZHGGOJERBpjiBMRaYwhTkSkMYY4EZHGGOJERBpjiBMRaYwhTkSkMYY4EZHGGOJERBpjiBMRaYwhTkSkMYY4EZHGGOJERBpjiBMRQV//C/8VzK8WvJMwAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 454.517x367.889 with 1 Axes>"
      ]
     },
     "execution_count": 164,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circ = qs.QuantumCircuit(2, 2)\n",
    "# prepare the |01⟩ state on the 0-th and the 1-st qubits\n",
    "circ.initialize(\"01\", [0, 1])\n",
    "circ.cx(0, 1)\n",
    "circ.measure(0, 0)\n",
    "circ.measure(1, 1)\n",
    "circ.draw(\"mpl\", cregbundle=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 165,
   "id": "fb38b332-4d91-461b-8f32-107c1882b4d9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'11': 1024}"
      ]
     },
     "execution_count": 165,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circ_tr = transpile(circ, simulator)\n",
    "job = simulator.run(circ_tr)\n",
    "result = job.result()\n",
    "result.get_counts(circ)\n",
    "# expect 11 because 1 for the control bit would change the target bit"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.14.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
