コード例 #1
0
    def reset_state(self, status, state, which_qubits):
        r"""用于重置你想要的量子比特上的部分量子态。

        Args:
            status (LoccStatus or list): 输入的 LOCC 态节点,其类型应该为 ``LoccStatus`` 或者由其组成的 ``list``
            state (Tensor): 输入的量子态的矩阵形式
            which_qubits (tuple or list): 指定需要被重置的量子比特编号,其形式为 ``(party_id, qubit_id)`` 的 ``tuple``,或者由其组成的 ``list``

        Returns:
            LoccStatus or list: 重置部分量子比特的量子态后的 LOCC 态节点,其类型为 ``LoccStatus`` 或者由其组成的 ``list``
        """
        if isinstance(which_qubits, tuple):
            which_qubits = [which_qubits]
        qubits_list = list()
        for party_id, qubit_id in which_qubits:
            if isinstance(party_id, str):
                qubits_list.append(self.parties_by_name[party_id][qubit_id])
            elif isinstance(party_id, int):
                qubits_list.append(self.parties_by_number[party_id][qubit_id])
            else:
                raise ValueError
        m = len(qubits_list)
        if isinstance(status, LoccStatus):
            n = int(log2(sqrt(status.state.numpy().size)))
        elif isinstance(status, list):
            n = int(log2(sqrt(status[0].state.numpy().size)))
        else:
            raise ValueError("can't recognize the input status")
        assert max(qubits_list) <= n, "qubit index out of range"

        origin_seq = list(range(0, n))
        target_seq = [idx for idx in origin_seq if idx not in qubits_list]
        target_seq = qubits_list + target_seq

        swaped = [False] * n
        swap_list = []
        for idx in range(0, n):
            if not swaped[idx]:
                next_idx = idx
                swaped[next_idx] = True
                while not swaped[target_seq[next_idx]]:
                    swaped[target_seq[next_idx]] = True
                    swap_list.append((next_idx, target_seq[next_idx]))
                    next_idx = target_seq[next_idx]

        cir0 = UAnsatz(n)
        for a, b in swap_list:
            cir0.swap([a, b])

        cir1 = UAnsatz(n)
        swap_list.reverse()
        for a, b in swap_list:
            cir1.swap([a, b])

        if isinstance(status, LoccStatus):
            _state = cir0.run_density_matrix(status.state)
            _state = partial_trace(_state, 2**m, 2**(n - m), 1)
            _state = kron(state, _state)
            _state = cir1.run_density_matrix(_state)
            new_status = LoccStatus(_state, status.prob,
                                    status.measured_result)
        elif isinstance(status, list):
            new_status = list()
            for each_status in status:
                _state = cir0.run_density_matrix(each_status.state)
                _state = partial_trace(_state, 2**m, 2**(n - m), 1)
                _state = kron(state, _state)
                _state = cir1.run_density_matrix(_state)
                new_status.append(
                    LoccStatus(_state, each_status.prob,
                               each_status.measured_result))
        else:
            raise ValueError("can't recognize the input status")

        return new_status
