I am trying to implement a general Grover's search for n
qubits searching for m
marked elements. I happened to observe that for the case of multiple solutions, I could stack together the oracles for each marked state and the result would be phase flip of each marked state. For example, for marked states 00
and 10
,I would design an oracle for both of them and stack them together. Same goes for higher qubits and more marked elements. Then I designed a general diffusion circuit. I'm then iterating the oracle and diffusion circuits T
times, where T
is given by
$$
T = \Bigg\lfloor{\frac{\pi\cdot k}{4\arcsin\sqrt{m/N}}}\Bigg\rfloor
$$
The problem is I'm getting correct results for almost every other state except n=3
qubits and m=4
solutions. I am taking marked states to be marked = [ '111', '010', '011', '000']
and the results I am getting from running the circuit through qasm simulator is not what I expect:
This is the code I wrote:
#Define and initialize the circuit
#Number of qubits
n = 3
#Define and initialize circuit
q = QuantumRegister(n, 'q')
c = ClassicalRegister(n ,'c')
ckt = QuantumCircuit(q, c)
#Put all initial states into superposition
ckt.h(q)
#Define the marked item
marked = [ '111', '010', '011', '000']
m = len(marked)
#Implement the oracle function for given marked item
#Checked, correct
def oracle(ckt, marked):
for j in marked:
#Put a X-gate for 0 qubits
for i in range(len(j)):
if j[i] == '0':
ckt.x(q[i])
#Implement a multi-controlled Z-gate
ckt.h(q[n-1])
ckt.mcx([q[i] for i in range(len(j)-1)], q[n-1])
ckt.h(q[n-1])
#Put X gates on those states that were acted upon by X-gates before
for i in range(len(j)):
if j[i] == '0':
ckt.x(q[i])
#Implement the diffuser function
def diffuser(ckt):
#Hadamard on all qubits
ckt.h(q)
#X-gates on all qubits
ckt.x(q)
#MCZ gate
ckt.h(q[n-1])
ckt.mcx([q[i] for i in range(n-1)], q[n-1])
ckt.h(q[n-1])
#X-gate on all qubits again
ckt.x(q)
#H-gates on all qubits again
ckt.h(q)
#Set number of iterations
import math
import numpy as np
N = 2**n
def T(k):
return math.floor((np.pi*k)/(4*np.arcsin(math.sqrt(m/N))))
k = 1
while True:
if T(k) > 0:
break
else:
k = k + 2
iterations = T(k)
#Iterate the circuit for 'iterations' times
for i in range(iterations):
oracle(ckt, marked)
diffuser(ckt)
I would really appreciate someone telling me the reason for this malfunction.