We will need to install Qiskit, IBM's quantum computing language. Then we will need to import qiskits tools for creating Bloch sphere representations of qubits.
pip install qiskit
Requirement already satisfied: qiskit in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (0.13.0) Requirement already satisfied: qiskit-aqua==0.6.1 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit) (0.6.1) Requirement already satisfied: qiskit-ignis==0.2.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit) (0.2.0) Requirement already satisfied: qiskit-aer==0.3.2 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit) (0.3.2) Requirement already satisfied: qiskit-ibmq-provider==0.3.3 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit) (0.3.3) Requirement already satisfied: qiskit-terra==0.10.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit) (0.10.0) Requirement already satisfied: psutil>=5 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (5.6.3) Requirement already satisfied: scikit-learn>=0.20.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (0.22) Requirement already satisfied: docplex in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (2.11.176) Requirement already satisfied: sympy>=1.3 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (1.4) Requirement already satisfied: quandl in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (3.4.8) Requirement already satisfied: setuptools>=40.1.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (41.0.1) Requirement already satisfied: scipy>=1.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (1.4.1) Requirement already satisfied: pyscf; sys_platform != "win32" in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (1.6.5) Requirement already satisfied: dlx in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (1.0.4) Requirement already satisfied: cvxopt in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (1.2.3) Requirement already satisfied: numpy>=1.13 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (1.18.0) Requirement already satisfied: jsonschema>=2.6 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (3.0.1) Requirement already satisfied: h5py in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (2.9.0) Requirement already satisfied: fastdtw in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (0.3.4) Requirement already satisfied: networkx>=2.2 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-aqua==0.6.1->qiskit) (2.3) Requirement already satisfied: nest-asyncio==1.0.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-ibmq-provider==0.3.3->qiskit) (1.0.0) Requirement already satisfied: requests-ntlm>=1.1.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-ibmq-provider==0.3.3->qiskit) (1.1.0) Requirement already satisfied: requests>=2.19 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-ibmq-provider==0.3.3->qiskit) (2.22.0) Requirement already satisfied: websockets<8,>=7 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-ibmq-provider==0.3.3->qiskit) (7.0) Requirement already satisfied: ply>=3.10 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-terra==0.10.0->qiskit) (3.11) Requirement already satisfied: marshmallow-polyfield<6,>=5.7 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-terra==0.10.0->qiskit) (5.7) Requirement already satisfied: marshmallow<4,>=3 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from qiskit-terra==0.10.0->qiskit) (3.3.0) Requirement already satisfied: joblib>=0.11 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from scikit-learn>=0.20.0->qiskit-aqua==0.6.1->qiskit) (0.13.2) Requirement already satisfied: six in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from docplex->qiskit-aqua==0.6.1->qiskit) (1.12.0) Requirement already satisfied: docloud>=1.0.375 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from docplex->qiskit-aqua==0.6.1->qiskit) (1.0.375) Requirement already satisfied: mpmath>=0.19 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from sympy>=1.3->qiskit-aqua==0.6.1->qiskit) (1.1.0) Requirement already satisfied: python-dateutil in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quandl->qiskit-aqua==0.6.1->qiskit) (2.8.0) Requirement already satisfied: pyOpenSSL in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quandl->qiskit-aqua==0.6.1->qiskit) (19.0.0) Requirement already satisfied: ndg-httpsclient in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quandl->qiskit-aqua==0.6.1->qiskit) (0.5.1) Requirement already satisfied: pandas>=0.14 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quandl->qiskit-aqua==0.6.1->qiskit) (0.24.2) Requirement already satisfied: more-itertools<=5.0.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quandl->qiskit-aqua==0.6.1->qiskit) (5.0.0) Requirement already satisfied: inflection>=0.3.1 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quandl->qiskit-aqua==0.6.1->qiskit) (0.3.1) Requirement already satisfied: pyasn1 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from quandl->qiskit-aqua==0.6.1->qiskit) (0.4.8) Requirement already satisfied: attrs>=17.4.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from jsonschema>=2.6->qiskit-aqua==0.6.1->qiskit) (19.1.0) Requirement already satisfied: pyrsistent>=0.14.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from jsonschema>=2.6->qiskit-aqua==0.6.1->qiskit) (0.14.11) Requirement already satisfied: decorator>=4.3.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from networkx>=2.2->qiskit-aqua==0.6.1->qiskit) (4.4.0) Requirement already satisfied: ntlm-auth>=1.0.2 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.3.3->qiskit) (1.4.0) Requirement already satisfied: cryptography>=1.3 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.3.3->qiskit) (2.7) Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from requests>=2.19->qiskit-ibmq-provider==0.3.3->qiskit) (3.0.4) Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from requests>=2.19->qiskit-ibmq-provider==0.3.3->qiskit) (1.24.2) Requirement already satisfied: certifi>=2017.4.17 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from requests>=2.19->qiskit-ibmq-provider==0.3.3->qiskit) (2019.6.16) Requirement already satisfied: idna<2.9,>=2.5 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from requests>=2.19->qiskit-ibmq-provider==0.3.3->qiskit) (2.8) Requirement already satisfied: pytz>=2011k in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from pandas>=0.14->quandl->qiskit-aqua==0.6.1->qiskit) (2019.1) Requirement already satisfied: asn1crypto>=0.21.0 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from cryptography>=1.3->requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.3.3->qiskit) (0.24.0) Requirement already satisfied: cffi!=1.11.3,>=1.8 in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from cryptography>=1.3->requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.3.3->qiskit) (1.12.3) Requirement already satisfied: pycparser in /Users/amelieschreiber/anaconda3/lib/python3.7/site-packages (from cffi!=1.11.3,>=1.8->cryptography>=1.3->requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.3.3->qiskit) (2.19) Note: you may need to restart the kernel to use updated packages.
import numpy as np
from qiskit import *
from qiskit.visualization import plot_bloch_vector
%matplotlib inline
Qubits are the basic unit of computation in a quantum computer, much like bits are the basic unit of computation in a "classical" computer. In bit based computing we have silicon chips with transistors which serve as "on/off" switches that serve as building blocks for complex systems of logic gates implementing Boolean logic. In a quantum computer, these "on/off" bits represented by strings of 0s and 1s are replaced by qubits. Qubits behave much differently from classical bits, but any classical computation involving bits can still be implemented on a quantum system of qubits. However, much more can be done qubits. They provide computational abilities that bits, classical computing, and classical information processing simply cannot replicate or accurately simulate. In some cases there are quantum information processes which provide a new paradigm for understanding information theory and computational complexity. Here we will focus on the basics and leave quantum complexity and subjects like entanglement entropy for the appendix at the end of the book on tensor networks.
Qubits have many representations, the most common of them being as a $2$-dimensional complex unit vector:
\begin{align} |\psi \rangle = \begin{pmatrix} \alpha \\ \beta \end{pmatrix}, \quad \text{where } \sqrt{\langle \psi | \psi \rangle} = 1. \end{align}From the condition that the vector be of length one, we can deduce the following:
\begin{align} \sqrt{\langle \psi | \psi \rangle} &= \begin{pmatrix} \alpha^*, & \beta^* \end{pmatrix}\begin{pmatrix} \alpha \\ \beta \end{pmatrix} \\ &= \sqrt{\alpha^* \alpha+ \beta^* \beta}\\ &= \sqrt{|\alpha|^2 +|\beta|^2} = 1 \implies |\alpha|^2 +|\beta|^2 = 1. \end{align}Remember, $\alpha$ and $\beta$ are complex numbers (elements of $\mathbb{C}$), and so the vector $|\psi \rangle \in \mathbb{C}^2$. The vectors representing qubit pure states actually live on the Riemann sphere also called the complex projective line $\mathbb{P}^1(\mathbb{C})$.
The second representation, which comes from the representation of pure states as points on the Riemann sphere and that is very common in the literature and in software packages for quantum computing is via the Bloch sphere, named after the Nobel laureate and physicist Felix Bloch. Generally, the north pole represents the basis state
\begin{align} |0\rangle = \begin{pmatrix} 1\\0 \end{pmatrix} \end{align}We can visualize this in Qiskit as follows:
plot_bloch_vector([0,0,1], title="Spin-Up")
In general we have the following six basis states in terms of the "Puali matrices" which we will define later.
plot_bloch_vector([0,0,1], title="Spin-Up")
plot_bloch_vector([0,0,-1], title="Spin-Down")
plot_bloch_vector([0,1,0], title="Spin-Right")
plot_bloch_vector([0,-1,0], title="Spin-Left")
plot_bloch_vector([1,0,0], title="Spin-Plus")
plot_bloch_vector([-1,0,0], title="Spin-Minus")
If we want to define an arbitrary sate vector on the Bloch sphere we simply need to define a unit vector in $3$-dimensional space as the input state. To do this, define any $3$-dimensional vector, then divide it by its length (or norm). This will give a vector of length one, which can then be used as an input for Qiskit to plot on the Bloch sphere.
An arbitrary pure state can be represented as some linear combination:
\begin{align} |\psi \rangle = \begin{pmatrix} \alpha \\ \beta \end{pmatrix} = \alpha |0\rangle + \beta |1\rangle \end{align}where $|\alpha|^2 + |\beta|^2 = 1$.
# Define a 3-dimensional vector
vect = np.array([1, -1, 1])
# Divide it by its length (or norm)
psi = vect/(np.linalg.norm(vect))
print(psi)
[ 0.57735027 -0.57735027 0.57735027]
# Plot psi on the Bloch sphere using Qiskit
plot_bloch_vector(psi, title="psi")
We could also use spherical coordinates to define a unit vector that always lies on the surface of the unit sphere in $3$-dimensions, which is the Bloch sphere. To do this, we choose $\rho = 1$, and then choose two angles $\phi \in [0, \pi]$ and $\theta \in [0, 2\pi]$. The $x, y,$ and $z$ coordinates are then:
\begin{align} x &= \rho \sin(\phi) \cos(\theta) \\ y &= \rho \sin(\phi) \sin(\theta) \\ z &= \rho \cos(\phi) \end{align}Let do an example with $\phi = 0$ and $\theta = 0$. This should correspond to spin-up since we get
\begin{align} x &= 0 \\ y &= 0 \\ z &= 1 \end{align}x = np.sin(0)*np.cos(0)
y = np.sin(0)*np.sin(0)
z = np.cos(0)
psi1 = np.array([x, y, z])
print("x=", x)
print("y=", y)
print("z=", z)
print("psi1=", psi1)
x= 0.0 y= 0.0 z= 1.0 psi1= [0. 0. 1.]
# Plot psi on the Bloch sphere using Qiskit
plot_bloch_vector(psi1, title="psi1")
Let's try to use spherical coordinates to create the spin-down state now.
x = np.sin(0)*np.cos(np.pi)
y = np.sin(0)*np.sin(np.pi)
z = np.cos(np.pi)
psi2 = np.array([x, y, z])
print("x=", x)
print("y=", y)
print("z=", z)
print("psi2=", psi2)
x= -0.0 y= 0.0 z= -1.0 psi2= [-0. 0. -1.]
# Plot psi on the Bloch sphere using Qiskit
plot_bloch_vector(psi2, title="psi2")
Let's define the six basis states in Python and compute some things with them.
spin_up = np.matrix([[1],
[0]])
spin_down = np.matrix([[0],
[1]])
spin_right = (1/np.sqrt(2))*(spin_up + 1j*spin_down)
spin_left = (1/np.sqrt(2))*(spin_up - 1j*spin_down)
spin_plus = (1/np.sqrt(2))*(spin_up + spin_down)
spin_minus = (1/np.sqrt(2))*(spin_up - spin_down)
print('spin up:', spin_up)
print('spin down:', spin_down)
print('spin right:', spin_right)
print('spin left:', spin_left)
print('spin plus:', spin_plus)
print('spin minus:', spin_minus)
spin up: [[1] [0]] spin down: [[0] [1]] spin right: [[0.70710678+0.j ] [0. +0.70710678j]] spin left: [[0.70710678+0.j ] [0. -0.70710678j]] spin plus: [[0.70710678] [0.70710678]] spin minus: [[ 0.70710678] [-0.70710678]]
np.dot(spin_down.H, spin_down)
matrix([[1]])
np.dot(spin_left.H, spin_right)
matrix([[0.+0.j]])
Compute the following inner products.
Plot the following states on the Bloch sphere using Qiskit for the given angles $\phi$ and $\theta$.