{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Pure State Entanglement\n", "$$\n", "\\newcommand{\\bra}[1]{\\langle#1|}\n", "\\newcommand{\\ket}[1]{|#1\\rangle}\n", "\\newcommand{\\ul}[1]{\\underline{#1}}\n", "\\newcommand{\\rvx}[0]{{\\ul{x}}}\n", "\\newcommand{\\rvy}[0]{{\\ul{y}}}\n", "$$\n", "\n", "The purpose of this notebook is to show how to use entanglish to\n", "calculate the entanglement of a pure state.\n", " \n", " Given a bipartite density matrix \n", " $\\rho_{\\rvx, \\rvy} = \\ket{\\psi_{\\rvx, \\rvy}}\\bra{\\psi_{\\rvx, \\rvy}}$\n", " with partial trace $\\rho_{\\rvx}={\\rm tr}_\\rvy \\rho_{\\rvx, \\rvy}$, we define\n", " its entanglement as $S(\\rho_{\\rvx})$. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First change your working directory to the entanglish directory in your computer, and add its path to the path environment variable." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/home/rrtucci/PycharmProjects/Entanglish/entanglish/jupyter_notebooks\n", "/home/rrtucci/PycharmProjects/Entanglish\n" ] } ], "source": [ "import os\n", "import sys\n", "print(os.getcwd())\n", "os.chdir('../../')\n", "print(os.getcwd())\n", "sys.path.insert(0,os.getcwd())" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from entanglish.PureStEnt import *\n", "from entanglish.SymNupState import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## pure state : symmetrized n-up state\n", "\n", " \n", "**Entanglish-Original-Ref**\n", "* \"A New Algorithm for Calculating\n", "Squashed Entanglement and a Python Implementation Thereof\", by R.R.Tucci\n", "\n", "In\n", "Entanglish-Original-Ref, we derive an analytical formula \n", "for the entanglement of any symmetrized n-up state.\n", "\n", "Next, we create a symmetrized n-up state and \n", "calculate its entanglement for various bi-partitions of the row axes,\n", "using both the analytical formula and\n", "the definition given above (von Neumann entropy of\n", "partial trace). As expected, both definitions give the same answer.\n", "\n", "To calculate an entanglement using the von Neumann entropy definition,\n", "it is necessary to calculate the log of a hermitian matrix.\n", "Entanglish allows you to choose among 3 possible methods for\n", "doing this: `eigen`, (using an eigenvalue decomposition\n", "of the hermitian matrix), `pade` (using Pade approximants) and\n", "`pert` (using bootstrapped perturbation theory as\n", "implented in class DenMatPertTheory)." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-------------------dm1\n", "-----method=eigen\n", "entang_023: algo value, known value\n", " 0.6931471805599452 0.6931471805599453\n", "entang_02: algo value, known value\n", " 0.8675632284814612 0.8675632284814612\n", "entang_1: algo value, known value\n", " 0.6931471805599452 0.6931471805599453\n", "-----method=pert, 40 steps\n", "entang_023: algo value, known value\n", " 0.9048564000559061 0.6931471805599453\n", "entang_02: algo value, known value\n", " 0.9690466827310458 0.8675632284814612\n", "entang_1: algo value, known value\n", " 0.6931471805599453 0.6931471805599453\n" ] } ], "source": [ "def extra_str(meth, num_steps):\n", " return ', ' + str(num_steps) + ' steps' \\\n", " if meth == 'pert' else ''\n", "num_qbits = 4\n", "num_up = 2\n", "dm1 = DenMat(1 << num_qbits, tuple([2]*num_qbits))\n", "st = SymNupState(num_up, num_qbits)\n", "st_vec = st.get_st_vec()\n", "dm1.set_arr_from_st_vec(st_vec)\n", "print('-------------------dm1')\n", "for method in ['eigen', 'pert']:\n", " num_bstrap_steps = 40\n", " print('-----method=' + method +\n", " extra_str(method, num_bstrap_steps))\n", " ecase = PureStEnt(dm1, method,\n", " num_bstrap_steps, verbose=False)\n", " print('entang_023: algo value, known value\\n',\n", " ecase.get_entang({0, 2, 3}),\n", " st.get_known_entang(3))\n", " print('entang_02: algo value, known value\\n',\n", " ecase.get_entang({0, 2}),\n", " st.get_known_entang(2))\n", " print('entang_1: algo value, known value\\n',\n", " ecase.get_entang({1}),\n", " st.get_known_entang(1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## pure state : random\n", "\n", "Next, we create a random state vector and \n", "calculate its entanglement for various bi-partitions of the row axes,\n", "using methods `eigen` and `pert`.\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-------------------dm2\n", "-----method= eigen\n", "entang_023: 0.5364009909037474\n", "entang_02: 1.0539432153468993\n", "entang_1: 0.5364009909037474\n", "-----method= pert, 40 steps\n", "entang_023: 0.6507512144573282\n", "entang_02: 1.0537529550284028\n", "entang_1: 0.5364009909037474\n" ] } ], "source": [ "dm2 = DenMat(24, (3, 2, 2, 2))\n", "np.random.seed(123)\n", "st_vec = ut.random_st_vec(24)\n", "dm2.set_arr_from_st_vec(st_vec)\n", "print('-------------------dm2')\n", "num_bstrap_steps = 40\n", "for method in ['eigen', 'pert']:\n", " print('-----method=', method +\n", " extra_str(method, num_bstrap_steps))\n", " ecase = PureStEnt(dm2, method,\n", " num_bstrap_steps, verbose=False)\n", " print('entang_023:', ecase.get_entang({0, 2, 3}))\n", " print('entang_02:', ecase.get_entang({0, 2}))\n", " print('entang_1:', ecase.get_entang({1}))\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" } }, "nbformat": 4, "nbformat_minor": 2 }