
    z	i                        S r SSKJr  SSKrSSKrSSKrSSKJr  SSK	J
r
  SSKrSSKJr  SSKJr  SSKJrJrJrJrJrJrJr  SS	KJr  SS
KJr  SSKJr  SSKJ r   SSK!J"r"  SSK#J$r$  SSK%J&r&J'r'  \
(       a  SSK(J)r)   " S S\"5      r*\$" \*5        g)z
Matrix Operator class.
    )annotationsN)Number)TYPE_CHECKING)_numpy_compat)Instruction)HGateIGateSGateTGateXGateYGateZGate)	Operation)QuantumCircuit)QiskitError)BaseOperator)LinearOp)generate_apidocs)is_unitary_matrixmatrix_equal)Layoutc                    ^  \ rS rSrSr  S%     S&U 4S jjjrS\R                  4S jrS r	U 4S jr
\S 5       r\S	 5       rS'S
 jrS r\S(S j5       rS)S*S jjr\   S+         S,S jj5       rS%S jrS-S jrS rS rS rS.S/S jjr\R6                  S-  S4   S0S jjrS1S jrS1S jr\S 5       rS'S jr S r!S%S2S jjr"S-S jr#S r$\S3S  j5       r%\S! 5       r&\S" 5       r'S'S# jr(S$r)U =r*$ )4Operator*   a  Matrix operator class

This represents a matrix operator :math:`M` that will
:meth:`~Statevector.evolve` a :class:`Statevector` :math:`|\psi\rangle`
by matrix-vector multiplication

.. math::

    |\psi\rangle \mapsto M|\psi\rangle,

and will :meth:`~DensityMatrix.evolve` a :class:`DensityMatrix` :math:`\rho`
by left and right multiplication

.. math::

    \rho \mapsto M \rho M^\dagger.

For example, the following operator :math:`M = X` applied to the zero state
:math:`|\psi\rangle=|0\rangle (\rho = |0\rangle\langle 0|)` changes it to the
one state :math:`|\psi\rangle=|1\rangle (\rho = |1\rangle\langle 1|)`:

.. plot::
   :include-source:
   :nofigs:

    >>> import numpy as np
    >>> from qiskit.quantum_info import Operator
    >>> op = Operator(np.array([[0.0, 1.0], [1.0, 0.0]]))  # Represents Pauli X operator

    >>> from qiskit.quantum_info import Statevector
    >>> sv = Statevector(np.array([1.0, 0.0]))
    >>> sv.evolve(op)
    Statevector([0.+0.j, 1.+0.j],
                dims=(2,))

    >>> from qiskit.quantum_info import DensityMatrix
    >>> dm = DensityMatrix(np.array([[1.0, 0.0], [0.0, 0.0]]))
    >>> dm.evolve(op)
    DensityMatrix([[0.+0.j, 0.+0.j],
                [0.+0.j, 1.+0.j]],
                dims=(2,))

