Я реализовал оптимизацию лидера группы для формирования квантовых цепей из унитарных матриц.Я взял четыре переменные, чтобы представить ворота, и взял в качестве одного члена 20 переменных, представляющих 5 ворот (фиксированное количество ворот).В группе 15 таких членов и всего 25 групп, которые я рассмотрел.
Мой код сводит к минимуму только ошибку верности и выбирает строку, представляющую схему с минимальной ошибкой верности (число вентилейнеподвижная = 5).То, что я хочу сделать, это установить максимальное количество вентилей равным 20 и иметь строку переменной длины для представления цепей с переменным числом вентилей.Это сводит к минимуму ошибку верности, а также стоимость (меньшее количество шлюзов = меньшую стоимость)
Как мне это сделать?
Это вывод моего кода.Первые четыре переменные представляют затвор, целевой кубит, управляющий кубит и угол поворота для первых затворов.Остальное, представляющее следующие 4 шлюза аналогичным образом, сгруппированные в четыре переменные, представляет собой
Код (для разложения унитарной матрицы Тоффоли Гейт):
import matplotlib.pyplot as plt
import numpy,random
import functions
num_x = 20
num_groups=25
pop_per_group = 15
pop_size = (num_groups,pop_per_group,num_x)
leaders= numpy.empty((num_groups, num_x))
r1=0.8
r2=0.1
r3=0.1
new_mem=numpy.random.uniform(low=0, high=4, size=20)
new_population = numpy.random.uniform(low=0, high=4, size=pop_size)
for g in range (num_groups):#num_groups
fitness=functions.cal_fitness(new_population[g, : ,:])
#print("fitness of group", g+1)
#print (fitness)
leaders[g,:]=functions.select_leader(new_population[g,: ,:],num_groups,g)
print (leaders)
y=numpy.zeros(shape=600)
for i in range (600):
print("-----------------------------")
print ("Generation:" ,i)
#print("-----------------------------")
print("-----------------------------")
for g in range (num_groups):
for p in range (pop_per_group):
rand_mem=numpy.random.uniform(low=0, high=4, size=20)
new_mem=r1*new_population[g,p,:]+r2*leaders[g,:]+r3*rand_mem
#print(new_population[g,p,:])
new_population[g,p,:] = functions.select_new_mem(new_population[g,p,:],new_mem)
#print(new_population[g,p,:])
for g in range (num_groups):
t=random.randint(0,9)
#print ('old',g,k)
#print(new_population[g,k,:])
for t in range (t+1):
x=int(random.random()*num_groups)
k=int(random.random()*pop_per_group)
pr=random.randint(0,19)
new_mem=new_population[g,k,:].copy()
new_mem[pr]=new_population[x,k,pr]
next_mem=functions.select_new_mem(new_population[g,k,:],new_mem)
new_population[g,k,:]=next_mem
#print (new_population[g,k,:])
#print (next_mem)
#print ('new',g,k)
#print(new_population[g,k,:])
for g in range (num_groups):#num_groups
fitness=functions.cal_fitness(new_population[g, : ,:])
#print("fitness of group", g+1)
#print (fitness)
leaders[g,:]=functions.select_leader(new_population[g,: ,:],num_groups,g)
print (leaders)
print (functions.cal_fitness(leaders))
y[i]=functions.select_best_leader(leaders)
xl = numpy.linspace(0, 600,600)
#Plot the data
plt.plot(xl, y, label='Fitness')
Функции (Код):
import numpy
from math import pi,sqrt,e
import UnitaryCalculation
from qiskit.quantum_info import process_fidelity
def val_pop(one_mem):
i=1
for var in range (20):
if (i%4==0):
one_mem[var]=one_mem[var] % (2*3.14)
i+=1
elif ((i-1)%4==0):
one_mem[var]=int(one_mem[var])
i+=1
else:#Nq = 3
one_mem[var]=int(one_mem[var] %3 )
i+=1
return one_mem
def ifitness(mem):
unitary_t=[[1,0,0,0,0,0,0,0],[0,1,0,0,0,0,0,0],[0,0,1,0,0,0,0,0],[0,0,0,1,0,0,0,0],[0,0,0,0,1,0,0,0],[0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1],[0,0,0,0,0,0,1,0]]
unitary_a=UnitaryCalculation.cal_unitary(mem)
fit=process_fidelity(unitary_t, unitary_a)
fit_mem=1-fit**2
return fit_mem
def cal_fitness(pop):
unitary_t=[[1,0,0,0,0,0,0,0],[0,1,0,0,0,0,0,0],[0,0,1,0,0,0,0,0],[0,0,0,1,0,0,0,0],[0,0,0,0,1,0,0,0],[0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1],[0,0,0,0,0,0,1,0]]
#print(unitary_t)
fitness=numpy.ndarray(shape=(0))
for p in range (pop.shape[0]):
unitary_a=UnitaryCalculation.cal_unitary(pop[p, :])
fit=process_fidelity(unitary_t, unitary_a)
fitness=numpy.append(fitness, values=1-fit**2)
#print (fitness)
return (fitness)
def select_leader(pop,num_groups,g):
#print(pop.shape[0])
fitness=cal_fitness(pop)
max_fitness_idx = numpy.where(fitness == numpy.min(fitness))
max_fitness_idx = max_fitness_idx[0][0]
fitness[max_fitness_idx] = +99999999999
return (pop[max_fitness_idx, :])
def select_new_mem(old_mem,new_mem):
of=ifitness(old_mem)
#print(of)
nf=ifitness(new_mem)
#print(new_mem)
#print(nf)
if (nf < of):
#print('changed')
return new_mem
else :
return old_mem
def select_best_leader(leaders):
best_leader = numpy.zeros((leaders.shape[1]))
fitness=cal_fitness(leaders)
max_fitness_idx = numpy.where(fitness == numpy.min(fitness))
max_fitness_idx = max_fitness_idx[0][0]
best_leader= leaders[max_fitness_idx, :]
print ("Best Soln is: ")
print (best_leader)
print ("Its fitness is: ")
print (fitness[max_fitness_idx])
return (fitness[max_fitness_idx])
Унитарный расчет (код):
import numpy
from math import sqrt,e,pi
from qiskit.quantum_info import process_fidelity
def get_gate(num):
i_=numpy.complex(0,1)
H=1./sqrt(2)*numpy.matrix('1 1; 1 -1')
X=numpy.matrix('0 1; 1 0')
Y=numpy.matrix([[0, -i_],[i_, 0]])
Z=numpy.matrix([[1,0],[0,-1]])
W=1/sqrt(2)*(X+Z)
V=numpy.matrix([[1+i_,1-i_],[1-i_,1+i_]]) * 1/2
Vdagger = V.conjugate().transpose()
S=numpy.matrix([[1,0],[0,i_]])
Sdagger=numpy.matrix([[1,0],[0,-i_]]) # convenience Sdagger = S.conjugate().transpose()
T=numpy.matrix([[1,0],[0, e**(i_*pi/4.)]])
Tdagger=numpy.matrix([[1,0],[0, e**(-i_*pi/4.)]]) # convenience Tdagger= T.conjugate().transpose()
if (num==0):
return V
elif (num==1):
return Z
elif (num==2):
return S
elif (num==3):
return Vdagger
def cal_mc_gate(gate):
Nq=3
zeros=[[1,0],[0,0]]
ones=[[0,0],[0,1]]
mat_to_tensor=numpy.empty(shape=(Nq,2,2),dtype=complex)
for n in range(Nq):
mat_to_tensor[n]=numpy.identity(2)
Cq=int(gate[2] %3)
Tq=int(gate[1] %3)
theta=gate[3]
g_matrix=get_gate(gate[0])
#print (g_matrix)
if (Cq!=Tq):
mat_to_tensor[Cq]=zeros
u1=numpy.kron(numpy.kron(mat_to_tensor[0],mat_to_tensor[1]),mat_to_tensor[2])
mat_to_tensor[Cq]=ones
mat_to_tensor[Tq]=g_matrix
u2=numpy.kron(numpy.kron(mat_to_tensor[0],mat_to_tensor[1]),mat_to_tensor[2])
unitary=numpy.add(u1,u2)
else:
mat_to_tensor[Tq]=g_matrix
unitary=numpy.kron(numpy.kron(mat_to_tensor[0],mat_to_tensor[1]),mat_to_tensor[2])
#print (unitary)
return unitary
def cal_u_gate(gate):
Nq=3
zeros=[[1,0],[0,0]]
ones=[[0,0],[0,1]]
mat_to_tensor=numpy.empty(shape=(Nq,2,2),dtype=complex)
for n in range(Nq):
mat_to_tensor[n]=numpy.identity(2)
Cq=int(gate[2] %3)
Tq=int(gate[1] %3)
theta=gate[3]
g_matrix=get_gate(gate[0])
#print (g_matrix)
if (Cq!=Tq):
mat_to_tensor[Cq]=zeros
u1=numpy.kron(numpy.kron(mat_to_tensor[0],mat_to_tensor[1]),mat_to_tensor[2])
mat_to_tensor[Cq]=ones
mat_to_tensor[Tq]=g_matrix
u2=numpy.kron(numpy.kron(mat_to_tensor[0],mat_to_tensor[1]),mat_to_tensor[2])
unitary=numpy.add(u1,u2)
else:
mat_to_tensor[Tq]=g_matrix
unitary=numpy.kron(numpy.kron(mat_to_tensor[0],mat_to_tensor[1]),mat_to_tensor[2])
#print (unitary)
return unitary #[[0,2,1,0],[1,2,0,0],[2,1,0,0],[3,2,1,0],[1,0,2,0]]
def cal_unitary(one_mem):
#one_mem=[0,2,1,0,1,2,0,0,2,1,0,0,3,2,1,0,1,0,2,0]
x=numpy.zeros(shape=(5,4))
u=numpy.zeros(shape=(5,8,8),dtype=complex)
k=0
for gate in range (5):
for var in range (0,3):
x[gate][var]=int(one_mem[k])
k+=1
x[gate][var+1]=one_mem[k]
k+=1
for gate in range (5):
u[gate]=cal_u_gate(x[gate,:])
#print ("The unitary matrix of U", gate )
#print (u[gate])
unitary=numpy.dot(numpy.dot(numpy.dot(numpy.dot(u[0],u[1]),u[2]),u[3]),u[4])
#np.set_printoptions(precision=1)
return unitary