def single_gate_construct(mat, n, which_qubit): r"""构建单量子比特门 Args: mat (Variable): 输入的矩阵 n (int): 量子比特数 which_qubit (int): 输入矩阵所在的量子比特号 Returns: Variable: 得到的单量子比特门矩阵 """ idty = identity_generator(n - 1) if which_qubit == 1: mat = pp_kron(mat, idty) elif which_qubit == n: mat = pp_kron(idty, mat) else: I_top = identity_generator(which_qubit - 1) I_bot = identity_generator(n - which_qubit) mat = pp_kron(pp_kron(I_top, mat), I_bot) return mat
def partial_trace(rho_AB, dim1, dim2, A_or_B): r"""计算量子态的偏迹。 Args: rho_AB (ComplexVariable): 输入的量子态 dim1 (int): 系统A的维数 dim2 (int): 系统B的维数 A_or_B (int): 1或者2,1表示去除A,2表示去除B Returns: ComplexVariable: 量子态的偏迹 """ if A_or_B == 2: dim1, dim2 = dim2, dim1 idty_np = identity(dim2).astype("complex128") idty_B = to_variable(idty_np) zero_np = np_zeros([dim2, dim2], "complex128") res = to_variable(zero_np) for dim_j in range(dim1): row_top = pp_zeros([1, dim_j], dtype="float64") row_mid = ones([1, 1], dtype="float64") row_bot = pp_zeros([1, dim1 - dim_j - 1], dtype="float64") bra_j_re = concat([row_top, row_mid, row_bot], axis=1) bra_j_im = pp_zeros([1, dim1], dtype="float64") bra_j = ComplexVariable(bra_j_re, bra_j_im) if A_or_B == 1: row_tmp = pp_kron(bra_j, idty_B) res = elementwise_add( res, matmul( matmul(row_tmp, rho_AB), pp_transpose(ComplexVariable(row_tmp.real, -row_tmp.imag), perm=[1, 0]), ), ) if A_or_B == 2: row_tmp = pp_kron(idty_B, bra_j) res = elementwise_add( res, matmul( matmul(row_tmp, rho_AB), pp_transpose(ComplexVariable(row_tmp.real, -row_tmp.imag), perm=[1, 0]), ), ) return res
def partial_trace(rho_AB, dim1, dim2, A_or_B): r"""求AB复合系统下的偏迹 Args: rho_AB (Variable): AB复合系统的密度矩阵 dim1 (int): A系统的维度 dim2 (int): B系统的维度 A_orB (int): 1表示求系统A,2表示求系统B Returns: ComplexVariable: 求得的偏迹 """ # dim_total = dim1 * dim2 if A_or_B == 2: dim1, dim2 = dim2, dim1 idty_np = identity(dim2).astype("complex64") idty_B = to_variable(idty_np) zero_np = np_zeros([dim2, dim2], "complex64") res = to_variable(zero_np) for dim_j in range(dim1): row_top = pp_zeros([1, dim_j], dtype="float32") row_mid = ones([1, 1], dtype="float32") row_bot = pp_zeros([1, dim1 - dim_j - 1], dtype="float32") bra_j_re = concat([row_top, row_mid, row_bot], axis=1) bra_j_im = pp_zeros([1, dim1], dtype="float32") bra_j = ComplexVariable(bra_j_re, bra_j_im) if A_or_B == 1: row_tmp = pp_kron(bra_j, idty_B) res = elementwise_add( res, matmul( matmul(row_tmp, rho_AB), pp_transpose(ComplexVariable(row_tmp.real, -row_tmp.imag), perm=[1, 0]), ), ) if A_or_B == 2: row_tmp = pp_kron(idty_B, bra_j) res += matmul( matmul(row_tmp, rho_AB), pp_transpose(ComplexVariable(row_tmp.real, -row_tmp.imag), perm=[1, 0]), ) return res
def partial_trace(rho_AB, dim1, dim2, A_or_B): """ :param rho_AB: the input density matrix :param dim1: dimension for system A :param dim2: dimension for system B :param A_or_B: 1 or 2, choose the system that you want trace out. :return: partial trace """ # dim_total = dim1 * dim2 if A_or_B == 2: dim1, dim2 = dim2, dim1 idty_np = identity(dim2).astype("complex64") idty_B = to_variable(idty_np) zero_np = np_zeros([dim2, dim2], "complex64") res = to_variable(zero_np) for dim_j in range(dim1): row_top = pp_zeros([1, dim_j], dtype="float32") row_mid = ones([1, 1], dtype="float32") row_bot = pp_zeros([1, dim1 - dim_j - 1], dtype="float32") bra_j_re = concat([row_top, row_mid, row_bot], axis=1) bra_j_im = pp_zeros([1, dim1], dtype="float32") bra_j = ComplexVariable(bra_j_re, bra_j_im) if A_or_B == 1: row_tmp = pp_kron(bra_j, idty_B) res = elementwise_add( res, matmul( matmul(row_tmp, rho_AB), pp_transpose( ComplexVariable(row_tmp.real, -row_tmp.imag), perm=[1, 0]), ), ) if A_or_B == 2: row_tmp = pp_kron(idty_B, bra_j) res += matmul( matmul(row_tmp, rho_AB), pp_transpose( ComplexVariable(row_tmp.real, -row_tmp.imag), perm=[1, 0]), ) return res
def single_gate_construct(mat, n, which_qubit): """ :param mat: the input matrix :param n: number of qubits :param which_qubit: indicate which qubit the matrix is placed on :return: the kronecker product of the matrix and identity """ idty = identity_generator(n - 1) if which_qubit == 1: mat = pp_kron(mat, idty) elif which_qubit == n: mat = pp_kron(idty, mat) else: I_top = identity_generator(which_qubit - 1) I_bot = identity_generator(n - which_qubit) mat = pp_kron(pp_kron(I_top, mat), I_bot) return mat
def local_H_prob(cir, hamiltonian, shots=1024): r""" 构造出Pauli测量电路并测量ancilla,处理实验结果来得到 ``H`` (只有一项)期望值的实验测量值。 Note: 这是内部函数,你并不需要直接调用到该函数。 """ # Add one ancilla, which we later measure and process the result new_cir = UAnsatz(cir.n + 1) input_state = pp_kron(cir.run_state_vector(store_state=False), init_state_gen(1)) # Used in fixed Rz gate _theta = fluid.dygraph.to_variable(np.array([-np.pi / 2])) op_list = hamiltonian.split(',') # Set up pauli measurement circuit for op in op_list: element = op[0] index = int(op[1:]) if element == 'x': new_cir.h(index) new_cir.cnot([index, cir.n]) elif element == 'z': new_cir.cnot([index, cir.n]) elif element == 'y': new_cir.rz(_theta, index) new_cir.h(index) new_cir.cnot([index, cir.n]) new_cir.run_state_vector(input_state) prob_result = new_cir.measure(shots=shots, which_qubits=[cir.n]) if shots > 0: if len(prob_result) == 1: if '0' in prob_result: result = (prob_result['0']) / shots else: result = (prob_result['1']) / shots else: result = (prob_result['0'] - prob_result['1']) / shots else: result = (prob_result['0'] - prob_result['1']) return result