diff --git a/examples/Theory of Qubits and Single Quantum Gates.ipynb b/examples/Theory of Qubits and Single Quantum Gates.ipynb new file mode 100644 index 0000000..7a57565 --- /dev/null +++ b/examples/Theory of Qubits and Single Quantum Gates.ipynb @@ -0,0 +1,471 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "from qutip import *\n", + "from qutip.qip import *\n", + "from IPython.display import Image" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Qubits" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Just as the bit is the fundamental concept of classical computation, so the qubit is for quantum computing. A qubit can be seen as analogous to the classical bit. Just as the classical bit has two states (either 0 or 1), so the qubit has those possible two states $ |0\\rangle $ and $|1 \\rangle$ (Dirac notation). However, the big difference between classical and quantum bits relies on the fact that a qubit can be in a state $\\textit{other}$ than $ |0\\rangle $ or $|1 \\rangle$. $\\textit{Superposition}$ is just the way physicist call a linear combination of states ($\\alpha$ and $\\beta$ are called the amplitudes for $|0\\rangle$ and $|1\\rangle$ respectively): $$ |\\psi\\rangle = \\alpha |0\\rangle + \\beta |1\\rangle $$ " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Single Quantum Gates" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Logic gates make operations upon bits in a classical computer. Following this analogy, quantum logic gates perform manipulations upon qubits. Single qubit gates are those who just act on a qubit, not a bunch of them. Something interesting that happens in the quantum computing world is that there are more than one non-trivial single-qubit gates, unlike the classic case (where there's only the NOT single logic gate)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Consider the case you would like to implement the classical logic gate NOT which sends the bit 0 to the bit 1 and the bit 1 to the bit 0. Then, we are looking to interchange state 0 and 1. This is the famous Pauli-X single quantum gate. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pauli-X Gate" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pauli-X gate is one of the most basic and fundamental gates in quantum circuits. Geometrically, the Pauli-X gate is a single-qubit rotation through $\\pi$ radians around the x-axis. Here you can see how to create this gate through a Qobj." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/latex": [ + "Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True\\begin{equation*}\\left(\\begin{array}{*{11}c}0.0 & 1.0\\\\1.0 & 0.0\\\\\\end{array}\\right)\\end{equation*}" + ], + "text/plain": [ + "Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True\n", + "Qobj data =\n", + "[[0. 1.]\n", + " [1. 0.]]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x_gate()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An easy way to see what the Pauli-X gate is doing to the qubit is to check the following calculation: $$ \\begin{bmatrix}\n", + " 0 && 1 \\\\\n", + " 1 && 0\n", + "\\end{bmatrix} \\begin{bmatrix}\n", + " \\alpha \\\\\n", + " \\beta\n", + "\\end{bmatrix} = \\begin{bmatrix}\n", + " \\beta \\\\\n", + " \\alpha\n", + "\\end{bmatrix} $$ " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Which means that x_gate() applied to a qubit is swapping the amplitudes for the state $|0\\rangle$ and $|1\\rangle$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pauli-Y Gate" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Pauli-Y gate is a single-qubit rotation through $\\pi$ radians around the y-axis. Here you can see how to create this gate through a Qobj." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/latex": [ + "Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True\\begin{equation*}\\left(\\begin{array}{*{11}c}0.0 & -1.0j\\\\1.0j & 0.0\\\\\\end{array}\\right)\\end{equation*}" + ], + "text/plain": [ + "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]]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_gate()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pauli-Z Gate" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Pauli-Z gate is a single-qubit rotation through $\\pi$ radians around the z-axis. Here you can see how to create this gate through a Qobj." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/latex": [ + "Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True\\begin{equation*}\\left(\\begin{array}{*{11}c}1.0 & 0.0\\\\0.0 & -1.0\\\\\\end{array}\\right)\\end{equation*}" + ], + "text/plain": [ + "Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True\n", + "Qobj data =\n", + "[[ 1. 0.]\n", + " [ 0. -1.]]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "z_gate()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So far, we have seen that Pauli-X, Pauli-Y, Pauli-Z gates are just single operations on a qubit." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## S and T Quantum Gates" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The S gate is also known as the phase gate or the Z90 gate, because it represents a 90° degree rotation around the z-axis. Here you can see how to create this gate through a Qobj." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/latex": [ + "Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = False\\begin{equation*}\\left(\\begin{array}{*{11}c}1.0 & 0.0\\\\0.0 & 1.0j\\\\\\end{array}\\right)\\end{equation*}" + ], + "text/plain": [ + "Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = False\n", + "Qobj data =\n", + "[[1.+0.j 0.+0.j]\n", + " [0.+0.j 0.+1.j]]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s_gate()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The T gate is just another phase gate that satisfies the property $S=T²$. Here you can see how to create this gate through a Qobj." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/latex": [ + "Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = False\\begin{equation*}\\left(\\begin{array}{*{11}c}1.0 & 0.0\\\\0.0 & (0.707+0.707j)\\\\\\end{array}\\right)\\end{equation*}" + ], + "text/plain": [ + "Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = False\n", + "Qobj data =\n", + "[[1. +0.j 0. +0.j ]\n", + " [0. +0.j 0.70710678+0.70710678j]]" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "t_gate()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "S and T gates are just special cases of a phase shift operation. The general shift gate is represented by (where $\\theta = \\frac{\\pi}{4}$ for T, and $\\theta = \\frac{\\pi}{2}$ for S): $$R_{\\theta} = \\begin{bmatrix}\n", + " 1 && 0 \\\\\n", + " 0 && e^{i\\theta}\n", + "\\end{bmatrix} $$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These gates are leaving the basis state $|0\\rangle$ unchanged and mapping $|1\\rangle$ to $e^{i\\phi}|1\\rangle$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Adding previous gates to a QubitCircuit" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Gate(X, targets=[0], controls=None)]" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "q = QubitCircuit(1)\n", + "q.add_gate(\"X\", targets=[0])\n", + "q.gates" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Gate(Y, targets=[0], controls=None)]" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "q = QubitCircuit(1)\n", + "q.add_gate(\"Y\", targets=[0])\n", + "q.gates" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Gate(Z, targets=[0], controls=None)]" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "q = QubitCircuit(1)\n", + "q.add_gate(\"Z\", targets=[0])\n", + "q.gates" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Gate(S, targets=[0], controls=None)]" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "q = QubitCircuit(1)\n", + "q.add_gate(\"S\", targets=[0])\n", + "q.gates" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Gate(T, targets=[0], controls=None)]" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "q = QubitCircuit(1)\n", + "q.add_gate(\"T\", targets=[0])\n", + "q.gates" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "QuTiP: Quantum Toolbox in Python\n", + "================================\n", + "Copyright (c) QuTiP team 2011 and later.\n", + "Original developers: R. J. Johansson & P. D. Nation.\n", + "Previous lead developers: Chris Granade & A. Grimsmo.\n", + "Current admin team: Alexander Pitchford, Paul D. Nation, Nathan Shammah, Shahnawaz Ahmed, Neill Lambert, Eric Giguère, and Boxi Li\n", + "Project Manager: Franco Nori.\n", + "Currently developed through wide collaboration. See https://github.com/qutip for details.\n", + "\n", + "QuTiP Version: 4.5.0.dev0+01132789\n", + "Numpy Version: 1.18.1\n", + "Scipy Version: 1.4.1\n", + "Cython Version: 0.29.15\n", + "Matplotlib Version: 3.1.3\n", + "Python Version: 3.8.1\n", + "Number of CPUs: 2\n", + "BLAS Info: INTEL MKL\n", + "OPENMP Installed: False\n", + "INTEL MKL Ext: True\n", + "Platform Info: Linux (x86_64)\n", + "Installation path: /home/mateo/GSoC2020/QuTiP/qutip-project/qutip/qutip\n", + "==============================================================================\n", + "Please cite QuTiP in your publication.\n", + "==============================================================================\n", + "For your convenience a bibtex reference can be easily generated using `qutip.cite()`\n" + ] + } + ], + "source": [ + "qutip.about()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "qutip-dev-py3", + "language": "python", + "name": "qutip-dev-py3" + }, + "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.8.1" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}