Quantum Walk Standard Version


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

Data Loading


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")

Setup


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]:
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*}

Classical - Quantum Probability Comparison

Steps = 100


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)


Postselecting Differently in the Strong Regime


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]:
[<matplotlib.lines.Line2D at 0x7f06944e3210>]

In [ ]: