{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 25460 characters]\n",
      "text/latex": [
       "$\\displaystyle \\left[ \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2} & \\frac{\\sqrt{2}}{2}\\\\\\frac{\\sqrt{2}}{2} & - \\frac{\\sqrt{2}}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}1 & 0\\\\0 & i\\end{matrix}\\right], \\  \\left[\\begin{matrix}1 & 0\\\\0 & 1\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2} & \\frac{\\sqrt{2}}{2}\\\\\\frac{\\sqrt{2} i}{2} & - \\frac{\\sqrt{2} i}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2} & \\frac{\\sqrt{2} i}{2}\\\\\\frac{\\sqrt{2}}{2} & - \\frac{\\sqrt{2} i}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}1 & 0\\\\0 & -1\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2} & \\frac{\\sqrt{2} i}{2}\\\\\\frac{\\sqrt{2} i}{2} & \\frac{\\sqrt{2}}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2} & - \\frac{\\sqrt{2}}{2}\\\\\\frac{\\sqrt{2}}{2} & \\frac{\\sqrt{2}}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}1 & 0\\\\0 & - i\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2} & - \\frac{\\sqrt{2}}{2}\\\\\\frac{\\sqrt{2} i}{2} & \\frac{\\sqrt{2} i}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2} & - \\frac{\\sqrt{2} i}{2}\\\\\\frac{\\sqrt{2}}{2} & \\frac{\\sqrt{2} i}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2} & - \\frac{\\sqrt{2} i}{2}\\\\\\frac{\\sqrt{2} i}{2} & - \\frac{\\sqrt{2}}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{1}{2} + \\frac{i}{2} & \\frac{1}{2} - \\frac{i}{2}\\\\\\frac{1}{2} - \\frac{i}{2} & \\frac{1}{2} + \\frac{i}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2} & \\frac{\\sqrt{2}}{2}\\\\- \\frac{\\sqrt{2}}{2} & \\frac{\\sqrt{2}}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}0 & 1\\\\1 & 0\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2} & \\frac{\\sqrt{2}}{2}\\\\- \\frac{\\sqrt{2} i}{2} & \\frac{\\sqrt{2} i}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}0 & 1\\\\i & 0\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{1}{2} - \\frac{i}{2} & \\frac{1}{2} + \\frac{i}{2}\\\\- \\frac{1}{2} + \\frac{i}{2} & \\frac{1}{2} + \\frac{i}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}0 & i\\\\1 & 0\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2} & \\frac{\\sqrt{2} i}{2}\\\\- \\frac{\\sqrt{2} i}{2} & - \\frac{\\sqrt{2}}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{1}{2} - \\frac{i}{2} & - \\frac{1}{2} + \\frac{i}{2}\\\\- \\frac{1}{2} + \\frac{i}{2} & - \\frac{1}{2} + \\frac{i}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}0 & -1\\\\1 & 0\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2} & - \\frac{\\sqrt{2}}{2}\\\\- \\frac{\\sqrt{2} i}{2} & - \\frac{\\sqrt{2} i}{2}\\end{matrix}\\right], \\  \\left[\\begin{matrix}\\frac{1}{2} - \\frac{i}{2} & \\frac{i \\left(-1 + i\\right)}{2}\\\\- \\frac{1}{2} + \\frac{i}{2} & \\frac{i \\left(-1 + i\\right)}{2}\\end{matrix}\\right]\\right]$"
      ],
      "text/plain": [
       "⎡⎡√2   √2 ⎤                  ⎡ √2     √2  ⎤  ⎡√2   √2⋅ⅈ ⎤           ⎡ √2   √2⋅\n",
       "⎢⎢──   ── ⎥                  ⎢ ──     ──  ⎥  ⎢──   ──── ⎥           ⎢ ──   ───\n",
       "⎢⎢2    2  ⎥  ⎡1  0⎤  ⎡1  0⎤  ⎢ 2      2   ⎥  ⎢2     2   ⎥  ⎡1  0 ⎤  ⎢ 2     2 \n",
       "⎢⎢        ⎥, ⎢    ⎥, ⎢    ⎥, ⎢            ⎥, ⎢          ⎥, ⎢     ⎥, ⎢         \n",
       "⎢⎢√2  -√2 ⎥  ⎣0  ⅈ⎦  ⎣0  1⎦  ⎢√2⋅ⅈ  -√2⋅ⅈ ⎥  ⎢√2  -√2⋅ⅈ ⎥  ⎣0  -1⎦  ⎢√2⋅ⅈ   √2\n",
       "⎢⎢──  ────⎥                  ⎢────  ──────⎥  ⎢──  ──────⎥           ⎢────   ──\n",
       "⎣⎣2    2  ⎦                  ⎣ 2      2   ⎦  ⎣2     2   ⎦           ⎣ 2     2 \n",
       "\n",
       "ⅈ⎤  ⎡√2  -√2 ⎤           ⎡ √2   -√2 ⎤  ⎡√2  -√2⋅ⅈ ⎤  ⎡ √2   -√2⋅ⅈ ⎤  ⎡1   ⅈ  1\n",
       "─⎥  ⎢──  ────⎥           ⎢ ──   ────⎥  ⎢──  ──────⎥  ⎢ ──   ──────⎥  ⎢─ + ─  ─\n",
       " ⎥  ⎢2    2  ⎥  ⎡1  0 ⎤  ⎢ 2     2  ⎥  ⎢2     2   ⎥  ⎢ 2      2   ⎥  ⎢2   2  2\n",
       " ⎥, ⎢        ⎥, ⎢     ⎥, ⎢          ⎥, ⎢          ⎥, ⎢            ⎥, ⎢        \n",
       " ⎥  ⎢√2   √2 ⎥  ⎣0  -ⅈ⎦  ⎢√2⋅ⅈ  √2⋅ⅈ⎥  ⎢√2   √2⋅ⅈ ⎥  ⎢√2⋅ⅈ   -√2  ⎥  ⎢1   ⅈ  1\n",
       " ⎥  ⎢──   ── ⎥           ⎢────  ────⎥  ⎢──   ──── ⎥  ⎢────   ──── ⎥  ⎢─ - ─  ─\n",
       " ⎦  ⎣2    2  ⎦           ⎣ 2     2  ⎦  ⎣2     2   ⎦  ⎣ 2      2   ⎦  ⎣2   2  2\n",
       "\n",
       "   ⅈ⎤  ⎡ √2   √2⎤          ⎡  √2     √2 ⎤          ⎡ 1   ⅈ   1   ⅈ⎤          ⎡\n",
       " - ─⎥  ⎢ ──   ──⎥          ⎢  ──     ── ⎥          ⎢ ─ - ─   ─ + ─⎥          ⎢\n",
       "   2⎥  ⎢ 2    2 ⎥  ⎡0  1⎤  ⎢  2      2  ⎥  ⎡0  1⎤  ⎢ 2   2   2   2⎥  ⎡0  ⅈ⎤  ⎢\n",
       "    ⎥, ⎢        ⎥, ⎢    ⎥, ⎢            ⎥, ⎢    ⎥, ⎢              ⎥, ⎢    ⎥, ⎢\n",
       "   ⅈ⎥  ⎢-√2   √2⎥  ⎣1  0⎦  ⎢-√2⋅ⅈ   √2⋅ⅈ⎥  ⎣ⅈ  0⎦  ⎢  1   ⅈ  1   ⅈ⎥  ⎣1  0⎦  ⎢\n",
       " + ─⎥  ⎢────  ──⎥          ⎢──────  ────⎥          ⎢- ─ + ─  ─ + ─⎥          ⎢\n",
       "   2⎦  ⎣ 2    2 ⎦          ⎣  2      2  ⎦          ⎣  2   2  2   2⎦          ⎣\n",
       "\n",
       "  √2    √2⋅ⅈ⎤  ⎡ 1   ⅈ     1   ⅈ⎤           ⎡  √2     -√2  ⎤  ⎡ 1   ⅈ   ⅈ⋅(-1 \n",
       "  ──    ────⎥  ⎢ ─ - ─   - ─ + ─⎥           ⎢  ──     ──── ⎥  ⎢ ─ - ─   ──────\n",
       "  2      2  ⎥  ⎢ 2   2     2   2⎥  ⎡0  -1⎤  ⎢  2       2   ⎥  ⎢ 2   2       2 \n",
       "            ⎥, ⎢                ⎥, ⎢     ⎥, ⎢              ⎥, ⎢               \n",
       "-√2⋅ⅈ   -√2 ⎥  ⎢  1   ⅈ    1   ⅈ⎥  ⎣1  0 ⎦  ⎢-√2⋅ⅈ   -√2⋅ⅈ ⎥  ⎢  1   ⅈ  ⅈ⋅(-1 \n",
       "──────  ────⎥  ⎢- ─ + ─  - ─ + ─⎥           ⎢──────  ──────⎥  ⎢- ─ + ─  ──────\n",
       "  2      2  ⎦  ⎣  2   2    2   2⎦           ⎣  2       2   ⎦  ⎣  2   2      2 \n",
       "\n",
       "+ ⅈ)⎤⎤\n",
       "────⎥⎥\n",
       "    ⎥⎥\n",
       "    ⎥⎥\n",
       "+ ⅈ)⎥⎥\n",
       "────⎥⎥\n",
       "    ⎦⎦"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import sympy\n",
    "import numpy as np\n",
    "\n",
    "from collections import defaultdict\n",
    "from itertools import product\n",
    "\n",
    "M = sympy.Matrix\n",
    "simplify = sympy.simplify\n",
    "sqrt = sympy.sqrt\n",
    "i = sympy.I\n",
    "i_ = i\n",
    "\n",
    "from sympy.physics.quantum import Dagger\n",
    "from sympy.physics.quantum import tensorproduct\n",
    "\n",
    "sympy.init_printing()\n",
    "H = simplify(M([[1, 1], [1, -1]]) / sqrt(2))\n",
    "S = M([[1, 0], [0, i]])\n",
    "C_L = [H, S]\n",
    "basis_vectors = [M([1, 0]), M([0, 1])]\n",
    "\n",
    "def getitem(m, i, j):\n",
    "    # Note that sympy uses an extremely weird way to store the matrices,\n",
    "    # in particular the internal representation is vastly different from what\n",
    "    # is printed. For instance the H matrix is stored as a Mul object\n",
    "    # (even after using simplify) instead of a matrix. \n",
    "    # Therefore m[i][j] will NOT work. This is a workaround.\n",
    "    return (Dagger(basis_vectors[i]) * m * basis_vectors[j])[0]\n",
    "\n",
    "def is_known(C_L, a):\n",
    "    for c in C_L:\n",
    "        test = c * Dagger(a)\n",
    "        if(simplify(getitem(test, 0, 1)) != 0):\n",
    "            continue\n",
    "        if(simplify(getitem(test, 0, 0) / getitem(test, 1, 1)) == 1):\n",
    "            return True\n",
    "    return False\n",
    "for i in range(5):\n",
    "    for m in (H, S):\n",
    "        for c in C_L:\n",
    "            c = simplify(c*m)\n",
    "            if(is_known(C_L, c)):\n",
    "                continue\n",
    "            C_L.append(c)\n",
    "C_L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEIAAAAzCAYAAAAjKt6MAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADb0lEQVRoBe1bi3ETMRC1GQrwQAdOBwlUgNMBoQOgAxhXwIQOAhUwuIOECjJJB6EDPO7AvHfsZnQXaXUyOtu60c7IZ31ute9pV6eT7OlkMpkhPZHtdrt5UjiCgul06sVLaA9I2066AhGTMSbgvO5gJfbrZ/ignAP01Ekf/xWP7xMYW1iBsMGqRIwPcSKi533bI7ZO0fYn0hlYPYr5AzZdiv1/cD1BuoRtv6Us6WISIRPLd2hcI71CmidpH7AxbLuD+i8AvmI3YusdrnT9ZDLM0ODII10gMY5+sMNjEID9ADtmsKshgTbRVlyYv2I+VUwiUpXtsf0F+rr39HeLsoV4h6c6XFQqEQtAYrh2Recu1idJcUT0HO0XSSygcXFEwGYFqaPvYlYvmbmFfb6XSEQfXC/7NHLblEiEjrqLQ7+rt3BdkSTFESGPSYL0ub+W5V1HJFG638Y36G7u6VI9gvVJUpxHCDou9bnS7coZCu4dr+nWB/NFEgGg34BojUfpW0Umj9V3yL/XspSr+a5BReiA7DP2dAS4nueq7hYGfcX1UMLRX8IWDZHXyL+BTbQtWaJEQDGXs0cnsGsDoz7nMqzI0MgF3tVTiRA2KhGVCDcwynzpaiPIlKuhUUOj7UrVI6pHVI9oMyC56BKb7bCez3aQ4rVi4ELY/wldnGBZHjzKjBIBJVkPUgbGHFJPAh7PQHyNTCJAgvcgBeV6kHLuU3psZfAEHgeaEntqZD9IMa05YGWMiAVs822W8hWYwvpRSDA04P66EWoB1T1Cq81B6sR+hjbD4gHhYW4iWR6hIHX0XUDqJX3Icu/b5/elgOcO2zLWsUVE7F7WJx+k9FH6v23gDXPo4IEwhfNcdHs/GBq4WUedyrqi3pJ8kNJVFMqLa/9CfYrX8ScM3LNc46qPS4ZHdEsvSAQUbWAM7fQZomVRpqlgF2H/uI8btMki93IhqLvc3PU2JRYa2Q9STGvyV3JuWCkxlvoYEdkPUixjctZJaJ1CZ/NLH+T1NcHbjUkEmMx+kOK1YpjC5hwGGFYggZMnf08alOAc4dyR9SDF0TvoVxBwAwKY+MLF34KZ80SUCCjgpBWddQdFtaNy2N77XcgMjR37L/K2SoQMWyWiEtGO4OoRwoc+NeZ4zOiyuamSp0WbthHkujgB6RF3/eMK/rjyFzozUuFUA8PIAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$\\displaystyle \\left[\\begin{matrix}1 & 0\\\\0 & - i\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "⎡1  0 ⎤\n",
       "⎢     ⎥\n",
       "⎣0  -ⅈ⎦"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "C_L[8]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sympy import exp,pi, I as i\n",
    "\n",
    "siZ = exp(i*pi/4)*Dagger(S)\n",
    "smiX = simplify(M([[1, -i], [-i, 1]]) / sqrt(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_product_index(a):\n",
    "    for i,c in enumerate(C_L):\n",
    "        test = c * Dagger(a)\n",
    "        if(simplify(getitem(test, 0, 1)) != 0):\n",
    "            continue\n",
    "        if(simplify(getitem(test, 0, 0) / getitem(test, 1, 1)) == 1):\n",
    "            return i\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABMAAAAOCAYAAADNGCeJAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA50lEQVQ4EaWTgQ2CQAxFD8MAzMAIRkcxbqAbsAs6AiM4g24gIygb4PuxJWAucmiTn7s2v78tXEPf98ERQliDOyg89u00fu2cPMuyguAZPMAGlCDVGog3J+eodjg7BRCuONTdrBl3wltNvEQHIRVUE8JgP4mRvWei06Bil8ViNl79KSR/kRhCJTkdXbV/iyFwjI3nwsmd0dWBpOh4i8RsPD3k6Hgulvtl5tS32iKqRzo2PZHS4u2wSlQVSY9Wl9R1esJtlCskfzOSYqZVFN5mHan9C1AldaZlV6zyquOTuH7EFYgrKLd6AYEOlZKRps3SAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$\\displaystyle 14$"
      ],
      "text/plain": [
       "14"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_product_index(siZ * siZ**3 * smiX**2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABMAAAAOCAYAAADNGCeJAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABEklEQVQ4EZWTgQ2CQAxFOeMAxBFwA2UERzA6AStonMDoBo5gdAPZwOgGsIHBDfB9cjWBiDma/PT41/5CS11d15GZc27G+QLm8G/ju564Q4c7E/8UFwMJnMADSD1WkS7gE1CAhd1xVm6h51YC5Ab8E1Oxkwk1AlF0g7sNEiNh+a+QxEYEhNqOwDdJvb0chyoRp+E8/ZDWnF9gCi4UyPFRkBgCGpJZSvLWHrirQAZ3DRoAiRLTYMhpTxlOf0EF4qCeIWB9KknqmiasYmmQmM+WkIl6quWSoWJ6gz4rh4hphZIfSnM4/TJ5sJiCScqZ3Hcv/ZRX8JmKOE0HUvvVNNF79UeLe+f+iP+aF7PPnXCxJ6ZZ8g/qi9kBXL0ZywAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$\\displaystyle 16$"
      ],
      "text/plain": [
       "16"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_product_index(siZ**2 * smiX**2 * siZ**3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABMAAAAOCAYAAADNGCeJAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABH0lEQVQ4EZWTgU3DQAxFe0wQlQ3KBtAROkJYgRGQGAE2YIawQbpBVTaADaDZILx3PVcKiqqLpR/f+ewfn+1L4ziuQlJK96w78IB9CHtozhvWL+AH3AL3Hb57dJZsYPUOjkD2xp/8hz4zNn/eap8EYHwGs2TYn8QMmckctd+wqJU7HB+vOS8h6yHaUbe+1C54X1lYovpr5pqcm2MZhCWRJNdrUc2iVgSbSRDasE2cLbnmiuu1BCvWz3FwlL6w79D118TVbk5Gg73kZnkCzZLRyAFxpdCQbAphW3XN0j0HeSBwIti+MXyAdRVZIRkgNYs5cXD3VWQl2oHtSpYXQvbWsjfDxMcu+b5k3xZt6p/gwPkbOgt+ds+H/nu25O/lof8B0j8TKAhBPH8AAAAASUVORK5CYII=\n",
      "text/latex": [
       "$\\displaystyle 18$"
      ],
      "text/plain": [
       "18"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_product_index(siZ**2 * smiX**2 * siZ**3 * siZ**2)"
   ]
  }
 ],
 "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.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
