Commits

committed fd7e345

WIP: Back up working draft of demo for class.

• Participants
• Parent commits a0fc88b
• Branches master

File docs/notebooks/demo.ipynb

+{
+ "metadata": {
+  "name": ""
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+  {
+   "cells": [
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "# PyQC\n",
+      "\n",
+      "[PyQC](https://bitbucket.org/embray/pyqc) is a project I put together specifically to make it easy to assemble and evaluate/simulate quantum circuits using a simple, terse syntax in Python--my programming language of choice.  I also wanted it to integrate with with the [IPython Notebook](http://ipython.org/notebook.html) environment; this is very similar (and in fact inspired by) the Mathematica Notebook, for those familiar with it.  This would enable users to render equations built up from objects representing quantum gates as $\\LaTeX$ equations, and to render quantum circuit diagrams.  I felt that such a tool might be of pedagogical value both for myself and others.\n",
+      "\n",
+      "## Motivation and introduction to QuTiP\n",
+      "\n",
+      "The idea for this project came in part from my earlier experiments with a larger Python library called [QuTiP](http://qutip.org/), which stands for Quantum Toolbox in Python.  QuTiP is designed primarily for efficient representation and evaluation of quantum operators on state vectors and simulation of complicated real world quantum systems.  It is built on a basic framework for representing operators and states in large-ish Hilbert spaces through use of \"time-tested\" numerical code on the backend--especially FORTRAN routines for working with sparse matrices.\n",
+      "\n",
+      "I have only begun to scratch the surface of QuTiP's functionality--much of it is built to solve problems that I have not personally encountered yet, such as evaluating the time-evolution of a state vector under the influence of an arbitrary Hamiltonian.  It is not especially useful for much abstract mathematical work either, but I have occasionally found it useful to check my results numerically.  I do not want to distract too much from my own work by dwelling on QuTiP, but it would be useful to introduce some of its most basic functionality, as it underlies much of PyQC.\n",
+      "\n",
+      "To get started using QuTiP, just:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "import qutip"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 1
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "One could also use the from qutip import * which in Python means to import every object defined in the qutip namespace into the current local namespace.  I avoid doing that here since I want to keep it clear what functions and classes come for qutip as opposed to my package pyqc."
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "The central data structure underlying most of QuTiP is a class called qutip.Qobj.  A Qobj can be used to represent either a bra/ket state vector, *or* a quantum operator.  All of these are represented internally by sparse matrices (for example a ket vector is just an $n \\times 1$ sparse matrix, while operators are $n \\times n$ where $n$ is the size of the Hilbert space that we're operating on).  Vectors and operators can be instantiated in many different ways in QuTiP, but the simplest is just to explicitly state their elements in some basis.  For example to create a 4-dimensional bra vector:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "bra = qutip.Qobj([0, 1])\n",
+      "bra"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "latex": [
+        "\$$\\text{Quantum object: dims = [[1], [2]], shape = [1, 2], type = bra}\\\\[1em]\\begin{pmatrix}0.0 & 1.0\\\\\\end{pmatrix}\$$"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 33,
+       "text": [
+        "Quantum object: dims = [[1], [2]], shape = [1, 2], type = bra\n",
+        "Qobj data =\n",
+        "[[ 0.  1.]]"
+       ]
+      }
+     ],
+     "prompt_number": 33
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "QuTiP tells us that this particular Qobj represents a bra (due to its shape) and displays its elements.  We can easily get the corresponding ket vector using the Qobj.dag() method:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "ket = bra.dag()\n",
+      "ket"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "latex": [
+        "\$$\\text{Quantum object: dims = [[2], [1]], shape = [2, 1], type = ket}\\\\[1em]\\begin{pmatrix}0.0\\\\1.0\\\\\\end{pmatrix}\$$"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 34,
+       "text": [
+        "Quantum object: dims = [[2], [1]], shape = [2, 1], type = ket\n",
+        "Qobj data =\n",
+        "[[ 0.]\n",
+        " [ 1.]]"
+       ]
+      }
+     ],
+     "prompt_number": 34
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "We can use the same syntax to create various quantum operators by specifying their matrix components (being careful to use the same basis in which we defined our state vectors).  For example we can define the Pauli matrix $\\sigma_y$ as follows (note:  Python uses the syntax 1j to represent the imaginary unit $i$):"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "sigma_y = qutip.Qobj([[ 0, -1j],\n",
+      "                      [1j,   0]])\n",
+      "sigma_y"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "latex": [
+        "\$$\\text{Quantum object: dims = [[2], [2]], shape = [2, 2], type = oper, isHerm = True}\\\\[1em]\\begin{pmatrix}0.0 & -1j\\\\1j & 0.0\\\\\\end{pmatrix}\$$"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 35,
+       "text": [
+        "Quantum object: dims = [[2], [2]], shape = [2, 2], type = oper, isherm = True\n",
+        "Qobj data =\n",
+        "[[ 0.+0.j  0.-1.j]\n",
+        " [ 0.+1.j  0.+0.j]]"
+       ]
+      }
+     ],
+     "prompt_number": 35
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "QuTiP recognizes that as an $n \\times n$ matrix this Qobj represents an operator.  It also tells use automatically that it is Hermitian (it does not, however, mention whether it is unitary but non-Hermitian).  Operators can operate on a state using Python's standard multiplication operator *, producing a new ket vector:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "sigma_y * ket"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "latex": [
+        "\$$\\text{Quantum object: dims = [[2], [1]], shape = [2, 1], type = ket}\\\\[1em]\\begin{pmatrix}-1j\\\\0.0\\\\\\end{pmatrix}\$$"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 37,
+       "text": [
+        "Quantum object: dims = [[2], [1]], shape = [2, 1], type = ket\n",
+        "Qobj data =\n",
+        "[[ 0.-1.j]\n",
+        " [ 0.+0.j]]"
+       ]
+      }
+     ],
+     "prompt_number": 37
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "I should note that many common operators are built in to QuTiP, though one of the problems I had with it early on are some of the long, relatively cumberson names they are given:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "qutip.sigmay()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "latex": [
+        "\$$\\text{Quantum object: dims = [[2], [2]], shape = [2, 2], type = oper, isHerm = True}\\\\[1em]\\begin{pmatrix}0.0 & -1j\\\\1j & 0.0\\\\\\end{pmatrix}\$$"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 38,
+       "text": [
+        "Quantum object: dims = [[2], [2]], shape = [2, 2], type = oper, isherm = True\n",
+        "Qobj data =\n",
+        "[[ 0.+0.j  0.-1.j]\n",
+        " [ 0.+1.j  0.+0.j]]"
+       ]
+      }
+     ],
+     "prompt_number": 38
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "qutip.identity(4)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "latex": [
+        "\$$\\text{Quantum object: dims = [[4], [4]], shape = [4, 4], type = oper, isHerm = True}\\\\[1em]\\begin{pmatrix}1.0 & 0.0 & 0.0 & 0.0\\\\0.0 & 1.0 & 0.0 & 0.0\\\\0.0 & 0.0 & 1.0 & 0.0\\\\0.0 & 0.0 & 0.0 & 1.0\\\\\\end{pmatrix}\$$"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 39,
+       "text": [
+        "Quantum object: dims = [[4], [4]], shape = [4, 4], type = oper, isherm = True\n",
+        "Qobj data =\n",
+        "[[ 1.  0.  0.  0.]\n",
+        " [ 0.  1.  0.  0.]\n",
+        " [ 0.  0.  1.  0.]\n",
+        " [ 0.  0.  0.  1.]]"
+       ]
+      }
+     ],
+     "prompt_number": 39
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Etc.  Sure, one could assign these operators to shorter names.  But I wanted a package that would give me a collection of short symbols that I can use out of the box to build up quantum circuits, rather than have to define them every time I need them.  To give one simple motivating example, say you wanted to create the following circuit, which implements the Deutsch algorithm for a single qubit with an oracle for the function $f(x) = x$:"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "<div style=\"text-align: center\"><img style=\"text-align: center\" src=\"https://bitbucket.org/embray/pyqc/raw/a99f2387650ce253b1387b35afd09ee56e41e531/docs/source/latex/figure1.png\" /></div>"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "To begin we want to create some $H$ and $\\mathrm{CNOT}$ gates (and assign them reasonably short names).  Note the use of the qutip.tensor() function which returns the tensor product of two operators.  This also uses the qutip.fock_dm() (for Fock density matrix) function as a shortcut for creating outer products like $|0\\rangle\\langle 0|$ and $|1\\rangle\\langle 1|$:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "H = (2 ** -0.5) * qutip.Qobj([[1, 1], [1, -1]])\n",
+      "H"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "latex": [
+        "\$$\\text{Quantum object: dims = [[2], [2]], shape = [2, 2], type = oper, isHerm = True}\\\\[1em]\\begin{pmatrix}0.707106781187 & 0.707106781187\\\\0.707106781187 & -0.707106781187\\\\\\end{pmatrix}\$$"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 42,
+       "text": [
+        "Quantum object: dims = [[2], [2]], shape = [2, 2], type = oper, isherm = True\n",
+        "Qobj data =\n",
+        "[[ 0.70710678  0.70710678]\n",
+        " [ 0.70710678 -0.70710678]]"
+       ]
+      }
+     ],
+     "prompt_number": 42
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "CNOT = qutip.tensor(qutip.fock_dm(2, 0), qutip.identity(2)) + qutip.tensor(qutip.fock_dm(2, 1), qutip.sigmax())\n",
+      "CNOT"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "latex": [
+        "\$$\\text{Quantum object: dims = [[2, 2], [2, 2]], shape = [4, 4], type = oper, isHerm = True}\\\\[1em]\\begin{pmatrix}1.0 & 0.0 & 0.0 & 0.0\\\\0.0 & 1.0 & 0.0 & 0.0\\\\0.0 & 0.0 & 0.0 & 1.0\\\\0.0 & 0.0 & 1.0 & 0.0\\\\\\end{pmatrix}\$$"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 43,
+       "text": [
+        "Quantum object: dims = [[2, 2], [2, 2]], shape = [4, 4], type = oper, isherm = True\n",
+        "Qobj data =\n",
+        "[[ 1.  0.  0.  0.]\n",
+        " [ 0.  1.  0.  0.]\n",
+        " [ 0.  0.  0.  1.]\n",
+        " [ 0.  0.  1.  0.]]"
+       ]
+      }
+     ],
+     "prompt_number": 43
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Then implement the circuit using a combination of multiplication operators and tensor products (returning the circuit as a new operator):"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "circuit = qutip.tensor(H, qutip.identity(2)) * CNOT * qutip.tensor(H, H)\n",
+      "circuit"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "latex": [
+        "\$$\\text{Quantum object: dims = [[2, 2], [2, 2]], shape = [4, 4], type = oper, isHerm = False}\\\\[1em]\\begin{pmatrix}0.707106781187 & 0.0 & 0.0 & 0.707106781187\\\\0.707106781187 & 0.0 & 0.0 & -0.707106781187\\\\0.0 & 0.707106781187 & 0.707106781187 & 0.0\\\\0.0 & -0.707106781187 & 0.707106781187 & 0.0\\\\\\end{pmatrix}\$$"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 44,
+       "text": [
+        "Quantum object: dims = [[2, 2], [2, 2]], shape = [4, 4], type = oper, isherm = False\n",
+        "Qobj data =\n",
+        "[[ 0.70710678  0.          0.          0.70710678]\n",
+        " [ 0.70710678  0.          0.         -0.70710678]\n",
+        " [ 0.          0.70710678  0.70710678  0.        ]\n",
+        " [ 0.         -0.70710678  0.70710678  0.        ]]"
+       ]
+      }
+     ],
+     "prompt_number": 44
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "This is fairly straightforward if you are already familiar with the circuit being implemented, but I found it difficult, just be looking at the code (without the circuit diagram) to understand wha tthis is doing.  Now we can apply this circuit to the input $|0\\rangle |1\\rangle$ by applying the circuit as an operator..."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "# Note: The basis function() returns computational basis vectors\n",
+      "# QuTiP is also (somewhat reasonably) very picky about vector spaces, and will not\n",
+      "# allow me to apply this circuit to qutip.basis(4, 1)\n",
+      "result = circuit * qutip.tensor(qutip.basis(2, 1), qutip.basis(2, 1))\n",
+      "result"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "latex": [
+        "\$$\\text{Quantum object: dims = [[2, 2], [1, 1]], shape = [4, 1], type = ket}\\\\[1em]\\begin{pmatrix}0.707106781187\\\\-0.707106781187\\\\0.0\\\\0.0\\\\\\end{pmatrix}\$$"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 49,
+       "text": [
+        "Quantum object: dims = [[2, 2], [1, 1]], shape = [4, 1], type = ket\n",
+        "Qobj data =\n",
+        "[[ 0.70710678]\n",
+        " [-0.70710678]\n",
+        " [ 0.        ]\n",
+        " [ 0.        ]]"
+       ]
+      }
+     ],
+     "prompt_number": 49
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "...and we can use qutip.expect() to return the expectation value for measurements of the first qubit:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "qutip.expect(qutip.tensor(qutip.sigmaz(), qutip.identity(2)), result)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 50,
+       "text": [
+        "1.0000000000000004"
+       ]
+      }
+     ],
+     "prompt_number": 50
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "This clearly gives the correct answer (ignoring floating point round-off errors), and it wasn\u2019t terribly difficult, but still a bit cumbersome.  But to be clear, PyQC set out to be more than just a collection of shorter names for QuTiP operations.  I wanted a way to more easily create quantum circuits in a format similar to how one might draw a circuit diagram."
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "## Introduction to vectors and operators in PyQC"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "from pyqc import *"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 5
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "CR_2 = ControlledGate(R_k(2))\n",
+      "CR_3 = ControlledGate(R_k(3))\n",
+      "CR_4 = ControlledGate(R_k(4))\n",
+      "qft = Circuit([\n",
+      "    [H, CR_2.target,  CR_3.target,  CR_4.target, I, I,            I,            I, I,            I, SWAP.qubit0, I],\n",
+      "    [I, CR_2.control, I,            I,           H, CR_2.target,  CR_3.target,  I, I,            I, I,           SWAP.qubit0],\n",
+      "    [I, I,            CR_3.control, I,           I, CR_2.control, I,            H, CR_2.target,  I, I,           SWAP.qubit1],\n",
+      "    [I, I,            I,            CR_4.control,I, I,            CR_3.control, I, CR_2.control, H, SWAP.qubit1, I]])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 6
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "qft"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "png": "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\nAElFTkSuQmCC\n",
+       "prompt_number": 15,
+       "text": [
+        "Gate([[  2.50000000e-01+0.j           2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j           2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j           2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j           2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j           2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j           2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j           2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j           2.50000000e-01+0.j        ]\n",
+        "      [  2.50000000e-01+0.j           2.30969883e-01+0.09567086j\n",
+        "         1.76776695e-01+0.1767767j    9.56708581e-02+0.23096988j\n",
+        "         1.53075794e-17+0.25j        -9.56708581e-02+0.23096988j\n",
+        "        -1.76776695e-01+0.1767767j   -2.30969883e-01+0.09567086j\n",
+        "        -2.50000000e-01+0.j          -2.30969883e-01-0.09567086j\n",
+        "        -1.76776695e-01-0.1767767j   -9.56708581e-02-0.23096988j\n",
+        "        -1.53075794e-17-0.25j         9.56708581e-02-0.23096988j\n",
+        "         1.76776695e-01-0.1767767j    2.30969883e-01-0.09567086j]\n",
+        "      [  2.50000000e-01+0.j           1.76776695e-01+0.1767767j\n",
+        "         1.53075794e-17+0.25j        -1.76776695e-01+0.1767767j\n",
+        "        -2.50000000e-01+0.j          -1.76776695e-01-0.1767767j\n",
+        "        -1.53075794e-17-0.25j         1.76776695e-01-0.1767767j\n",
+        "         2.50000000e-01+0.j           1.76776695e-01+0.1767767j\n",
+        "         1.53075794e-17+0.25j        -1.76776695e-01+0.1767767j\n",
+        "        -2.50000000e-01+0.j          -1.76776695e-01-0.1767767j\n",
+        "        -1.53075794e-17-0.25j         1.76776695e-01-0.1767767j ]\n",
+        "      [  2.50000000e-01+0.j           9.56708581e-02+0.23096988j\n",
+        "        -1.76776695e-01+0.1767767j   -2.30969883e-01-0.09567086j\n",
+        "        -1.53075794e-17-0.25j         2.30969883e-01-0.09567086j\n",
+        "         1.76776695e-01+0.1767767j   -9.56708581e-02+0.23096988j\n",
+        "        -2.50000000e-01+0.j          -9.56708581e-02-0.23096988j\n",
+        "         1.76776695e-01-0.1767767j    2.30969883e-01+0.09567086j\n",
+        "         1.53075794e-17+0.25j        -2.30969883e-01+0.09567086j\n",
+        "        -1.76776695e-01-0.1767767j    9.56708581e-02-0.23096988j]\n",
+        "      [  2.50000000e-01+0.j           1.53075794e-17+0.25j\n",
+        "        -2.50000000e-01+0.j          -1.53075794e-17-0.25j\n",
+        "         2.50000000e-01+0.j           1.53075794e-17+0.25j\n",
+        "        -2.50000000e-01+0.j          -1.53075794e-17-0.25j\n",
+        "         2.50000000e-01+0.j           1.53075794e-17+0.25j\n",
+        "        -2.50000000e-01+0.j          -1.53075794e-17-0.25j\n",
+        "         2.50000000e-01+0.j           1.53075794e-17+0.25j\n",
+        "        -2.50000000e-01+0.j          -1.53075794e-17-0.25j      ]\n",
+        "      [  2.50000000e-01+0.j          -9.56708581e-02+0.23096988j\n",
+        "        -1.76776695e-01-0.1767767j    2.30969883e-01-0.09567086j\n",
+        "         1.53075794e-17+0.25j        -2.30969883e-01-0.09567086j\n",
+        "         1.76776695e-01-0.1767767j    9.56708581e-02+0.23096988j\n",
+        "        -2.50000000e-01+0.j           9.56708581e-02-0.23096988j\n",
+        "         1.76776695e-01+0.1767767j   -2.30969883e-01+0.09567086j\n",
+        "        -1.53075794e-17-0.25j         2.30969883e-01+0.09567086j\n",
+        "        -1.76776695e-01+0.1767767j   -9.56708581e-02-0.23096988j]\n",
+        "      [  2.50000000e-01+0.j          -1.76776695e-01+0.1767767j\n",
+        "        -1.53075794e-17-0.25j         1.76776695e-01+0.1767767j\n",
+        "        -2.50000000e-01+0.j           1.76776695e-01-0.1767767j\n",
+        "         1.53075794e-17+0.25j        -1.76776695e-01-0.1767767j\n",
+        "         2.50000000e-01+0.j          -1.76776695e-01+0.1767767j\n",
+        "        -1.53075794e-17-0.25j         1.76776695e-01+0.1767767j\n",
+        "        -2.50000000e-01+0.j           1.76776695e-01-0.1767767j\n",
+        "         1.53075794e-17+0.25j        -1.76776695e-01-0.1767767j ]\n",
+        "      [  2.50000000e-01+0.j          -2.30969883e-01+0.09567086j\n",
+        "         1.76776695e-01-0.1767767j   -9.56708581e-02+0.23096988j\n",
+        "        -1.53075794e-17-0.25j         9.56708581e-02+0.23096988j\n",
+        "        -1.76776695e-01-0.1767767j    2.30969883e-01+0.09567086j\n",
+        "        -2.50000000e-01+0.j           2.30969883e-01-0.09567086j\n",
+        "        -1.76776695e-01+0.1767767j    9.56708581e-02-0.23096988j\n",
+        "         1.53075794e-17+0.25j        -9.56708581e-02-0.23096988j\n",
+        "         1.76776695e-01+0.1767767j   -2.30969883e-01-0.09567086j]\n",
+        "      [  2.50000000e-01+0.j          -2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j          -2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j          -2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j          -2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j          -2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j          -2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j          -2.50000000e-01+0.j\n",
+        "         2.50000000e-01+0.j          -2.50000000e-01+0.j        ]\n",
+        "      [  2.50000000e-01+0.j          -2.30969883e-01-0.09567086j\n",
+        "         1.76776695e-01+0.1767767j   -9.56708581e-02-0.23096988j\n",
+        "         1.53075794e-17+0.25j         9.56708581e-02-0.23096988j\n",
+        "        -1.76776695e-01+0.1767767j    2.30969883e-01-0.09567086j\n",
+        "        -2.50000000e-01+0.j           2.30969883e-01+0.09567086j\n",
+        "        -1.76776695e-01-0.1767767j    9.56708581e-02+0.23096988j\n",
+        "        -1.53075794e-17-0.25j        -9.56708581e-02+0.23096988j\n",
+        "         1.76776695e-01-0.1767767j   -2.30969883e-01+0.09567086j]\n",
+        "      [  2.50000000e-01+0.j          -1.76776695e-01-0.1767767j\n",
+        "         1.53075794e-17+0.25j         1.76776695e-01-0.1767767j\n",
+        "        -2.50000000e-01+0.j           1.76776695e-01+0.1767767j\n",
+        "        -1.53075794e-17-0.25j        -1.76776695e-01+0.1767767j\n",
+        "         2.50000000e-01+0.j          -1.76776695e-01-0.1767767j\n",
+        "         1.53075794e-17+0.25j         1.76776695e-01-0.1767767j\n",
+        "        -2.50000000e-01+0.j           1.76776695e-01+0.1767767j\n",
+        "        -1.53075794e-17-0.25j        -1.76776695e-01+0.1767767j ]\n",
+        "      [  2.50000000e-01+0.j          -9.56708581e-02-0.23096988j\n",
+        "        -1.76776695e-01+0.1767767j    2.30969883e-01+0.09567086j\n",
+        "        -1.53075794e-17-0.25j        -2.30969883e-01+0.09567086j\n",
+        "         1.76776695e-01+0.1767767j    9.56708581e-02-0.23096988j\n",
+        "        -2.50000000e-01+0.j           9.56708581e-02+0.23096988j\n",
+        "         1.76776695e-01-0.1767767j   -2.30969883e-01-0.09567086j\n",
+        "         1.53075794e-17+0.25j         2.30969883e-01-0.09567086j\n",
+        "        -1.76776695e-01-0.1767767j   -9.56708581e-02+0.23096988j]\n",
+        "      [  2.50000000e-01+0.j          -1.53075794e-17-0.25j\n",
+        "        -2.50000000e-01+0.j           1.53075794e-17+0.25j\n",
+        "         2.50000000e-01+0.j          -1.53075794e-17-0.25j\n",
+        "        -2.50000000e-01+0.j           1.53075794e-17+0.25j\n",
+        "         2.50000000e-01+0.j          -1.53075794e-17-0.25j\n",
+        "        -2.50000000e-01+0.j           1.53075794e-17+0.25j\n",
+        "         2.50000000e-01+0.j          -1.53075794e-17-0.25j\n",
+        "        -2.50000000e-01+0.j           1.53075794e-17+0.25j      ]\n",
+        "      [  2.50000000e-01+0.j           9.56708581e-02-0.23096988j\n",
+        "        -1.76776695e-01-0.1767767j   -2.30969883e-01+0.09567086j\n",
+        "         1.53075794e-17+0.25j         2.30969883e-01+0.09567086j\n",
+        "         1.76776695e-01-0.1767767j   -9.56708581e-02-0.23096988j\n",
+        "        -2.50000000e-01+0.j          -9.56708581e-02+0.23096988j\n",
+        "         1.76776695e-01+0.1767767j    2.30969883e-01-0.09567086j\n",
+        "        -1.53075794e-17-0.25j        -2.30969883e-01-0.09567086j\n",
+        "        -1.76776695e-01+0.1767767j    9.56708581e-02+0.23096988j]\n",
+        "      [  2.50000000e-01+0.j           1.76776695e-01-0.1767767j\n",
+        "        -1.53075794e-17-0.25j        -1.76776695e-01-0.1767767j\n",
+        "        -2.50000000e-01+0.j          -1.76776695e-01+0.1767767j\n",
+        "         1.53075794e-17+0.25j         1.76776695e-01+0.1767767j\n",
+        "         2.50000000e-01+0.j           1.76776695e-01-0.1767767j\n",
+        "        -1.53075794e-17-0.25j        -1.76776695e-01-0.1767767j\n",
+        "        -2.50000000e-01+0.j          -1.76776695e-01+0.1767767j\n",
+        "         1.53075794e-17+0.25j         1.76776695e-01+0.1767767j ]\n",
+        "      [  2.50000000e-01+0.j           2.30969883e-01-0.09567086j\n",
+        "         1.76776695e-01-0.1767767j    9.56708581e-02-0.23096988j\n",
+        "        -1.53075794e-17-0.25j        -9.56708581e-02-0.23096988j\n",
+        "        -1.76776695e-01-0.1767767j   -2.30969883e-01-0.09567086j\n",
+        "        -2.50000000e-01+0.j          -2.30969883e-01+0.09567086j\n",
+        "        -1.76776695e-01+0.1767767j   -9.56708581e-02+0.23096988j\n",
+        "         1.53075794e-17+0.25j         9.56708581e-02+0.23096988j\n",
+        "         1.76776695e-01+0.1767767j    2.30969883e-01+0.09567086j]])"
+       ]
+      }
+     ],
+     "prompt_number": 15
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "qft|Ket(0, 0, 0, 0)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "latex": [
+        "\$$\\text{Quantum object: dims = [[16], [1]], shape = [16, 1], type = ket}\\\\[1em]\\begin{pmatrix}0.25\\\\0.25\\\\0.25\\\\0.25\\\\0.25\\\\0.25\\\\0.25\\\\0.25\\\\0.25\\\\0.25\\\\0.25\\\\0.25\\\\0.25\\\\0.25\\\\0.25\\\\0.25\\\\\\end{pmatrix}\$$"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 21,
+       "text": [
+        "Quantum object: dims = [[16], [1]], shape = [16, 1], type = ket\n",
+        "Qobj data =\n",
+        "[[ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]\n",
+        " [ 0.25]]"
+       ]
+      }
+     ],
+     "prompt_number": 21
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "0.5 * (2**-0.5)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 5,
+       "text": [
+        "0.3535533905932738"
+       ]
+      }
+     ],
+     "prompt_number": 5
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "qft.qobj"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "latex": [
+        "\$$\\text{Quantum object: dims = [[8], [8]], shape = [8, 8], type = oper, isHerm = False}\\\\[1em]\\begin{pmatrix}0.353553390593 & 0.353553390593 & 0.353553390593 & 0.353553390593 & 0.353553390593 & 0.353553390593 & 0.353553390593 & 0.353553390593\\\\0.353553390593 & -0.353553390593 & (2.16481864268e-17+0.353553390593j) & (-2.16481864268e-17-0.353553390593j) & (0.25+0.25j) & (-0.25-0.25j) & (-0.25+0.25j) & (0.25-0.25j)\\\\0.353553390593 & 0.353553390593 & -0.353553390593 & -0.353553390593 & (2.16481864268e-17+0.353553390593j) & (2.16481864268e-17+0.353553390593j) & (-2.16481864268e-17-0.353553390593j) & (-2.16481864268e-17-0.353553390593j)\\\\0.353553390593 & -0.353553390593 & (-2.16481864268e-17-0.353553390593j) & (2.16481864268e-17+0.353553390593j) & (-0.25+0.25j) & (0.25-0.25j) & (0.25+0.25j) & (-0.25-0.25j)\\\\0.353553390593 & 0.353553390593 & 0.353553390593 & 0.353553390593 & -0.353553390593 & -0.353553390593 & -0.353553390593 & -0.353553390593\\\\0.353553390593 & -0.353553390593 & (2.16481864268e-17+0.353553390593j) & (-2.16481864268e-17-0.353553390593j) & (-0.25-0.25j) & (0.25+0.25j) & (0.25-0.25j) & (-0.25+0.25j)\\\\0.353553390593 & 0.353553390593 & -0.353553390593 & -0.353553390593 & (-2.16481864268e-17-0.353553390593j) & (-2.16481864268e-17-0.353553390593j) & (2.16481864268e-17+0.353553390593j) & (2.16481864268e-17+0.353553390593j)\\\\0.353553390593 & -0.353553390593 & (-2.16481864268e-17-0.353553390593j) & (2.16481864268e-17+0.353553390593j) & (0.25-0.25j) & (-0.25+0.25j) & (-0.25-0.25j) & (0.25+0.25j)\\\\\\end{pmatrix}\$$"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 6,
+       "text": [
+        "Quantum object: dims = [[8], [8]], shape = [8, 8], type = oper, isherm = False\n",
+        "Qobj data =\n",
+        "[[  3.53553391e-01+0.j           3.53553391e-01+0.j           3.53553391e-01+0.j\n",
+        "    3.53553391e-01+0.j           3.53553391e-01+0.j           3.53553391e-01+0.j\n",
+        "    3.53553391e-01+0.j           3.53553391e-01+0.j        ]\n",
+        " [  3.53553391e-01+0.j          -3.53553391e-01+0.j\n",
+        "    2.16481864e-17+0.35355339j  -2.16481864e-17-0.35355339j\n",
+        "    2.50000000e-01+0.25j        -2.50000000e-01-0.25j\n",
+        "   -2.50000000e-01+0.25j         2.50000000e-01-0.25j      ]\n",
+        " [  3.53553391e-01+0.j           3.53553391e-01+0.j          -3.53553391e-01+0.j\n",
+        "   -3.53553391e-01+0.j           2.16481864e-17+0.35355339j\n",
+        "    2.16481864e-17+0.35355339j  -2.16481864e-17-0.35355339j\n",
+        "   -2.16481864e-17-0.35355339j]\n",
+        " [  3.53553391e-01+0.j          -3.53553391e-01+0.j\n",
+        "   -2.16481864e-17-0.35355339j   2.16481864e-17+0.35355339j\n",
+        "   -2.50000000e-01+0.25j         2.50000000e-01-0.25j\n",
+        "    2.50000000e-01+0.25j        -2.50000000e-01-0.25j      ]\n",
+        " [  3.53553391e-01+0.j           3.53553391e-01+0.j           3.53553391e-01+0.j\n",
+        "    3.53553391e-01+0.j          -3.53553391e-01+0.j          -3.53553391e-01+0.j\n",
+        "   -3.53553391e-01+0.j          -3.53553391e-01+0.j        ]\n",
+        " [  3.53553391e-01+0.j          -3.53553391e-01+0.j\n",
+        "    2.16481864e-17+0.35355339j  -2.16481864e-17-0.35355339j\n",
+        "   -2.50000000e-01-0.25j         2.50000000e-01+0.25j\n",
+        "    2.50000000e-01-0.25j        -2.50000000e-01+0.25j      ]\n",
+        " [  3.53553391e-01+0.j           3.53553391e-01+0.j          -3.53553391e-01+0.j\n",
+        "   -3.53553391e-01+0.j          -2.16481864e-17-0.35355339j\n",
+        "   -2.16481864e-17-0.35355339j   2.16481864e-17+0.35355339j\n",
+        "    2.16481864e-17+0.35355339j]\n",
+        " [  3.53553391e-01+0.j          -3.53553391e-01+0.j\n",
+        "   -2.16481864e-17-0.35355339j   2.16481864e-17+0.35355339j\n",
+        "    2.50000000e-01-0.25j        -2.50000000e-01+0.25j\n",
+        "   -2.50000000e-01-0.25j         2.50000000e-01+0.25j      ]]"
+       ]
+      }
+     ],
+     "prompt_number": 6
+    }
+   ],
+   "metadata": {}
+  }
+ ]
+}