{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e5e44fb3",
   "metadata": {},
   "source": [
    "## Ejemplo 6.2: Evolución reversible en fibra óptica"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71cd75b7",
   "metadata": {},
   "source": [
    "$\\newcommand{\\ket}[1]{|{#1}\\rangle}\\newcommand{\\bra}[1]{\\langle{#1}|}$Considere el ejemplo anterior de la transmisión de un fotón por una línea óptica:\n",
    "\n",
    "<img src=\"figs/transmission-fiber.svg\" alt=\"transmission-fiber\" style=\"width: 280px;\"/>\n",
    "\n",
    "Ésta se puede modelar como $U_{\\alpha}$ donde $\\alpha$ se corresponde con el ángulo de rotación de polarización:\n",
    "\\begin{align*}\n",
    "U_{\\alpha} = \\left[\\begin{matrix} \\cos(\\alpha)& -\\sin(\\alpha)\\\\\\sin(\\alpha)& \\cos(\\alpha) \\end{matrix}\\right].\n",
    "\\end{align*}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e51496e6",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "def fibra(alpha): # Transformación unitaria de una fibra optica\n",
    "    U = np.array([[np.cos(alpha), -np.sin(alpha)], [np.sin(alpha), np.cos(alpha)]])\n",
    "    return U"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7625c52a",
   "metadata": {},
   "source": [
    "- Si el ángulo $\\alpha$ es conocido, basta aplicar una rotación con un ángulo $-\\alpha$ para recuperar el fotón original.\n",
    "De hecho, en este caso $U_{\\alpha}^H = U_{\\alpha}^{-1} = U_{-\\alpha}$:\n",
    "\\begin{align*}\n",
    "  U_{\\alpha} U_{-\\alpha} &= \\left[\\begin{matrix} \\cos(\\alpha)& -\\sin(\\alpha)\\\\\\sin(\\alpha)& \\cos(\\alpha) \\end{matrix}\\right] \\left[\\begin{matrix} \\cos(\\alpha)& \\sin(\\alpha)\\\\-\\sin(\\alpha)& \\cos(\\alpha) \\end{matrix}\\right]\\\\\n",
    "  &= \\left[\\begin{matrix} \\cos(\\alpha)^2 + \\sin(\\alpha)^2 & \\cos(\\alpha)\\sin(\\alpha)-\\sin(\\alpha)\\cos(\\alpha)\\\\\n",
    "  \\sin(\\alpha)\\cos(\\alpha)-\\cos(\\alpha)\\sin(\\alpha)&  \\sin(\\alpha)^2 + \\cos(\\alpha)^2 \\end{matrix}\\right]= \\boldsymbol{I},\n",
    "\\end{align*}\n",
    "donde hemos utilizado que $\\cos(-\\alpha)=\\cos(\\alpha)$ y que $\\sin(-\\alpha) = -\\sin(\\alpha)$ al ser funciones par e impar, respectivamente; y la conocida identidad trigonométrica $\\cos(\\alpha)^2 + \\sin(\\alpha)^2=1$.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "746f0b09",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Comprobamos que U_{-alpha} es de hecho la inversa de U_{alpha}:\n",
      "\n",
      "Ua =\n",
      " [[ 0.98006658 -0.19866933]\n",
      " [ 0.19866933  0.98006658]] \n",
      "\n",
      "U_a =\n",
      " [[ 0.98006658  0.19866933]\n",
      " [-0.19866933  0.98006658]]\n",
      "\n",
      "Ua @ U_a =\n",
      " [[ 1.00000000e+00 -1.23079293e-17]\n",
      " [-1.23079293e-17  1.00000000e+00]]\n",
      "\n",
      "U_a @ Ua =\n",
      " [[1.00000000e+00 1.23079293e-17]\n",
      " [1.23079293e-17 1.00000000e+00]]\n"
     ]
    }
   ],
   "source": [
    "print(\"Comprobamos que U_{-alpha} es de hecho la inversa de U_{alpha}:\\n\")\n",
    "alpha = 0.2;\n",
    "Ua  = fibra(alpha)\n",
    "U_a = fibra(-alpha)\n",
    "\n",
    "print(\"Ua =\\n\", str(Ua), \"\\n\\nU_a =\\n\", str(U_a))\n",
    "print(\"\\nUa @ U_a =\\n\", Ua @ U_a)\n",
    "print(\"\\nU_a @ Ua =\\n\", U_a @ Ua)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b12d197",
   "metadata": {},
   "source": [
    "- Si el ángulo $\\alpha$ es desconocido, en cambio, no es posible recuperar\n",
    "el fotón original al no poder construir la transformación inversa.\n",
    "En este caso sería necesario estimar de alguna forma la rotación que introduce la fibra para así poder compensarla."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "33b73a6e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fibra que introduce una rotación aleatoria:\n",
      "\n",
      "\n",
      "\n",
      "rho =\n",
      " [[1. 0.]\n",
      " [0. 0.]] \n",
      "\n",
      "U =\n",
      " [[ 0.01240582  0.99992304]\n",
      " [-0.99992304  0.01240582]] \n",
      "\n",
      "sigma =\n",
      " [[ 1.53904362e-04 -1.24048650e-02]\n",
      " [-1.24048650e-02  9.99846096e-01]]\n"
     ]
    }
   ],
   "source": [
    "def foton(theta): # Matriz de densidad de probabilidad de un foton polarizado\n",
    "    ket_theta = np.array([np.cos(theta), np.sin(theta)])\n",
    "    rho = np.outer(ket_theta, ket_theta)\n",
    "    return rho\n",
    "\n",
    "print(\"Fibra que introduce una rotación aleatoria:\\n\\n\")\n",
    "rho = foton(0)\n",
    "U = fibra(2*np.pi*np.random.rand())\n",
    "sigma = U @ rho @ U.conj().T\n",
    "\n",
    "print(\"\\nrho =\\n\", str(rho), \"\\n\\nU =\\n\", str(U), \"\\n\\nsigma =\\n\", str(sigma))\n"
   ]
  }
 ],
 "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
}
