!python --version
!pip install qiskit

!pip install pylatexenc

from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit, execute, Aer
from qiskit.visualization import plot_histogram
import matplotlib.pyplot as plt
from qiskit.visualization import plot_state_city
%matplotlib inline
import matplotlib as mpl
from random import randrange
import numpy as np
import networkx as nx
import random
import math 
from qiskit.tools.monitor import job_monitor

from random import randrange
pose=[]
for i in range(400): 
     pose.append([])
#print(pose)
#pose[-1]=1
#print(pose[-1])
pose[0]=200
for k in range(200):
    rand = randrange(0,2)
    if rand==0:
        #print(rand)
        pose[k+1]=pose[k]+1
    if rand==1:
        pose[k+1]=pose[k]-1
#print(pose)
yc=[]
for e in range(400): 
     yc.append([])
for q in range(400):
    yc[q]=0
    for h in range(400):
        if pose[h]==q:
            yc[q]=yc[q]+1
#print((yc))
#print(len(yc))
xc = np.arange(0, 400, 1)
plt.plot(yc)
plt.xlim(150, 250)

class quantom_walk:   
    def __init__(self):
        self.__n=2
        self.__steps=1
        self.__theta=0
        self.__phi=0
        self.__qtype=1
        self.__shot=5000
    
    def main_qw(self,n,steps,qtype,theta,phi):
        self.__qpos = QuantumRegister(n,'qpos')
        self.__qcoin = QuantumRegister(1,'qcoin')
        self.__cpos = ClassicalRegister(n,'cr')
        self.__QC = QuantumCircuit(self.__qpos, self.__qcoin)
        if qtype==2: self.__QC.x(self.__qcoin[0])
        if qtype==3: self.__QC.u(theta, phi, 0, self.__qcoin[0])
        for i in range(steps):
            self.__QC.h(self.__qcoin[0])
            self.__QC.barrier()
            for i in range(n):
                self.__QC.mct([self.__qcoin[0]]+self.__qpos[i+1:], self.__qpos[i], None, mode='noancilla')
            self.__QC.barrier()
  
            self.__QC.x(self.__qcoin[0])
            for i in range(n):
                if i+1 < n: self.__QC.x(self.__qpos[i+1:])
                self.__QC.mct([self.__qcoin[0]]+self.__qpos[i+1:], self.__qpos[i], None, mode='noancilla')
                if i+1 < n: self.__QC.x(self.__qpos[i+1:])
            self.__QC.barrier()
        a=n/2
        p=math.floor(a)
        for k in range(n):
            if(k<p):
                self.__QC.swap(self.__qpos[n-1-k],self.__qpos[k])

    def displayh(self):
        display(self.__QC.draw(output="mpl"))
    def histagramh(self,shot):
        self.__QC.measure_all()
        job = execute(self.__QC,Aer.get_backend('aer_simulator'),shots=5000)
        counts = job.result().get_counts(self.__QC)   
        return counts
    def spacevectorh(self):
        backend = Aer.get_backend('statevector_simulator')
        job = execute(self.__QC, backend)
        result = job.result()
        outputstate = result.get_statevector(self.__QC, decimals=3)
        print(outputstate)
    def plotcityh(self):
        backend = Aer.get_backend('statevector_simulator')
        job = execute(self.__QC, backend)
        result = job.result()
        outputstate = result.get_statevector(self.__QC, decimals=3)
        from qiskit.visualization import plot_state_city
        plot_state_city(outputstate)
        return outputstate
    def unitaryh(self):
        backend = Aer.get_backend('unitary_simulator')
        job = execute(self.__QC, backend)
        result = job.result()
        yy=result.get_unitary(self.__QC, decimals=3)
        print(yy)
    def IBMQh(self):  
        from qiskit import IBMQ
        IBMQ.save_account('d1441affe8622903745ae099f50bce72c21036f85b14600d18195c977b9efcdee621dd4a981b92d8028c03c4dc1860c82d70f501d345023471402f4f8dad0181',overwrite=True)
        provider = IBMQ.load_account()
        device = provider.get_backend('ibmq_quito')     #we use ibmq_16_melbourne quantum device 
        job = execute(self.__QC, backend = device) #we pass our circuit and backend as usual 
        from qiskit.tools.monitor import job_monitor
        job_monitor(job)    #to see our status in queue
        result = job.result()
        counts= result.get_counts(self.__QC)
        return counts
    def instructionset(self):
        print(self.__QC.qasm())
        


qw = quantom_walk()
qw.main_qw(4,4,1,1.5,4)
#qw.instructionset()
#qw.displayh()
#plot_histogram(qw.histagramh(3000), figsize=(20, 5), color=None, number_to_keep=None, sort='asc', target_string=None, legend=None, bar_labels=True, title=None, ax=None)
#qw.histagramh(3000)
#qw.spacevectorh()
#qw.unitaryh()
#qw.plotcityh()
#plot_state_city(qw.plotcityh(), figsize=(20, 10))
#plot_histogram(qw.IBMQh(), figsize=(5, 2), color=None, number_to_keep=None, sort='asc', target_string=None, legend=None, bar_labels=True, title=None, ax=None, filename=None)
#qw.IBMQh()

qw = quantom_walk()
qw.main_qw(2,2,1,1.5,4)
qw.displayh()

qw.main_qw(6,25,1,1.5,4)
plot_histogram(qw.histagramh(3000), figsize=(20, 5), color=None, number_to_keep=None, sort='asc', target_string=None, legend=None, bar_labels=True, title=None, ax=None)


qw.main_qw(3,4,1,1.5,4)
qw.spacevectorh()

qw.main_qw(3,15,1,1.5,4)
plot_state_city(qw.plotcityh(), figsize=(20, 10))

qw.main_qw(2,3,1,1.5,4)
qw.unitaryh()

qw.main_qw(3,2,1,1.5,4)
qw.instructionset()

qw.main_qw(2,1,1,1.5,4)
plot_histogram(qw.IBMQh(), figsize=(5, 2), color=None, number_to_keep=None, sort='asc', target_string=None, legend=None, bar_labels=True, title=None, ax=None, filename=None)

#hadamrad...qtype=1 
qw = quantom_walk()
qw.main_qw(3,32,1,0,0)
plot_histogram(qw.histagramh(3000), figsize=(20, 5), color=None, number_to_keep=None, sort='asc', target_string=None, legend=None, bar_labels=True, title=None, ax=None)

#optimized ugate applied...qtype=3
qw = quantom_walk()
qw.main_qw(3,32,3,1.57,1.57)
plot_histogram(qw.histagramh(3000), figsize=(20, 5), color=None, number_to_keep=None, sort='asc', target_string=None, legend=None, bar_labels=True, title=None, ax=None)



