def permute(self, permutation: List[int]) -> 'VectorStateFn':
        new_self = self
        new_num_qubits = max(permutation) + 1

        if self.num_qubits != len(permutation):
            # raise OpflowError("New index must be defined for each qubit of the operator.")
            pass
        if self.num_qubits < new_num_qubits:
            # pad the operator with identities
            new_self = self._expand_dim(new_num_qubits - self.num_qubits)
        qc = QuantumCircuit(new_num_qubits)

        # extend the permutation indices to match the size of the new matrix
        permutation \
            = list(filter(lambda x: x not in permutation, range(new_num_qubits))) + permutation

        # decompose permutation into sequence of transpositions
        transpositions = arithmetic.transpositions(permutation)
        for trans in transpositions:
            qc.swap(trans[0], trans[1])
        from .. import CircuitOp
        matrix = CircuitOp(qc).to_matrix()
        vector = new_self.primitive.data
        return VectorStateFn(primitive=matrix.dot(vector),
                             coeff=self.coeff,
                             is_measurement=self.is_measurement)
Exemple #2
0
    def permute(self, permutation: Optional[List[int]] = None) -> 'MatrixOp':
        """Creates a new MatrixOp that acts on the permuted qubits.

        Args:
            permutation: A list defining where each qubit should be permuted. The qubit at index
                j should be permuted to position permutation[j].

        Returns:
            A new MatrixOp representing the permuted operator.

        Raises:
            OpflowError: if indices do not define a new index for each qubit.
        """
        new_self = self
        new_matrix_size = max(permutation) + 1

        if self.num_qubits != len(permutation):
            raise OpflowError(
                "New index must be defined for each qubit of the operator.")
        if self.num_qubits < new_matrix_size:
            # pad the operator with identities
            new_self = self._expand_dim(new_matrix_size - self.num_qubits)
        qc = QuantumCircuit(new_matrix_size)

        # extend the indices to match the size of the new matrix
        permutation \
            = list(filter(lambda x: x not in permutation, range(new_matrix_size))) + permutation

        # decompose permutation into sequence of transpositions
        transpositions = arithmetic.transpositions(permutation)
        for trans in transpositions:
            qc.swap(trans[0], trans[1])
        matrix = CircuitOp(qc).to_matrix()
        return MatrixOp(matrix.transpose()) @ new_self @ MatrixOp(
            matrix)  # type: ignore
Exemple #3
0
    def permute(self, permutation: List[int]) -> "OperatorBase":
        """Permute the qubits of the operator.

        Args:
            permutation: A list defining where each qubit should be permuted. The qubit at index
                j should be permuted to position permutation[j].

        Returns:
            A new ListOp representing the permuted operator.

        Raises:
            OpflowError: if indices do not define a new index for each qubit.
        """
        new_self = self
        circuit_size = max(permutation) + 1

        try:
            if self.num_qubits != len(permutation):
                raise OpflowError(
                    "New index must be defined for each qubit of the operator."
                )
        except ValueError:
            raise OpflowError(
                "Permute is only possible if all operators in the ListOp have the "
                "same number of qubits.") from ValueError
        if self.num_qubits < circuit_size:
            # pad the operator with identities
            new_self = self._expand_dim(circuit_size - self.num_qubits)
        qc = QuantumCircuit(circuit_size)
        # extend the indices to match the size of the circuit
        permutation = (
            list(filter(lambda x: x not in permutation, range(circuit_size))) +
            permutation)

        # decompose permutation into sequence of transpositions
        transpositions = arithmetic.transpositions(permutation)
        for trans in transpositions:
            qc.swap(trans[0], trans[1])

        # pylint: disable=cyclic-import
        from ..primitive_ops.circuit_op import CircuitOp

        return CircuitOp(qc.reverse_ops()) @ new_self @ CircuitOp(qc)