Example #1
0
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
Example #2
0
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
Example #3
0
 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))
Example #4
0
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
Example #5
0
    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]))
Example #6
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)