{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e5e44fb3",
   "metadata": {},
   "source": [
    "## Ejemplo 8.2: Transmisión por entrelazamiento"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71cd75b7",
   "metadata": {},
   "source": [
    "$\\newcommand{\\ket}[1]{|{#1}\\rangle}\\newcommand{\\bra}[1]{\\langle{#1}|}$La idea de la transmisión de información por entrelazamiento aparece representada en la siguiente figura:\n",
    "\n",
    "<img src=\"figs/medida-bipartida-alice.svg\" alt=\"Medida parcial de una estado cuantico compuesto compartico entre Alice y Bob\" style=\"width:380px;\"/>\n",
    "\n",
    "Definimos el estado máximamente entrelazado\n",
    "\\begin{align*}\n",
    "   \\delta^{AB} = \\frac{1}{2} \\left[\\begin{smallmatrix}\n",
    "                 1 & 0 & 0 & 1\\\\\n",
    "                 0 & 0 & 0 & 0\\\\\n",
    "                 0 & 0 & 0 & 0\\\\\n",
    "                 1 & 0 & 0 & 1 \\end{smallmatrix}\\right]\n",
    "\\end{align*}\n",
    "donde el superíndice $AB$ hace referencia a que la primera parte del estado pertenece a Alice y la segunda a Bob."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e51496e6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "deltaAB =\n",
      " [[0.5 0.  0.  0.5]\n",
      " [0.  0.  0.  0. ]\n",
      " [0.  0.  0.  0. ]\n",
      " [0.5 0.  0.  0.5]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "deltaAB = np.array([[1,0,0,1],[0,0,0,0],[0,0,0,0],[1,0,0,1]])/2\n",
    "print('deltaAB =\\n', deltaAB)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7625c52a",
   "metadata": {},
   "source": [
    "Consideramos los proyectores de medida:\n",
    "\\begin{align*}\n",
    "\\Pi_{0}^A=\\begin{bmatrix}1&0\\\\0&0\\end{bmatrix},\\quad\n",
    "\\Pi_{1}^A=\\begin{bmatrix}0&0\\\\0&1\\end{bmatrix},\\quad\n",
    "\\Pi_{+}^A=\\frac{1}{2}\\begin{bmatrix}+1&+1\\\\+1&+1\\end{bmatrix},\\quad\n",
    "\\Pi_{-}^A=\\frac{1}{2}\\begin{bmatrix}+1&-1\\\\-1&+1\\end{bmatrix}.\n",
    "\\end{align*}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "da91962a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Pi0A =\n",
      " [[1 0]\n",
      " [0 0]] \n",
      "Pi1A =\n",
      " [[0 0]\n",
      " [0 1]] \n",
      "PipA =\n",
      " [[0.5 0.5]\n",
      " [0.5 0.5]] \n",
      "PimA =\n",
      " [[ 0.5 -0.5]\n",
      " [-0.5  0.5]]\n"
     ]
    }
   ],
   "source": [
    "Pi0A = np.array([[1,0],[0,0]])\n",
    "Pi1A = np.array([[0,0],[0,1]])\n",
    "PipA = np.array([[+1,+1],[+1,+1]])/2\n",
    "PimA = np.array([[+1,-1],[-1,+1]])/2\n",
    "\n",
    "print('Pi0A =\\n', Pi0A, '\\nPi1A =\\n', Pi1A,'\\nPipA =\\n', PipA,'\\nPimA =\\n', PimA)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0a8faad0",
   "metadata": {},
   "source": [
    "Ahora, Alice aplica una medida a su parte del estado compartido con Bob:\n",
    "\n",
    "- Si $m=0$, Alice aplica la medida con respecto al POVM$_{01} = \\bigl\\{\\Pi^A_{0},\\Pi^A_{1}\\bigr\\}$.\n",
    "- Si $m=1$, Alice aplica la medida con respecto al POVM$_{+-} =\\bigl\\{\\Pi^A_{+},\\Pi^A_{-}\\bigr\\}$.\n",
    "\n",
    "Para aplicar la medida al estado conjunto, definimos las matrices de dimensión $4\\times 4$ dadas por $\\Pi_k^{AB} = \\Pi_k^A \\otimes \\boldsymbol{I}_2^B$, donde $k\\in\\{0,1,+,-\\}$. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "746f0b09",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Pi0AB =\n",
      " [[1 0 0 0]\n",
      " [0 1 0 0]\n",
      " [0 0 0 0]\n",
      " [0 0 0 0]] \n",
      "Pi1AB =\n",
      " [[0 0 0 0]\n",
      " [0 0 0 0]\n",
      " [0 0 1 0]\n",
      " [0 0 0 1]] \n",
      "PipAB =\n",
      " [[0.5 0.  0.5 0. ]\n",
      " [0.  0.5 0.  0.5]\n",
      " [0.5 0.  0.5 0. ]\n",
      " [0.  0.5 0.  0.5]] \n",
      "PimAB =\n",
      " [[ 0.5  0.  -0.5 -0. ]\n",
      " [ 0.   0.5 -0.  -0.5]\n",
      " [-0.5 -0.   0.5  0. ]\n",
      " [-0.  -0.5  0.   0.5]]\n"
     ]
    }
   ],
   "source": [
    "I2B = np.array([[1,0],[0,1]]) # Bob no hace nada en su parte\n",
    "# Definimos las medidas conjuntas:\n",
    "Pi0AB = np.kron(Pi0A,I2B)\n",
    "Pi1AB = np.kron(Pi1A,I2B)\n",
    "PipAB = np.kron(PipA,I2B)\n",
    "PimAB = np.kron(PimA,I2B)\n",
    "\n",
    "print('Pi0AB =\\n', Pi0AB, '\\nPi1AB =\\n', Pi1AB,'\\nPipAB =\\n', PipAB,'\\nPimAB =\\n', PimAB)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94c1b5e6",
   "metadata": {},
   "source": [
    "Si Alice aplica el POVM$_{01}= \\bigl\\{\\Pi_{0}^A,\\Pi_{1}^A\\bigr\\}$, y teniendo en cuenta que Bob no puede conocer el resultado de la medida, obtenemos el nuevo estado conjunto:\n",
    "\\begin{align*}        \n",
    "   \\theta_{01}^{AB} = \\Pi_{0}^{AB} \\delta^{AB} \\Pi_{0}^{AB} + \n",
    "                   \\Pi_{1}^{AB} \\delta^{AB} \\Pi_{1}^{AB}  = \\frac{1}{2} \\left[\\begin{smallmatrix}\n",
    "                 1 & 0 & 0 & 0\\\\\n",
    "                 0 & 0 & 0 & 0\\\\\n",
    "                 0 & 0 & 0 & 0\\\\\n",
    "                 0 & 0 & 0 & 1 \\end{smallmatrix}\\right].\n",
    "\\end{align*}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "dfd352b5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "theta01AB =\n",
      " [[0.5 0.  0.  0. ]\n",
      " [0.  0.  0.  0. ]\n",
      " [0.  0.  0.  0. ]\n",
      " [0.  0.  0.  0.5]]\n"
     ]
    }
   ],
   "source": [
    "theta01AB = Pi0AB@deltaAB@Pi0AB + Pi1AB@deltaAB@Pi1AB\n",
    "\n",
    "print('theta01AB =\\n', theta01AB)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd44255a",
   "metadata": {},
   "source": [
    "Si Alice aplica el POVM$_{+-}  =\\bigl\\{\\Pi_{+}^A,\\Pi_{-}^A\\bigr\\}$, como Bob no conoce el resultado de la medida, obtenemos:\n",
    "\\begin{align*}        \n",
    "   \\theta_{+-}^{AB} = \\Pi_{+}^{AB} \\delta^{AB} \\Pi_{+}^{AB} + \n",
    "                   \\Pi_{-}^{AB} \\delta^{AB} \\Pi_{-}^{AB}  = \\frac{1}{4} \\left[\\begin{smallmatrix}\n",
    "                 1 & 0 & 0 & 1\\\\\n",
    "                 0 & 1 & 1 & 0\\\\\n",
    "                 0 & 1 & 1 & 0\\\\\n",
    "                 1 & 0 & 0 & 1 \\end{smallmatrix}\\right].\n",
    "\\end{align*}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "cbb0598a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "thetapmAB =\n",
      " [[0.25 0.   0.   0.25]\n",
      " [0.   0.25 0.25 0.  ]\n",
      " [0.   0.25 0.25 0.  ]\n",
      " [0.25 0.   0.   0.25]]\n"
     ]
    }
   ],
   "source": [
    "thetapmAB = PipAB@deltaAB@PipAB + PimAB@deltaAB@PimAB\n",
    "\n",
    "print('thetapmAB =\\n', thetapmAB)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d54c0c2f",
   "metadata": {},
   "source": [
    "El estado conjunto tras aplicar la medida es diferente en los dos casos, $\\theta_{01}^{AB} \\neq \\theta_{+-}^{AB}$.\n",
    "\n",
    "Sin embargo, Bob no tiene acceso a este estado conjunto, sino solo a una parte del mismo. Para conocer el estado desde el punto de vista de Bob, debemos marginalizar $\\theta^{AB}$ eliminando la parte de Alice. Se tiene que\n",
    "\\begin{align*}        \n",
    " \\sigma^B_{01} = \\text{Tr}_A\\bigl[\\theta_{01}^{AB}\\bigr] = \\frac{1}{2} \\left[\\begin{matrix} 1 & 0 \\\\ 0 & 1 \\end{matrix}\\right],\\qquad\n",
    " \\sigma^B_{+-} = \\text{Tr}_A\\bigl[\\theta_{+-}^{AB}\\bigr] = \\frac{1}{2} \\left[\\begin{matrix} 1 & 0 \\\\ 0 & 1 \\end{matrix}\\right].\n",
    "\\end{align*}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "df045697",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sigma_01B =\n",
      " [[0.5 0. ]\n",
      " [0.  0.5]] \n",
      "sigma_pmB =\n",
      " [[0.5 0. ]\n",
      " [0.  0.5]]\n"
     ]
    }
   ],
   "source": [
    "def traceA(delta): # traces out part A of a bipartite system\n",
    "    return np.array([[delta[0, 0] + delta[2, 2], delta[0, 1] + delta[2, 3]],\n",
    "                     [delta[1, 0] + delta[3, 2], delta[1, 1] + delta[3, 3]]])\n",
    "\n",
    "sigma_01B = traceA(theta01AB)\n",
    "sigma_pmB = traceA(thetapmAB)\n",
    "\n",
    "print('sigma_01B =\\n', sigma_01B, '\\nsigma_pmB =\\n', sigma_pmB)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e225f01",
   "metadata": {},
   "source": [
    "Podemos ver que $\\sigma^B_0 = \\sigma^B_1$. Así, Bob no puede distinguir ambos casos teniendo aceso únicamente a su parte del estado. Por tanto, la comunicación no es posible con este esquema."
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Raw Cell Format",
  "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.10.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
