In [34]:
%matplotlib inline
from IPython.display import Image
from qutip import *    # here is where we import QuTiP
from qutip.qip.operations import cnot   # CNOT op
from qutip.qip.operations import snot   # Hadamard op
from qutip.qip.circuit import QubitCircuit
from qutip.qip.circuit import gate_sequence_product
import numpy as np

We are using the QuTiP package which is a Quantum Toolbox in Python, see http://qutip.org/

In [2]:
# we make some states for a 2 qubit system
ket("10")    # this is |10> 
Out[2]:
Quantum object: dims = [[2, 2], [1, 1]], shape = (4, 1), type = ket\begin{equation*}\left(\begin{array}{*{11}c}0.0\\0.0\\1.0\\0.0\\\end{array}\right)\end{equation*}
In [3]:
ket('100')
Out[3]:
Quantum object: dims = [[2, 2, 2], [1, 1, 1]], shape = (8, 1), type = ket\begin{equation*}\left(\begin{array}{*{11}c}0.0\\0.0\\0.0\\0.0\\1.0\\0.0\\0.0\\0.0\\\end{array}\right)\end{equation*}
In [4]:
bra('10') # this is <10|
Out[4]:
Quantum object: dims = [[1, 1], [2, 2]], shape = (1, 4), type = bra\begin{equation*}\left(\begin{array}{*{11}c}0.0 & 0.0 & 1.0 & 0.0\\\end{array}\right)\end{equation*}
In [5]:
bra('10')*ket('10')  # dot product
Out[5]:
Quantum object: dims = [[1], [1]], shape = (1, 1), type = bra\begin{equation*}\left(\begin{array}{*{11}c}1.0\\\end{array}\right)\end{equation*}
In [7]:
ket("10")*bra("10")   # projection operator
Out[7]:
Quantum object: dims = [[2, 2], [2, 2]], shape = (4, 4), type = oper, isherm = True\begin{equation*}\left(\begin{array}{*{11}c}0.0 & 0.0 & 0.0 & 0.0\\0.0 & 0.0 & 0.0 & 0.0\\0.0 & 0.0 & 1.0 & 0.0\\0.0 & 0.0 & 0.0 & 0.0\\\end{array}\right)\end{equation*}

This gives a projection operator $|10\rangle \langle 10|$

In [8]:
bra("00").overlap(ket("10"))  # does the dot product
Out[8]:
0j
In [9]:
z = ket('10') + ket('01')  # this adds but does not normalize the state vector
z = z.unit()  # normalizes
z  #  z is a now a normalized and entangled state!
Out[9]:
Quantum object: dims = [[2, 2], [1, 1]], shape = (4, 1), type = ket\begin{equation*}\left(\begin{array}{*{11}c}0.0\\0.707\\0.707\\0.0\\\end{array}\right)\end{equation*}
In [10]:
z = ket('00') + ket('11')
z = z.unit()
# the Bell state!
z
Out[10]:
Quantum object: dims = [[2, 2], [1, 1]], shape = (4, 1), type = ket\begin{equation*}\left(\begin{array}{*{11}c}0.707\\0.0\\0.0\\0.707\\\end{array}\right)\end{equation*}
In [11]:
snot()   # the Hadamard on a single qubit
Out[11]:
Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True\begin{equation*}\left(\begin{array}{*{11}c}0.707 & 0.707\\0.707 & -0.707\\\end{array}\right)\end{equation*}
In [13]:
snot()*ket('0')  # create a superposition state from |0>
Out[13]:
Quantum object: dims = [[2], [1]], shape = (2, 1), type = ket\begin{equation*}\left(\begin{array}{*{11}c}0.707\\0.707\\\end{array}\right)\end{equation*}
In [14]:
sigmaz() # Pauli matrix
Out[14]:
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*}
In [15]:
q=sigmay()*sigmax()
q.type  # what type is it?
Out[15]:
'oper'
In [16]:
z = ket('00')
z.type
Out[16]:
'ket'
In [17]:
qeye(2) # is the 2x2 identity matrix
Out[17]:
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*}

Make the operator $\sigma_z \otimes {\bf I} \otimes {\bf I}$

