
    z	iMO                        S r SSKJr  SSKrSSK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  SS
KJrJr  SSKJr  SSKJr   " S S\	\5      r\" \5        g)z
CNOTDihedral operator class.
    )annotationsN)QiskitError)BaseOperator)Operator)Pauli)ScalarOp)generate_apidocsAdjointMixin)QuantumCircuitInstruction   )_append_circuit)SpecialPolynomialc                    ^  \ rS rSrSr   S     SU 4S jjjr\S 5       r\S 5       rS r	S r
S rS	 rS
 rS rS rS rS rS rS rS rS S jrS rS!S jr S"       S#S jjrS$S jrS%S jrS%S jrS rS rS rS rSr U =r!$ )&CNOTDihedral   a  An N-qubit operator from the CNOT-Dihedral group.

 The CNOT-Dihedral group is generated by the quantum gates,
 :class:`~qiskit.circuit.library.CXGate`, :class:`~qiskit.circuit.library.TGate`,
 and :class:`~qiskit.circuit.library.XGate`.

 **Representation**

 An :math:`N`-qubit CNOT-Dihedral operator is stored as an affine function and a
 phase polynomial, based on the convention in references [1, 2].

 The affine function consists of an :math:`N \times N` invertible binary matrix,
 and an :math:`N` binary vector.

 The phase polynomial is a polynomial of degree at most 3,
 in :math:`N` variables, whose coefficients are in the ring Z_8 with 8 elements.

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

     from qiskit import QuantumCircuit
     from qiskit.quantum_info import CNOTDihedral

     circ = QuantumCircuit(3)
     circ.cx(0, 1)
     circ.x(2)
     circ.t(1)
     circ.t(1)
     circ.t(1)
     elem = CNOTDihedral(circ)

     # Print the CNOTDihedral element
     print(elem)

.. code-block:: text

    phase polynomial =
    0 + 3*x_0 + 3*x_1 + 2*x_0*x_1
    affine function =
     (x_0,x_0 + x_1,x_2 + 1)


**Circuit Conversion**

 CNOTDihedral operators can be initialized from circuits containing *only* the
 following gates: :class:`~qiskit.circuit.library.IGate`,
 :class:`~qiskit.circuit.library.XGate`, :class:`~qiskit.circuit.library.YGate`,
 :class:`~qiskit.circuit.library.ZGate`,
 :class:`~qiskit.circuit.library.TGate`, :class:`~qiskit.circuit.library.TdgGate`
 :class:`~qiskit.circuit.library.SGate`, :class:`~qiskit.circuit.library.SdgGate`,
 :class:`~qiskit.circuit.library.CXGate`, :class:`~qiskit.circuit.library.CZGate`,
 :class:`~qiskit.circuit.library.CSGate`, :class:`~qiskit.circuit.library.CSdgGate`,
 :class:`~qiskit.circuit.library.SwapGate`, :class:`~qiskit.circuit.library.CCZGate`.
 They can be converted back into a :class:`~qiskit.circuit.QuantumCircuit`,
 or :class:`~qiskit.circuit.Gate` object using the :meth:`~CNOTDihedral.to_circuit`
 or :meth:`~CNOTDihderal.to_instruction` methods respectively. Note that this
 decomposition is not necessarily optimal in terms of number of gates
 if the number of qubits is more than two.

 CNOTDihedral operators can also be converted to
 :class:`~qiskit.quantum_info.Operator` objects using the
 :meth:`to_operator` method. This is done via decomposing to a circuit,
 and then simulating the circuit as a unitary operator.

 References:
     1. Shelly Garion and Andrew W. Cross, *Synthesis of CNOT-Dihedral circuits
        with optimal number of two qubit gates*, `Quantum 4(369), 2020
        <https://quantum-journal.org/papers/q-2020-12-07-369/>`_
     2. Andrew W. Cross, Easwar Magesan, Lev S. Bishop, John A. Smolin and Jay M. Gambetta,
        *Scalable randomized benchmarking of non-Clifford gates*,
        npj Quantum Inf 2, 16012 (2016).
