mat_maker
概要
この関数では線型結合の係数を補助ビット部分にセットする行列を作成する 量子回路でもちいる行列はユニタリ性を満たす必要があるので複雑な過程が必要だが第一列目の要素と係数さえ入力すれば自動的に作成する
引数一覧
argument name |
type |
role |
---|---|---|
elelist |
list(element:float) |
線形結合で用いられている係数の一覧 |
coeff_list |
list(element:float) |
行列を計算する際に必要な値の一覧 |
戻り値
mat_ele_list(np.array): 作成したユニタリ行列が格納されたnp.array
格納されている要素はfloat型
Python code
def mat_maker(elelist, coeff_lst):
mat_ele_list = []
# append the first colum of the desired matrix
mat_ele_list.append(elelist)
# search the border between non-zero elements and zero elements
for i in range(len(elelist)//2):
zero_num = i*2
if np.abs(elelist[i*2]) == 0:
break
if elelist[zero_num] != 0:
zero_num = len(elelist)
# copy list of coeffcients to use ".reverse()"
cf_copy = copy.deepcopy(coeff_lst)
cf_copy.reverse()
for i in range(len(coeff_lst)):
# copy elements of matrix, this copy will be append to returned matrix after some process
mat_copy = copy.deepcopy(mat_ele_list)
for j in range(len(mat_copy)):
# calculate non-zero elements of unitary matrix as list
app_list = vec_make(mat_copy[j], cf_copy[i])
# append elemnets zero to list of non-zero elements
if i < (len(coeff_lst) - 1.1):
if zero_num < (len(elelist) - 0.1):
if zero_num%2**(i+2) != 0:
input_ele = 0
for s in range(2**(i+1) + 2*j):
input_ele += mat_copy[i][(zero_num//(2**(i+2)))*(2**(i+2)) + s]**2
app_list[(zero_num//(2**(i+2)))*(2**(i+2)) + s] = 0
app_list[zero_num] = np.sqrt(input_ele)
zero_num += 2
mat_ele_list.append(np.array(app_list))
base_mat = [[0, -1], [1, 0]]
unit = np.eye(2)
convert = np.kron(unit, base_mat)
# exchange ith line and i+1th line (i = 0, 1, 2, ..., len(coeff_lst) - 1)
for i in range(len(coeff_lst) - 1):
convert = np.kron(unit, convert)
mel_len = len(mat_ele_list)
if (np.log2(len(elelist)) > 1):
for i in range(mel_len):
mat_ele_list.append(np.dot(convert, mat_ele_list[i]))
if (np.log2(len(elelist)) < 1.1):
mat_ele_list = [[elelist[0], elelist[1]], [elelist[1], -elelist[0]]]
# transpose the matrix to make it the optimal shape for sandwiching between quantum states
return np.array(mat_ele_list).T
実行例
[1]:
import numpy as np
import pitbe
[4]:
ele_lst = [0.5, 0.433, 0.25, 0.433, 0.433, 0.3536, 0., 0.]
cf_lst = [[1.483], [1.322, 0.5590]]
unit_mat = pitbe.mat_maker(ele_lst, cf_lst)
print(np.round(unit_mat, 4))
[[ 0.5 -0.3782 -0.3372 0.255 -0.433 0.3275 0.292 -0.2209]
[ 0.433 -0.3275 -0.292 0.2209 0.5 -0.3782 -0.3372 0.255 ]
[ 0.25 0.3305 -0.1686 -0.2229 -0.433 -0.5724 0.292 0.386 ]
[ 0.433 0.5724 -0.292 -0.386 0.25 0.3305 -0.1686 -0.2229]
[ 0.433 0. 0.6421 0. -0.3536 0. -0.5244 0. ]
[ 0.3536 0. 0.5244 0. 0.433 0. 0.6421 0. ]
[ 0. 0.559 0. 0.8291 0. 0. 0. 0. ]
[ 0. 0. 0. 0. 0. 0.559 0. 0.8291]]
作成された行列がユニタリ行列であることは以下のように確認される。
[9]:
# Norm of all eigenvalues are one.
eigenvalue = np.linalg.eig(unit_mat)[0]
for i in range(len(eigenvalue)):
print(np.round(np.linalg.norm(eigenvalue[i]), 3))
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
[8]:
# The product with the complex conjugate of the matrix is the identity matrix.
print(np.round(np.dot(unit_mat.T, unit_mat), 3))
[[ 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. 1. -0.]
[-0. 0. 0. 0. 0. 0. -0. 1.]]