{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e5e44fb3",
   "metadata": {},
   "source": [
    "## Ejemplo 5.6: Marginalización de un estado independiente"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71cd75b7",
   "metadata": {},
   "source": [
    "$\\newcommand{\\ket}[1]{|{#1}\\rangle}\\newcommand{\\bra}[1]{\\langle{#1}|}$Considere un sistema cuántico compuesto formado por dos estados independientes\n",
    "\\begin{align*}\n",
    "   \\delta^{AB} \n",
    "     = \\rho^A \\otimes \\sigma^B \n",
    "     = \\left[\\begin{matrix}\n",
    "             \\rho_{11}\\sigma^B& \\rho_{12}\\sigma^B \\\\ \\rho_{21}\\sigma^B & \\rho_{22}\\sigma^B \\end{matrix}\\right]\n",
    "     = \\left[\\begin{matrix}\n",
    "             \\rho_{11}\\sigma_{11} & \\rho_{11}\\sigma_{12} & \\rho_{12}\\sigma_{11} & \\rho_{12}\\sigma_{12} \\\\\n",
    "             \\rho_{11}\\sigma_{21} & \\rho_{11}\\sigma_{22} & \\rho_{12}\\sigma_{21} & \\rho_{12}\\sigma_{22} \\\\\n",
    "             \\rho_{21}\\sigma_{11} & \\rho_{21}\\sigma_{12} & \\rho_{22}\\sigma_{11} & \\rho_{22}\\sigma_{12} \\\\\n",
    "             \\rho_{21}\\sigma_{21} & \\rho_{21}\\sigma_{22} & \\rho_{22}\\sigma_{21} & \\rho_{22}\\sigma_{22} \n",
    "        \\end{matrix}\\right].\n",
    "\\end{align*}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e51496e6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Definimos un estado compuesto independiente:\n",
      "\n",
      "rhoA = \n",
      " [[0.75 0.  ]\n",
      " [0.   0.25]] \n",
      "sigmaB = \n",
      " [[0.5 0.5]\n",
      " [0.5 0.5]] \n",
      "deltaAB = kron(rhoA, sigmaB) =\n",
      " [[0.375 0.375 0.    0.   ]\n",
      " [0.375 0.375 0.    0.   ]\n",
      " [0.    0.    0.125 0.125]\n",
      " [0.    0.    0.125 0.125]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "print('Definimos un estado compuesto independiente:\\n')\n",
    "rhoA = np.array([[3/4, 0], [0, 1/4]])\n",
    "sigmaB = np.array([[1/2, 1/2], [1/2, 1/2]])\n",
    "deltaAB = np.kron(rhoA, sigmaB)\n",
    "\n",
    "print(\"rhoA = \\n\", rhoA, \"\\nsigmaB = \\n\", sigmaB, \"\\ndeltaAB = kron(rhoA, sigmaB) =\\n\", deltaAB)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7625c52a",
   "metadata": {},
   "source": [
    "Si descartamos la parte $A$ del sistema obtenemos\n",
    "\\begin{align*}\n",
    "   \\text{Tr}_{A} \\left[ \\delta^{AB} \\right]\n",
    "     &= \\left[\\begin{matrix}\n",
    "              \\rho_{11}\\sigma_{11} + \\rho_{22}\\sigma_{11}  & \\rho_{11}\\sigma_{12} + \\rho_{22}\\sigma_{12} \\\\\n",
    "              \\rho_{11}\\sigma_{21} + \\rho_{22}\\sigma_{21} & \\rho_{11}\\sigma_{22} + \\rho_{22}\\sigma_{22} \n",
    "        \\end{matrix}\\right]\n",
    "      = \\underbrace{\\text{Tr}[\\rho^A]}_{=1} \\left[\\begin{matrix}\n",
    "              \\sigma_{11}  & \\sigma_{12} \\\\\n",
    "              \\sigma_{21} & \\sigma_{22}  \\end{matrix}\\right]\n",
    "      = \\sigma^B.\n",
    "\\end{align*}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "746f0b09",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Descartamos la parte A del estado compuesto:\n",
      "\n",
      "sigmaB = \n",
      " [[0.5 0.5]\n",
      " [0.5 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",
    "print('Descartamos la parte A del estado compuesto:\\n')\n",
    "sigmaB = traceA(deltaAB)\n",
    "print(\"sigmaB = \\n\", sigmaB)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ba2e0e6",
   "metadata": {},
   "source": [
    "Si descartamos la parte $B$ del mismo queda\n",
    "\\begin{align*}      \n",
    "   \\text{Tr}_{B} \\left[ \\delta^{AB} \\right] &= \\left[\\begin{matrix}\n",
    "                 \\rho_{11}\\sigma_{11} + \\rho_{11}\\sigma_{22} & \\rho_{12}\\sigma_{11} + \\rho_{12}\\sigma_{22} \\\\\n",
    "                 \\rho_{21}\\sigma_{11} + \\rho_{21}\\sigma_{22} & \\rho_{22}\\sigma_{11} + \\rho_{22}\\sigma_{22} \\end{matrix}\\right]\n",
    "      = \\underbrace{\\text{Tr}[\\sigma^B]}_{=1} \\left[\\begin{matrix}\n",
    "              \\rho_{11}  & \\rho_{12} \\\\\n",
    "              \\rho_{21} & \\rho_{22}  \\end{matrix}\\right]\n",
    "      = \\rho^A.\n",
    "\\end{align*}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "7ddfa306",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Descartamos la parte B del estado compuesto:\n",
      "\n",
      "rhoA = \n",
      " [[0.75 0.  ]\n",
      " [0.   0.25]]\n"
     ]
    }
   ],
   "source": [
    "def traceB(delta): # traces out part B of a bipartite system\n",
    "    return np.array([[delta[0, 0] + delta[1, 1], delta[0, 2] + delta[1, 3]],\n",
    "                     [delta[2, 0] + delta[3, 1], delta[2, 2] + delta[3, 3]]])\n",
    "\n",
    "print('Descartamos la parte B del estado compuesto:\\n')\n",
    "rhoA = traceB(deltaAB)\n",
    "print(\"rhoA = \\n\", rhoA)"
   ]
  }
 ],
 "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
}