In [18]:
spinz0 = tensor(sigmaz(),qeye(2),qeye(2)) 
spinz0  # this is a tensor product working on 3 qubits
Out[18]:
Quantum object: dims = [[2, 2, 2], [2, 2, 2]], shape = (8, 8), type = oper, isherm = True\begin{equation*}\left(\begin{array}{*{11}c}1.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\0.0 & 1.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\0.0 & 0.0 & 1.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\0.0 & 0.0 & 0.0 & 1.0 & 0.0 & 0.0 & 0.0 & 0.0\\0.0 & 0.0 & 0.0 & 0.0 & -1.0 & 0.0 & 0.0 & 0.0\\0.0 & 0.0 & 0.0 & 0.0 & 0.0 & -1.0 & 0.0 & 0.0\\0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & -1.0 & 0.0\\0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & -1.0\\\end{array}\right)\end{equation*}
In [19]:
spinz0.shape
Out[19]:
(8, 8)

compute $\langle 000| Z \otimes I \otimes I |000 \rangle$

In [20]:
expect(spinz0,ket('000'))   # compute <000| Z \otimes I \otimes I |000>
Out[20]:
1.0
In [21]:
# the CNOT with 2 qubits!
cnot(2,control=0,target=1)
Out[21]:
Quantum object: dims = [[2, 2], [2, 2]], shape = (4, 4), type = oper, isherm = True\begin{equation*}\left(\begin{array}{*{11}c}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{array}\right)\end{equation*}
In [22]:
cnot(2,control=1,target=0)  # control and target reversed
Out[22]:
Quantum object: dims = [[2, 2], [2, 2]], shape = (4, 4), type = oper, isherm = True\begin{equation*}\left(\begin{array}{*{11}c}1.0 & 0.0 & 0.0 & 0.0\\0.0 & 0.0 & 0.0 & 1.0\\0.0 & 0.0 & 1.0 & 0.0\\0.0 & 1.0 & 0.0 & 0.0\\\end{array}\right)\end{equation*}
In [25]:
fock(10,0)  # a wave vector in a Hilbert space with 10 states
# this gives the first one
Out[25]:
Quantum object: dims = [[10], [1]], shape = (10, 1), type = ket\begin{equation*}\left(\begin{array}{*{11}c}1.0\\0.0\\0.0\\0.0\\0.0\\0.0\\0.0\\0.0\\0.0\\0.0\\\end{array}\right)\end{equation*}
In [26]:
fock(10,3)  # a wave vector in a Hilbert space with 10 states
# this gives the third one
Out[26]:
Quantum object: dims = [[10], [1]], shape = (10, 1), type = ket\begin{equation*}\left(\begin{array}{*{11}c}0.0\\0.0\\0.0\\1.0\\0.0\\0.0\\0.0\\0.0\\0.0\\0.0\\\end{array}\right)\end{equation*}
In [28]:
N=4
psi0 = tensor(ket('0'),fock(N,0))
psi0
# returns a wave vector in a tensor product space 
# that is a qubit times a space with 4 different basis vectors
# this returns |0> |0>
Out[28]:
Quantum object: dims = [[2, 4], [1, 1]], shape = (8, 1), type = ket\begin{equation*}\left(\begin{array}{*{11}c}1.0\\0.0\\0.0\\0.0\\0.0\\0.0\\0.0\\0.0\\\end{array}\right)\end{equation*}
In [31]:
N=4
projection(N,3,0)
# make a projection operator
# the first argument is the dimension of the Hilbert space
# the second two arguments are i,j giving |i><j|
# this makes |3><0|
Out[31]:
Quantum object: dims = [[4], [4]], shape = (4, 4), type = oper, isherm = False\begin{equation*}\left(\begin{array}{*{11}c}0.0 & 0.0 & 0.0 & 0.0\\0.0 & 0.0 & 0.0 & 0.0\\0.0 & 0.0 & 0.0 & 0.0\\1.0 & 0.0 & 0.0 & 0.0\\\end{array}\right)\end{equation*}
In [32]:
N=4
projection(N,1,2)
Out[32]:
Quantum object: dims = [[4], [4]], shape = (4, 4), type = oper, isherm = False\begin{equation*}\left(\begin{array}{*{11}c}0.0 & 0.0 & 0.0 & 0.0\\0.0 & 0.0 & 1.0 & 0.0\\0.0 & 0.0 & 0.0 & 0.0\\0.0 & 0.0 & 0.0 & 0.0\\\end{array}\right)\end{equation*}
In [33]:
# Let's make a circuit
qc3 = QubitCircuit(2)  # 2 qubit circuit
qc3.add_gate("CNOT", 1, 0)  #  1 is control bit, 0 is operated on
qc3.add_gate("CNOT", 0, 1)  
qc3.add_gate("CNOT", 1, 0)  
qc3.png
Out[33]:
In [35]:
# Let's make an operator from the circuit
U3 = gate_sequence_product(qc3.propagators())
In [36]:
U3  # it's a swap!
Out[36]:
Quantum object: dims = [[2, 2], [2, 2]], shape = (4, 4), type = oper, isherm = True\begin{equation*}\left(\begin{array}{*{11}c}1.0 & 0.0 & 0.0 & 0.0\\0.0 & 0.0 & 1.0 & 0.0\\0.0 & 1.0 & 0.0 & 0.0\\0.0 & 0.0 & 0.0 & 1.0\\\end{array}\right)\end{equation*}
In [38]:
U3*ket('10')
Out[38]:
Quantum object: dims = [[2, 2], [1, 1]], shape = (4, 1), type = ket\begin{equation*}\left(\begin{array}{*{11}c}0.0\\1.0\\0.0\\0.0\\\end{array}\right)\end{equation*}
In [39]:
# print out the state of a bipartite 2 qubit system
# in the form a |00> + b|01> + c|10> + d|11>
# with a,b,c,d complex numbers
# psi is assumed to be a ket with 2 bits
def print_bipartite(psi):
    a = bra("00").overlap(psi) # dot product if psi is a ket for 2 bits
    b = bra("01").overlap(psi)
    c = bra("10").overlap(psi)
    d = bra("11").overlap(psi)
    print("{}|00> + {}|01> + {}|10> + {}|11>".format(a,b,c,d) )
