{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Maximally Entangled States\n", "$$\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 construct a maximally entangled state vector and its\n", " corresponding density matrix, and then to calculate the \"entanglement profile\"\n", " of that state. \n", " \n", " In Entaglish, density matrices are stored in the class DenMat.\n", " That class contains attributes: num_rows, row_shape and arr.\n", " arr is a numpy array of shape=(num_rows, num_rows).\n", " row_shape is a tuple such that the product of its components is num_rows.\n", " For example, a state with row_shape=(2,3,4) consists of 3 qudits with\n", " d=2,3,4 and num_rows=24.\n", "\n", " \n", " See Entanglish-Original-Ref for an explicit definition of the maximally entangled states that we use. The basic requirement for a density matrix $\\rho_{\\rvx, \\rvy}$\n", " to be maximally entangled is for its partial trace $\\rho_{\\rvx}={\\rm tr}_\\rvy \\rho_{\\rvx, \\rvy}$ to be a diagonal matrix with all terms in the diagonal equal to the same constant. The sum of the diagonal elements must of course be one. For example, $\\rho_{\\rvx}={\\rm diag}(0.25, 0.25, 0.25, 0.25)$. (If $\\rvx$ and $\\rvy$ have different numbers of possible values, this assumes that\n", " $\\rvx$ is the one with the smaller number of values.)\n", " \n", "Given a state with num_row_axes qudits, one can define\n", "a (bipartite) entanglement for each possible bi-partitions of range(\n", "num_row_axes). By a bi-partition we mean two nonempty disjoint subsets\n", "whose union is range(num_row_axes). An entanglement profile \n", "is a dictionary mapping bi-partition half-size to a dictionary that \n", "maps each bi-partition of that half-size to its entanglement.\n", "\n", "**Entanglish-Original-Ref**\n", "* \"A New Algorithm for Calculating\n", "Squashed Entanglement and a Python Implementation Thereof\", by R.R.Tucci" ] }, { "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.DenMat import *\n", "from entanglish.MaxEntangState import *\n", "from entanglish.EntangCase import *\n", "from entanglish.PureStEnt import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create a DenMat object called dm_max with num_rows=24 and row_shape=(2, 2, 3 ,2).Then\n", "set its arr to a maximally entangled state." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "st_vec=\n", " [0.57735027+0.j 0. +0.j 0. +0.j 0.57735027+0.j\n", " 0. +0.j 0. +0.j 0. +0.j 0. +0.j\n", " 0. +0.j 0. +0.j 0.57735027+0.j 0. +0.j\n", " 0. +0.j 0. +0.j 0. +0.j 0. +0.j\n", " 0. +0.j 0. +0.j 0. +0.j 0. +0.j\n", " 0. +0.j 0. +0.j 0. +0.j 0. +0.j]\n", "entang= 1.0986122886681098\n" ] } ], "source": [ "dm_max = DenMat(24, (2, 2, 3, 2))\n", "max_ent_st = MaxEntangState(dm_max.num_rows, dm_max.row_shape,\n", " [0, 1, 3], [2])\n", "EntangCase.check_max_entang_st(max_ent_st)\n", "st_vec = max_ent_st.get_st_vec()\n", "entang = max_ent_st.get_known_entang()\n", "dm_max.set_arr_from_st_vec(st_vec)\n", "\n", "print('st_vec=\\n', st_vec)\n", "print(\"entang=\", entang)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Class PureStEnt is a child of class EntangCase.\n", "\n", "All objects with EntangCase as a parent\n", "calculate entanglement numerically, from\n", "an algorithm, not from a known analytical formula. \n", "For a pure state, that algo is the von Neumann entropy of a partial trace of dm.\n", "\n", "All objects with EntangCase as a parent\n", "inherit methods for calculating and printing entanglement profiles" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "bi-partition half-size=1\n", "(0 | 1, 2, 3) :\t-0.00000, max-entang= 0.69315\n", "(1 | 0, 2, 3) :\t 0.63651, max-entang= 0.69315\n", "(2 | 0, 1, 3) :\t 1.09861, max-entang= 1.09861\n", "(3 | 0, 1, 2) :\t 0.63651, max-entang= 0.69315\n", "bi-partition half-size=2\n", "(0, 1 | 2, 3) :\t 0.63651, max-entang= 1.38629\n", "(0, 2 | 1, 3) :\t 1.09861, max-entang= 1.38629\n", "(0, 3 | 1, 2) :\t 0.63651, max-entang= 1.38629\n", "(1, 2 | 0, 3) :\t 0.63651, max-entang= 1.38629\n", "(1, 3 | 0, 2) :\t 1.09861, max-entang= 1.38629\n", "(2, 3 | 0, 1) :\t 0.63651, max-entang= 1.38629\n", "\n" ] } ], "source": [ "ecase = PureStEnt(dm_max, 'eigen')\n", "pf = ecase.get_entang_profile()\n", "ecase.print_entang_profiles([pf], dm_max.row_shape)" ] } ], "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 }