%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/
# we make some states for a 2 qubit system
ket("10") # this is |10>
ket('100')
bra('10') # this is <10|
bra('10')*ket('10') # dot product
ket("10")*bra("10") # projection operator
This gives a projection operator $|10\rangle \langle 10|$
bra("00").overlap(ket("10")) # does the dot product
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!
z = ket('00') + ket('11')
z = z.unit()
# the Bell state!
z
snot() # the Hadamard on a single qubit
snot()*ket('0') # create a superposition state from |0>
sigmaz() # Pauli matrix
q=sigmay()*sigmax()
q.type # what type is it?
z = ket('00')
z.type
qeye(2) # is the 2x2 identity matrix
Make the operator $\sigma_z \otimes {\bf I} \otimes {\bf I}$
spinz0 = tensor(sigmaz(),qeye(2),qeye(2))
spinz0 # this is a tensor product working on 3 qubits
spinz0.shape
compute $\langle 000| Z \otimes I \otimes I |000 \rangle$
expect(spinz0,ket('000')) # compute <000| Z \otimes I \otimes I |000>
# the CNOT with 2 qubits!
cnot(2,control=0,target=1)
cnot(2,control=1,target=0) # control and target reversed
fock(10,0) # a wave vector in a Hilbert space with 10 states
# this gives the first one
fock(10,3) # a wave vector in a Hilbert space with 10 states
# this gives the third one
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>
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|
N=4
projection(N,1,2)
# 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
# Let's make an operator from the circuit
U3 = gate_sequence_product(qc3.propagators())
U3 # it's a swap!
U3*ket('10')
# 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) )
z=U3*ket("01")
print_bipartite(z)
# 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
about()
from qutip.ipynbtools import version_table
version_table()