In [40]:
z=U3*ket("01")
print_bipartite(z)
0j|00> + 0j|01> + (1+0j)|10> + 0j|11>
In [44]:
# this routine takes as argument a ket of 2 qubits
# and returns the probability that first qubit is up
def prob_up_first(psi):
    P0 = ket('0')*bra('0')  # projection operator
    #P0 = projection(2,0,0) same thing
    probability = expect(tensor(P0,qeye(2)),psi)
    if (abs(probability) < 1e-10):  # cuts off extremely small numbers
        probability = 0
    if (abs(probability-1) < 1e-10):  # cuts off extremely small numbers
        probability = 1
    return probability

# create a Bell pair state
psi = ket('00') + ket('11')
psi = psi.unit()
# check the probabilty of first qu-bit being 0  (or spin up)
# should be 1/2
print(prob_up_first(psi)) 
psi = ket('00')
print(prob_up_first(psi)) 
#should be 1
0.4999999999999999
1
In [45]:
about()
QuTiP: Quantum Toolbox in Python
================================
Copyright (c) QuTiP team 2011 and later.
Current admin team: Alexander Pitchford, Nathan Shammah, Shahnawaz Ahmed, Neill Lambert, Eric Giguère, Boxi Li and Jake Lishman.
Board members: Daniel Burgarth, Robert Johansson, Anton F. Kockum, Franco Nori and Will Zeng.
Original developers: R. J. Johansson & P. D. Nation.
Previous lead developers: Chris Granade & A. Grimsmo.
Currently developed through wide collaboration. See https://github.com/qutip for details.

QuTiP Version:      4.5.3
Numpy Version:      1.18.5
Scipy Version:      1.5.0
Cython Version:     0.29.21
Matplotlib Version: 3.2.2
Python Version:     3.8.3
Number of CPUs:     6
BLAS Info:          INTEL MKL
OPENMP Installed:   False
INTEL MKL Ext:      True
Platform Info:      Darwin (x86_64)
Installation path:  /Users/aquillen/opt/anaconda3/lib/python3.8/site-packages/qutip
================================================================================
Please cite QuTiP in your publication.
================================================================================
For your convenience a bibtex reference can be easily generated using `qutip.cite()`
In [46]:
from qutip.ipynbtools import version_table
version_table()
Out[46]:
SoftwareVersion
QuTiP4.5.3
Numpy1.18.5
SciPy1.5.0
matplotlib3.2.2
Cython0.29.21
Number of CPUs6
BLAS InfoINTEL MKL
IPython7.16.1
Python3.8.3 (default, Jul 2 2020, 11:26:31) [Clang 10.0.0 ]
OSposix [darwin]
Sun Apr 11 15:48:32 2021 EDT
In [ ]: