out = np.zeros(<NUM_LIT:4>, dtype=float)<EOL>if axis == '<STR_LIT:x>':<EOL><INDENT>out[<NUM_LIT:1>] = <NUM_LIT:1><EOL><DEDENT>elif axis == '<STR_LIT:y>':<EOL><INDENT>out[<NUM_LIT:2>] = <NUM_LIT:1><EOL><DEDENT>elif axis == '<STR_LIT:z>':<EOL><INDENT>out[<NUM_LIT:3>] = <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>out *= math.sin(angle/<NUM_LIT>)<EOL>out[<NUM_LIT:0>] = math.cos(angle/<NUM_LIT>)<EOL>return Quaternion(out)<EOL>

Return quaternion for rotation about given axis.

    Args:
        angle (float): Angle in radians.
        axis (str): Axis for rotation

    Returns:
        Quaternion: Quaternion for axis rotation.

    Raises:
        ValueError: Invalid input axis.


angles = np.asarray(angles, dtype=float)<EOL>quat = quaternion_from_axis_rotation(angles[<NUM_LIT:0>], order[<NUM_LIT:0>])* (quaternion_from_axis_rotation(angles[<NUM_LIT:1>], order[<NUM_LIT:1>])<EOL>* quaternion_from_axis_rotation(angles[<NUM_LIT:2>], order[<NUM_LIT:2>]))<EOL>quat.normalize(inplace=True)<EOL>return quat<EOL>

Generate a quaternion from a set of Euler angles.

    Args:
        angles (array_like): Array of Euler angles.
        order (str): Order of Euler rotations.  'yzy' is default.

    Returns:
        Quaternion: Quaternion representation of Euler rotation.


return la.norm(self.data)<EOL>


if inplace:<EOL><INDENT>nrm = self.norm()<EOL>self.data /= nrm<EOL>return None<EOL><DEDENT>nrm = self.norm()<EOL>data_copy = np.array(self.data, copy=True)<EOL>data_copy /= nrm<EOL>return Quaternion(data_copy)<EOL>

Normalizes a Quaternion to unit length
        so that it represents a valid rotation.

        Args:
            inplace (bool): Do an inplace normalization.

        Returns:
            Quaternion: Normalized quaternion.


w, x, y, z = self.normalize().data  <EOL>mat = np.array([<EOL>[<NUM_LIT:1>-<NUM_LIT:2>*y**<NUM_LIT:2>-<NUM_LIT:2>*z**<NUM_LIT:2>, <NUM_LIT:2>*x*y-<NUM_LIT:2>*z*w, <NUM_LIT:2>*x*z+<NUM_LIT:2>*y*w],<EOL>[<NUM_LIT:2>*x*y+<NUM_LIT:2>*z*w, <NUM_LIT:1>-<NUM_LIT:2>*x**<NUM_LIT:2>-<NUM_LIT:2>*z**<NUM_LIT:2>, <NUM_LIT:2>*y*z-<NUM_LIT:2>*x*w],<EOL>[<NUM_LIT:2>*x*z-<NUM_LIT:2>*y*w, <NUM_LIT:2>*y*z+<NUM_LIT:2>*x*w, <NUM_LIT:1>-<NUM_LIT:2>*x**<NUM_LIT:2>-<NUM_LIT:2>*y**<NUM_LIT:2>]<EOL>], dtype=float)<EOL>return mat<EOL>

Converts a unit-length quaternion to a rotation matrix.

        Returns:
            ndarray: Rotation matrix.


mat = self.to_matrix()<EOL>euler = np.zeros(<NUM_LIT:3>, dtype=float)<EOL>if mat[<NUM_LIT:2>, <NUM_LIT:2>] < <NUM_LIT:1>:<EOL><INDENT>if mat[<NUM_LIT:2>, <NUM_LIT:2>] > -<NUM_LIT:1>:<EOL><INDENT>euler[<NUM_LIT:0>] = math.atan2(mat[<NUM_LIT:1>, <NUM_LIT:2>], mat[<NUM_LIT:0>, <NUM_LIT:2>])<EOL>euler[<NUM_LIT:1>] = math.acos(mat[<NUM_LIT:2>, <NUM_LIT:2>])<EOL>euler[<NUM_LIT:2>] = math.atan2(mat[<NUM_LIT:2>, <NUM_LIT:1>], -mat[<NUM_LIT:2>, <NUM_LIT:0>])<EOL><DEDENT>else:<EOL><INDENT>euler[<NUM_LIT:0>] = -math.atan2(mat[<NUM_LIT:1>, <NUM_LIT:0>], mat[<NUM_LIT:1>, <NUM_LIT:1>])<EOL>euler[<NUM_LIT:1>] = np.pi<EOL><DEDENT><DEDENT>else:<EOL><INDENT>euler[<NUM_LIT:0>] = math.atan2(mat[<NUM_LIT:1>, <NUM_LIT:0>], mat[<NUM_LIT:1>, <NUM_LIT:1>])<EOL><DEDENT>return euler<EOL>

Converts a unit-length quaternion to a sequence
        of ZYZ Euler angles.

        Returns:
            ndarray: Array of Euler angles.


mat = np.array(mat)<EOL>if mat.ndim != <NUM_LIT:2>:<EOL><INDENT>return False<EOL><DEDENT>shape = mat.shape<EOL>return shape[<NUM_LIT:0>] == shape[<NUM_LIT:1>]<EOL>


def is_diagonal_matrix(mat, rtol=RTOL_DEFAULT, atol=ATOL_DEFAULT):

if atol is None:<EOL><INDENT>atol = ATOL_DEFAULT<EOL><DEDENT>if rtol is None:<EOL><INDENT>rtol = RTOL_DEFAULT<EOL><DEDENT>mat = np.array(mat)<EOL>if mat.ndim != <NUM_LIT:2>:<EOL><INDENT>return False<EOL><DEDENT>return np.allclose(mat, np.diag(np.diagonal(mat)), rtol=rtol, atol=atol)<EOL>


def is_symmetric_matrix(op, rtol=RTOL_DEFAULT, atol=ATOL_DEFAULT):

if atol is None:<EOL><INDENT>atol = ATOL_DEFAULT<EOL><DEDENT>if rtol is None:<EOL><INDENT>rtol = RTOL_DEFAULT<EOL><DEDENT>mat = np.array(op)<EOL>if mat.ndim != <NUM_LIT:2>:<EOL><INDENT>return False<EOL><DEDENT>return np.allclose(mat, mat.T, rtol=rtol, atol=atol)<EOL>


def is_hermitian_matrix(mat, rtol=RTOL_DEFAULT, atol=ATOL_DEFAULT):

if atol is None:<EOL><INDENT>atol = ATOL_DEFAULT<EOL><DEDENT>if rtol is None:<EOL><INDENT>rtol = RTOL_DEFAULT<EOL><DEDENT>mat = np.array(mat)<EOL>if mat.ndim != <NUM_LIT:2>:<EOL><INDENT>return False<EOL><DEDENT>return np.allclose(mat, np.conj(mat.T), rtol=rtol, atol=atol)<EOL>


def is_positive_semidefinite_matrix(mat, rtol=RTOL_DEFAULT, atol=ATOL_DEFAULT):

if atol is None:<EOL><INDENT>atol = ATOL_DEFAULT<EOL><DEDENT>if rtol is None:<EOL><INDENT>rtol = RTOL_DEFAULT<EOL><DEDENT>if not is_hermitian_matrix(mat, rtol=rtol, atol=atol):<EOL><INDENT>return False<EOL><DEDENT>vals = np.linalg.eigvalsh(mat)<EOL>for v in vals:<EOL><INDENT>if v < -atol:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>return True<EOL>

Test if a matrix is positive semidefinite


if atol is None:<EOL><INDENT>atol = ATOL_DEFAULT<EOL><DEDENT>if rtol is None:<EOL><INDENT>rtol = RTOL_DEFAULT<EOL><DEDENT>mat = np.array(mat)<EOL>if mat.ndim != <NUM_LIT:2>:<EOL><INDENT>return False<EOL><DEDENT>if ignore_phase:<EOL><INDENT>theta = np.angle(mat[<NUM_LIT:0>, <NUM_LIT:0>])<EOL>mat = np.exp(-<NUM_LIT> * theta) * mat<EOL><DEDENT>iden = np.eye(len(mat))<EOL>return np.allclose(mat, iden, rtol=rtol, atol=atol)<EOL>


def is_unitary_matrix(mat, rtol=RTOL_DEFAULT, atol=ATOL_DEFAULT):

if atol is None:<EOL><INDENT>atol = ATOL_DEFAULT<EOL><DEDENT>if rtol is None:<EOL><INDENT>rtol = RTOL_DEFAULT<EOL><DEDENT>mat = np.array(mat)<EOL>mat = np.conj(mat.T).dot(mat)<EOL>return is_identity_matrix(mat, ignore_phase=False, rtol=rtol, atol=atol)<EOL>


def __init__(self, rep, data, input_dims, output_dims):

if not isinstance(rep, str):<EOL><INDENT>raise QiskitError("<STR_LIT>".format(<EOL>rep.__class__))<EOL><DEDENT>self._rep = rep<EOL>self._data = data<EOL>self._input_dims = tuple(input_dims)<EOL>self._output_dims = tuple(output_dims)<EOL>self._input_dim = np.product(input_dims)<EOL>self._output_dim = np.product(output_dims)<EOL>


return self._rep<EOL>


return self._input_dim, self._output_dim<EOL>

Return tuple (input_shape, output_shape).


return self._data<EOL>


return self.__class__.ATOL<EOL>

The absolute tolerence parameter for float comparisons.


<EOL>max_tol = self.__class__.MAX_TOL<EOL>if atol < <NUM_LIT:0>:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>if atol > max_tol:<EOL><INDENT>raise QiskitError(<EOL>"<STR_LIT>".format(max_tol))<EOL><DEDENT>self.__class__.ATOL = atol<EOL>

Set the absolute tolerence parameter for float comparisons.


return self.__class__.RTOL<EOL>

The relative tolerence parameter for float comparisons.


<EOL>max_tol = self.__class__.MAX_TOL<EOL>if rtol < <NUM_LIT:0>:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>if rtol > max_tol:<EOL><INDENT>raise QiskitError(<EOL>"<STR_LIT>".format(max_tol))<EOL><DEDENT>self.__class__.RTOL = rtol<EOL>

Set the relative tolerence parameter for float comparisons.


def _reshape(self, input_dims=None, output_dims=None):