Nc                b  > Sn[        U[        [        R                  45      (       a  [        R                  " U[
        S9U l        O[        U[        [        45      (       a!  U R                  U5      R                  U l        O[        US5      (       a.  UR                  5       nUR                  U l        UR                  nOI[        US5      (       a-  [        R                  " UR                  5       [
        S9U l        O[        S5      e[         TU ]E  UUUU R                  R$                  S9  g)a  Initialize an operator object.

Args:
    data (QuantumCircuit or Operation 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 specified by the shape of the input.
    Note that two operators initialized via this method are only considered equivalent if they
    match up to their canonical qubit order (or: permutation). See :meth:`.Operator.from_circuit`
    to specify a different qubit permutation.
Ndtypeto_operator	to_matrixz&Invalid input data format for Operator)op_shape
input_dimsoutput_dimsshape)
isinstancelistnpndarrayasarraycomplex_datar   r   _init_instructiondatahasattrr   	_op_shaper   r   super__init__r#   )selfr,   r!   r"   r    	__class__s        `/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/quantum_info/operators/operator.pyr0   Operator.__init__W   s    : dT2::.//D8DJ~y9:: //5::DJT=)) ##%DDJ~~HT;'' DNN$4GDDJFGG!#**""	 	 	
    c                v    Uc  U R                   R                  OUn[        R                  " U R                   XS9$ )N)r   copy)r,   r   r&   array)r1   r   r7   s      r3   	__array__Operator.__array__   s*    #(=		exx		::r5   c           	         Sn[        U5      S-  nU [        R                  " U R                  SUS9 SU SU R	                  5        SU R                  5        S3	$ )	Nz	Operator( z, )	separatorprefixz,
zinput_dims=z, output_dims=))lenr&   array2stringr,   r!   r"   )r1   r>   pads      r3   __repr__Operator.__repr__   sd    &kChrtyyDPQQTe;t01@P@P@R?SSTV	
r5   c                   > [         TU ]  U5      (       d  g[        R                  " U R                  UR                  U R
                  U R                  S9$ )z Test if two Operators are equal.Frtolatol)r/   __eq__r&   allcloser,   rG   rH   )r1   otherr2   s     r3   rI   Operator.__eq__   s:    w~e$${{499ejjtyytyyQQr5   c                    U R                   $ )zThe underlying Numpy array.r*   r1   s    r3   r,   Operator.data   s     zzr5   c                Z    U R                   U R                  5       U R                  5       S.$ )zReturn operator settings.)r,   r!   r"   )r*   r!   r"   rO   s    r3   settingsOperator.settings   s+     JJ//+++-
 	
r5   c                    SSK Jn  SnUc  UnUS:X  a  U R                  5       $ US:X  a  SSKJn  U" U 40 UD6$ US:X  a	  U" U 40 UD6$ US:X  a  U" U 4SS	0UD6$ [        S
U S[        U 5      R                   S35      e)a  Return a visualization of the Operator.

**repr**: String of the state's ``__repr__``.

**text**: ASCII TextMatrix that can be printed in the console.

**latex**: An IPython Latex object for displaying in Jupyter Notebooks.

**latex_source**: Raw, uncompiled ASCII source to generate array using LaTeX.

Args:
    output (str): Select the output method to use for drawing the
        state. Valid choices are `repr`, `text`, `latex`, `latex_source`,
        Default is `repr`.
    drawer_args: Arguments to be passed directly to the relevant drawing
        function or constructor (`TextMatrix()`, `array_to_latex()`).
        See the relevant function under `qiskit.visualization` for that function's
        documentation.

Returns:
    :class:`str` or :class:`TextMatrix` or :class:`IPython.display.Latex`:
    Drawing of the Operator.

Raises:
    ValueError: when an invalid output method is selected.
    MissingOptionalLibrary: If SymPy isn't installed and ``'latex'`` or
        ``'latex_source'`` is selected for ``output``.

r   )array_to_latexreprtext)
TextMatrixlatexlatex_sourcesourceT'z$' is not a valid option for drawing zM objects.
            Please choose from: 'text', 'latex', or 'latex_source'.)qiskit.visualizationrU   rC   (qiskit.visualization.state_visualizationrX   
ValueErrortype__name__)r1   outputdrawer_argsrU   default_outputrX   s         r3   drawOperator.draw   s    > 	8>#FV==?"vKd2k22w!$6+66~%!$CtC{CC fXA$t*BUBUAV WD G r5   c                    U R                  5       n[        U[        5      (       a  [        U5        g SSKJn  U" U5        g )Nr   )display)re   r$   strprintIPython.displayrh   )r1   outrh   s      r3   _ipython_display_Operator._ipython_display_   s+    iikc3#J/CLr5   c                   [        5       R                  5       [        5       R                  5       [        5       R                  5       [	        5       R                  5       [        5       R                  5       [        5       R                  5       [        5       R                  5       [        R                  " SS/SS//[        S9[        R                  " SS/SS//[        S9[        R                  " SS/SS//[        S9[        R                  " SS/SS//[        S9[        R                  " SS/SS//[        S9[        R                  " SS/SS//[        S9S.n[        R                  " S	U5      c  [        S
5      e[        U5      n[        [        R                   " SU-  [        S95      n[#        [%        U5      5       H   u  pVUS:w  d  M  UR'                  X&   U/S9nM"     U$ )a=  Return a tensor product of single-qubit operators.

Args:
    label (string): single-qubit operator string.

Returns:
    Operator: The N-qubit operator.

Raises:
    QiskitError: if the label contains invalid characters, or the
                 length of the label is larger than an explicitly
                 specified num_qubits.

Additional Information:
    The labels correspond to the single-qubit matrices:
    'I': [[1, 0], [0, 1]]
    'X': [[0, 1], [1, 0]]
    'Y': [[0, -1j], [1j, 0]]
    'Z': [[1, 0], [0, -1]]
    'H': [[1, 1], [1, -1]] / sqrt(2)
    'S': [[1, 0], [0 , 1j]]
    'T': [[1, 0], [0, (1+1j) / sqrt(2)]]
    '0': [[1, 0], [0, 0]]
    '1': [[0, 0], [0, 1]]
    '+': [[0.5, 0.5], [0.5 , 0.5]]
    '-': [[0.5, -0.5], [-0.5 , 0.5]]
    'r': [[0.5, -0.5j], [0.5j , 0.5]]
    'l': [[0.5, 0.5j], [-0.5j , 0.5]]
   r   r   g      ?g      y             y              ?)IXYZHST01+-rlz^[IXYZHST01rl\-+]+$z"Label contains invalid characters.   rq   qargs)r	   r   r   r   r   r   r
   r   r&   r8   r)   rematchr   r@   r   eye	enumeratereversedcompose)clslabel
label_mats
num_qubitsopqubitchars          r3   
from_labelOperator.from_label   s   B ""$""$""$""$""$""$""$Aq6Aq6*':Aq6Aq6*':C:Sz2'BC;s4GDC<$5WEC;5WE

 88*E2:BCCZ
bffQ
]':;$Xe_5KEs{ZZ
 0Z@ 6 	r5   Fc           	     P  ^ ^^^^ [         R                  " U5      nT R                  R                  5       m[	        T5      mT R                  R                  5       m[	        T5      mU(       a  [	        U5      T:w  a  [        S5      eT R                  R                  5       n[        UU4S j[        U5       5       5      n[        S [        T R                  R                  5       5       5      n[        U 4S j[         R                  " USSS2   5      SSS2    5       5      nT R                  R                  5       n[        UU4S j[        U5       5       5      n	O[	        U5      T:w  a  [        S5      e[        UU4S j[        U5       5       5      nT R                  R                  5       n[        [         R                  " USSS2   5      SSS2   5      n[        U 4S	 j[        T R                  R                  5       5       5      n[        UU4S
 j[        U5       5       5      nT R                  R                  5       n	XE-   n
Xg-   nT R                  R                  U
5      R                  U5      R                  T R                  R                  5      n[!        XUS9nU$ )a  Modifies operator's data by composing it with a permutation.

Args:
    perm (list): permutation pattern, describing which qubits
        occupy the positions 0, 1, 2, etc. after applying the permutation.
    front (bool): When set to ``True`` the permutation is applied before the
        operator, when set to ``False`` the permutation is applied after the
        operator.
Returns:
    Operator: The modified operator.

Raises:
    QiskitError: if the size of the permutation pattern does not match the
        dimensions of the operator.
zNThe size of the permutation pattern does not match dimensions of the operator.c              3  :   >#    U  H  nTTU-
  S -
     v   M     g7frp   N .0nn_dims_rraw_shape_rs     r3   	<genexpr>-Operator.apply_permutation.<locals>.<genexpr>W  s     R>aK1q(89>   c              3  $   #    U  H  ov   M     g 7fNr   )r   xs     r3   r   r   Z  s     I&H1&Hs   c              3  V   >#    U  H  nTR                   R                  U-   v   M      g 7fr   r.   _num_qargs_lr   r   r1   s     r3   r   r   [  s"     cDbq4>>66:Db   &)Nc              3  :   >#    U  H  nTTU-
  S -
     v   M     g7fr   r   r   s     r3   r   r   _  s!     ZGY!HqL1,< =GYr   c              3  :   >#    U  H  nTTU-
  S -
     v   M     g7fr   r   r   r   n_dims_lraw_shape_ls     r3   r   r   k  s!     VCUaK1q(89CUr   c              3  V   >#    U  H  nTR                   R                  U-   v   M      g 7fr   r   r   s     r3   r   r   p  s$      9[A++a/9[r   c              3  :   >#    U  H  nTTU-
  S -
     v   M     g7fr   r   r   s     r3   r   r   u  s     V~!HqL1,< =~r   )r!   r"   )r&   argsortr.   dims_lr@   dims_rr   tupler   ranger   _num_qargs_rr*   reshape	transposer#   r   )r1   permfrontinv_permshape_lshape_raxes_laxes_rnew_shape_lnew_shape_rsplit_shape
axes_ordernew_matnew_opr   r   r   r   s   `             @@@@r3   apply_permutationOperator.apply_permutation2  s(   ( ::d#nn++-{#nn++-{# 4yH$!d 
 nn++-GR8D>RRG IeDNN,G,G&HIIFcRZZPTUYWYUYPZE[]a_a]aDbccF ..//1KZxPXGYZZK 4yH$!d 
 V8HCUVVGnn++-G BJJx"~6"=>F 9>t~~?Z?Z9[ F
  VxPT~VVK..//1K '_
JJ{+55jAII$..J^J^_ 	 '{Sr5   c           	        Uc  U(       d  [        USS5      nO5SSKJn  U" U[        UR                  5       VVs0 s H  u  pgXv_M	     snnS9nUb  UR
                  OSnUc  U(       d  Ub  [        USS5      nSSKJn	  [        U5      n
Ub  S/[        UR                  5      -  nUR                  R                  5        H	  u  pXU'   M     UR                  U5      nU	" U5      nU
R                  US5      n
Ub5  UR                  UR                  5      nU	" U5      nU
R                  US	5      n
U
R                  US	5      n
U
$ Ub5  UR                  UR                  5      nU	" U5      nU
R                  US	5      n
U
$ s  snnf )
a  Create a new Operator object from a :class:`.QuantumCircuit`

While a :class:`~.QuantumCircuit` object can passed directly as ``data``
to the class constructor this provides no options on how the circuit
is used to create an :class:`.Operator`. This constructor method lets
you control how the :class:`.Operator` is created so it can be adjusted
for a particular use case.

By default this constructor method will permute the qubits based on a
configured initial layout (i.e. after it was transpiled). It also
provides an option to manually provide a :class:`.Layout` object
directly.

Args:
    circuit (QuantumCircuit): The :class:`.QuantumCircuit` to create an Operator
        object from.
    ignore_set_layout (bool): When set to ``True`` if the input ``circuit``
        has a layout set it will be ignored
    layout (Layout): If specified this kwarg can be used to specify a
        particular layout to use to permute the qubits in the created
        :class:`.Operator`. If this is specified it will be used instead
        of a layout contained in the ``circuit`` input. If specified
        the virtual bits in the :class:`~.Layout` must be present in the
        ``circuit`` input.
    final_layout (Layout): If specified this kwarg can be used to represent the
        output permutation caused by swap insertions during the routing stage
        of the transpiler.
Returns:
    Operator: An operator representing the input circuit
N_layoutr   )TranspileLayout)initial_layoutinput_qubit_mappingfinal_layout)_inverse_patternTF)getattrqiskit.transpiler.layoutr   r   qubitsr   .qiskit.synthesis.permutation.permutation_utilsr   r   r@   r   itemsto_permutationr   )r   circuitignore_set_layoutlayoutr   r   indexr   r   r   r   input_qubitsqpinitial_permutationinitial_permutation_inversefinal_permutationfinal_permutation_inverses                     r3   from_circuitOperator.from_circuit  s   N >$ )T:@$%FOPWP^P^F_$`F_leU\F_$`F
 392D..$$);&v~tDSg% 6C(B(B$CCL2288:"#Q ; #1"?"?"M*:;N*O'%%&94@B'$0$?$?$O!,<=N,O)))*CUK%%&A5IB 	 % , ; ;GNN K(89J(K%%%&?GB	A %as   E>c                f    Uc  U R                   nUc  U R                  n[        U R                  X!S9$ )z,Return True if operator is a unitary matrix.rF   )rH   rG   r   r*   )r1   rH   rG   s      r3   
is_unitaryOperator.is_unitary  s/    <99D<99D $BBr5   c                    U $ )z)Convert operator to matrix operator classr   rO   s    r3   r   Operator.to_operator  s    r5   c                2    SSK Jn  U" U R                  5      $ )z%Convert to a UnitaryGate instruction.r   )UnitaryGate)0qiskit.circuit.library.generalized_gates.unitaryr   r,   )r1   r   s     r3   to_instructionOperator.to_instruction  s     	Q499%%r5   c                |    [         R                  " U 5      n[        R                  " U R                  5      Ul        U$ r   )_copyr7   r&   conjr*   r1   rets     r3   	conjugateOperator.conjugate  s)    jjGGDJJ'	
r5   c                    [         R                  " U 5      n[        R                  " U R                  5      Ul        U R
                  R                  5       Ul        U$ r   )r   r7   r&   r   r*   r.   r   s     r3   r   Operator.transpose  s=    jjLL,	002
r5   c           	     :   Uc  [        USS 5      n[        U[        5      (       d  [        U5      nU R                  R	                  UR                  X#5      nUR                  5       nUR                  5       nUcr  U(       a,  [        R                  " U R                  UR                  5      nO+[        R                  " UR                  U R                  5      n[        XuU5      nXHl        U$ U R                  R                  u  pU(       a  U
nU	nSnOU	nSnSn[        R                  " U R                  U R                  R                  5      n[        R                  " UR                  UR                  R                  5      nU Vs/ s H  nUS-
  U-
  PM     nn[        [        R                  " U5      5      [        [        R                  " U5      5      /n[        R                  " [        R!                  XUX5      U5      n[        XuU5      nXHl        U$ s  snf )Nr   Tr   Frp   )r   r$   r   r.   r   r   r   r&   dotr*   r,   	num_qargsr   tensor_shapeintprod_einsum_matmul)r1   rK   r   r   	new_shaper!   r"   r,   r   num_qargs_lnum_qargs_rnum_indicesshift	right_multensormatr   indicesfinal_shapes                      r3   r   Operator.compose  s   =E7D1E%**UOE NN**5??EI	%%'
&&( =vvdjj%**5 vvejj$**54[9C%MJ $(>>#;#; %KEI%KEI DIIt~~'B'BCjjU__%A%AB8=>u;?U*>277;/0#bggj6I2JKzz##F%K[
 t5!
 ?s   Hg-q=c                v   U R                  5       U R                  5       :w  a  [        S5      e[        R                  " U 5      n[        U[        5      (       a1  [        R                  R                  U R                  U5      Ul        U$ SSKnU(       a  UR                  R                  [        R                  " SU* 5      U R                  -  SS9u  pgUR!                  5       nU V	s/ s H  n	[#        X5      PM     n
n	U[        R$                  " U
5      -  UR'                  5       R(                  -  n[        R                  " SX!-  5      U-  Ul        U$ [        R                  " SX!-  5      UR                  R+                  [        R                  " SU* 5      U R                  -  U5      -  Ul        U$ s  sn	f )aP	  Return the matrix power of the operator.

Non-integer powers of operators with an eigenvalue whose complex phase is :math:`\pi` have
a branch cut in the complex plane, which makes the calculation of the principal root around
this cut subject to precision / differences in BLAS implementation.  For example, the square
root of Pauli Y can return the :math:`\pi/2` or :math:`-\pi/2` Y rotation depending on
whether the -1 eigenvalue is found as ``complex(-1, tiny)`` or ``complex(-1, -tiny)``. Such
eigenvalues are really common in quantum information, so this function first phase-rotates
the input matrix to shift the branch cut to a far less common point.  The underlying
numerical precision issues around the branch-cut point remain, if an operator has an
eigenvalue close to this phase.  The magnitude of this rotation can be controlled with the
``branch_cut_rotation`` parameter.

The choice of ``branch_cut_rotation`` affects the principal root that is found.  For
example, the square root of :class:`.ZGate` will be calculated as either :class:`.SGate` or
:class:`.SdgGate` depending on which way the rotation is done::

    from qiskit.circuit import library
    from qiskit.quantum_info import Operator

    z_op = Operator(library.ZGate())
    assert z_op.power(0.5, branch_cut_rotation=1e-3) == Operator(library.SGate())
    assert z_op.power(0.5, branch_cut_rotation=-1e-3) == Operator(library.SdgGate())

Args:
    n (float): the power to raise the matrix to.
    branch_cut_rotation (float): The rotation angle to apply to the branch cut in the
        complex plane.  This shifts the branch cut away from the common point of :math:`-1`,
        but can cause a different root to be selected as the principal root.  The rotation
        is anticlockwise, following the standard convention for complex phase.
    assume_unitary (bool): if ``True``, the operator is assumed to be unitary. In this case,
        for fractional powers we employ a faster implementation based on Schur's decomposition.

Returns:
    Operator: the resulting operator ``O ** n``.

Raises:
    QiskitError: if the input and output dimensions of the operator
                 are not equal.

.. note::
    It is only safe to set the argument ``assume_unitary`` to ``True`` when the operator
    is unitary (or, more generally, normal). Otherwise, the function will return an
    incorrect output.
z-Can only power with input_dims = output_dims.r   Nrp   r)   )rb   )r!   r"   r   r   r7   r$   r   r&   linalgmatrix_powerr,   r*   scipy.linalgschurcmathrectdiagonalpowdiagr   rw   fractional_matrix_power)r1   r   branch_cut_rotationassume_unitaryr   scipydecompositionunitarydecomposition_diagonalelementdecomposition_powerunitary_powers               r3   powerOperator.power$  sy   ` ?? 0 0 22MNNjja		..tyy!<CI* 
'   */););JJq#6"67$))CI *< *& *7)?)?)A&F\&]F\7s7F\#&] '"''2E*F FIYIY Y!JJq*=*AB]R	 
 "JJ*.LL88JJq#6"67$))CQ	 
 '^s   (F6c                d    [        U[        5      (       d  [        U5      nU R                  X5      $ r   r$   r   _tensorr1   rK   s     r3   r   Operator.tensoro  s'    %**UOE||D((r5   c                d    [        U[        5      (       d  [        U5      nU R                  X5      $ r   r  r  s     r3   expandOperator.expandt  s'    %**UOE||E((r5   c                    [         R                  " U5      nUR                  R                  UR                  5      Ul        [        R
                  " UR                  UR                  5      Ul        U$ r   )r   r7   r.   r   r&   kronr,   r*   )r   abr   s       r3   r  Operator._tensory  sH    jjm**1;;7GGAFFAFF+	
r5   c                J   SSK Jn  Uc  [        USS5      n[        U[        5      (       d  [	        U5      nU R
                  R                  UR
                  U5        UR                  XU5      n[        R                  " U 5      nU R                  UR                  -   Ul        U$ )a  Return the operator self + other.

If ``qargs`` are specified the other operator will be added
assuming it is identity on all other subsystems.

Args:
    other (Operator): an operator object.
    qargs (None or list): optional subsystems to add on
                          (Default: None)

Returns:
    Operator: the operator self + other.

Raises:
    QiskitError: if other is not an operator, or has incompatible
                 dimensions.
r   ScalarOpNr   )'qiskit.quantum_info.operators.scalar_opr'  r   r$   r   r.   _validate_add_pad_with_identityr   r7   r,   r*   )r1   rK   r   r'  r   s        r3   _addOperator._add  s    & 	E=E7D1E%**UOE$$U__e<++D?jjII

*	
r5   c                    [        U[        5      (       d  [        S5      e[        R                  " U 5      nXR
                  -  Ul        U$ )zReturn 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.
zother is not a number)r$   r   r   r   r7   r*   )r1   rK   r   s      r3   	_multiplyOperator._multiply  s>     %((566jjJJ&	
r5   c                   [        U[        5      (       d   [        U5      nU R                  UR                  :w  a  gUc  U R                  nUc  U R
                  n[        U R                  UR                  SX#S9$ ! [         a     gf = f)a,  Return True if operators are equivalent up to global phase.

Args:
    other (Operator): an operator object.
    rtol (float): relative tolerance value for comparison.
    atol (float): absolute tolerance value for comparison.

Returns:
    bool: True if operators are equivalent up to global phase.
FT)ignore_phaserG   rH   )r$   r   r   dimrH   rG   r   r,   )r1   rK   rG   rH   s       r3   equivOperator.equiv  s}     %**  88uyy <99D<99DDIIuzz4[[  s   A; ;
BBc                  ^ [         R                  " U 5      n[        [        U R                  R
                  S-
  SS5      5      mT[        U4S jT 5       5      -   m[        R                  " [        R                  " [        R                  " U R                  U R                  R                  5      T5      U R                  R                  5      Ul        U R                  R                  5       Ul        U$ )ac  Return an Operator with reversed subsystem ordering.

For a tensor product operator this is equivalent to reversing
the order of tensor product subsystems. For an operator
:math:`A = A_{n-1} \otimes ... \otimes A_0`
the returned operator will be
:math:`A_0 \otimes ... \otimes A_{n-1}`.

Returns:
    Operator: the operator with reversed subsystem order.
rp   r   c              3  @   >#    U  H  n[        T5      U-   v   M     g 7fr   )r@   )r   iaxess     r3   r   )Operator.reverse_qargs.<locals>.<genexpr>  s     84aCIM4s   )r   r7   r   r   r.   r   r&   r   r   r,   r   r#   r*   reverse)r1   r   r8  s     @r3   reverse_qargsOperator.reverse_qargs  s     jjU4>>66:BCDe84888JJLLDIIt~~/J/JKTRNN  
	 ..0
r5   c                    U R                   $ )z!Convert operator to NumPy matrix.)r,   rO   s    r3   r   Operator.to_matrix  s    yyr5   c                   UR                   nUR                   nUS-  S:w  a  [        S5      e[        [        U5      5      n[	        U5       H  u  pXi-   XU-   '   M     [        [        [        Xf[        U5      -   5      5      5      n[        U5       V
s/ s H  oU-   PM	     nn
U(       a  X-   nOX-   n[        R                  " XX-5      $ s  sn
f )a)  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 indices 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.
r~   r   z6Contracted matrix must have an even number of indices.)	ndimr   r%   r   r   r   r@   r&   einsum)r   r   r   r   r   r   rankrank_matindices_tensorjr   mat_contractmat_freeindices_mats                 r3   r   Operator._einsum_matmul  s    $ {{88a<1VWWeDk*!'*HA,0HN5=) + HU4G1D%EFG/7/@A/@eEM/@A&1K"1KyyBB Bs   Cc                4   [        US5      (       a"  [        [        R                  " U[        S95      $ SUR
                  -  n[        [        R                  " U5      5      n[        U[        5      (       a  UR                  5       nUR                  U5        U$ )z5Convert a QuantumCircuit or Operation to an Operator.r9   r   r~   )r-   r   r&   r8   r)   r   r   r$   r   r   _append_instruction)r   instruction	dimensionr   s       r3   r+   Operator._init_instruction	  sx     ;,,BHH[@AA{---	bffY'(k>22%446K
{+	r5   c                    SSK Jn  SSKJn  [	        U[
        X#45      (       d  [        S5      eSn[        US5      (       a   UR                  5       nU$ U$ ! [         a     U$ f = f)z=Return Operator for instruction if defined or None otherwise.r   )Clifford)AnnotatedOperationz=Input is neither Instruction, Clifford or AnnotatedOperation.Nr   )	qiskit.quantum_inforP  "qiskit.circuit.annotated_operationrQ  r$   r   r   r-   r   )r   objrP  rQ  r   s        r3   _instruction_to_matrixOperator._instruction_to_matrix  sn     	1I#XJKK]^^3$$mmo 
s
  
s   A 
A%$A%c                   SSK Jn  SSKJn  U R	                  U5      nUb!  U R                  XRS9nUR                  U l        g[        X5      (       a  gUR                  c  [        SUR                   35      e[        UR                  [        5      (       d/  [        SUR                   S	[        UR                  5       S
35      eUR                  R                  (       ak  SUR                  -  nU R                  U" U[         R"                  " S[%        UR                  R                  5      -  5      5      US9nUR                  U l        UR                  nUR&                  UR(                  4 V	V
Vs0 s H  n	[+        U	5        H  u  pX_M	     M     nn
n	nU H  nUR(                  (       a"  [        SUR,                  R                   35      eUc  UR&                   Vs/ s H  oU   PM	     nnO UR&                   Vs/ s H	  oX      PM     nnU R/                  UR,                  US9  M     gs  snn
n	f s  snf s  snf )z4Update the current Operator by apply an instruction.r   )Barrierrp   r&  Nr   zCannot apply Operation: zOperation "z" definition is z but expected QuantumCircuit.r~   y              ?z,Cannot apply operation with classical bits: )qiskit.circuit.barrierrX  	scalar_opr'  rU  r   r,   r*   r$   
definitionr   namer   r`   global_phaser   r&   expfloatr   clbitsr   	operationrK  )r1   rT  r   rX  r'  r   r   rM  
flat_instrbitsr   bitbit_indicesrL  tup	new_qargss                   r3   rK  Operator._append_instruction0  s   2'))#.? c/BDJ%%
 ~~%!$<SXXJ"GHHcnnn==!!#(( ,%%)#..%9$::WY  ~~**s~~-	\\YrE#..:U:U4V/V(WX "   WW
J (..
0A0ABBD"+D/JE 
"1 B    *%%%'116679 
 ==H=O=O P=OcS!1=OI PIDODVDV WDVS{'7!8DVI W(()>)>i(P  * !Q Ws   4!H2"H9H>rN   )NN)r,   z6QuantumCircuit | Operation | BaseOperator | np.ndarrayr!   tuple | Noner"   ri  r   )r   ri   returnr   )F)r   r%   r   boolrj  r   )FNN)
r   r   r   rk  r   Layout | Noner   rl  rj  r   )rj  r   )NF)rK   r   r   zlist | Noner   rk  rj  r   )r   r_  rj  r   )rK   r   rj  r   )rK   r   rG   float | NonerH   rm  rj  rk  )r   F)+ra   
__module____qualname____firstlineno____doc__r0   r   COPY_ONLY_IF_NEEDEDr9   rC   rI   propertyr,   rR   re   rm   classmethodr   r   r   r   r   r   r   r   r   r  pir  r   r  r  r+  r.  r3  r;  r   r   r+   rU  rK  __static_attributes____classcell__)r2   s   @r3   r   r   *   s   *^ $($(	>
D>
 !>
 "	>
 >
@ #)J)J ;
R   
 
7r 6 6pM^  #( $&*NN  N 	N
 $N 
N N`C&0f -2HHu,<UII	IV)
)
   D$\0,  C  CD    .1Q 1Qr5   r   )+rq  
__future__r   r  r7   r   r   numbersr   typingr   numpyr&   qiskitr   qiskit.circuit.instructionr   %qiskit.circuit.library.standard_gatesr   r	   r
   r   r   r   r   qiskit.circuit.operationr   qiskit.circuit.quantumcircuitr   qiskit.exceptionsr   +qiskit.quantum_info.operators.base_operatorr   'qiskit.quantum_info.operators.linear_opr   $qiskit.quantum_info.operators.mixinsr   (qiskit.quantum_info.operators.predicatesr   r   r   r   r   r   r5   r3   <module>r     sf    #   	       2 a a a . 8 ) D < A T/wQx wQv  r5   