コード例 #2
0
ファイル: locc.py プロジェクト: Shahip2016/Quantum
    def reset_state(self, status, state, which_qubits):
        r"""用于重置你想要的量子比特上的部分量子态。

        Args:
            status (LoccStatus or list): 输入的 LOCC 态节点,其类型应该为 ``LoccStatus`` 或者由其组成的 ``list``
            state (ComplexVariable): 输入的量子态的矩阵形式
            which_qubits (tuple or list): 指定需要被重置的量子比特编号,其形式为 ``(party_id, qubit_id)`` 的 ``tuple``,或者由其组成的 ``list``

        Returns:
            LoccStatus or list: 重置部分量子比特的量子态后的 LOCC 态节点,其类型为 ``LoccStatus`` 或者由其组成的 ``list``
        """
        if isinstance(which_qubits, tuple):
            which_qubits = [which_qubits]
        qubits_list = list()
        for party_id, qubit_id in which_qubits:
            if isinstance(party_id, str):
                qubits_list.append(self.parties_by_name[party_id][qubit_id])
            elif isinstance(party_id, int):
                qubits_list.append(self.parties_by_number[party_id][qubit_id])
            else:
                raise ValueError
        m = len(qubits_list)
        if isinstance(status, LoccStatus):
            n = int(log2(sqrt(status.state.numpy().size)))
        elif isinstance(status, list):
            n = int(log2(sqrt(status[0].state.numpy().size)))
        else:
            raise ValueError("can't recognize the input status")
        assert max(qubits_list) <= n, "qubit index out of range"

        qubit2idx = list(range(0, n))
        idx2qubit = list(range(0, n))
        swap_history = list()

        cir0 = UAnsatz(n)
        for i, ele in enumerate(qubits_list):
            if qubit2idx[
                    ele] != i:  # if qubit2idx[ele] is i, then swap([ele, i]) is identity
                swap_history.append((i, qubit2idx[ele]))
                cir0.swap([i, qubit2idx[ele]])
                qubit2idx[idx2qubit[i]] = qubit2idx[ele]
                idx2qubit[qubit2idx[ele]] = idx2qubit[i]
                idx2qubit[i] = ele
                qubit2idx[ele] = i

        cir1 = UAnsatz(n)
        swap_cnt = len(swap_history)
        for idx in range(0, swap_cnt):
            a, b = swap_history[swap_cnt - 1 - idx]
            cir1.swap([b, a])

        if isinstance(status, LoccStatus):
            _state = cir0.run_density_matrix(status.state)
            _state = partial_trace(_state, 2**m, 2**(n - m), 1)
            _state = kron(state, _state)
            _state = cir1.run_density_matrix(_state)
            new_status = LoccStatus(_state, status.prob,
                                    status.measured_result)
        elif isinstance(status, list):
            new_status = list()
            for each_status in status:
                _state = cir0.run_density_matrix(each_status.state)
                _state = partial_trace(_state, 2**m, 2**(n - m), 1)
                _state = kron(state, _state)
                _state = cir1.run_density_matrix(_state)
                new_status.append(
                    LoccStatus(_state, each_status.prob,
                               each_status.measured_result))
        else:
            raise ValueError("can't recognize the input status")

        return new_status
コード例 #3
0
    def partial_state(self, status, which_qubits, is_desired=True):
        r"""得到你想要的部分量子比特上的量子态。

        Args:
            status (LoccStatus or list): 输入的 LOCC 态节点,其类型应该为 ``LoccStatus`` 或者由其组成的 ``list``
            which_qubits (tuple or list): 指定的量子比特编号,其形式为 ``(party_id, qubit_id)`` 的 ``tuple`` ,或者由其组成的 ``list``
            is_desired (bool, optional): 默认是 ``True`` ,即返回量子比特上的部分量子态。如果为 ``False`` ,则抛弃这部分量子比特上的量子态,返回剩下的部分量子态

        Returns:
            LoccStatus or list: 得到部分量子态后的 LOCC 态节点,其类型为 ``LoccStatus`` 或者由其组成的 ``list``
        """
        if isinstance(which_qubits, tuple):
            which_qubits = [which_qubits]
        qubits_list = list()
        for party_id, qubit_id in which_qubits:
            if isinstance(party_id, str):
                qubits_list.append(self.parties_by_name[party_id][qubit_id])
            elif isinstance(party_id, int):
                qubits_list.append(self.parties_by_number[party_id][qubit_id])
            else:
                raise ValueError
        m = len(qubits_list)
        if isinstance(status, LoccStatus):
            n = int(log2(sqrt(status.state.numpy().size)))
        elif isinstance(status, list):
            n = int(log2(sqrt(status[0].state.numpy().size)))
        else:
            raise ValueError("can't recognize the input status")

        assert max(qubits_list) <= n, "qubit index out of range"
        origin_seq = list(range(0, n))
        target_seq = [idx for idx in origin_seq if idx not in qubits_list]
        target_seq = qubits_list + target_seq

        swaped = [False] * n
        swap_list = []
        for idx in range(0, n):
            if not swaped[idx]:
                next_idx = idx
                swaped[next_idx] = True
                while not swaped[target_seq[next_idx]]:
                    swaped[target_seq[next_idx]] = True
                    swap_list.append((next_idx, target_seq[next_idx]))
                    next_idx = target_seq[next_idx]

        cir = UAnsatz(n)
        for a, b in swap_list:
            cir.swap([a, b])

        if isinstance(status, LoccStatus):
            state = cir.run_density_matrix(status.state)
            if is_desired:
                state = partial_trace(state, 2**m, 2**(n - m), 2)
            else:
                state = partial_trace(state, 2**m, 2**(n - m), 1)
            new_status = LoccStatus(state, status.prob, status.measured_result)
        elif isinstance(status, list):
            new_status = list()
            for each_status in status:
                state = cir.run_density_matrix(each_status.state)
                if is_desired:
                    state = partial_trace(state, 2**m, 2**(n - m), 2)
                else:
                    state = partial_trace(state, 2**m, 2**(n - m), 1)
                new_status.append(
                    LoccStatus(state, each_status.prob,
                               each_status.measured_result))
        else:
            raise ValueError("can't recognize the input status")

        return new_status