if input_dims is not None:<EOL><INDENT>if np.product(input_dims) != self._input_dim:<EOL><INDENT>raise QiskitError(<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>self._input_dims = tuple(input_dims)<EOL><DEDENT>if output_dims is not None:<EOL><INDENT>if np.product(output_dims) != self._output_dim:<EOL><INDENT>raise QiskitError(<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>self._output_dims = tuple(output_dims)<EOL><DEDENT>return self<EOL>

Reshape input and output dimensions of operator.

        Arg:
            input_dims (tuple): new subsystem input dimensions.
            output_dims (tuple): new subsystem output dimensions.

        Returns:
            Operator: returns self with reshaped input and output dimensions.

        Raises:
            QiskitError: if combined size of all subsystem input dimension or
            subsystem output dimensions is not constant.


if qargs is None:<EOL><INDENT>return self._input_dims<EOL><DEDENT>return tuple(self._input_dims[i] for i in qargs)<EOL>

Return tuple of input dimension for specified subsystems.


if qargs is None:<EOL><INDENT>return self._output_dims<EOL><DEDENT>return tuple(self._output_dims[i] for i in qargs)<EOL>

Return tuple of output dimension for specified subsystems.


<EOL>return self.__class__(self.data, self.input_dims(), self.output_dims())<EOL>


return self.conjugate().transpose()<EOL>


@abstractmethod<EOL><INDENT>def is_unitary(self, atol=None, rtol=None):<DEDENT>

pass<EOL>

Return True if operator is a unitary matrix.


pass<EOL>

Convert operator to matrix operator class


pass<EOL>


@abstractmethod<EOL><INDENT>def compose(self, other, qargs=None, front=False):<DEDENT>

pass<EOL>

Return the composition channel self∘other.

        Args:
            other (BaseOperator): an operator object.
            qargs (list): a list of subsystem positions to compose other on.
            front (bool): If False compose in standard order other(self(input))
                          otherwise compose in reverse order self(other(input))
                          [default: False]

        Returns:
            BaseOperator: The composed operator.

        Raises:
            QiskitError: if other cannot be converted to an operator, or has
            incompatible dimensions for specified subsystems.


<EOL>if not isinstance(n, (int, np.integer)) or n < <NUM_LIT:1>:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>if self._input_dim != self._output_dim:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>ret = self.copy()<EOL>for _ in range(<NUM_LIT:1>, n):<EOL><INDENT>ret = ret.compose(self)<EOL><DEDENT>return ret<EOL>

Return the compose of a operator with itself n times.

        Args:
            n (int): the number of times to compose with self (n>0).

        Returns:
            BaseOperator: the n-times composed operator.

        Raises:
            QiskitError: if the input and output dimensions of the operator
            are not equal, or the power is not a positive integer.


pass<EOL>

Return the tensor product operator self ⊗ other.

        Args:
            other (BaseOperator): a operator subclass object.

        Returns:
            BaseOperator: the tensor product operator self ⊗ other.

        Raises:
            QiskitError: if other is not an operator.


pass<EOL>

Return the tensor product operator other ⊗ self.

        Args:
            other (BaseOperator): an operator object.

        Returns:
            BaseOperator: the tensor product operator other ⊗ self.

        Raises:
            QiskitError: if other is not an operator.


pass<EOL>

Return the linear operator self + other.

        Args:
            other (BaseOperator): an operator object.

        Returns:
            LinearOperator: the linear operator self + other.

        Raises:
            QiskitError: if other is not an operator, or has incompatible
            dimensions.


pass<EOL>

Return the linear operator self - other.

        Args:
            other (BaseOperator): an operator object.

        Returns:
            LinearOperator: the linear operator self - other.

        Raises:
            QiskitError: if other is not an operator, or has incompatible
            dimensions.


pass<EOL>

Return the linear operator self + other.

        Args:
            other (complex): a complex number.

        Returns:
            Operator: the linear operator other * self.

        Raises:
            QiskitError: if other is not a valid complex number.


@abstractmethod<EOL><INDENT>def _evolve(self, state, qargs=None):<DEDENT>

pass<EOL>

Evolve a quantum state by the operator.

        Args:
            state (QuantumState): The input statevector or density matrix.
            qargs (list): a list of QuantumState subsystem positions to apply
                           the operator on.

        Returns:
            QuantumState: the output quantum state.

        Raises:
            QiskitError: if the operator dimension does not match the
            specified QuantumState subsystem dimensions.


@classmethod<EOL><INDENT>def _automatic_dims(cls, dims, size):<DEDENT>

if dims is None:<EOL><INDENT>dims = size<EOL><DEDENT>elif np.product(dims) != size:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>if isinstance(dims, (int, np.integer)):<EOL><INDENT>num_qubits = int(np.log2(dims))<EOL>if <NUM_LIT:2> ** num_qubits == size:<EOL><INDENT>return num_qubits * (<NUM_LIT:2>,)<EOL><DEDENT>return (dims,)<EOL><DEDENT>return tuple(dims)<EOL>

Check if input dimension corresponds to qubit subsystems.


@classmethod<EOL><INDENT>def _einsum_matmul(cls, tensor, mat, indices, shift=<NUM_LIT:0>, right_mul=False):<DEDENT>

rank = tensor.ndim<EOL>rank_mat = mat.ndim<EOL>if rank_mat % <NUM_LIT:2> != <NUM_LIT:0>:<EOL><INDENT>raise QiskitError(<EOL>"<STR_LIT>")<EOL><DEDENT>indices_tensor = list(range(rank))<EOL>for j, index in enumerate(indices):<EOL><INDENT>indices_tensor[index + shift] = rank + j<EOL><DEDENT>mat_contract = list(reversed(range(rank, rank + len(indices))))<EOL>mat_free = [index + shift for index in reversed(indices)]<EOL>if right_mul:<EOL><INDENT>indices_mat = mat_contract + mat_free<EOL><DEDENT>else:<EOL><INDENT>indices_mat = mat_free + mat_contract<EOL><DEDENT>return np.einsum(tensor, indices_tensor, mat, indices_mat)<EOL>

Perform a contraction using Numpy.einsum

        Args:
            tensor (np.array): a vector or matrix reshaped to a rank-N tensor.
            mat (np.array): a matrix reshaped to a rank-2M tensor.
            indices (list): tensor indices to contract with mat.
            shift (int): shift for indicies of tensor to contract [Default: 0].
            right_mul (bool): if True right multiply tensor by mat
                              (else left multiply) [Default: False].

        Returns:
            Numpy.ndarray: the matrix multiplied rank-N tensor.

        Raises:
            QiskitError: if mat is not an even rank tensor.


if number_of_qubits < <NUM_LIT:5>:<EOL><INDENT>temp_set = []<EOL>if case == '<STR_LIT>':<EOL><INDENT>tmp = pauli_group(number_of_qubits, case='<STR_LIT>')<EOL>return sorted(tmp, key=lambda x: -np.count_nonzero(<EOL>np.array(x.to_label(), '<STR_LIT:c>') == b'<STR_LIT:I>'))<EOL><DEDENT>elif case == '<STR_LIT>':<EOL><INDENT>for k in range(<NUM_LIT:4> ** number_of_qubits):<EOL><INDENT>z = np.zeros(number_of_qubits, dtype=np.bool)<EOL>x = np.zeros(number_of_qubits, dtype=np.bool)<EOL>for j in range(number_of_qubits):<EOL><INDENT>element = (k // (<NUM_LIT:4> ** j)) % <NUM_LIT:4><EOL>if element == <NUM_LIT:1>:<EOL><INDENT>x[j] = True<EOL><DEDENT>elif element == <NUM_LIT:2>:<EOL><INDENT>z[j] = True<EOL>x[j] = True<EOL><DEDENT>elif element == <NUM_LIT:3>:<EOL><INDENT>z[j] = True<EOL><DEDENT><DEDENT>temp_set.append(Pauli(z, x))<EOL><DEDENT>return temp_set<EOL><DEDENT>else:<EOL><INDENT>raise QiskitError("<STR_LIT>"<EOL>"<STR_LIT>".format(case))<EOL><DEDENT><DEDENT>raise QiskitError("<STR_LIT>")<EOL>

Return the Pauli group with 4^n elements.

    The phases have been removed.
    case 'weight' is ordered by Pauli weights and
    case 'tensor' is ordered by I,X,Y,Z counting lowest qubit fastest.

    Args:
        number_of_qubits (int): number of qubits
        case (str): determines ordering of group elements ('weight' or 'tensor')

    Returns:
        list: list of Pauli objects

    Raises:
        QiskitError: case is not 'weight' or 'tensor'
        QiskitError: number_of_qubits is larger than 4


def __init__(self, z=None, x=None, label=None):

if label is not None:<EOL><INDENT>a = Pauli.from_label(label)<EOL>self._z = a.z<EOL>self._x = a.x<EOL><DEDENT>else:<EOL><INDENT>self._init_from_bool(z, x)<EOL><DEDENT>

r"""Make the Pauli object.

        Note that, for the qubit index:
            - Order of z, x vectors is q_0 ... q_{n-1},
            - Order of pauli label is q_{n-1} ... q_0

        E.g.,
            - z and x vectors: z = [z_0 ... z_{n-1}], x = [x_0 ... x_{n-1}]
            - a pauli is $P_{n-1} \otimes ... \otimes P_0$

        Args:
            z (numpy.ndarray): boolean, z vector
            x (numpy.ndarray): boolean, x vector
            label (str): pauli label


z = np.zeros(len(label), dtype=np.bool)<EOL>x = np.zeros(len(label), dtype=np.bool)<EOL>for i, char in enumerate(label):<EOL><INDENT>if char == '<STR_LIT:X>':<EOL><INDENT>x[-i - <NUM_LIT:1>] = True<EOL><DEDENT>elif char == '<STR_LIT>':<EOL><INDENT>z[-i - <NUM_LIT:1>] = True<EOL><DEDENT>elif char == '<STR_LIT:Y>':<EOL><INDENT>z[-i - <NUM_LIT:1>] = True<EOL>x[-i - <NUM_LIT:1>] = True<EOL><DEDENT>elif char != '<STR_LIT:I>':<EOL><INDENT>raise QiskitError("<STR_LIT>"<EOL>"<STR_LIT>".format(char))<EOL><DEDENT><DEDENT>return cls(z=z, x=x)<EOL>

r"""Take pauli string to construct pauli.

        The qubit index of pauli label is q_{n-1} ... q_0.
        E.g., a pauli is $P_{n-1} \otimes ... \otimes P_0$

        Args:
            label (str): pauli label

        Returns:
            Pauli: the constructed pauli

        Raises:
            QiskitError: invalid character in the label


if z is None:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>if x is None:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>if len(z) != len(x):<EOL><INDENT>raise QiskitError("<STR_LIT>"<EOL>"<STR_LIT>".format(len(z), len(x)))<EOL><DEDENT>z = _make_np_bool(z)<EOL>x = _make_np_bool(x)<EOL>self._z = z<EOL>self._x = x<EOL>return self<EOL>

Construct pauli from boolean array.

        Args:
            z (numpy.ndarray): boolean, z vector
            x (numpy.ndarray): boolean, x vector

        Returns:
            Pauli: self

        Raises:
            QiskitError: if z or x are None or the length of z and x are different.


return len(self._z)<EOL>


z = [p for p in self._z]<EOL>x = [p for p in self._x]<EOL>ret = self.__class__.__name__ + "<STR_LIT>".format(z, x)<EOL>return ret<EOL>


label = '<STR_LIT>'<EOL>for z, x in zip(self._z[::-<NUM_LIT:1>], self._x[::-<NUM_LIT:1>]):<EOL><INDENT>if not z and not x:<EOL><INDENT>label = '<STR_LIT>'.join([label, '<STR_LIT:I>'])<EOL><DEDENT>elif not z and x:<EOL><INDENT>label = '<STR_LIT>'.join([label, '<STR_LIT:X>'])<EOL><DEDENT>elif z and not x:<EOL><INDENT>label = '<STR_LIT>'.join([label, '<STR_LIT>'])<EOL><DEDENT>else:<EOL><INDENT>label = '<STR_LIT>'.join([label, '<STR_LIT:Y>'])<EOL><DEDENT><DEDENT>return label<EOL>


res = False<EOL>if len(self) == len(other):<EOL><INDENT>if np.all(self._z == other.z) and np.all(self._x == other.x):<EOL><INDENT>res = True<EOL><DEDENT><DEDENT>return res<EOL>

Return True if all Pauli terms are equal.

        Args:
            other (Pauli): other pauli

        Returns:
            bool: are self and other equal.


if len(self) != len(other):<EOL><INDENT>raise QiskitError("<STR_LIT>"<EOL>"<STR_LIT>".format(len(self), len(other)))<EOL><DEDENT>z_new = np.logical_xor(self._z, other.z)<EOL>x_new = np.logical_xor(self._x, other.x)<EOL>return Pauli(z_new, x_new)<EOL>

Multiply two Paulis.

        Returns:
            Pauli: the multiplied pauli.

        Raises:
            QiskitError: if the number of qubits of two paulis are different.


if len(self) != len(other):<EOL><INDENT>raise QiskitError("<STR_LIT>"<EOL>"<STR_LIT>".format(len(self), len(other)))<EOL><DEDENT>self._z = np.logical_xor(self._z, other.z)<EOL>self._x = np.logical_xor(self._x, other.x)<EOL>return self<EOL>

Multiply two Paulis.

        Returns:
            Pauli: the multiplied pauli and save to itself, in-place computation.

        Raises:
            QiskitError: if the number of qubits of two paulis are different.


return hash(str(self))<EOL>

Make object is hashable, based on the pauli label to hash.


return self._z<EOL>


return self._x<EOL>


phase = Pauli._prod_phase(p1, p2)<EOL>new_pauli = p1 * p2<EOL>return new_pauli, phase<EOL>

r"""
        Multiply two Paulis and track the phase.

        $P_3 = P_1 \otimes P_2$: X*Y

        Args:
            p1 (Pauli): pauli 1
            p2 (Pauli): pauli 2

        Returns:
            Pauli: the multiplied pauli
            complex: the sign of the multiplication, 1, -1, 1j or -1j


return len(self)<EOL>


return str(self)<EOL>

Present the pauli labels in I, X, Y, Z format.

        Order is $q_{n-1} .... q_0$

        Returns:
            str: pauli label


mat = self.to_spmatrix()<EOL>return mat.toarray()<EOL>

r"""
        Convert Pauli to a matrix representation.

        Order is q_{n-1} .... q_0, i.e., $P_{n-1} \otimes ... P_0$

        Returns:
            numpy.array: a matrix that represents the pauli.


mat = sparse.coo_matrix(<NUM_LIT:1>)<EOL>for z, x in zip(self._z, self._x):<EOL><INDENT>if not z and not x:  <EOL><INDENT>mat = sparse.bmat([[mat, None], [None, mat]], format='<STR_LIT>')<EOL><DEDENT>elif z and not x:  <EOL><INDENT>mat = sparse.bmat([[mat, None], [None, -mat]], format='<STR_LIT>')<EOL><DEDENT>elif not z and x:  <EOL><INDENT>mat = sparse.bmat([[None, mat], [mat, None]], format='<STR_LIT>')<EOL><DEDENT>else:  <EOL><INDENT>mat = mat * <NUM_LIT><EOL>mat = sparse.bmat([[None, -mat], [mat, None]], format='<STR_LIT>')<EOL><DEDENT><DEDENT>return mat.tocsr()<EOL>

r"""
        Convert Pauli to a sparse matrix representation (CSR format).

        Order is q_{n-1} .... q_0, i.e., $P_{n-1} \otimes ... P_0$

        Returns:
            scipy.sparse.csr_matrix: a sparse matrix with CSR format that
            represnets the pauli.


<EOL>from qiskit.quantum_info.operators.operator import Operator<EOL>return Operator(self.to_matrix())<EOL>


from qiskit.circuit import QuantumCircuit, QuantumRegister<EOL>from qiskit.extensions.standard import IdGate, XGate, YGate, ZGate<EOL>gates = {'<STR_LIT:I>': IdGate(), '<STR_LIT:X>': XGate(), '<STR_LIT:Y>': YGate(), '<STR_LIT>': ZGate()}<EOL>label = self.to_label()<EOL>n_qubits = self.numberofqubits<EOL>qreg = QuantumRegister(n_qubits)<EOL>circuit = QuantumCircuit(qreg, name='<STR_LIT>'.format(label))<EOL>for i, pauli in enumerate(reversed(label)):<EOL><INDENT>circuit.append(gates[pauli], [qreg[i]])<EOL><DEDENT>return circuit.to_instruction()<EOL>


z = _make_np_bool(z)<EOL>if indices is None:<EOL><INDENT>if len(self._z) != len(z):<EOL><INDENT>raise QiskitError("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>self._z = z<EOL><DEDENT>else:<EOL><INDENT>if not isinstance(indices, list) and not isinstance(indices, np.ndarray):<EOL><INDENT>indices = [indices]<EOL><DEDENT>for p, idx in enumerate(indices):<EOL><INDENT>self._z[idx] = z[p]<EOL><DEDENT><DEDENT>return self<EOL>

Update partial or entire z.

Args:
    z (numpy.ndarray or list): to-be-updated z
    indices (numpy.ndarray or list or optional): to-be-updated qubit indices

Returns:
    Pauli: self

Raises:
    QiskitError: when updating whole z, the number of qubits must be the same.


x = _make_np_bool(x)<EOL>if indices is None:<EOL><INDENT>if len(self._x) != len(x):<EOL><INDENT>raise QiskitError("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>self._x = x<EOL><DEDENT>else:<EOL><INDENT>if not isinstance(indices, list) and not isinstance(indices, np.ndarray):<EOL><INDENT>indices = [indices]<EOL><DEDENT>for p, idx in enumerate(indices):<EOL><INDENT>self._x[idx] = x[p]<EOL><DEDENT><DEDENT>return self<EOL>

Update partial or entire x.

Args:
    x (numpy.ndarray or list): to-be-updated x
    indices (numpy.ndarray or list or optional): to-be-updated qubit indices

Returns:
    Pauli: self

Raises:
    QiskitError: when updating whole x, the number of qubits must be the same.


def insert_paulis(self, indices=None, paulis=None, pauli_labels=None):

if pauli_labels is not None:<EOL><INDENT>if paulis is not None:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>if isinstance(pauli_labels, str):<EOL><INDENT>pauli_labels = list(pauli_labels)<EOL><DEDENT>paulis = Pauli.from_label(pauli_labels[::-<NUM_LIT:1>])<EOL><DEDENT>if indices is None:  <EOL><INDENT>self._z = np.concatenate((self._z, paulis.z))<EOL>self._x = np.concatenate((self._x, paulis.x))<EOL><DEDENT>else:<EOL><INDENT>if not isinstance(indices, list):<EOL><INDENT>indices = [indices]<EOL><DEDENT>self._z = np.insert(self._z, indices, paulis.z)<EOL>self._x = np.insert(self._x, indices, paulis.x)<EOL><DEDENT>return self<EOL>

Insert or append pauli to the targeted indices.

If indices is None, it means append at the end.

Args:
    indices (list[int]): the qubit indices to be inserted
    paulis (Pauli): the to-be-inserted or appended pauli
    pauli_labels (list[str]): the to-be-inserted or appended pauli label

Note:
    the indices refers to the localion of original paulis,
    e.g. if indices = [0, 2], pauli_labels = ['Z', 'I'] and original pauli = 'ZYXI'
    the pauli will be updated to ZY'I'XI'Z'
    'Z' and 'I' are inserted before the qubit at 0 and 2.

Returns:
    Pauli: self

Raises:
    QiskitError: provide both `paulis` and `pauli_labels` at the same time


def append_paulis(self, paulis=None, pauli_labels=None):

return self.insert_paulis(None, paulis=paulis, pauli_labels=pauli_labels)<EOL>

Append pauli at the end.

Args:
    paulis (Pauli): the to-be-inserted or appended pauli
    pauli_labels (list[str]): the to-be-inserted or appended pauli label

Returns:
    Pauli: self


if not isinstance(indices, list):<EOL><INDENT>indices = [indices]<EOL><DEDENT>self._z = np.delete(self._z, indices)<EOL>self._x = np.delete(self._x, indices)<EOL>return self<EOL>

Delete pauli at the indices.

Args:
    indices(list[int]): the indices of to-be-deleted paulis

Returns:
    Pauli: self


@classmethod<EOL><INDENT>def random(cls, num_qubits, seed=None):<DEDENT>

if seed is not None:<EOL><INDENT>np.random.seed(seed)<EOL><DEDENT>z = np.random.randint(<NUM_LIT:2>, size=num_qubits).astype(np.bool)<EOL>x = np.random.randint(<NUM_LIT:2>, size=num_qubits).astype(np.bool)<EOL>return cls(z, x)<EOL>

Return a random Pauli on number of qubits.

        Args:
            num_qubits (int): the number of qubits
            seed (int): Optional. To set a random seed.
        Returns:
            Pauli: the random pauli


@classmethod<EOL><INDENT>def pauli_single(cls, num_qubits, index, pauli_label):<DEDENT>

tmp = Pauli.from_label(pauli_label)<EOL>z = np.zeros(num_qubits, dtype=np.bool)<EOL>x = np.zeros(num_qubits, dtype=np.bool)<EOL>z[index] = tmp.z[<NUM_LIT:0>]<EOL>x[index] = tmp.x[<NUM_LIT:0>]<EOL>return cls(z, x)<EOL>

Generate single qubit pauli at index with pauli_label with length num_qubits.

Args:
    num_qubits (int): the length of pauli
    index (int): the qubit index to insert the single qubii
    pauli_label (str): pauli

Returns:
    Pauli: single qubit pauli


self.insert_paulis(indices=None, paulis=other)<EOL>return self<EOL>

r"""Kron product of two paulis.

        Order is $P_2 (other) \otimes P_1 (self)$

        Args:
            other (Pauli): P2

        Returns:
            Pauli: self


def __init__(self, data, input_dims=None, output_dims=None):

if isinstance(data, (QuantumCircuit, Instruction)):<EOL><INDENT>mat = self._instruction_to_operator(data).data<EOL><DEDENT>elif hasattr(data, '<STR_LIT>'):<EOL><INDENT>data = data.to_operator()<EOL>mat = data.data<EOL>if input_dims is None:<EOL><INDENT>input_dims = data.input_dims()<EOL><DEDENT>if output_dims is None:<EOL><INDENT>output_dims = data.output_dims()<EOL><DEDENT><DEDENT>elif hasattr(data, '<STR_LIT>'):<EOL><INDENT>mat = np.array(data.to_matrix(), dtype=complex)<EOL><DEDENT>elif isinstance(data, (list, np.ndarray)):<EOL><INDENT>mat = np.array(data, dtype=complex)<EOL><DEDENT>else:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>dout, din = mat.shape<EOL>output_dims = self._automatic_dims(output_dims, dout)<EOL>input_dims = self._automatic_dims(input_dims, din)<EOL>super().__init__('<STR_LIT>', mat, input_dims, output_dims)<EOL>

Initialize an operator object.

        Args:
            data (QuantumCircuit or
                  Instruction or
                  BaseOperator or
                  matrix): data to initialize operator.
            input_dims (tuple): the input subsystem dimensions.
                                [Default: None]
            output_dims (tuple): the output subsystem dimensions.
                                 [Default: None]

        Raises:
            QiskitError: if input data cannot be initialized as an operator.

        Additional Information
        ----------------------
        If the input or output dimensions are None, they will be
        automatically determined from the input data. If the input data is
        a Numpy array of shape (2**N, 2**N) qubit systems will be used. If
        the input operator is not an N-qubit operator, it will assign a
        single subsystem with dimension specifed by the shape of the input.


def is_unitary(self, atol=None, rtol=None):

if atol is None:<EOL><INDENT>atol = self._atol<EOL><DEDENT>if rtol is None:<EOL><INDENT>rtol = self._rtol<EOL><DEDENT>return is_unitary_matrix(self._data, rtol=rtol, atol=atol)<EOL>

Return True if operator is a unitary matrix.


return self<EOL>

Convert operator to matrix operator class


from qiskit.extensions.unitary import UnitaryGate<EOL>return UnitaryGate(self.data)<EOL>


return Operator(<EOL>np.conj(self.data), self.input_dims(), self.output_dims())<EOL>


return Operator(<EOL>np.transpose(self.data), self.input_dims(), self.output_dims())<EOL>


def compose(self, other, qargs=None, front=False):

<EOL>if not isinstance(other, Operator):<EOL><INDENT>other = Operator(other)<EOL><DEDENT>if front and self.input_dims(qargs=qargs) != other.output_dims():<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>')<EOL><DEDENT>if not front and self.output_dims(qargs=qargs) != other.input_dims():<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>')<EOL><DEDENT>if qargs is None:<EOL><INDENT>if front:<EOL><INDENT>input_dims = other.input_dims()<EOL>output_dims = self.output_dims()<EOL>data = np.dot(self._data, other.data)<EOL><DEDENT>else:<EOL><INDENT>input_dims = self.input_dims()<EOL>output_dims = other.output_dims()<EOL>data = np.dot(other.data, self._data)<EOL><DEDENT>return Operator(data, input_dims, output_dims)<EOL><DEDENT>return self._compose_subsystem(other, qargs, front)<EOL>

Return the composition channel self∘other.

        Args:
            other (Operator): an operator object.
            qargs (list): a list of subsystem positions to compose other on.
            front (bool): If False compose in standard order other(self(input))
                          otherwise compose in reverse order self(other(input))
                          [default: False]

        Returns:
            Operator: The composed operator.

        Raises:
            QiskitError: if other cannot be converted to an Operator or has
            incompatible dimensions.


if not isinstance(n, int):<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>if self.input_dims() != self.output_dims():<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return Operator(<EOL>np.linalg.matrix_power(self.data, n), self.input_dims(),<EOL>self.output_dims())<EOL>

Return the matrix power of the operator.

        Args:
            n (int): the power to raise the matrix to.

        Returns:
            BaseOperator: the n-times composed operator.

        Raises:
            QiskitError: if the input and output dimensions of the operator
            are not equal, or the power is not a positive integer.


return self._tensor_product(other, reverse=False)<EOL>

Return the tensor product operator self ⊗ other.

        Args:
            other (Operator): a operator subclass object.

        Returns:
            Operator: the tensor product operator self ⊗ other.

        Raises:
            QiskitError: if other cannot be converted to an operator.


return self._tensor_product(other, reverse=True)<EOL>

Return the tensor product operator other ⊗ self.

        Args:
            other (Operator): an operator object.

        Returns:
            Operator: the tensor product operator other ⊗ self.

        Raises:
            QiskitError: if other cannot be converted to an operator.


if not isinstance(other, Operator):<EOL><INDENT>other = Operator(other)<EOL><DEDENT>if self.dim != other.dim:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return Operator(self.data + other.data, self.input_dims(),<EOL>self.output_dims())<EOL>

Return the operator self + other.

        Args:
            other (Operator): an operator object.

        Returns:
            Operator: the operator self + other.

        Raises:
            QiskitError: if other is not an operator, or has incompatible
            dimensions.


if not isinstance(other, Operator):<EOL><INDENT>other = Operator(other)<EOL><DEDENT>if self.dim != other.dim:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return Operator(self.data - other.data, self.input_dims(),<EOL>self.output_dims())<EOL>

Return the operator self - other.

        Args:
            other (Operator): an operator object.

        Returns:
            Operator: the operator self - other.

        Raises:
            QiskitError: if other is not an operator, or has incompatible
            dimensions.


if not isinstance(other, Number):<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return Operator(other * self.data, self.input_dims(),<EOL>self.output_dims())<EOL>

Return the operator self + other.

        Args:
            other (complex): a complex number.

        Returns:
            Operator: the operator other * self.

        Raises:
            QiskitError: if other is not a valid complex number.


return tuple(reversed(self.output_dims())) + tuple(<EOL>reversed(self.input_dims()))<EOL>

Return the tensor shape of the matrix operator


state = self._format_state(state)<EOL>if qargs is None:<EOL><INDENT>if state.shape[<NUM_LIT:0>] != self._input_dim:<EOL><INDENT>raise QiskitError(<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>if state.ndim == <NUM_LIT:1>:<EOL><INDENT>return np.dot(self.data, state)<EOL><DEDENT>return np.dot(<EOL>np.dot(self.data, state), np.transpose(np.conj(self.data)))<EOL><DEDENT>return self._evolve_subsystem(state, qargs)<EOL>

Evolve a quantum state by the operator.

        Args:
            state (QuantumState): The input statevector or density matrix.
            qargs (list): a list of QuantumState subsystem positions to apply
                           the operator on.

        Returns:
            QuantumState: the output quantum state.

        Raises:
            QiskitError: if the operator dimension does not match the
            specified QuantumState subsystem dimensions.


def _tensor_product(self, other, reverse=False):

<EOL>if not isinstance(other, Operator):<EOL><INDENT>other = Operator(other)<EOL><DEDENT>if reverse:<EOL><INDENT>input_dims = self.input_dims() + other.input_dims()<EOL>output_dims = self.output_dims() + other.output_dims()<EOL>data = np.kron(other._data, self._data)<EOL><DEDENT>else:<EOL><INDENT>input_dims = other.input_dims() + self.input_dims()<EOL>output_dims = other.output_dims() + self.output_dims()<EOL>data = np.kron(self._data, other._data)<EOL><DEDENT>return Operator(data, input_dims, output_dims)<EOL>

Return the tensor product operator.

        Args:
            other (Operator): another operator.
            reverse (bool): If False return self ⊗ other, if True return
                            if True return (other ⊗ self) [Default: False
        Returns:
            Operator: the tensor product operator.

        Raises:
            QiskitError: if other cannot be converted into an Operator.


def _compose_subsystem(self, other, qargs, front=False):

<EOL>input_dims = list(self.input_dims())<EOL>output_dims = list(self.output_dims())<EOL>if front:<EOL><INDENT>num_indices = len(self.input_dims())<EOL>shift = len(self.output_dims())<EOL>right_mul = True<EOL>for pos, qubit in enumerate(qargs):<EOL><INDENT>input_dims[qubit] = other._input_dims[pos]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>num_indices = len(self.output_dims())<EOL>shift = <NUM_LIT:0><EOL>right_mul = False<EOL>for pos, qubit in enumerate(qargs):<EOL><INDENT>output_dims[qubit] = other._output_dims[pos]<EOL><DEDENT><DEDENT>tensor = np.reshape(self.data, self._shape)<EOL>mat = np.reshape(other.data, other._shape)<EOL>indices = [num_indices - <NUM_LIT:1> - qubit for qubit in qargs]<EOL>final_shape = [np.product(output_dims), np.product(input_dims)]<EOL>data = np.reshape(<EOL>self._einsum_matmul(tensor, mat, indices, shift, right_mul),<EOL>final_shape)<EOL>return Operator(data, input_dims, output_dims)<EOL>


def _evolve_subsystem(self, state, qargs):

mat = np.reshape(self.data, self._shape)<EOL>state_size = len(state)<EOL>state_dims = self._automatic_dims(None, state_size)<EOL>if self.input_dims() != len(qargs) * (<NUM_LIT:2>,):<EOL><INDENT>raise QiskitError(<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>if state.ndim == <NUM_LIT:1>:<EOL><INDENT>tensor = np.reshape(state, state_dims)<EOL>indices = [len(state_dims) - <NUM_LIT:1> - qubit for qubit in qargs]<EOL>tensor = self._einsum_matmul(tensor, mat, indices)<EOL>return np.reshape(tensor, state_size)<EOL><DEDENT>tensor = np.reshape(state, <NUM_LIT:2> * state_dims)<EOL>indices = [len(state_dims) - <NUM_LIT:1> - qubit for qubit in qargs]<EOL>right_shift = len(state_dims)<EOL>tensor = self._einsum_matmul(tensor, mat, indices)<EOL>tensor = self._einsum_matmul(<EOL>tensor, np.conj(mat), indices, shift=right_shift)<EOL>return np.reshape(tensor, [state_size, state_size])<EOL>


state = np.array(state)<EOL>shape = state.shape<EOL>ndim = state.ndim<EOL>if ndim > <NUM_LIT:2>:<EOL><INDENT>raise QiskitError('<STR_LIT>')<EOL><DEDENT>if ndim == <NUM_LIT:2>:<EOL><INDENT>if shape[<NUM_LIT:1>] != <NUM_LIT:1> and shape[<NUM_LIT:1>] != shape[<NUM_LIT:0>]:<EOL><INDENT>raise QiskitError('<STR_LIT>')<EOL><DEDENT>if shape[<NUM_LIT:1>] == <NUM_LIT:1>:<EOL><INDENT>state = np.reshape(state, shape[<NUM_LIT:0>])<EOL><DEDENT><DEDENT>return state<EOL>

Format input state so it is statevector or density matrix


<EOL>if isinstance(instruction, QuantumCircuit):<EOL><INDENT>instruction = instruction.to_instruction()<EOL><DEDENT>op = Operator(np.eye(<NUM_LIT:2> ** instruction.num_qubits))<EOL>op._append_instruction(instruction)<EOL>return op<EOL>

Convert a QuantumCircuit or Instruction to an Operator.


def _append_instruction(self, obj, qargs=None):

if isinstance(obj, Instruction):<EOL><INDENT>mat = None<EOL>if hasattr(obj, '<STR_LIT>'):<EOL><INDENT>try:<EOL><INDENT>mat = obj.to_matrix()<EOL><DEDENT>except QiskitError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>if mat is not None:<EOL><INDENT>op = self.compose(mat, qargs=qargs)<EOL>self._data = op.data<EOL><DEDENT>else:<EOL><INDENT>if obj.definition is None:<EOL><INDENT>raise QiskitError('<STR_LIT>'.format(obj.name))<EOL><DEDENT>for instr, qregs, cregs in obj.definition:<EOL><INDENT>if cregs:<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>'.format(<EOL>instr.name))<EOL><DEDENT>new_qargs = [tup[<NUM_LIT:1>] for tup in qregs]<EOL>self._append_instruction(instr, qargs=new_qargs)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>raise QiskitError('<STR_LIT>')<EOL><DEDENT>

Update the current Operator by apply an instruction.


<EOL>if isinstance(data, (list, np.ndarray)):<EOL><INDENT>chi_mat = np.array(data, dtype=complex)<EOL>dim_l, dim_r = chi_mat.shape<EOL>if dim_l != dim_r:<EOL><INDENT>raise QiskitError('<STR_LIT>')<EOL><DEDENT>if input_dims:<EOL><INDENT>input_dim = np.product(input_dims)<EOL><DEDENT>if output_dims:<EOL><INDENT>output_dim = np.product(input_dims)<EOL><DEDENT>if output_dims is None and input_dims is None:<EOL><INDENT>output_dim = int(np.sqrt(dim_l))<EOL>input_dim = dim_l // output_dim<EOL><DEDENT>elif input_dims is None:<EOL><INDENT>input_dim = dim_l // output_dim<EOL><DEDENT>elif output_dims is None:<EOL><INDENT>output_dim = dim_l // input_dim<EOL><DEDENT>if input_dim * output_dim != dim_l:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if isinstance(data, (QuantumCircuit, Instruction)):<EOL><INDENT>data = SuperOp._instruction_to_superop(data)<EOL><DEDENT>else:<EOL><INDENT>data = self._init_transformer(data)<EOL><DEDENT>input_dim, output_dim = data.dim<EOL>chi_mat = _to_chi(data.rep, data._data, input_dim, output_dim)<EOL>if input_dims is None:<EOL><INDENT>input_dims = data.input_dims()<EOL><DEDENT>if output_dims is None:<EOL><INDENT>output_dims = data.output_dims()<EOL><DEDENT><DEDENT>n_qubits = int(np.log2(input_dim))<EOL>if <NUM_LIT:2>**n_qubits != input_dim:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>input_dims = self._automatic_dims(input_dims, input_dim)<EOL>output_dims = self._automatic_dims(output_dims, output_dim)<EOL>super().__init__('<STR_LIT>', chi_mat, input_dims, output_dims)<EOL>

Initialize a quantum channel Chi-matrix operator.

        Args:
            data (QuantumCircuit or
                  Instruction or
                  BaseOperator or
                  matrix): data to initialize superoperator.
            input_dims (tuple): the input subsystem dimensions.
                                [Default: None]
            output_dims (tuple): the output subsystem dimensions.
                                 [Default: None]

        Raises:
            QiskitError: if input data is not an N-qubit channel or
            cannot be initialized as a Chi-matrix.

        Additional Information
        ----------------------
        If the input or output dimensions are None, they will be
        automatically determined from the input data. The Chi matrix
        representation is only valid for N-qubit channels.


return (self._input_dim, self._output_dim, self._input_dim,<EOL>self._output_dim)<EOL>


<EOL>return Chi(Choi(self).conjugate())<EOL>

Return the conjugate of the QuantumChannel.


<EOL>return Chi(Choi(self).transpose())<EOL>

Return the transpose of the QuantumChannel.


if qargs is not None:<EOL><INDENT>return Chi(<EOL>SuperOp(self).compose(other, qargs=qargs, front=front))<EOL><DEDENT>if not isinstance(other, Choi):<EOL><INDENT>other = Choi(other)<EOL><DEDENT>if front and self._input_dim != other._output_dim:<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>')<EOL><DEDENT>if not front and self._output_dim != other._input_dim:<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>')<EOL><DEDENT>return Chi(Choi(self).compose(other, front=front))<EOL>

Return the composition channel self∘other.

        Args:
            other (QuantumChannel): a quantum channel.
            qargs (list): a list of subsystem positions to compose other on.
            front (bool): If False compose in standard order other(self(input))
                          otherwise compose in reverse order self(other(input))
                          [default: False]

        Returns:
            Chi: The composition channel as a Chi object.

        Raises:
            QiskitError: if other is not a QuantumChannel subclass, or
            has incompatible dimensions.


if n > <NUM_LIT:0>:<EOL><INDENT>return super().power(n)<EOL><DEDENT>return Chi(SuperOp(self).power(n))<EOL>

The matrix power of the channel.

        Args:
            n (int): compute the matrix power of the superoperator matrix.

        Returns:
            Chi: the matrix power of the SuperOp converted to a Chi channel.

        Raises:
            QiskitError: if the input and output dimensions of the
            QuantumChannel are not equal, or the power is not an integer.


return self._tensor_product(other, reverse=False)<EOL>

Return the tensor product channel self ⊗ other.

        Args:
            other (QuantumChannel): a quantum channel.

        Returns:
            Chi: the tensor product channel self ⊗ other as a Chi object.

        Raises:
            QiskitError: if other is not a QuantumChannel subclass.


return self._tensor_product(other, reverse=True)<EOL>

Return the tensor product channel other ⊗ self.

        Args:
            other (QuantumChannel): a quantum channel.

        Returns:
            Chi: the tensor product channel other ⊗ self as a Chi object.

        Raises:
            QiskitError: if other is not a QuantumChannel subclass.


if not isinstance(other, Chi):<EOL><INDENT>other = Chi(other)<EOL><DEDENT>if self.dim != other.dim:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return Chi(self._data + other.data, self._input_dims,<EOL>self._output_dims)<EOL>

Return the QuantumChannel self + other.

        Args:
            other (QuantumChannel): a quantum channel.

        Returns:
            Chi: the linear addition self + other as a Chi object.

        Raises:
            QiskitError: if other is not a QuantumChannel subclass, or
            has incompatible dimensions.


if not isinstance(other, Chi):<EOL><INDENT>other = Chi(other)<EOL><DEDENT>if self.dim != other.dim:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return Chi(self._data - other.data, self._input_dims,<EOL>self._output_dims)<EOL>

Return the QuantumChannel self - other.

        Args:
            other (QuantumChannel): a quantum channel.

        Returns:
            Chi: the linear subtraction self - other as Chi object.

        Raises:
            QiskitError: if other is not a QuantumChannel subclass, or
            has incompatible dimensions.


if not isinstance(other, Number):<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return Chi(other * self._data, self._input_dims, self._output_dims)<EOL>

Return the QuantumChannel self + other.

        Args:
            other (complex): a complex number.

        Returns:
            Chi: the scalar multiplication other * self as a Chi object.

        Raises:
            QiskitError: if other is not a valid scalar.


return Choi(self)._evolve(state, qargs)<EOL>

Evolve a quantum state by the QuantumChannel.

        Args:
            state (QuantumState): The input statevector or density matrix.
            qargs (list): a list of QuantumState subsystem positions to apply
                           the operator on.

        Returns:
            DensityMatrix: the output quantum state as a density matrix.


if not isinstance(other, Chi):<EOL><INDENT>other = Chi(other)<EOL><DEDENT>if reverse:<EOL><INDENT>input_dims = self.input_dims() + other.input_dims()<EOL>output_dims = self.output_dims() + other.output_dims()<EOL>data = np.kron(other.data, self._data)<EOL><DEDENT>else:<EOL><INDENT>input_dims = other.input_dims() + self.input_dims()<EOL>output_dims = other.output_dims() + self.output_dims()<EOL>data = np.kron(self._data, other.data)<EOL><DEDENT>return Chi(data, input_dims, output_dims)<EOL>

Return the tensor product channel.

        Args:
            other (QuantumChannel): a quantum channel.
            reverse (bool): If False return self ⊗ other, if True return
                            if True return (other ⊗ self) [Default: False
        Returns:
            Chi: the tensor product channel as a Chi object.

        Raises:
            QiskitError: if other is not a QuantumChannel subclass.


<EOL>if isinstance(data, (list, np.ndarray)):<EOL><INDENT>super_mat = np.array(data, dtype=complex)<EOL>dout, din = super_mat.shape<EOL>input_dim = int(np.sqrt(din))<EOL>output_dim = int(np.sqrt(dout))<EOL>if output_dim**<NUM_LIT:2> != dout or input_dim**<NUM_LIT:2> != din:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if isinstance(data, (QuantumCircuit, Instruction)):<EOL><INDENT>data = self._instruction_to_superop(data)<EOL><DEDENT>else:<EOL><INDENT>data = self._init_transformer(data)<EOL><DEDENT>input_dim, output_dim = data.dim<EOL>super_mat = _to_superop(data.rep, data._data, input_dim,<EOL>output_dim)<EOL>if input_dims is None:<EOL><INDENT>input_dims = data.input_dims()<EOL><DEDENT>if output_dims is None:<EOL><INDENT>output_dims = data.output_dims()<EOL><DEDENT><DEDENT>input_dims = self._automatic_dims(input_dims, input_dim)<EOL>output_dims = self._automatic_dims(output_dims, output_dim)<EOL>super().__init__('<STR_LIT>', super_mat, input_dims, output_dims)<EOL>

Initialize a quantum channel Superoperator operator.

        Args:
            data (QuantumCircuit or
                  Instruction or
                  BaseOperator or
                  matrix): data to initialize superoperator.
            input_dims (tuple): the input subsystem dimensions.
                                [Default: None]
            output_dims (tuple): the output subsystem dimensions.
                                 [Default: None]

        Raises:
            QiskitError: if input data cannot be initialized as a
            superoperator.

        Additional Information
        ----------------------
        If the input or output dimensions are None, they will be
        automatically determined from the input data. If the input data is
        a Numpy array of shape (4**N, 4**N) qubit systems will be used. If
        the input operator is not an N-qubit operator, it will assign a
        single subsystem with dimension specifed by the shape of the input.


return <NUM_LIT:2> * tuple(reversed(self.output_dims())) + <NUM_LIT:2> * tuple(<EOL>reversed(self.input_dims()))<EOL>

Return the tensor shape of the superopertor matrix


return (self._output_dim, self._output_dim, self._input_dim,<EOL>self._input_dim)<EOL>


return SuperOp(<EOL>np.conj(self._data), self.input_dims(), self.output_dims())<EOL>


return SuperOp(<EOL>np.transpose(self._data),<EOL>input_dims=self.output_dims(),<EOL>output_dims=self.input_dims())<EOL>


<EOL>if not isinstance(other, SuperOp):<EOL><INDENT>other = SuperOp(other)<EOL><DEDENT>if front and self.input_dims(qargs=qargs) != other.output_dims():<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>')<EOL><DEDENT>if not front and self.output_dims(qargs=qargs) != other.input_dims():<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>')<EOL><DEDENT>if qargs is None:<EOL><INDENT>if front:<EOL><INDENT>return SuperOp(<EOL>np.dot(self._data, other.data),<EOL>input_dims=other.input_dims(),<EOL>output_dims=self.output_dims())<EOL><DEDENT>return SuperOp(<EOL>np.dot(other.data, self._data),<EOL>input_dims=self.input_dims(),<EOL>output_dims=other.output_dims())<EOL><DEDENT>return self._compose_subsystem(other, qargs, front)<EOL>

Return the composition channel self∘other.

        Args:
            other (QuantumChannel): a quantum channel.
            qargs (list): a list of subsystem positions to compose other on.
            front (bool): If False compose in standard order other(self(input))
                          otherwise compose in reverse order self(other(input))
                          [default: False]

        Returns:
            SuperOp: The composition channel as a SuperOp object.

        Raises:
            QiskitError: if other is not a QuantumChannel subclass, or
            has incompatible dimensions.


if not isinstance(n, (int, np.integer)):<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>if self._input_dim != self._output_dim:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return SuperOp(<EOL>np.linalg.matrix_power(self._data, n), self.input_dims(),<EOL>self.output_dims())<EOL>

Return the compose of a QuantumChannel with itself n times.

        Args:
            n (int): compute the matrix power of the superoperator matrix.

        Returns:
            SuperOp: the n-times composition channel as a SuperOp object.

        Raises:
            QiskitError: if the input and output dimensions of the
            QuantumChannel are not equal, or the power is not an integer.


Return the tensor product channel self ⊗ other.

        Args:
            other (QuantumChannel): a quantum channel.

        Returns:
            SuperOp: the tensor product channel self ⊗ other as a SuperOp
            object.

        Raises:
            QiskitError: if other cannot be converted to a channel.


Return the tensor product channel other ⊗ self.

        Args:
            other (QuantumChannel): a quantum channel.

        Returns:
            SuperOp: the tensor product channel other ⊗ self as a SuperOp
            object.

        Raises:
            QiskitError: if other cannot be converted to a channel.


<EOL>if not isinstance(other, SuperOp):<EOL><INDENT>other = SuperOp(other)<EOL><DEDENT>if self.dim != other.dim:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return SuperOp(self._data + other.data, self.input_dims(),<EOL>self.output_dims())<EOL>

Return the QuantumChannel self + other.

        Args:
            other (QuantumChannel): a quantum channel.

        Returns:
            SuperOp: the linear addition self + other as a SuperOp object.

        Raises:
            QiskitError: if other cannot be converted to a channel or
            has incompatible dimensions.


<EOL>if not isinstance(other, SuperOp):<EOL><INDENT>other = SuperOp(other)<EOL><DEDENT>if self.dim != other.dim:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return SuperOp(self._data - other.data, self.input_dims(),<EOL>self.output_dims())<EOL>

Return the QuantumChannel self - other.

        Args:
            other (QuantumChannel): a quantum channel.

        Returns:
            SuperOp: the linear subtraction self - other as SuperOp object.

        Raises:
            QiskitError: if other cannot be converted to a channel or
            has incompatible dimensions.


if not isinstance(other, Number):<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return SuperOp(other * self._data, self.input_dims(),<EOL>self.output_dims())<EOL>

Return the QuantumChannel self + other.

        Args:
            other (complex): a complex number.

        Returns:
            SuperOp: the scalar multiplication other * self as a SuperOp object.

        Raises:
            QiskitError: if other is not a valid scalar.


state = self._format_state(state, density_matrix=True)<EOL>if qargs is None:<EOL><INDENT>if state.shape[<NUM_LIT:0>] != self._input_dim:<EOL><INDENT>raise QiskitError(<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>shape_in = self._input_dim * self._input_dim<EOL>shape_out = (self._output_dim, self._output_dim)<EOL>return np.reshape(<EOL>np.dot(self._data, np.reshape(state, shape_in, order='<STR_LIT:F>')),<EOL>shape_out,<EOL>order='<STR_LIT:F>')<EOL><DEDENT>return self._evolve_subsystem(state, qargs)<EOL>

Evolve a quantum state by the QuantumChannel.

        Args:
            state (QuantumState): The input statevector or density matrix.
            qargs (list): a list of QuantumState subsystem positions to apply
                           the operator on.

        Returns:
            DensityMatrix: the output quantum state as a density matrix.

        Raises:
            QiskitError: if the operator dimension does not match the
            specified QuantumState subsystem dimensions.


<EOL>input_dims = list(self.input_dims())<EOL>output_dims = list(self.output_dims())<EOL>if front:<EOL><INDENT>num_indices = len(self.input_dims())<EOL>shift = <NUM_LIT:2> * len(self.output_dims())<EOL>right_mul = True<EOL>for pos, qubit in enumerate(qargs):<EOL><INDENT>input_dims[qubit] = other._input_dims[pos]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>num_indices = len(self.output_dims())<EOL>shift = <NUM_LIT:0><EOL>right_mul = False<EOL>for pos, qubit in enumerate(qargs):<EOL><INDENT>output_dims[qubit] = other._output_dims[pos]<EOL><DEDENT><DEDENT>tensor = np.reshape(self.data, self._shape)<EOL>mat = np.reshape(other.data, other._shape)<EOL>indices = [<NUM_LIT:2> * num_indices - <NUM_LIT:1> - qubit for qubit in qargs<EOL>] + [num_indices - <NUM_LIT:1> - qubit for qubit in qargs]<EOL>final_shape = [np.product(output_dims)**<NUM_LIT:2>, np.product(input_dims)**<NUM_LIT:2>]<EOL>data = np.reshape(<EOL>self._einsum_matmul(tensor, mat, indices, shift, right_mul),<EOL>final_shape)<EOL>return SuperOp(data, input_dims, output_dims)<EOL>


mat = np.reshape(self.data, self._shape)<EOL>state_size = len(state)<EOL>state_dims = self._automatic_dims(None, state_size)<EOL>if self.input_dims() != len(qargs) * (<NUM_LIT:2>, ):<EOL><INDENT>raise QiskitError(<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>tensor = np.reshape(state, <NUM_LIT:2> * state_dims)<EOL>num_inidices = len(state_dims)<EOL>indices = [num_inidices - <NUM_LIT:1> - qubit for qubit in qargs<EOL>] + [<NUM_LIT:2> * num_inidices - <NUM_LIT:1> - qubit for qubit in qargs]<EOL>tensor = self._einsum_matmul(tensor, mat, indices)<EOL>return np.reshape(tensor, [state_size, state_size])<EOL>

Evolve a quantum state by the operator.

        Args:
            state (QuantumState): The input statevector or density matrix.
            qargs (list): a list of QuantumState subsystem positions to apply
                           the operator on.

        Returns:
            QuantumState: the output quantum state.

        Raises:
            QiskitError: if the operator dimension does not match the
            specified QuantumState subsystem dimensions.


<EOL>if not isinstance(other, SuperOp):<EOL><INDENT>other = SuperOp(other)<EOL><DEDENT>if reverse:<EOL><INDENT>input_dims = self.input_dims() + other.input_dims()<EOL>output_dims = self.output_dims() + other.output_dims()<EOL>data = _bipartite_tensor(<EOL>other.data,<EOL>self._data,<EOL>shape1=other._bipartite_shape,<EOL>shape2=self._bipartite_shape)<EOL><DEDENT>else:<EOL><INDENT>input_dims = other.input_dims() + self.input_dims()<EOL>output_dims = other.output_dims() + self.output_dims()<EOL>data = _bipartite_tensor(<EOL>self._data,<EOL>other.data,<EOL>shape1=self._bipartite_shape,<EOL>shape2=other._bipartite_shape)<EOL><DEDENT>return SuperOp(data, input_dims, output_dims)<EOL>

Return the tensor product channel.

        Args:
            other (QuantumChannel): a quantum channel.
            reverse (bool): If False return self ⊗ other, if True return
                            if True return (other ⊗ self) [Default: False
        Returns:
            SuperOp: the tensor product channel as a SuperOp object.

        Raises:
            QiskitError: if other cannot be converted to a channel.


<EOL>if isinstance(instruction, QuantumCircuit):<EOL><INDENT>instruction = instruction.to_instruction()<EOL><DEDENT>op = SuperOp(np.eye(<NUM_LIT:4> ** instruction.num_qubits))<EOL>op._append_instruction(instruction)<EOL>return op<EOL>

Convert a QuantumCircuit or Instruction to a SuperOp.


if isinstance(obj, Instruction):<EOL><INDENT>chan = None<EOL>if obj.name == '<STR_LIT>':<EOL><INDENT>chan = SuperOp(<EOL>np.array([[<NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>], [<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>], [<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>],<EOL>[<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>]]))<EOL><DEDENT>if obj.name == '<STR_LIT>':<EOL><INDENT>kraus = obj.params<EOL>dim = len(kraus[<NUM_LIT:0>])<EOL>chan = SuperOp(_to_superop('<STR_LIT>', (kraus, None), dim, dim))<EOL><DEDENT>elif hasattr(obj, '<STR_LIT>'):<EOL><INDENT>try:<EOL><INDENT>kraus = [obj.to_matrix()]<EOL>dim = len(kraus[<NUM_LIT:0>])<EOL>chan = SuperOp(<EOL>_to_superop('<STR_LIT>', (kraus, None), dim, dim))<EOL><DEDENT>except QiskitError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>if chan is not None:<EOL><INDENT>op = self.compose(chan, qargs=qargs)<EOL>self._data = op.data<EOL><DEDENT>else:<EOL><INDENT>if obj.definition is None:<EOL><INDENT>raise QiskitError('<STR_LIT>'.format(<EOL>obj.name))<EOL><DEDENT>for instr, qregs, cregs in obj.definition:<EOL><INDENT>if cregs:<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>'<EOL>.format(instr.name))<EOL><DEDENT>new_qargs = [tup[<NUM_LIT:1>] for tup in qregs]<EOL>self._append_instruction(instr, qargs=new_qargs)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>raise QiskitError('<STR_LIT>')<EOL><DEDENT>

Update the current Operator by apply an instruction.


<EOL>if isinstance(data, (list, tuple, np.ndarray)):<EOL><INDENT>if not isinstance(data, tuple):<EOL><INDENT>stine = (np.array(data, dtype=complex), None)<EOL><DEDENT>if isinstance(data, tuple) and len(data) == <NUM_LIT:2>:<EOL><INDENT>if data[<NUM_LIT:1>] is None:<EOL><INDENT>stine = (np.array(data[<NUM_LIT:0>], dtype=complex), None)<EOL><DEDENT>else:<EOL><INDENT>stine = (np.array(data[<NUM_LIT:0>], dtype=complex),<EOL>np.array(data[<NUM_LIT:1>], dtype=complex))<EOL><DEDENT><DEDENT>dim_left, dim_right = stine[<NUM_LIT:0>].shape<EOL>if stine[<NUM_LIT:1>] is not None:<EOL><INDENT>if stine[<NUM_LIT:1>].shape != (dim_left, dim_right):<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT><DEDENT>input_dim = dim_right<EOL>if output_dims:<EOL><INDENT>output_dim = np.product(output_dims)<EOL><DEDENT>else:<EOL><INDENT>output_dim = input_dim<EOL><DEDENT>if dim_left % output_dim != <NUM_LIT:0>:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if isinstance(data, (QuantumCircuit, Instruction)):<EOL><INDENT>data = SuperOp._instruction_to_superop(data)<EOL><DEDENT>else:<EOL><INDENT>data = self._init_transformer(data)<EOL><DEDENT>data = self._init_transformer(data)<EOL>input_dim, output_dim = data.dim<EOL>stine = _to_stinespring(data.rep, data._data, input_dim,<EOL>output_dim)<EOL>if input_dims is None:<EOL><INDENT>input_dims = data.input_dims()<EOL><DEDENT>if output_dims is None:<EOL><INDENT>output_dims = data.output_dims()<EOL><DEDENT><DEDENT>input_dims = self._automatic_dims(input_dims, input_dim)<EOL>output_dims = self._automatic_dims(output_dims, output_dim)<EOL>if stine[<NUM_LIT:1>] is None or (stine[<NUM_LIT:1>] == stine[<NUM_LIT:0>]).all():<EOL><INDENT>super().__init__(<EOL>'<STR_LIT>', (stine[<NUM_LIT:0>], None),<EOL>input_dims=input_dims,<EOL>output_dims=output_dims)<EOL><DEDENT>else:<EOL><INDENT>super().__init__(<EOL>'<STR_LIT>',<EOL>stine,<EOL>input_dims=input_dims,<EOL>output_dims=output_dims)<EOL><DEDENT>

Initialize a quantum channel Stinespring operator.

        Args:
            data (QuantumCircuit or
                  Instruction or
                  BaseOperator or
                  matrix): data to initialize superoperator.
            input_dims (tuple): the input subsystem dimensions.
                                [Default: None]
            output_dims (tuple): the output subsystem dimensions.
                                 [Default: None]

        Raises:
            QiskitError: if input data cannot be initialized as a
            a list of Kraus matrices.

        Additional Information
        ----------------------
        If the input or output dimensions are None, they will be
        automatically determined from the input data. This can fail for the
        Stinespring operator if the output dimension cannot be automatically
        determined.


def is_cptp(self, atol=None, rtol=None):

if atol is None:<EOL><INDENT>atol = self._atol<EOL><DEDENT>if rtol is None:<EOL><INDENT>rtol = self._rtol<EOL><DEDENT>if self._data[<NUM_LIT:1>] is not None:<EOL><INDENT>return False<EOL><DEDENT>check = np.dot(np.transpose(np.conj(self._data[<NUM_LIT:0>])), self._data[<NUM_LIT:0>])<EOL>return is_identity_matrix(check, rtol=self._rtol, atol=self._atol)<EOL>

Return True if completely-positive trace-preserving.


<EOL>stine_l = np.conjugate(self._data[<NUM_LIT:0>])<EOL>stine_r = None<EOL>if self._data[<NUM_LIT:1>] is not None:<EOL><INDENT>stine_r = np.conjugate(self._data[<NUM_LIT:1>])<EOL><DEDENT>return Stinespring((stine_l, stine_r), self.input_dims(),<EOL>self.output_dims())<EOL>

Return the conjugate of the QuantumChannel.


din, dout = self.dim<EOL>dtr = self._data[<NUM_LIT:0>].shape[<NUM_LIT:0>] // dout<EOL>stine = [None, None]<EOL>for i, mat in enumerate(self._data):<EOL><INDENT>if mat is not None:<EOL><INDENT>stine[i] = np.reshape(<EOL>np.transpose(np.reshape(mat, (dout, dtr, din)), (<NUM_LIT:2>, <NUM_LIT:1>, <NUM_LIT:0>)),<EOL>(din * dtr, dout))<EOL><DEDENT><DEDENT>return Stinespring(<EOL>tuple(stine),<EOL>input_dims=self.output_dims(),<EOL>output_dims=self.input_dims())<EOL>

Return the transpose of the QuantumChannel.


if qargs is not None:<EOL><INDENT>return Stinespring(<EOL>SuperOp(self).compose(other, qargs=qargs, front=front))<EOL><DEDENT>if not isinstance(other, Kraus):<EOL><INDENT>other = Kraus(other)<EOL><DEDENT>if front and self._input_dim != other._output_dim:<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>')<EOL><DEDENT>if not front and self._output_dim != other._input_dim:<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>')<EOL><DEDENT>return Stinespring(Kraus(self).compose(other, front=front))<EOL>

Return the composition channel self∘other.

        Args:
            other (QuantumChannel): a quantum channel subclass.
            qargs (list): a list of subsystem positions to compose other on.
            front (bool): If False compose in standard order other(self(input))
                          otherwise compose in reverse order self(other(input))
                          [default: False]

        Returns:
            Stinespring: The composition channel as a Stinespring object.

        Raises:
            QiskitError: if other cannot be converted to a channel or
            has incompatible dimensions.


if n > <NUM_LIT:0>:<EOL><INDENT>return super().power(n)<EOL><DEDENT>return Stinespring(SuperOp(self).power(n))<EOL>

The matrix power of the channel.

        Args:
            n (int): compute the matrix power of the superoperator matrix.

        Returns:
            Stinespring: the matrix power of the SuperOp converted to a
            Stinespring channel.

        Raises:
            QiskitError: if the input and output dimensions of the
            QuantumChannel are not equal, or the power is not an integer.


return self._tensor_product(other, reverse=False)<EOL>

Return the tensor product channel self ⊗ other.

        Args:
            other (QuantumChannel): a quantum channel subclass.

        Returns:
            Stinespring: the tensor product channel other ⊗ self as a
            Stinespring object.

        Raises:
            QiskitError: if other cannot be converted to a channel.


return self._tensor_product(other, reverse=True)<EOL>

Return the tensor product channel other ⊗ self.

        Args:
            other (QuantumChannel): a quantum channel subclass.

        Returns:
            Stinespring: the tensor product channel other ⊗ self as a
            Stinespring object.

        Raises:
            QiskitError: if other cannot be converted to a channel.


<EOL>return Stinespring(Choi(self).add(other))<EOL>

Return the QuantumChannel self + other.

        Args:
            other (QuantumChannel): a quantum channel subclass.

        Returns:
            Stinespring: the linear addition self + other as a
            Stinespring object.

        Raises:
            QiskitError: if other cannot be converted to a channel or
            has incompatible dimensions.


<EOL>return Stinespring(Choi(self).subtract(other))<EOL>

Return the QuantumChannel self - other.

        Args:
            other (QuantumChannel): a quantum channel subclass.

        Returns:
            Stinespring: the linear subtraction self - other as
            Stinespring object.

        Raises:
            QiskitError: if other cannot be converted to a channel or
            has incompatible dimensions.


if not isinstance(other, Number):<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>if isinstance(other, complex) or other < <NUM_LIT:1>:<EOL><INDENT>return Stinespring(Choi(self).multiply(other))<EOL><DEDENT>num = np.sqrt(other)<EOL>stine_l, stine_r = self._data<EOL>stine_l = num * self._data[<NUM_LIT:0>]<EOL>stine_r = None<EOL>if self._data[<NUM_LIT:1>] is not None:<EOL><INDENT>stine_r = num * self._data[<NUM_LIT:1>]<EOL><DEDENT>return Stinespring((stine_l, stine_r), self.input_dims(),<EOL>self.output_dims())<EOL>

Return the QuantumChannel self + other.

        Args:
            other (complex): a complex number.

        Returns:
            Stinespring: the scalar multiplication other * self as a
            Stinespring object.

        Raises:
            QiskitError: if other is not a valid scalar.


<EOL>if qargs is not None:<EOL><INDENT>return SuperOp(self)._evolve(state, qargs)<EOL><DEDENT>state = self._format_state(state)<EOL>if state.shape[<NUM_LIT:0>] != self._input_dim:<EOL><INDENT>raise QiskitError(<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>if state.ndim == <NUM_LIT:1> and self._data[<NUM_LIT:1>] is None andself._data[<NUM_LIT:0>].shape[<NUM_LIT:0>] // self._output_dim == <NUM_LIT:1>:<EOL><INDENT>return np.dot(self._data[<NUM_LIT:0>], state)<EOL><DEDENT>state = self._format_state(state, density_matrix=True)<EOL>stine_l, stine_r = self._data<EOL>if stine_r is None:<EOL><INDENT>stine_r = stine_l<EOL><DEDENT>din, dout = self.dim<EOL>dtr = stine_l.shape[<NUM_LIT:0>] // dout<EOL>shape = (dout, dtr, din)<EOL>return np.einsum('<STR_LIT>', np.reshape(stine_l, shape), state,<EOL>np.reshape(np.conjugate(stine_r), shape))<EOL>

Evolve a quantum state by the QuantumChannel.

        Args:
            state (QuantumState): The input statevector or density matrix.
            qargs (list): a list of QuantumState subsystem positions to apply
                           the operator on.

        Returns:
            QuantumState: the output quantum state.

        Raises:
            QiskitError: if the operator dimension does not match the
            specified QuantumState subsystem dimensions.


<EOL>if not isinstance(other, Stinespring):<EOL><INDENT>other = Stinespring(other)<EOL><DEDENT>sa_l, sa_r = self._data<EOL>sb_l, sb_r = other._data<EOL>din_a, dout_a = self.dim<EOL>din_b, dout_b = other.dim<EOL>dtr_a = sa_l.shape[<NUM_LIT:0>] // dout_a<EOL>dtr_b = sb_l.shape[<NUM_LIT:0>] // dout_b<EOL>if reverse:<EOL><INDENT>shape_in = (dout_b, dtr_b, dout_a, dtr_a, din_b * din_a)<EOL>shape_out = (dout_b * dtr_b * dout_a * dtr_a, din_b * din_a)<EOL><DEDENT>else:<EOL><INDENT>shape_in = (dout_a, dtr_a, dout_b, dtr_b, din_a * din_b)<EOL>shape_out = (dout_a * dtr_a * dout_b * dtr_b, din_a * din_b)<EOL><DEDENT>if reverse:<EOL><INDENT>input_dims = self.input_dims() + other.input_dims()<EOL>output_dims = self.output_dims() + other.output_dims()<EOL>sab_l = np.kron(sb_l, sa_l)<EOL><DEDENT>else:<EOL><INDENT>input_dims = other.input_dims() + self.input_dims()<EOL>output_dims = other.output_dims() + self.output_dims()<EOL>sab_l = np.kron(sa_l, sb_l)<EOL><DEDENT>sab_l = np.reshape(<EOL>np.transpose(np.reshape(sab_l, shape_in), (<NUM_LIT:0>, <NUM_LIT:2>, <NUM_LIT:1>, <NUM_LIT:3>, <NUM_LIT:4>)),<EOL>shape_out)<EOL>if sa_r is None and sb_r is None:<EOL><INDENT>sab_r = None<EOL><DEDENT>else:<EOL><INDENT>if sa_r is None:<EOL><INDENT>sa_r = sa_l<EOL><DEDENT>elif sb_r is None:<EOL><INDENT>sb_r = sb_l<EOL><DEDENT>if reverse:<EOL><INDENT>sab_r = np.kron(sb_r, sa_r)<EOL><DEDENT>else:<EOL><INDENT>sab_r = np.kron(sa_r, sb_r)<EOL><DEDENT>sab_r = np.reshape(<EOL>np.transpose(np.reshape(sab_r, shape_in), (<NUM_LIT:0>, <NUM_LIT:2>, <NUM_LIT:1>, <NUM_LIT:3>, <NUM_LIT:4>)),<EOL>shape_out)<EOL><DEDENT>return Stinespring((sab_l, sab_r), input_dims, output_dims)<EOL>

Return the tensor product channel.

        Args:
            other (QuantumChannel): a quantum channel subclass.
            reverse (bool): If False return self ⊗ other, if True return
                            if True return (other ⊗ self) [Default: False]
        Returns:
            Stinespring: the tensor product channel as a Stinespring object.

        Raises:
            QiskitError: if other cannot be converted to a channel.


def _to_choi(rep, data, input_dim, output_dim):

if rep == '<STR_LIT>':<EOL><INDENT>return data<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _from_operator('<STR_LIT>', data, input_dim, output_dim)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _superop_to_choi(data, input_dim, output_dim)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _kraus_to_choi(data, input_dim, output_dim)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _chi_to_choi(data, input_dim, output_dim)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>data = _ptm_to_superop(data, input_dim, output_dim)<EOL>return _superop_to_choi(data, input_dim, output_dim)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _stinespring_to_choi(data, input_dim, output_dim)<EOL><DEDENT>raise QiskitError('<STR_LIT>'.format(rep))<EOL>

Transform a QuantumChannel to the Choi representation.


def _to_superop(rep, data, input_dim, output_dim):

if rep == '<STR_LIT>':<EOL><INDENT>return data<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _from_operator('<STR_LIT>', data, input_dim, output_dim)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _choi_to_superop(data, input_dim, output_dim)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _kraus_to_superop(data, input_dim, output_dim)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>data = _chi_to_choi(data, input_dim, output_dim)<EOL>return _choi_to_superop(data, input_dim, output_dim)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _ptm_to_superop(data, input_dim, output_dim)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _stinespring_to_superop(data, input_dim, output_dim)<EOL><DEDENT>raise QiskitError('<STR_LIT>'.format(rep))<EOL>

Transform a QuantumChannel to the SuperOp representation.


def _to_kraus(rep, data, input_dim, output_dim):

if rep == '<STR_LIT>':<EOL><INDENT>return data<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _stinespring_to_kraus(data, input_dim, output_dim)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _from_operator('<STR_LIT>', data, input_dim, output_dim)<EOL><DEDENT>if rep != '<STR_LIT>':<EOL><INDENT>data = _to_choi(rep, data, input_dim, output_dim)<EOL><DEDENT>return _choi_to_kraus(data, input_dim, output_dim)<EOL>

Transform a QuantumChannel to the Kraus representation.


def _to_chi(rep, data, input_dim, output_dim):

if rep == '<STR_LIT>':<EOL><INDENT>return data<EOL><DEDENT>_check_nqubit_dim(input_dim, output_dim)<EOL>if rep == '<STR_LIT>':<EOL><INDENT>return _from_operator('<STR_LIT>', data, input_dim, output_dim)<EOL><DEDENT>if rep != '<STR_LIT>':<EOL><INDENT>data = _to_choi(rep, data, input_dim, output_dim)<EOL><DEDENT>return _choi_to_chi(data, input_dim, output_dim)<EOL>

Transform a QuantumChannel to the Chi representation.


def _to_ptm(rep, data, input_dim, output_dim):

if rep == '<STR_LIT>':<EOL><INDENT>return data<EOL><DEDENT>_check_nqubit_dim(input_dim, output_dim)<EOL>if rep == '<STR_LIT>':<EOL><INDENT>return _from_operator('<STR_LIT>', data, input_dim, output_dim)<EOL><DEDENT>if rep != '<STR_LIT>':<EOL><INDENT>data = _to_superop(rep, data, input_dim, output_dim)<EOL><DEDENT>return _superop_to_ptm(data, input_dim, output_dim)<EOL>

Transform a QuantumChannel to the PTM representation.


def _to_stinespring(rep, data, input_dim, output_dim):

if rep == '<STR_LIT>':<EOL><INDENT>return data<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _from_operator('<STR_LIT>', data, input_dim, output_dim)<EOL><DEDENT>if rep != '<STR_LIT>':<EOL><INDENT>data = _to_kraus(rep, data, input_dim, output_dim)<EOL><DEDENT>return _kraus_to_stinespring(data, input_dim, output_dim)<EOL>

Transform a QuantumChannel to the Stinespring representation.


def _to_operator(rep, data, input_dim, output_dim):

if rep == '<STR_LIT>':<EOL><INDENT>return data<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return _stinespring_to_operator(data, input_dim, output_dim)<EOL><DEDENT>if rep != '<STR_LIT>':<EOL><INDENT>data = _to_kraus(rep, data, input_dim, output_dim)<EOL><DEDENT>return _kraus_to_operator(data, input_dim, output_dim)<EOL>

Transform a QuantumChannel to the Operator representation.


def _from_operator(rep, data, input_dim, output_dim):

if rep == '<STR_LIT>':<EOL><INDENT>return data<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return np.kron(np.conj(data), data)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>vec = np.ravel(data, order='<STR_LIT:F>')<EOL>return np.outer(vec, np.conj(vec))<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return ([data], None)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>return (data, None)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>_check_nqubit_dim(input_dim, output_dim)<EOL>data = _from_operator('<STR_LIT>', data, input_dim, output_dim)<EOL>return _choi_to_chi(data, input_dim, output_dim)<EOL><DEDENT>if rep == '<STR_LIT>':<EOL><INDENT>_check_nqubit_dim(input_dim, output_dim)<EOL>data = _from_operator('<STR_LIT>', data, input_dim, output_dim)<EOL>return _superop_to_ptm(data, input_dim, output_dim)<EOL><DEDENT>raise QiskitError('<STR_LIT>'.format(rep))<EOL>

Transform Operator representation to other representation.


def _kraus_to_operator(data, input_dim, output_dim):

if data[<NUM_LIT:1>] is not None or len(data[<NUM_LIT:0>]) > <NUM_LIT:1>:<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>')<EOL><DEDENT>return data[<NUM_LIT:0>][<NUM_LIT:0>]<EOL>

Transform Kraus representation to Operator representation.


def _stinespring_to_operator(data, input_dim, output_dim):

trace_dim = data[<NUM_LIT:0>].shape[<NUM_LIT:0>] // output_dim<EOL>if data[<NUM_LIT:1>] is not None or trace_dim != <NUM_LIT:1>:<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>')<EOL><DEDENT>return data[<NUM_LIT:0>]<EOL>

Transform Stinespring representation to Operator representation.


def _superop_to_choi(data, input_dim, output_dim):

shape = (output_dim, output_dim, input_dim, input_dim)<EOL>return _reshuffle(data, shape)<EOL>

Transform SuperOp representation to Choi representation.


def _choi_to_superop(data, input_dim, output_dim):

shape = (input_dim, output_dim, input_dim, output_dim)<EOL>return _reshuffle(data, shape)<EOL>

Transform Choi to SuperOp representation.


def _kraus_to_choi(data, input_dim, output_dim):

choi = <NUM_LIT:0><EOL>kraus_l, kraus_r = data<EOL>if kraus_r is None:<EOL><INDENT>for i in kraus_l:<EOL><INDENT>vec = i.ravel(order='<STR_LIT:F>')<EOL>choi += np.outer(vec, vec.conj())<EOL><DEDENT><DEDENT>else:<EOL><INDENT>for i, j in zip(kraus_l, kraus_r):<EOL><INDENT>choi += np.outer(i.ravel(order='<STR_LIT:F>'), j.ravel(order='<STR_LIT:F>').conj())<EOL><DEDENT><DEDENT>return choi<EOL>

Transform Kraus representation to Choi representation.


def _choi_to_kraus(data, input_dim, output_dim, atol=ATOL_DEFAULT):

<EOL>if is_hermitian_matrix(data, atol=atol):<EOL><INDENT>w, v = la.eigh(data)<EOL>if len(w[w < -atol]) == <NUM_LIT:0>:<EOL><INDENT>kraus = []<EOL>for val, vec in zip(w, v.T):<EOL><INDENT>if abs(val) > atol:<EOL><INDENT>k = np.sqrt(val) * vec.reshape(<EOL>(output_dim, input_dim), order='<STR_LIT:F>')<EOL>kraus.append(k)<EOL><DEDENT><DEDENT>if not kraus:<EOL><INDENT>kraus.append(np.zeros((output_dim, input_dim), dtype=complex))<EOL><DEDENT>return (kraus, None)<EOL><DEDENT><DEDENT>mat_u, svals, mat_vh = la.svd(data)<EOL>kraus_l = []<EOL>kraus_r = []<EOL>for val, vec_l, vec_r in zip(svals, mat_u.T, mat_vh.conj()):<EOL><INDENT>kraus_l.append(<EOL>np.sqrt(val) * vec_l.reshape((output_dim, input_dim), order='<STR_LIT:F>'))<EOL>kraus_r.append(<EOL>np.sqrt(val) * vec_r.reshape((output_dim, input_dim), order='<STR_LIT:F>'))<EOL><DEDENT>return (kraus_l, kraus_r)<EOL>

Transform Choi representation to Kraus representation.


def _stinespring_to_kraus(data, input_dim, output_dim):

kraus_pair = []<EOL>for stine in data:<EOL><INDENT>if stine is None:<EOL><INDENT>kraus_pair.append(None)<EOL><DEDENT>else:<EOL><INDENT>trace_dim = stine.shape[<NUM_LIT:0>] // output_dim<EOL>iden = np.eye(output_dim)<EOL>kraus = []<EOL>for j in range(trace_dim):<EOL><INDENT>vec = np.zeros(trace_dim)<EOL>vec[j] = <NUM_LIT:1><EOL>kraus.append(np.kron(iden, vec[None, :]).dot(stine))<EOL><DEDENT>kraus_pair.append(kraus)<EOL><DEDENT><DEDENT>return tuple(kraus_pair)<EOL>

Transform Stinespring representation to Kraus representation.


def _stinespring_to_choi(data, input_dim, output_dim):

trace_dim = data[<NUM_LIT:0>].shape[<NUM_LIT:0>] // output_dim<EOL>stine_l = np.reshape(data[<NUM_LIT:0>], (output_dim, trace_dim, input_dim))<EOL>if data[<NUM_LIT:1>] is None:<EOL><INDENT>stine_r = stine_l<EOL><DEDENT>else:<EOL><INDENT>stine_r = np.reshape(data[<NUM_LIT:1>], (output_dim, trace_dim, input_dim))<EOL><DEDENT>return np.reshape(<EOL>np.einsum('<STR_LIT>', stine_l, stine_r.conj()),<EOL><NUM_LIT:2> * [input_dim * output_dim])<EOL>

Transform Stinespring representation to Choi representation.


def _stinespring_to_superop(data, input_dim, output_dim):

trace_dim = data[<NUM_LIT:0>].shape[<NUM_LIT:0>] // output_dim<EOL>stine_l = np.reshape(data[<NUM_LIT:0>], (output_dim, trace_dim, input_dim))<EOL>if data[<NUM_LIT:1>] is None:<EOL><INDENT>stine_r = stine_l<EOL><DEDENT>else:<EOL><INDENT>stine_r = np.reshape(data[<NUM_LIT:1>], (output_dim, trace_dim, input_dim))<EOL><DEDENT>return np.reshape(<EOL>np.einsum('<STR_LIT>', stine_r.conj(), stine_l),<EOL>(output_dim * output_dim, input_dim * input_dim))<EOL>

Transform Stinespring representation to SuperOp representation.


def _kraus_to_stinespring(data, input_dim, output_dim):

stine_pair = [None, None]<EOL>for i, kraus in enumerate(data):<EOL><INDENT>if kraus is not None:<EOL><INDENT>num_kraus = len(kraus)<EOL>stine = np.zeros((output_dim * num_kraus, input_dim),<EOL>dtype=complex)<EOL>for j, mat in enumerate(kraus):<EOL><INDENT>vec = np.zeros(num_kraus)<EOL>vec[j] = <NUM_LIT:1><EOL>stine += np.kron(mat, vec[:, None])<EOL><DEDENT>stine_pair[i] = stine<EOL><DEDENT><DEDENT>return tuple(stine_pair)<EOL>

Transform Kraus representation to Stinespring representation.


def _kraus_to_superop(data, input_dim, output_dim):

kraus_l, kraus_r = data<EOL>superop = <NUM_LIT:0><EOL>if kraus_r is None:<EOL><INDENT>for i in kraus_l:<EOL><INDENT>superop += np.kron(np.conj(i), i)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>for i, j in zip(kraus_l, kraus_r):<EOL><INDENT>superop += np.kron(np.conj(j), i)<EOL><DEDENT><DEDENT>return superop<EOL>

Transform Kraus representation to SuperOp representation.


def _chi_to_choi(data, input_dim, output_dim):

num_qubits = int(np.log2(input_dim))<EOL>return _transform_from_pauli(data, num_qubits)<EOL>

Transform Chi representation to a Choi representation.


def _choi_to_chi(data, input_dim, output_dim):

num_qubits = int(np.log2(input_dim))<EOL>return _transform_to_pauli(data, num_qubits)<EOL>

Transform Choi representation to the Chi representation.


def _ptm_to_superop(data, input_dim, output_dim):

Transform PTM representation to SuperOp representation.


def _superop_to_ptm(data, input_dim, output_dim):

Transform SuperOp representation to PTM representation.


def _bipartite_tensor(mat1, mat2, shape1=None, shape2=None):

<EOL>mat1 = np.array(mat1)<EOL>mat2 = np.array(mat2)<EOL>dim_a0, dim_a1 = mat1.shape<EOL>dim_b0, dim_b1 = mat2.shape<EOL>if shape1 is None:<EOL><INDENT>sdim_a0 = int(np.sqrt(dim_a0))<EOL>sdim_a1 = int(np.sqrt(dim_a1))<EOL>shape1 = (sdim_a0, sdim_a0, sdim_a1, sdim_a1)<EOL><DEDENT>if shape2 is None:<EOL><INDENT>sdim_b0 = int(np.sqrt(dim_b0))<EOL>sdim_b1 = int(np.sqrt(dim_b1))<EOL>shape2 = (sdim_b0, sdim_b0, sdim_b1, sdim_b1)<EOL><DEDENT>if len(shape1) != <NUM_LIT:4> or shape1[<NUM_LIT:0>] * shape1[<NUM_LIT:1>] != dim_a0 orshape1[<NUM_LIT:2>] * shape1[<NUM_LIT:3>] != dim_a1:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>if len(shape2) != <NUM_LIT:4> or shape2[<NUM_LIT:0>] * shape2[<NUM_LIT:1>] != dim_b0 orshape2[<NUM_LIT:2>] * shape2[<NUM_LIT:3>] != dim_b1:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return _reravel(mat1, mat2, shape1, shape2)<EOL>

Tensor product (A ⊗ B) to bipartite matrices and reravel indicies.

    This is used for tensor product of superoperators and Choi matrices.

    Args:
        mat1 (matrix_like): a bipartite matrix A
        mat2 (matrix_like): a bipartite matrix B
        shape1 (tuple): bipartite-shape for matrix A (a0, a1, a2, a3)
        shape2 (tuple): bipartite-shape for matrix B (b0, b1, b2, b3)

    Returns:
        np.array: a bipartite matrix for reravel(A ⊗ B).

    Raises:
        QiskitError: if input matrices are wrong shape.


def _reravel(mat1, mat2, shape1, shape2):

<EOL>left_dims = shape1[:<NUM_LIT:2>] + shape2[:<NUM_LIT:2>]<EOL>right_dims = shape1[<NUM_LIT:2>:] + shape2[<NUM_LIT:2>:]<EOL>tensor_shape = left_dims + right_dims<EOL>final_shape = (np.product(left_dims), np.product(right_dims))<EOL>data = np.kron(mat1, mat2)<EOL>data = np.reshape(<EOL>np.transpose(np.reshape(data, tensor_shape), (<NUM_LIT:0>, <NUM_LIT:2>, <NUM_LIT:1>, <NUM_LIT:3>, <NUM_LIT:4>, <NUM_LIT:6>, <NUM_LIT:5>, <NUM_LIT:7>)),<EOL>final_shape)<EOL>return data<EOL>


<EOL>basis_mat = np.array(<EOL>[[<NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>], [<NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>], [<NUM_LIT:0>, -<NUM_LIT>, <NUM_LIT>, <NUM_LIT:0>], [<NUM_LIT:1>, <NUM_LIT>, <NUM_LIT:0>, -<NUM_LIT:1>]],<EOL>dtype=complex)<EOL>cob = basis_mat<EOL>for _ in range(num_qubits - <NUM_LIT:1>):<EOL><INDENT>dim = int(np.sqrt(len(cob)))<EOL>cob = np.reshape(<EOL>np.transpose(<EOL>np.reshape(<EOL>np.kron(basis_mat, cob), (<NUM_LIT:4>, dim * dim, <NUM_LIT:2>, <NUM_LIT:2>, dim, dim)),<EOL>(<NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:2>, <NUM_LIT:4>, <NUM_LIT:3>, <NUM_LIT:5>)), (<NUM_LIT:4> * dim * dim, <NUM_LIT:4> * dim * dim))<EOL><DEDENT>return np.dot(np.dot(cob, data), cob.conj().T) / <NUM_LIT:2>**num_qubits<EOL>

Change of basis of bipartite matrix represenation.


<EOL>basis_mat = np.array(<EOL>[[<NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>], [<NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT>, <NUM_LIT:0>], [<NUM_LIT:0>, <NUM_LIT:1>, -<NUM_LIT>, <NUM_LIT:0>], [<NUM_LIT:1>, <NUM_LIT>, <NUM_LIT:0>, -<NUM_LIT:1>]],<EOL>dtype=complex)<EOL>cob = basis_mat<EOL>for _ in range(num_qubits - <NUM_LIT:1>):<EOL><INDENT>dim = int(np.sqrt(len(cob)))<EOL>cob = np.reshape(<EOL>np.transpose(<EOL>np.reshape(<EOL>np.kron(basis_mat, cob), (<NUM_LIT:2>, <NUM_LIT:2>, dim, dim, <NUM_LIT:4>, dim * dim)),<EOL>(<NUM_LIT:0>, <NUM_LIT:2>, <NUM_LIT:1>, <NUM_LIT:3>, <NUM_LIT:4>, <NUM_LIT:5>)), (<NUM_LIT:4> * dim * dim, <NUM_LIT:4> * dim * dim))<EOL><DEDENT>return np.dot(np.dot(cob, data), cob.conj().T) / <NUM_LIT:2>**num_qubits<EOL>


return np.reshape(<EOL>np.transpose(np.reshape(mat, shape), (<NUM_LIT:3>, <NUM_LIT:1>, <NUM_LIT:2>, <NUM_LIT:0>)),<EOL>(shape[<NUM_LIT:3>] * shape[<NUM_LIT:1>], shape[<NUM_LIT:0>] * shape[<NUM_LIT:2>]))<EOL>

Reshuffle the indicies of a bipartite matrix A[ij,kl] -> A[lj,ki].


if input_dim != output_dim:<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>' +<EOL>'<STR_LIT>'.format(input_dim, output_dim))<EOL><DEDENT>num_qubits = int(np.log2(input_dim))<EOL>if <NUM_LIT:2>**num_qubits != input_dim:<EOL><INDENT>raise QiskitError('<STR_LIT>')<EOL><DEDENT>

Return true if dims correspond to an n-qubit channel.


def is_cptp(self, atol=None, rtol=None):

choi = _to_choi(self.rep, self._data, *self.dim)<EOL>return self._is_cp_helper(choi, atol, rtol) and self._is_tp_helper(<EOL>choi, atol, rtol)<EOL>

Return True if completely-positive trace-preserving (CPTP).


choi = _to_choi(self.rep, self._data, *self.dim)<EOL>return self._is_tp_helper(choi, atol, rtol)<EOL>

Test if a channel is completely-positive (CP)


choi = _to_choi(self.rep, self._data, *self.dim)<EOL>return self._is_cp_helper(choi, atol, rtol)<EOL>

Test if Choi-matrix is completely-positive (CP)


def is_unitary(self, atol=None, rtol=None):

try:<EOL><INDENT>op = self.to_operator()<EOL>return op.is_unitary(atol=atol, rtol=rtol)<EOL><DEDENT>except QiskitError:<EOL><INDENT>return False<EOL><DEDENT>

Return True if QuantumChannel is a unitary channel.


mat = _to_operator(self.rep, self._data, *self.dim)<EOL>return Operator(mat, self.input_dims(), self.output_dims())<EOL>

Try to convert channel to a unitary representation Operator.


from qiskit.circuit.instruction import Instruction<EOL>n_qubits = int(np.log2(self._input_dim))<EOL>if self._input_dim != self._output_dim or <NUM_LIT:2>**n_qubits != self._input_dim:<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>'<EOL>)<EOL><DEDENT>if not self.is_cptp():<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>'<EOL>)<EOL><DEDENT>kraus, _ = _to_kraus(self.rep, self._data, *self.dim)<EOL>if len(kraus) == <NUM_LIT:1>:<EOL><INDENT>return Operator(kraus[<NUM_LIT:0>]).to_instruction()<EOL><DEDENT>return Instruction('<STR_LIT>', n_qubits, <NUM_LIT:0>, kraus)<EOL>

Convert to a Kraus or UnitaryGate circuit instruction.

        If the channel is unitary it will be added as a unitary gate,
        otherwise it will be added as a kraus simulator instruction.

        Returns:
            Instruction: A kraus instruction for the channel.

        Raises:
            QiskitError: if input data is not an N-qubit CPTP quantum channel.


def _is_cp_helper(self, choi, atol, rtol):

if atol is None:<EOL><INDENT>atol = self._atol<EOL><DEDENT>if rtol is None:<EOL><INDENT>rtol = self._rtol<EOL><DEDENT>return is_positive_semidefinite_matrix(choi, rtol=rtol, atol=atol)<EOL>


def _is_tp_helper(self, choi, atol, rtol):

if atol is None:<EOL><INDENT>atol = self._atol<EOL><DEDENT>if rtol is None:<EOL><INDENT>rtol = self._rtol<EOL><DEDENT>d_in, d_out = self.dim<EOL>mat = np.trace(<EOL>np.reshape(choi, (d_in, d_out, d_in, d_out)), axis1=<NUM_LIT:1>, axis2=<NUM_LIT:3>)<EOL>return is_identity_matrix(mat, rtol=rtol, atol=atol)<EOL>

Test if Choi-matrix is trace-preserving (TP)


def _format_state(self, state, density_matrix=False):

state = np.array(state)<EOL>shape = state.shape<EOL>ndim = state.ndim<EOL>if ndim > <NUM_LIT:2>:<EOL><INDENT>raise QiskitError('<STR_LIT>')<EOL><DEDENT>if ndim == <NUM_LIT:2>:<EOL><INDENT>if shape[<NUM_LIT:1>] != <NUM_LIT:1> and shape[<NUM_LIT:1>] != shape[<NUM_LIT:0>]:<EOL><INDENT>raise QiskitError('<STR_LIT>')<EOL><DEDENT>if shape[<NUM_LIT:1>] == <NUM_LIT:1>:<EOL><INDENT>state = np.reshape(state, shape[<NUM_LIT:0>])<EOL><DEDENT><DEDENT>if density_matrix and ndim == <NUM_LIT:1>:<EOL><INDENT>state = np.outer(state, np.transpose(np.conj(state)))<EOL><DEDENT>return state<EOL>

Format input state so it is statevector or density matrix


<EOL>if isinstance(data, QuantumChannel):<EOL><INDENT>return data<EOL><DEDENT>if hasattr(data, '<STR_LIT>'):<EOL><INDENT>return data.to_channel()<EOL><DEDENT>if hasattr(data, '<STR_LIT>'):<EOL><INDENT>return data.to_channel()<EOL><DEDENT>return Operator(data)<EOL>

Convert input into a QuantumChannel subclass object or Operator object


def __init__(self, data, input_dims=None, output_dims=None):

<EOL>if isinstance(data, (list, np.ndarray)):<EOL><INDENT>choi_mat = np.array(data, dtype=complex)<EOL>dim_l, dim_r = choi_mat.shape<EOL>if dim_l != dim_r:<EOL><INDENT>raise QiskitError('<STR_LIT>')<EOL><DEDENT>if input_dims:<EOL><INDENT>input_dim = np.product(input_dims)<EOL><DEDENT>if output_dims:<EOL><INDENT>output_dim = np.product(output_dims)<EOL><DEDENT>if output_dims is None and input_dims is None:<EOL><INDENT>output_dim = int(np.sqrt(dim_l))<EOL>input_dim = dim_l // output_dim<EOL><DEDENT>elif input_dims is None:<EOL><INDENT>input_dim = dim_l // output_dim<EOL><DEDENT>elif output_dims is None:<EOL><INDENT>output_dim = dim_l // input_dim<EOL><DEDENT>if input_dim * output_dim != dim_l:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if isinstance(data, (QuantumCircuit, Instruction)):<EOL><INDENT>data = SuperOp._instruction_to_superop(data)<EOL><DEDENT>else:<EOL><INDENT>data = self._init_transformer(data)<EOL><DEDENT>input_dim, output_dim = data.dim<EOL>choi_mat = _to_choi(data.rep, data._data, input_dim, output_dim)<EOL>if input_dims is None:<EOL><INDENT>input_dims = data.input_dims()<EOL><DEDENT>if output_dims is None:<EOL><INDENT>output_dims = data.output_dims()<EOL><DEDENT><DEDENT>input_dims = self._automatic_dims(input_dims, input_dim)<EOL>output_dims = self._automatic_dims(output_dims, output_dim)<EOL>super().__init__('<STR_LIT>', choi_mat, input_dims, output_dims)<EOL>

Initialize a quantum channel Choi matrix operator.

        Args:
            data (QuantumCircuit or
                  Instruction or
                  BaseOperator or
                  matrix): data to initialize superoperator.
            input_dims (tuple): the input subsystem dimensions.
                                [Default: None]
            output_dims (tuple): the output subsystem dimensions.
                                 [Default: None]

        Raises:
            QiskitError: if input data cannot be initialized as a
            Choi matrix.

        Additional Information
        ----------------------
        If the input or output dimensions are None, they will be
        automatically determined from the input data. If the input data is
        a Numpy array of shape (4**N, 4**N) qubit systems will be used. If
        the input operator is not an N-qubit operator, it will assign a
        single subsystem with dimension specifed by the shape of the input.


return (self._input_dim, self._output_dim, self._input_dim,<EOL>self._output_dim)<EOL>


return Choi(np.conj(self._data), self.input_dims(), self.output_dims())<EOL>

Return the conjugate of the QuantumChannel.


<EOL>d_in, d_out = self.dim<EOL>data = np.reshape(self._data, (d_in, d_out, d_in, d_out))<EOL>data = np.transpose(data, (<NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:3>, <NUM_LIT:2>))<EOL>data = np.reshape(data, (d_in * d_out, d_in * d_out))<EOL>return Choi(<EOL>data, input_dims=self.output_dims(), output_dims=self.input_dims())<EOL>

Return the transpose of the QuantumChannel.


def compose(self, other, qargs=None, front=False):

if qargs is not None:<EOL><INDENT>return Choi(<EOL>SuperOp(self).compose(other, qargs=qargs, front=front))<EOL><DEDENT>if not isinstance(other, Choi):<EOL><INDENT>other = Choi(other)<EOL><DEDENT>if front and self._input_dim != other._output_dim:<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>')<EOL><DEDENT>if not front and self._output_dim != other._input_dim:<EOL><INDENT>raise QiskitError(<EOL>'<STR_LIT>')<EOL><DEDENT>if front:<EOL><INDENT>first = np.reshape(other._data, other._bipartite_shape)<EOL>second = np.reshape(self._data, self._bipartite_shape)<EOL>input_dim = other._input_dim<EOL>input_dims = other.input_dims()<EOL>output_dim = self._output_dim<EOL>output_dims = self.output_dims()<EOL><DEDENT>else:<EOL><INDENT>first = np.reshape(self._data, self._bipartite_shape)<EOL>second = np.reshape(other._data, other._bipartite_shape)<EOL>input_dim = self._input_dim<EOL>input_dims = self.input_dims()<EOL>output_dim = other._output_dim<EOL>output_dims = other.output_dims()<EOL><DEDENT>data = np.reshape(<EOL>np.einsum('<STR_LIT>', first, second),<EOL>(input_dim * output_dim, input_dim * output_dim))<EOL>return Choi(data, input_dims, output_dims)<EOL>

Return the composition channel self∘other.

        Args:
            other (QuantumChannel): a quantum channel.
            qargs (list): a list of subsystem positions to compose other on.
            front (bool): If False compose in standard order other(self(input))
                          otherwise compose in reverse order self(other(input))
                          [default: False]

        Returns:
            Choi: The composition channel as a Choi object.

        Raises:
            QiskitError: if other cannot be converted to a channel or
            has incompatible dimensions.


if n > <NUM_LIT:0>:<EOL><INDENT>return super().power(n)<EOL><DEDENT>return Choi(SuperOp(self).power(n))<EOL>

The matrix power of the channel.

        Args:
            n (int): compute the matrix power of the superoperator matrix.

        Returns:
            Choi: the matrix power of the SuperOp converted to a Choi channel.

        Raises:
            QiskitError: if the input and output dimensions of the
            QuantumChannel are not equal, or the power is not an integer.


return self._tensor_product(other, reverse=False)<EOL>

Return the tensor product channel self ⊗ other.

        Args:
            other (QuantumChannel): a quantum channel.

        Returns:
            Choi: the tensor product channel self ⊗ other as a Choi object.

        Raises:
            QiskitError: if other cannot be converted to a channel.


return self._tensor_product(other, reverse=True)<EOL>

Return the tensor product channel other ⊗ self.

        Args:
            other (QuantumChannel): a quantum channel.

        Returns:
            Choi: the tensor product channel other ⊗ self as a Choi object.

        Raises:
            QiskitError: if other cannot be converted to a channel.


if not isinstance(other, Choi):<EOL><INDENT>other = Choi(other)<EOL><DEDENT>if self.dim != other.dim:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return Choi(self._data + other.data, self._input_dims,<EOL>self._output_dims)<EOL>

Return the QuantumChannel self + other.

        Args:
            other (QuantumChannel): a quantum channel.

        Returns:
            Choi: the linear addition self + other as a Choi object.

        Raises:
            QiskitError: if other cannot be converted to a channel or
            has incompatible dimensions.


if not isinstance(other, Choi):<EOL><INDENT>other = Choi(other)<EOL><DEDENT>if self.dim != other.dim:<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return Choi(self._data - other.data, self._input_dims,<EOL>self._output_dims)<EOL>

Return the QuantumChannel self - other.

        Args:
            other (QuantumChannel): a quantum channel.

        Returns:
            Choi: the linear subtraction self - other as Choi object.

        Raises:
            QiskitError: if other cannot be converted to a channel or
            has incompatible dimensions.


if not isinstance(other, Number):<EOL><INDENT>raise QiskitError("<STR_LIT>")<EOL><DEDENT>return Choi(other * self._data, self._input_dims, self._output_dims)<EOL>

Return the QuantumChannel self + other.

        Args:
            other (complex): a complex number.

        Returns:
            Choi: the scalar multiplication other * self as a Choi object.

        Raises:
            QiskitError: if other is not a valid scalar.


<EOL>if qargs is not None:<EOL><INDENT>return SuperOp(self)._evolve(state, qargs)<EOL><DEDENT>state = self._format_state(state, density_matrix=True)<EOL>if state.shape[<NUM_LIT:0>] != self._input_dim:<EOL><INDENT>raise QiskitError(<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>return np.einsum('<STR_LIT>', state,<EOL>np.reshape(self._data, self._bipartite_shape))<EOL>

Evolve a quantum state by the QuantumChannel.

        Args:
            state (QuantumState): The input statevector or density matrix.
            qargs (list): a list of QuantumState subsystem positions to apply
                           the operator on.

        Returns:
            DensityMatrix: the output quantum state as a density matrix.

        Raises:
            QiskitError: if the operator dimension does not match the
            specified QuantumState subsystem dimensions.


def _tensor_product(self, other, reverse=False):

<EOL>if not isinstance(other, Choi):<EOL><INDENT>other = Choi(other)<EOL><DEDENT>if reverse:<EOL><INDENT>input_dims = self.input_dims() + other.input_dims()<EOL>output_dims = self.output_dims() + other.output_dims()<EOL>data = _bipartite_tensor(<EOL>other.data,<EOL>self._data,<EOL>shape1=other._bipartite_shape,<EOL>shape2=self._bipartite_shape)<EOL><DEDENT>else:<EOL><INDENT>input_dims = other.input_dims() + self.input_dims()<EOL>output_dims = other.output_dims() + self.output_dims()<EOL>data = _bipartite_tensor(<EOL>self._data,<EOL>other.data,<EOL>shape1=self._bipartite_shape,<EOL>shape2=other._bipartite_shape)<EOL><DEDENT>return Choi(data, input_dims, output_dims)<EOL>

Return the tensor product channel.

        Args:
            other (QuantumChannel): a quantum channel.
            reverse (bool): If False return self ⊗ other, if True return
                            if True return (other ⊗ self) [Default: False
        Returns:
            Choi: the tensor product channel as a Choi object.

        Raises:
            QiskitError: if other is not a QuantumChannel subclass.