
    z	i!                    l    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
S jjrS rg)z
Implementation of the GraySynth algorithm for synthesizing CNOT-Phase
circuits with efficient CNOT cost, and the Patel-Hayes-Markov algorithm
for optimal synthesis of linear (CNOT-only) reversible circuits.
    )annotationsN)QuantumCircuit)QiskitError)synth_cnot_count_full_pmhc                   [        U 5      n[        U5      n[        U S   5      [        U5      :w  a  [        S5      e[        [	        U5      5      nUn/ n[
        R                  " [
        R                  " [        R                  " U 5      5      5      n[
        R                  " U5      R                  S5      n	[	        U5       GH  n
SnU H  n[
        R                  " XU
   5      (       a  X   S:X  a  UR                  U
5        OX   S:X  a  UR                  U
5        OsX   S:X  a  UR                  U
5        OYX   S:X  a  UR!                  U
5        O?X   S:X  a  UR#                  U
5        O%UR%                  X   [
        R&                  -  U
5        X	 [
        R(                  " XSS	9nU[        U5      :X  a    M  US
-  nUS
-  nM     GM
     UR+                  XU/5        U(       Ga  UR-                  5       u  pn
U / :X  a  M#  SU
s=::  a  U:  Ga  O  GOSnU(       Ga  Sn[	        U5       GH  nX:w  d  M  [/        X   5      [        X   5      :X  d  M)  SnUR1                  X5        X==   X   -  ss'   SnU H  n[
        R                  " XU
   5      (       a  X   S:X  a  UR                  U
5        OX   S:X  a  UR                  U
5        OsX   S:X  a  UR                  U
5        OYX   S:X  a  UR!                  U
5        O?X   S:X  a  UR#                  U
5        O%UR%                  X   [
        R&                  -  U
5        X	 [
        R(                  " XSS	9nU[        U5      :X  a    OUS
-  nUS
-  nM     [3        XpX//-   5       HE  nUu  n  nU/ :X  a  M  [	        [        UU   5      5       H  nUU   U==   UU
   U   -  ss'   M     MG     GM     U(       a  GM  U/ :X  a  GM	  U[
        R4                  " U VVs/ s HA  nU  Vs/ s H-  n[7        UR9                  S5      UR9                  S
5      5      PM/     snU   PMC     snn5         n/ n/ n[        [;        [        [=        U 6 5      5       H;  nUU   S:X  a  UR+                  U5        M  UU   S
:X  d  M*  UR+                  U5        M=     [        [;        [        [=        U6 5      5      n[        [;        [        [=        U6 5      5      nX:X  a7  UR+                  U[        [?        U5      RA                  U/5      5      U/5        O6UR+                  U[        [?        U5      RA                  U/5      5      U
/5        UR+                  U[        [?        U5      RA                  U/5      5      U
/5        U(       a  GM  U[C        X5      RE                  5       -  nU$ s  snf s  snnf )u	  This function is an implementation of the `GraySynth` algorithm of
Amy, Azimadeh and Mosca.

GraySynth is a heuristic algorithm from [1] for synthesizing small parity networks.
It is inspired by Gray codes. Given a set of binary strings :math:`S`
(called ``cnots`` bellow), the algorithm synthesizes a parity network for :math:`S` by
repeatedly choosing an index :math:`i` to expand and then effectively recursing on
the co-factors :math:`S_0` and :math:`S_1`, consisting of the strings :math:`y \in S`,
with :math:`y_i = 0` or :math:`1` respectively. As a subset :math:`S` is recursively expanded,
``cx`` gates are applied so that a designated target bit contains the
(partial) parity :math:`\chi_y(x)` where :math:`y_i = 1` if and only if :math:`y'_i = 1` for all
:math:`y' \in S`. If :math:`S` contains a single element :math:`\{y'\}`, then :math:`y = y'`,
and the target bit contains the value :math:`\chi_{y'}(x)` as desired.

Notably, rather than uncomputing this sequence of ``cx`` (CNOT) gates when a subset :math:`S`
is finished being synthesized, the algorithm maintains the invariant
that the remaining parities to be computed are expressed over the current state
of bits. This allows the algorithm to avoid the 'backtracking' inherent in
uncomputing-based methods.

The algorithm is described in detail in section 4 of [1].

Args:
    cnots: A matrix whose columns are the parities to be synthesized
        e.g.::

            [[0, 1, 1, 1, 1, 1],
             [1, 0, 0, 1, 1, 1],
             [1, 0, 0, 1, 0, 0],
             [0, 0, 1, 0, 1, 0]]

        corresponds to::

             x1^x2 + x0 + x0^x3 + x0^x1^x2 + x0^x1^x3 + x0^x1

    angles: A list containing all the phase-shift gates which are
        to be applied, in the same order as in ``cnots``. A number is
        interpreted as the angle of :math:`p(angle)`, otherwise the elements
        have to be ``'t'``, ``'tdg'``, ``'s'``, ``'sdg'`` or ``'z'``.

    section_size: The size of every section in the Patel–Markov–Hayes algorithm.
        ``section_size`` must be a factor of the number of qubits.

Returns:
    The decomposed quantum circuit.

Raises:
    QiskitError: when dimensions of ``cnots`` and ``angles`` don't align.

References:
    1. Matthew Amy, Parsiad Azimzadeh, and Michele Mosca.
       *On the controlled-NOT complexity of controlled-NOT–phase circuits.*,
       Quantum Science and Technology 4.1 (2018): 015002.
       `arXiv:1712.01859 <https://arxiv.org/abs/1712.01859>`_
r   z*Size of "cnots" and "angles" do not match.intttdgssdgz)axis   TF)#lenr   r   listrangenp	transposearraycopydeepcopyeyeastypearray_equalr	   r
   r   r   r   ppideleteappendpopsumcx_remove_duplicatesargmaxmaxcountmapzipset
differencer   inverse)cnotsanglessection_size
num_qubitsqcir
range_listepsilonsta
cnots_copystatequbitindexicnotsilist	conditionjxcnotsp_tttkrowcnots0cnots1ys                            h/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/synthesis/linear_phase/cnot_phase_synth.pysynth_cnot_phase_aamrE      s   t UJ *%D
58}F#FGGeJ'(JG
Cbhht}}U';<=JFF:%%e,E z" F~~fEl33=C'FF5M]e+HHUO]c)FF5M]e+HHUO]c)FF5MFF6=2550%8MYYzqA
C
O+
QJE' ! #0 JJ7+,
 #	uB;"
""I!	z*A
UX#eh-)G$(	)0 !&0F!~~fElCC#)=C#7$(FF5M%+]e%;$(HHUO%+]c%9$(FF5M%+]e%;$(HHUO%+]c%9$(FF5M$(FF6=255+@%$H$*M-/YYzq-Q
#(C
O#;$) %
!QJE' '1( "4C5;P:Q4Q!RA-.NVQ%| (',S^'< &q	#&-2D D (=	 "S5 + )D B;
 "))\ab\aWXO#c#))A,		!=OPQR\abcdc$U,-Atqya 1a 	 .
 c$V-.c$V-.JJSZ%:%:A3%? @!DEJJSZ%:%:A3%? @%HI

FDU!6!6s!;<eDEy #z 	%e:BBDDDK! Pbs   
W4W?
WWc                L    / nU  H  nX!;  d  M
  UR                  U5        M     U$ )z
Remove duplicates in list

Args:
    lists (list): a list which may contain duplicate elements.

Returns:
    list: a list which contains only unique elements.
)r   )listsunique_listelements      rD   r"   r"      s/     K%w'      )   )r+   zlist[list[int]]r,   z	list[str]r-   r   returnr   )__doc__
__future__r   r   numpyr   qiskit.circuitr   qiskit.exceptionsr   qiskit.synthesis.linearr   rE   r"    rJ   rD   <module>rT      sU   
 #   ) ) = DEaa$-a=@aaHrJ   