In [1]:
import qutip as qt
import numpy as np
import matplotlib as mpl
from matplotlib import pylab as plt
from matplotlib import rc
import scipy as scp
from scipy import stats
%matplotlib inline
In [2]:
## Loading of previously saved data
N = 1021
try:
data = np.load('data.npz')
qresults = data['qresults']
cresults = data['cresults']
quantum = data['quantumP500']
classic = data['classicalP500']
xq = data['xq']
x = data['x']
except IOError:
print("There is no data to be loaded")
In [3]:
## Declaration of unitary evolution operators
N = 1021
## Initial Quantum State
psisim = (qt.tensor(qt.basis(2,1),qt.basis(N,int(N/2)-3)) + 1j*qt.tensor(qt.basis(2,0),qt.basis(N,int(N/2)-3))).unit()
## Half Wave Plate(Theta)
def hwp(theta):
hwp_rta = (-np.cos(2*theta)*qt.basis(2,0)*qt.basis(2,0).dag()+np.sin(2*theta)*qt.basis(2,0)*qt.basis(2,1).dag()
+np.sin(2*theta)*qt.basis(2,1)*qt.basis(2,0).dag()+np.cos(2*theta)*qt.basis(2,1)*qt.basis(2,1).dag())
return hwp_rta
## Coin Operator(HWP(3pi/8))
Cpol = hwp(3*np.pi/8)
## Coin Operator(Hadamard)
#H = qt.hadamard_transform(N=1)
##
I = qt.qeye(N=N)
## Coin Operator
C = qt.tensor(Cpol,I)
## Conditional Displacement Operator
S0 = qt.Qobj(np.zeros((N,N)))
S1 = qt.Qobj(np.zeros((N,N)))
for i in range(N-1):
S0+= qt.basis(N,i+1)*qt.basis(N,i).dag()
Sd = qt.tensor(qt.basis(2,1)*qt.basis(2,1).dag(),S0)
for i in range(1,N):
S1+= qt.basis(N,i-1)*qt.basis(N,i).dag()
Si = qt.tensor(qt.basis(2,0)*qt.basis(2,0).dag(),S1)
S = Sd + Si
In [4]:
hwp(3*np.pi/8)
Out[4]:
In [5]:
steps = 300
## Quantum Walk Routine Defintion
def qw(coin,shift,psi_ini,steps):
U = (S*C)**steps
quantum = (((U*psi_ini).unit()).ptrace(1)).diag()
xq = np.arange(-1*int(len(quantum)/2),int(len(quantum)/2+1))
return (xq,quantum)
## "Unbiased" Random Walk
def ucrw(steps):
'''
Unbiased classical random walk. p=q=1/2
'''
x = np.arange(-(steps) , steps+1)
classic = np.zeros(2*steps+1)+(np.mod(x+steps,2)==0)*(1./(2**steps))*scp.special.binom(steps,(x+steps)/2.)
return (x,classic)
xq,quantum=qw(C,S,psisim,steps)
x,classic=ucrw(steps)
# In[20]:
plt.figure(figsize=(10,6))
plt.plot(x,classic,label="Classical Random Walk",alpha=0.85)
plt.plot(xq,quantum,label="Quantum Walk",alpha=0.85)
plt.legend(fontsize=10)
plt.xlim(-steps,steps)
plt.xlabel("Distance[arbitrary units]")
plt.ylabel("Probability")
plt.title("Probability of ending up in site i after N={nsteps} steps".format(nsteps=steps))
plt.savefig("probability.png")
In [6]:
import seaborn as sns
sns.set()
sns.set_context('poster')
sns.set_style('ticks')
plt.figure(figsize=(14,6))
select = np.logical_and(-100<=x , x<=100)
plt.plot(x[select],classic[select],label="Classical Random Walk",color='#ffbd4a',linewidth=5)
sns.despine()
plt.xlabel("Cuadra",fontweight='bold')
plt.ylabel("Probabilidad",fontweight='bold')
plt.text(40,0.03,"{x} lanzamientos".format(x=steps),fontweight='bold',
bbox={'facecolor':'#ffbd4a','alpha':0.5,'pad':10})
plt.savefig('classical.png', transparent = True)
In [7]:
## Quantum Walk Routine Defintion
def qw_postv(coin,shift,psi_ini,steps,theta):
U = (S*C)**steps
psi_n = (U*psi_ini).unit()
## Position Identity
I_pos = qt.qeye(N=N)
## Pseudorator
p_rotate = qt.tensor(hwp(theta),I_pos)
## Pseudorotator acting over psi_n
psi_n_rotate = p_rotate*psi_n
## Postselection State. (v) with the help of the additional displacer of distinguishing the state of . Projection operator
post = qt.tensor(qt.projection(N=2,n=1,m=1),I_pos)
psi_f = post*(psi_n_rotate.unit())
quantum = ((psi_f.ptrace(1)).diag())
xq = np.arange(-1*int(len(quantum)/2),int(len(quantum)/2+1))
return (xq,quantum)
In [8]:
f,axs = plt.subplots(nrows=3, ncols=2,figsize=(12,10))
thetas = np.linspace(np.pi*0.2,np.pi*.44,6)
index_th = 0
for i in range(3):
for j in range(2):
x,qw = qw_postv(C,S,psisim,steps,thetas[index_th])
axs[i][j].plot(x,qw)
axs[i][j].set_xlim([-250,250])
axs[i][j].set_title(r"$\theta={0:.2f}\pi$".format(thetas[index_th]/np.pi))
axs[i][j].set_xlabel(r"$x(arbitrary\ units)$")
axs[i][j].set_ylabel(r"$P(x,\theta)$")
index_th += 1
f.suptitle("Standard Quantum Random Walk\nOne Shot Postselection\nN=300",y=1.09)
f.tight_layout()
f.savefig('different_theta.png', dpi=f.dpi)
In [41]:
## Show N figure
% matplotlib inline
f1 = plt.figure(figsize=(12,8))
x,qw = qw_postv(C,S,psisim,steps,0.3109*np.pi)
plt.plot(x,qw)
plt.xlim([-250,250])
plt.title(r"$P(x,\theta)\ with\ \theta=0.312\pi\ and\ N=300$")
plt.xlabel(r"$x(arbitrary\ units)$")
plt.ylabel(r"$P(x,\theta)$")
f1.savefig('prob300.png', dpi=f1.dpi)
def gauss_state(x,x0,sigma):
return np.power((2*np.pi*sigma**2),-1/4)*np.exp(-1*np.power(x-x0,2)/(4*sigma**2))
## Show Camera Image
f2 = plt.figure(figsize=(14,10))
ztot = 0
bool_x = np.logical_and(x<=285,x>=-285)
sigma = 4
for i in range(6):
_,qw = qw_postv(C,S,psisim,steps/(6-i),0.3109*np.pi)
yspace = np.linspace(-5*sigma,55*sigma,10000)
yvals = np.power(gauss_state(yspace,10*i*sigma,sigma),2)
ztot += np.outer(yvals,qw[bool_x])
xp = x[bool_x]
plt.xlabel(r"$x(arbitrary\ units)$")
plt.ylabel(r"$y(arbitrary\ units)$")
plt.imshow(ztot,cmap=mpl.cm.afmhot,extent=[np.min(xp),np.max(xp),-5*sigma,60*sigma],origin='lower',vmin=0,vmax = np.max(ztot)/10)
plt.text(47,-0.8,r"$n=50$",color='white',fontsize=16)
plt.text(55,43,r"$n=100$",color='white',fontsize=16)
plt.text(65,86,r"$n=150$",color='white',fontsize=16)
plt.text(85,130,r"$n=200$",color='white',fontsize=16)
plt.text(125,173,r"$n=250$",color='white',fontsize=16)
plt.text(225,215,r"$n=300$",color='white',fontsize=16)
f2.savefig("ccd_qw.png",transparent=True,bbox_inches = 'tight',pad_inches=0,dpi=f2.dpi)
In [10]:
i=0
yspace = np.linspace(-5*sigma,55*sigma,10000)
yvals = np.power(gauss_state(yspace,10*i*sigma,sigma),2)
plt.plot(yspace,yvals)
Out[10]:
In [ ]: