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)
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
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)