mat_maker
Outline
This function generates the matrix that sets the coefficients of the linear combination into the ancillary qubit part.
Since the matrix used in the quantum circuit must be unitary, the construction process is nontrivial; however, by simply providing the first column elements and the corresponding coefficients, the function automatically generates a valid unitary matrix.
Index List
argument name |
type |
role |
|---|---|---|
elelist |
list(element:float) |
Coefficient List for the Linear Combination |
coeff_list |
list(element:float) |
Parameters Used in Matrix Computation |
Return
mat_ele_list(np.array):
np.array storing the generated unitary matrix (elements of type 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
Sample Run
[ ]:
import numpy as np
import pitbe
[ ]:
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]]
The unitarity of the constructed matrix can be verified as follows.
[ ]:
# 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
[ ]:
# 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.]]