def partial_trace(rho_AB, dim1, dim2, A_or_B): r"""计算量子态的偏迹。 Args: rho_AB (Tensor): 输入的量子态 dim1 (int): 系统A的维数 dim2 (int): 系统B的维数 A_or_B (int): 1或者2,1表示计算系统A上的偏迹,2表示计算系统B上的偏迹 Returns: Tensor: 输入的量子态的偏迹 """ if A_or_B == 2: dim1, dim2 = dim2, dim1 idty_np = np.identity(dim2).astype("complex128") idty_B = to_tensor(idty_np) zero_np = np.zeros([dim2, dim2], "complex128") res = to_tensor(zero_np) for dim_j in range(dim1): row_top = zeros([1, dim_j], dtype="float64") row_mid = ones([1, 1], dtype="float64") row_bot = zeros([1, dim1 - dim_j - 1], dtype="float64") bra_j = concat([row_top, row_mid, row_bot], axis=1) bra_j = paddle.cast(bra_j, 'complex128') if A_or_B == 1: row_tmp = kron(bra_j, idty_B) row_tmp_conj = paddle.conj(row_tmp) res = add( res, matmul( matmul(row_tmp, rho_AB), transpose(row_tmp_conj, perm=[1, 0]), ), ) if A_or_B == 2: row_tmp = kron(idty_B, bra_j) row_tmp_conj = paddle.conj(row_tmp) res = add( res, matmul( matmul(row_tmp, rho_AB), transpose(row_tmp_conj, perm=[1, 0]), ), ) return res
def dagger(matrix): r"""计算矩阵的埃尔米特转置,即Hermitian transpose。 Args: matrix (Tensor): 需要埃尔米特转置的矩阵 Returns: Tensor: 输入矩阵的埃尔米特转置 代码示例: .. code-block:: python from paddle_quantum.utils import dagger import numpy as np rho = paddle.to_tensor(np.array([[1+1j, 2+2j], [3+3j, 4+4j]])) print(dagger(rho).numpy()) :: [[1.-1.j 3.-3.j] [2.-2.j 4.-4.j]] """ matrix_conj = paddle.conj(matrix) matrix_dagger = transpose(matrix_conj, perm=[1, 0]) return matrix_dagger
def test_conj_api_real_number(self): for dtype in self._dtypes: input = rand([2, 20, 2, 3]).astype(dtype) for place in self._places: with dg.guard(place): var_x = paddle.to_tensor(input) result = paddle.conj(var_x).numpy() target = np.conj(input) self.assertTrue(np.array_equal(result, target))
def vec_expecval(H, vec): r""" It returns expectation value of H with respect to vector vec Note: 这是内部函数,你并不需要直接调用到该函数。 """ vec_conj = paddle.conj(vec) result = paddle.sum(multiply(vec_conj, H_vec(H, vec))) return result
def test_conj_static_mode(self): def init_input_output(dtype): input = rand([2, 20, 2, 3]).astype(dtype) + 1j * rand( [2, 20, 2, 3]).astype(dtype) return {'x': input}, np.conj(input) for dtype in self._dtypes: input_dict, np_res = init_input_output(dtype) for place in self._places: with static.program_guard(static.Program()): x_dtype = np.complex64 if dtype == "float32" else np.complex128 x = static.data( name="x", shape=[2, 20, 2, 3], dtype=x_dtype) out = paddle.conj(x) exe = static.Executor(place) out_value = exe.run(feed=input_dict, fetch_list=[out.name]) self.assertTrue(np.array_equal(np_res, out_value[0]))
def run_state_vector(self, input_state=None, store_state=True): r"""运行当前的量子线路,输入输出的形式为态矢量。 Args: input_state (Tensor, optional): 输入的态矢量,默认为 :math:`|00...0\rangle` store_state (Bool, optional): 是否存储输出的态矢量,默认为 ``True`` ,即存储 Returns: Tensor: 量子线路输出的态矢量 代码示例: .. code-block:: python import numpy as np import paddle from paddle_quantum.circuit import UAnsatz from paddle_quantum.state import vec n = 2 theta = np.ones(3) input_state = paddle.to_tensor(vec(n)) theta = paddle.to_tensor(theta) cir = UAnsatz(n) cir.h(0) cir.ry(theta[0], 1) cir.rz(theta[1], 1) output_state = cir.run_state_vector(input_state).numpy() print(f"The output state vector is {output_state}") :: The output state vector is [[0.62054458+0.j 0.18316521+0.28526291j 0.62054458+0.j 0.18316521+0.28526291j]] """ state = init_state_gen(self.n, 0) if input_state is None else input_state old_shape = state.shape assert reduce( lambda x, y: x * y, old_shape ) == 2**self.n, 'The length of the input vector is not right' state = complex_reshape(state, (2**self.n, )) state_conj = paddle.conj(state) assert paddle.abs(paddle.real(paddle.sum(multiply(state_conj, state))) - 1) < 1e-8, \ 'Input state is not a normalized vector' for history_ele in self.__history: if history_ele[0] == 'u': state = StateTransfer(state, 'u', history_ele[1], history_ele[2]) elif history_ele[0] in {'x', 'y', 'z', 'h'}: state = StateTransfer(state, history_ele[0], history_ele[1], params=history_ele[2]) elif history_ele[0] == 'SWAP': state = StateTransfer(state, 'SWAP', history_ele[1]) elif history_ele[0] == 'CNOT': state = StateTransfer(state, 'CNOT', history_ele[1]) if store_state: self.__state = state # Add info about which function user called self.__run_state = 'state_vector' return complex_reshape(state, old_shape)