コード例 #4
0
ファイル: locc.py プロジェクト: Shahip2016/Quantum
    def partial_state(self, status, which_qubits, is_desired=True):
        r"""得到你想要的部分量子比特上的量子态。

        Args:
            status (LoccStatus or list): 输入的 LOCC 态节点,其类型应该为 ``LoccStatus`` 或者由其组成的 ``list``
            which_qubits (tuple or list): 指定的量子比特编号,其形式为 ``(party_id, qubit_id)`` 的 ``tuple`` ,或者由其组成的 ``list``
            is_desired (bool, optional): 默认是 ``True`` ,即返回量子比特上的部分量子态。如果为 ``False`` ,则抛弃这部分量子比特上的量子态,返回剩下的部分量子态

        Returns:
            LoccStatus or list: 得到部分量子态后的 LOCC 态节点,其类型为 ``LoccStatus`` 或者由其组成的 ``list``
        """
        if isinstance(which_qubits, tuple):
            which_qubits = [which_qubits]
        qubits_list = list()
        for party_id, qubit_id in which_qubits:
            if isinstance(party_id, str):
                qubits_list.append(self.parties_by_name[party_id][qubit_id])
            elif isinstance(party_id, int):
                qubits_list.append(self.parties_by_number[party_id][qubit_id])
            else:
                raise ValueError
        m = len(qubits_list)
        if isinstance(status, LoccStatus):
            n = int(log2(sqrt(status.state.numpy().size)))
        elif isinstance(status, list):
            n = int(log2(sqrt(status[0].state.numpy().size)))
        else:
            raise ValueError("can't recognize the input status")

        assert max(qubits_list) <= n, "qubit index out of range"
        qubit2idx = list(range(0, n))
        idx2qubit = list(range(0, n))

        cir = UAnsatz(n)
        for i, ele in enumerate(qubits_list):
            if qubit2idx[ele] != i:
                # if qubit2idx[ele] is i, then swap([ele, i]) is identity
                cir.swap([i, qubit2idx[ele]])
                qubit2idx[idx2qubit[i]] = qubit2idx[ele]
                idx2qubit[qubit2idx[ele]] = idx2qubit[i]
                idx2qubit[i] = ele
                qubit2idx[ele] = i

        if isinstance(status, LoccStatus):
            state = cir.run_density_matrix(status.state)
            if is_desired:
                state = partial_trace(state, 2**m, 2**(n - m), 2)
            else:
                state = partial_trace(state, 2**m, 2**(n - m), 1)
            new_status = LoccStatus(state, status.prob, status.measured_result)
        elif isinstance(status, list):
            new_status = list()
            for each_status in status:
                state = cir.run_density_matrix(each_status.state)
                if is_desired:
                    state = partial_trace(state, 2**m, 2**(n - m), 2)
                else:
                    state = partial_trace(state, 2**m, 2**(n - m), 1)
                new_status.append(
                    LoccStatus(state, each_status.prob,
                               each_status.measured_result))
        else:
            raise ValueError("can't recognize the input status")

        return new_status