Query Grover algorithm¶
see paper "Variational learning algorithms for quantum query complexity" arxiv-link for details
In [1]:
Copied!
import numpy as np
import torch
try:
import numqi
except ImportError:
%pip install numqi
import numqi
import numpy as np
import torch
try:
import numqi
except ImportError:
%pip install numqi
import numqi
In [2]:
Copied!
def hf_grover_oracle_wrapper(x:int):
def hf0(q0):
q0 = q0.copy()
q0[x] *= -1
return q0
return hf0
def hf_grover_oracle_wrapper(x:int):
def hf0(q0):
q0 = q0.copy()
q0[x] *= -1
return q0
return hf0
In [3]:
Copied!
num_qubit = 4
num_query = 3
model = numqi.query.QueryGroverModel(num_qubit, num_query, use_fractional=False)
theta_optim = numqi.optimize.minimize(model, theta0='uniform', tol=1e-10, num_repeat=3, early_stop_threshold=1e-4)
print('error rate:', model.error_rate.item())
print('loss function:', theta_optim.fun)
if theta_optim.fun < 1e-5:
np_rng = np.random.default_rng()
xstar = np_rng.integers(2**num_qubit)
hf_oracle = hf_grover_oracle_wrapper(xstar)
with torch.no_grad():
unitary_list = model.manifold_SU().detach().numpy().transpose(0,2,1)
q0 = np.zeros(2**num_qubit, dtype=np.complex128)
q0[0] = 1
for ind0 in range(num_query):
q0 = unitary_list[ind0] @ q0
q0 = hf_oracle(q0)
q0 = unitary_list[-1] @ q0
prob = (q0.conj() * q0).real
x_found = np.argmax(prob)
assert x_found==xstar
assert abs(prob.max() - 1) < 1e-4
num_qubit = 4
num_query = 3
model = numqi.query.QueryGroverModel(num_qubit, num_query, use_fractional=False)
theta_optim = numqi.optimize.minimize(model, theta0='uniform', tol=1e-10, num_repeat=3, early_stop_threshold=1e-4)
print('error rate:', model.error_rate.item())
print('loss function:', theta_optim.fun)
if theta_optim.fun < 1e-5:
np_rng = np.random.default_rng()
xstar = np_rng.integers(2**num_qubit)
hf_oracle = hf_grover_oracle_wrapper(xstar)
with torch.no_grad():
unitary_list = model.manifold_SU().detach().numpy().transpose(0,2,1)
q0 = np.zeros(2**num_qubit, dtype=np.complex128)
q0[0] = 1
for ind0 in range(num_query):
q0 = unitary_list[ind0] @ q0
q0 = hf_oracle(q0)
q0 = unitary_list[-1] @ q0
prob = (q0.conj() * q0).real
x_found = np.argmax(prob)
assert x_found==xstar
assert abs(prob.max() - 1) < 1e-4
[round=0] min(f)=2.2386411613339874e-09, current(f)=2.2386411613339874e-09 error rate: 3.2048981246646235e-09 loss function: 2.2386411613339874e-09