c                  > U(       a  X l         [        U R                   5      U l        [        R                  " U R                   [        R
                  S9U l        [        R                  " U R                   [        R
                  S9U l        GO+[        U[        5      (       a5  UR                  U l        UR                  U l        UR                  U l        GO[        U[        5      (       a  UR                  5       (       a'  [        UR                  5      S1:w  d  UR                  c  [!        S5      eUR                  U l         [        U R                   5      U l        [        R                  " U R                   [        R
                  S9U l        [        R                  " U R                   [        R
                  S9U l        O[        U["        [$        45      (       aV  UR                  U l         U R'                  U5      nUR                  U l        UR                  U l        UR                  U l        O[        U[(        5      (       ad  UR                  U l         U R'                  UR+                  5       5      nUR                  U l        UR                  U l        UR                  U l        O[!        S5      e[,        TU ]]  U R                   S9  U(       a!  U R1                  5       (       d  [!        S5      egg)a  Initialize a CNOTDihedral operator object.

Args:
    data (CNOTDihedral or QuantumCircuit or ~qiskit.circuit.Instruction):
        Optional, operator to initialize.
    num_qubits (int): Optional, initialize an empty CNOTDihedral operator.
    validate (bool): if True, validates the CNOTDihedral element.

Raises:
    QiskitError: if the type is invalid.
    QiskitError: if validate=True and the CNOTDihedral element is invalid.
dtype   Nz3Can only initialize from N-qubit identity ScalarOp.z*Invalid input type for CNOTDihedral class.
num_qubitszInvalid CNOTDihedral element.)_num_qubitsr   polynpeyeint8linearzerosshift
isinstancer   r   
is_unitaryset_input_dimsr   r   r   r   _from_circuitr   to_instructionsuper__init__	_is_valid)selfdatar   validateelem	__class__s        i/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/quantum_info/operators/dihedral/dihedral.pyr(   CNOTDihedral.__init__j   s   & ))$*:*:;DI&&!1!1ADK$"2"2"''BDJ l++++DKDJ		DI h''??$$D,<,<(=!(DH_!"WXX#D)$*:*:;DI&&!1!1ADK$"2"2"''BDJ ~{;<<#D%%d+D		DI++DKDJe$$#D%%d&9&9&;<D		DI++DKDJ JKK 	D$4$45 DNN,,=>> -8    c                    g)z,Unique string identifier for operation type.cnotdihedral r*   s    r/   nameCNOTDihedral.name   s     r1   c                    g)zNumber of classical bits.r   r4   r5   s    r/   
num_clbitsCNOTDihedral.num_clbits   s     r1   c                \    [         R                  " [         R                  " X5      S5      nU$ )z)Compute product of two n x n z2 matrices.r   r   moddot)r*   leftrightprods       r/   	_z2matmulCNOTDihedral._z2matmul   s     vvbffT)1-r1   c                \    [         R                  " [         R                  " X5      S5      nU$ )z.Compute mat*vec of n x n z2 matrix and vector.r   r<   )r*   matvecrA   s       r/   _z2matvecmulCNOTDihedral._z2matvecmul   s     vvbffS&*r1   c                v   U R                   UR                   :w  a  [        S5      e[        U R                   S9n[        U R	                  U R
                  UR                  5      U R                  5       Vs/ s H  o3S   US   -   S-  PM     snUl        U R                  U R
                  UR
                  5      Ul        / n[        U R                   5       H  n[        R                  " U R                   5      [        R                  " UR
                  U   5         n[        U R                   5      nUR                  U5        UR                  U   S:X  a  SU-  nUR                  S-   S-  Ul        UR                  U5        M     UR                   U R                   R#                  U5      -   Ul        U$ s  snf )z!Left multiplication self * other.-Multiplication on different number of qubits.r   r   r   r      r   r   r   ziprG   r   r    rB   ranger   arangenonzeror   set_pjweight_0appendr   evaluater*   otherresultxnew_varsisupportr   s           r/   _dotCNOTDihedral._dot   sW   ??e...MNN9'*4+<+<T[[%+++VX\XbXb'c
'c!qTAaD[A'c
 t{{ELLAt'Aii0ELLO1LMG$T__5DKK {{1~"Dy!%!2a 7OOD! ( jj499#5#5h#??!
   5F6c                v   U R                   UR                   :w  a  [        S5      e[        U R                   S9n[        U R	                  UR
                  U R                  5      UR                  5       Vs/ s H  o3S   US   -   S-  PM     snUl        U R                  UR
                  U R
                  5      Ul        / n[        U R                   5       H  n[        R                  " UR                   5      [        R                  " U R
                  U   5         n[        U R                   5      nUR                  U5        U R                  U   S:X  a  SU-  nUR                  S-   S-  Ul        UR                  U5        M     U R                   UR                   R#                  U5      -   Ul        U$ s  snf )z"Right multiplication other * self.rJ   r   r   r   r   rK   rL   rM   rV   s           r/   _composeCNOTDihedral._compose   sY   ??e...MNN9'*4+<+<U\\4::+VX]XcXc'd
'd!qTAaD[A'd
 u||T[[At'Aii 0 01"**T[[^2LMG$T__5DKK zz!}!Dy!%!2a 7OOD! ( ii%**"5"5h"??!
r_   c                   [        U[        5      =(       au    U R                  UR                  :H  =(       aU    U R                  UR                  :H  R	                  5       =(       a'    U R
                  UR
                  :H  R	                  5       $ )zTest equality.)r!   r   r   r   allr    r*   rW   s     r/   __eq__CNOTDihedral.__eq__   sf     ul+ 2		UZZ'2,1132 u{{*//1		
r1   c                <   SUs=::  a  U R                   :  a  O  OSUs=::  a  U R                   :  d  O  [        S5      eU R                  U   U R                  U   -   S-  U R                  U'   U R                  U   U R                  U   -   S-  U R                  U'   g)zHApply a CX gate to this element.
Left multiply the element by CX(i, j).
r   zCX qubits are out of bounds.r   N)r   r   r   r    )r*   r[   js      r/   
_append_cxCNOTDihedral._append_cx   s    
 A''qA/G/G<==++a.4;;q>9Q>AAA6!;

1r1   c                `   SUs=::  a  U R                   :  d  O  [        S5      eU R                  U   S:X  a  SU-  S-  n[        R                  " U R                   5      [        R
                  " U R                  U   5         n[        R                  " US5      n[        R                  " US5      nU HA  nU R                  R                  U/5      nU R                  R                  U/Xq-   S-  5        MC     U HU  nU R                  R                  [        U5      5      nU R                  R                  [        U5      USU-  -   S-  5        MW     U HU  nU R                  R                  [        U5      5      nU R                  R                  [        U5      US	U-  -   S-  5        MW     g
)zNApply an k-th power of T to this element.
Left multiply the element by T_i^k.
r   zphase qubit out of bounds.r      rL   r         N)r   r   r    r   rP   rQ   r   	itertoolscombinationsr   get_termset_termlist)r*   kr[   r\   	subsets_2	subsets_3ri   values           r/   _append_phaseCNOTDihedral._append_phase  sZ    A'':;;::a=AQ!A ))DOO,RZZA-GH**7A6	**7A6	AII&&s+EIIsUY!O4  AII&&tAw/EIItAwa1(<=  AII&&tAw/EIItAwQ!(;< r1   c                    SUs=::  a  U R                   :  d  O  [        S5      eU R                  U   S-   S-  U R                  U'   g)z<Apply X to this element.
Left multiply the element by X(i).
r   zX qubit out of bounds.r   r   N)r   r   r    )r*   r[   s     r/   	_append_xCNOTDihedral._append_x!  s@     A''677A*a/

1r1   c                   SnU[        U R                  5      -  nUS-  nUS-  n[        U R                  5       H  nSn[        U R                  5       HH  nU R                  U   U   S:w  d  M  U(       a  US[        U5      -   -  nM5  US[        U5      -   -  nSnMJ     U R
                  U   S:w  a  US	-  nX R                  S
-
  :w  d  M  US-  nM     US-  nU$ )z'Return formatted string representation.zphase polynomial = 
z
affine function = 
z (Fr   z + x_x_Tz + 1r   ,z)
)strr   rO   r   r   r    )r*   outrowwrotecols        r/   __str__CNOTDihedral.__str__)  s    %s499~''t)CET__-;;s#C(A-wS11tc#h. $ . zz#!#voo))s
 * 	u
r1   c                    SSK Jn  U" U 5      $ )a8  Return a QuantumCircuit implementing the CNOT-Dihedral element.

Return:
    QuantumCircuit: a circuit implementation of the CNOTDihedral object.

References:
    1. Shelly Garion and Andrew W. Cross, *Synthesis of CNOT-Dihedral circuits
       with optimal number of two qubit gates*, `Quantum 4(369), 2020
       <https://quantum-journal.org/papers/q-2020-12-07-369/>`_
    2. Andrew W. Cross, Easwar Magesan, Lev S. Bishop, John A. Smolin and Jay M. Gambetta,
       *Scalable randomized benchmarking of non-Clifford gates*,
       npj Quantum Inf 2, 16012 (2016).
r   )synth_cnotdihedral_full)qiskit.synthesis.cnotdihedralr   )r*   r   s     r/   
to_circuitCNOTDihedral.to_circuit?  s     	J&t,,r1   c                >    U R                  5       R                  5       $ )z?Return a Gate instruction implementing the CNOTDihedral object.)r   to_gater5   s    r/   r&   CNOTDihedral.to_instructionR  s     ((**r1   c                    [        U[        [        45      (       d  [        S5      e[	        U R
                  S9n[        X!5        U$ )a_  Initialize from a QuantumCircuit or Instruction.

Args:
    circuit (QuantumCircuit or ~qiskit.circuit.Instruction):
        instruction to initialize.
Returns:
    CNOTDihedral: the CNOTDihedral object for the circuit.
Raises:
    QiskitError: if the input instruction is not CNOTDihedral or contains
                 classical register instruction.
z-Input must be a QuantumCircuit or Instructionr   )r!   r   r   r   r   r   r   )r*   circuitr-   s      r/   r%   CNOTDihedral._from_circuitV  sA     'NK#@AAMNN t'7'78&r1   c                l    USL a  [        S5      eU R                  5       nUc  U$ UR                  USS9$ )NFz9unable to avoid copy while creating an array as requested)copy)
ValueError	to_matrixastype)r*   r   r   arrs       r/   	__array__CNOTDihedral.__array__j  s=    5=XYYnnmsFE)FFr1   c                6    U R                  5       R                  $ )z!Convert operator to Numpy matrix.)to_operatorr+   r5   s    r/   r   CNOTDihedral.to_matrixp  s    !&&&r1   c                4    [        U R                  5       5      $ )zConvert to an Operator object.)r   r&   r5   s    r/   r   CNOTDihedral.to_operatort  s    ++-..r1   c                    Ub  [        S5      eU R                  UR                  :w  a  [        S5      eU(       a  U R                  U5      nOU R	                  U5      nSUR
                  l        U$ )Nz&compose method does not support qargs.z&Incompatible dimension for compositionr   )NotImplementedErrorr   r   r]   ra   r   rS   )r*   rW   qargsfronts       r/   composeCNOTDihedral.composex  sd     %&NOO??e...FGGIIe$EMM%(E

r1   c           	        [        U[        5      (       d  [        S5      eU(       a  U nUnOUnU n[        UR                  UR                  -   S9n[        R
                  " UR                  [        R                  " UR                  UR                  4[        R                  S9/[        R                  " UR                  UR                  4[        R                  S9UR                  //5      nXel        [        R
                  " UR                  UR                  /5      nXul	        [        UR                  5       H  nUR                  R                  U/5      n	UR                  R                  U/U	5        [        U5       H  n
UR                  R                  X/5      n	UR                  R                  X/U	5        [        U
5       H>  nUR                  R                  XU/5      n	UR                  R                  XU/U	5        M@     M     M     [        UR                  5       GH  nUR                  R                  U/5      n	UR                  R                  XR                  -   /U	5        [        U5       H  n
UR                  R                  X/5      n	UR                  R                  XR                  -   XR                  -   /U	5        [        U
5       Hc  nUR                  R                  XU/5      n	UR                  R                  XR                  -   XR                  -   XR                  -   /U	5        Me     M     GM"     U$ )z$Returns the tensor product operator.z.Tensored element is not a CNOTDihderal object.r   r   )r!   r   r   r   r   blockr   r   r   r    rO   r   rs   rt   )r*   rW   reverseelem0elem1rX   r   r    r[   ry   ri   rv   s               r/   _tensorCNOTDihedral._tensor  s    %..NOOEEEE)9)9E<L<L)LMrxx)9)95;K;K(LTVT[T[\]5++U-=-=>bggNPUP\P\]
 %++u{{34u''(AJJ'',EKK  !e,1X

++QF3$$aVU3qA!JJ//q	:EKK((!E: "  ) u''(AJJ'',EKK  !&6&6"6!7?1X

++QF3$$a*:*:&:A@P@P<P%QSXYqA!JJ//q	:EKK((---q3C3C/CQIYIYEYZ\a "  ) r1   c                "    U R                  USS9$ )NTr   r   re   s     r/   tensorCNOTDihedral.tensor  s    ||E4|00r1   c                "    U R                  USS9$ )NFr   r   re   s     r/   expandCNOTDihedral.expand  s    ||E5|11r1   c                d    U R                  5       nU R                  UR                  5       5      nU$ N)r&   r%   inverser*   circrX   s      r/   adjointCNOTDihedral.adjoint  s+    ""$##DLLN3r1   c                   U R                  5       n[        U R                  5      n[        UR                  R
                  5       VVs0 s H  u  p4XC_M	     nnnUR                   GH  nUR
                   Vs/ s H  ouU   PM	     nnUR                  R                  S:X  a@  S[        R                  -  UR                  R                  S   -
  n	UR                  X5        M|  UR                  R                  S:X  a/  SUR                  l        UR                  UR                  U5        M  UR                  R                  S:X  a0  SUR                  l        UR                  UR                  U5        GM  UR                  R                  S:X  a0  SUR                  l        UR                  UR                  U5        GMY  UR                  R                  S:X  a0  SUR                  l        UR                  UR                  U5        GM  UR                  UR                  U5        GM     U R                  U5      n
U
$ s  snnf s  snf )Npr   r   ttdgssdg)r&   r   r   	enumerate
definitionqubits	operationr6   r   piparamsr   rT   r%   )r*   r   new_circindexbitbit_indicesinstructiontup
new_qubitsr   rX   s              r/   	conjugateCNOTDihedral.conjugate  s   ""$!$//24=doo>T>T4UV4Ujesz4UV??K6A6H6HI6Hsc*6HJI$$))S0RUU[%:%:%A%A!%DD

6.&&++s2-2%%* 5 5zB&&++u4-0%%* 5 5zB&&++s2-2%%* 5 5zB&&++u4-0%%* 5 5zB 5 5zB% +& ##H-+ WIs   H<7Ic                d    U R                  5       nU R                  UR                  5       5      nU$ r   )r&   r%   reverse_opsr   s      r/   	transposeCNOTDihedral.transpose  s.    ""$##D$4$4$67r1   c                   U R                   R                  S:w  d  [        U R                   R                  5      U R                  :w  d  [        U R                   R
                  5      [        U R                  U R                  S-
  -  S-  5      :w  dY  [        U R                   R                  5      [        U R                  U R                  S-
  -  U R                  S-
  -  S-  5      :w  a  gU R                  R                  U R                  U R                  4:w  di  [        U R                  5      U R                  :w  dF  [        R                  " [        R                  R                  U R                  5      S-  S5      (       d  g[        U R                   R                  R!                  5       5      R#                  1 Sk5      (       a  [        U R                   R
                  R!                  5       5      R#                  1 Sk5      (       aC  [        U R                   R                  R!                  5       5      R#                  SS15      (       d  g[        U R                  R!                  5       5      R#                  SS15      (       a9  [        U R                  R!                  5       5      R#                  SS15      (       d  gg	)
z/Return True if input is a CNOTDihedral element.r   r   r      F>   r   r   r   rn   rp      r   rm   >   r   r   rp   r   rp   T)r   rS   lenweight_1r   weight_2intweight_3r   shaper    r   allcloselinalgdetr#   flattenissubsetr5   s    r/   r)   CNOTDihedral._is_valid  s    II!#499%%&$//9499%%&#dooSTAT.UXY.Y*ZZ499%%&4??doo&9:dooPQ>QRUVVWX [[DOOT__#EE4::$//1;;		dkk :Q >CCTYY''//12<<=UVV		**2245??MM		**2245??AGGDJJ&&()33QF;;##%&
(Aq6
D r1   )r   r   r   r    )NNT)r+   z2CNOTDihedral | QuantumCircuit | Instruction | Noner   z
int | Noner,   bool)NN)returnr   )NF)rW   r   r   zlist | Noner   r   r   r   )F)rW   r   r   r   )"__name__
__module____qualname____firstlineno____doc__r(   propertyr6   r9   rB   rG   r]   ra   rf   rj   rz   r}   r   r   r&   r%   r   r   r   r   r   r   r   r   r   r   r)   __static_attributes____classcell__)r.   s   @r/   r   r      s   HX DH!%	G?@G? G? 	G? G?R    

..
<=20,-&+(G'/
 MR!*5EI	.`12
4
 r1   r   )r   
__future__r   rq   numpyr   qiskit.exceptionsr   +qiskit.quantum_info.operators.base_operatorr   &qiskit.quantum_info.operators.operatorr   .qiskit.quantum_info.operators.symplectic.paulir   'qiskit.quantum_info.operators.scalar_opr   $qiskit.quantum_info.operators.mixinsr	   r
   qiskit.circuitr   r   dihedral_circuitsr   
polynomialr   r   r4   r1   r/   <module>r      sK    #   ) D ; @ < O 6 . )\< \@  r1   