§
    º³ÙgX%  ã                   ó:  — d Z ddlZddlZddlZg d¢Zg d¢Z ej        e¦  «        Z	de
de
fd„Z	 	 	 dde
d
edede
dej        f
d„Zde
dedefd„Zde
dede
dej        fd„Zde
de
dej        fd„Zde
dej        fd„Zde
de
dej        fd„Zde
de
dej        fd„ZdS )z\
These are the CNOT structure methods: anything that you need for creating CNOT structures.
é    N)ÚsequÚspinÚcartÚcyclic_spinÚcyclic_line)ÚfullÚlineÚstarÚ
num_qubitsÚreturnc                 óL   — t          j        d| z  d| z  z
  dz
  dz  ¦  «        }|S )zú
    Returns lower limit on the number of CNOT units that guarantees exact representation of
    a unitary operator by quantum gates.

    Args:
        num_qubits: number of qubits.

    Returns:
        lower limit on the number of CNOT units.
    é   é   é   g      @)ÚmathÚceil)r   Ú	num_cnotss     úb/granary/edev/quantum/lib/python3.11/site-packages/qiskit/synthesis/unitary/aqc/cnot_structures.pyÚ_lower_limitr      s0   € õ ”	˜1˜j™=¨1¨z©>Ñ9¸AÑ=ÀÑDÑEÔE€IØÐó    r   r   Únetwork_layoutÚconnectivity_typeÚdepthc                 óš  — | dk     rt          d¦  «        ‚|dk    r-t          | ¦  «        }t                               d||¦  «         |}|dk    r#t	          | |¬¦  «        }t          | ||¬¦  «        S |dk    rt          | |¬	¦  «        S |d
k    rFt          | ¬¦  «        }t                               dt          | ¦  «        |j        d         ¦  «         |S |dk    r)|dk    rt          d|› d�¦  «        ‚t          | |¦  «        S |dk    r)|dk    rt          d|› d�¦  «        ‚t          | |¦  «        S t          dt          › d|› �¦  «        ‚)a…  
    Generates a network consisting of building blocks each containing a CNOT gate and possibly some
    single-qubit ones. This network models a quantum operator in question. Note, each building
    block has 2 input and outputs corresponding to a pair of qubits. What we actually return here
    is a chain of indices of qubit pairs shared by every building block in a row.

    Args:
        num_qubits: number of qubits.
        network_layout: type of network geometry, ``{"sequ", "spin", "cart", "cyclic_spin",
            "cyclic_line"}``.
        connectivity_type: type of inter-qubit connectivity, ``{"full", "line", "star"}``.
        depth: depth of the CNOT-network, i.e. the number of layers, where each layer consists of
            a single CNOT-block; default value will be selected, if ``L <= 0``.

    Returns:
        A matrix of size ``(2, N)`` matrix that defines layers in cnot-network, where ``N``
            is either equal ``L``, or defined by a concrete type of the network.

    Raises:
         ValueError: if unsupported type of CNOT-network layout or number of qubits or combination
            of parameters are passed.
    é   z.Number of qubits must be greater or equal to 2r   zPNumber of CNOT units chosen as the lower limit: %d, got a non-positive value: %dr   )r   Úconnectivity)r   Úlinksr   r   )r   r   r   )r   z)Optimal lower bound: %d; Cartan CNOTs: %dr   r   r   ú'z$' layout expects 'full' connectivityr   r	   z$' layout expects 'line' connectivityz4Unknown type of CNOT-network layout, expects one of ú, got )Ú
ValueErrorr   ÚloggerÚdebugÚ_get_connectivityÚ_sequential_networkÚ_spin_networkÚ_cartan_networkÚshapeÚ_cyclic_spin_networkÚ_cyclic_line_networkÚ_NETWORK_LAYOUTS)r   r   r   r   Ú	new_depthr   Úcnotss          r   Úmake_cnot_networkr-   *   s«  € ð8 �A‚~€~ÝÐIÑJÔJÐJà�‚z€zÝ  Ñ,Ô,ˆ	Ý�ŠØ^ØØñ	
ô 	
ð 	
ð
 ˆà˜ÒÐÝ!¨ZÐFWÐXÑXÔXˆÝ"¨jÀÈUÐSÑSÔSÐSà	˜6Ò	!Ð	!Ý¨
¸%Ð@Ñ@Ô@Ð@à	˜6Ò	!Ð	!Ý¨:Ð6Ñ6Ô6ˆÝ�ŠØ7½ÀjÑ9QÔ9QÐSXÔS^Ð_`ÔSañ	
ô 	
ð 	
ð ˆà	˜=Ò	(Ð	(Ø Ò&Ð&ÝÐU ÐUÐUÐUÑVÔVÐVå# J°Ñ6Ô6Ð6à	˜=Ò	(Ð	(Ø Ò&Ð&ÝÐU ÐUÐUÐUÑVÔVÐVå# J°Ñ6Ô6Ð6åð$ÕCSð $ð $Ø!ð$ð $ñ
ô 
ð 	
r   r   c                 óŽ  ‡ — ‰ dk    rddgi}n·|dk    rˆ fd„t          ‰ ¦  «        D ¦   «         }n•|dk    r5d„ t          d‰ dz
  ¦  «        D ¦   «         }ddg|d<   ‰ dz
  ‰ dz
  g|‰ dz
  <   nZ|dk    r:d	„ t          d‰ ¦  «        D ¦   «         }t          t          ‰ ¦  «        ¦  «        |d<   nt          d
t          › d|› �¦  «        ‚|S )aY  
    Generates connectivity structure between qubits.

    Args:
        num_qubits: number of qubits.
        connectivity: type of connectivity structure, ``{"full", "line", "star"}``.

    Returns:
        dictionary of allowed links between qubits.

    Raises:
         ValueError: if unsupported type of CNOT-network layout is passed.
    r   r   r   c                 óJ   •— i | ]}|t          t          ‰¦  «        ¦  «        “Œ S © )ÚlistÚrange)Ú.0Úir   s     €r   ú
<dictcomp>z%_get_connectivity.<locals>.<dictcomp>…   s+   ø€ ÐGÐGÐG°�•D�˜zÑ*Ô*Ñ+Ô+ÐGÐGÐGr   r	   c                 ó&   — i | ]}||d z
  ||d z   g“ŒS )r   r0   ©r3   r4   s     r   r5   z%_get_connectivity.<locals>.<dictcomp>‰   s)   € ÐHÐHÐH¨!��Q˜‘U˜A˜q 1™uÐ%ÐHÐHÐHr   r   r
   c                 ó   — i | ]}|d |g“ŒS )r   r0   r7   s     r   r5   z%_get_connectivity.<locals>.<dictcomp>“   s   € Ð9Ð9Ð9˜q��Q˜�FÐ9Ð9Ð9r   z*Unknown connectivity type, expects one of r   )r2   r1   r    Ú_CONNECTIVITY_TYPES)r   r   r   s   `  r   r#   r#   r   s  ø€ ð �Q‚€Ø�Q�C�ˆˆà	˜Ò	Ð	àGÐGÐGÐGµU¸:Ñ5FÔ5FÐGÑGÔGˆˆà	˜Ò	Ð	àHÐH­u°Q¸
ÀQ¹Ñ/GÔ/GÐHÑHÔHˆð �q�6ˆˆa‰ð ",¨a¡°¸a±Ð @ˆˆj˜1‰nÑÐà	˜Ò	Ð	à9Ð9¥E¨!¨ZÑ$8Ô$8Ð9Ñ9Ô9ˆõ �˜jÑ)Ô)Ñ*Ô*ˆˆa‰ˆõ ØbÕ9LÐbÐbÐT`ÐbÐbñ
ô 
ð 	
ð €Lr   r   c                 óî   — d}t          j        d|ft          ¬¦  «        }	 t          d| dz
  ¦  «        D ]A}t          |dz   | ¦  «        D ]+}|||         v r||d|f<   ||d|f<   |dz  }||k    r|c c S Œ,ŒBŒV)a)  
    Generates a sequential network.

    Args:
        num_qubits: number of qubits.
        links: dictionary of connectivity links.
        depth: depth of the network (number of layers of building blocks).

    Returns:
        A matrix of ``(2, N)`` that defines layers in qubit network.
    r   r   ©ÚdtypeTr   ©ÚnpÚzerosÚintr2   )r   r   r   Úlayerr,   r4   Újs          r   r$   r$   Ÿ   s±   € ð €EÝŒH�a˜�Z¥sÐ+Ñ+Ô+€Eð%Ý�q˜* q™.Ñ)Ô)ð 	%ð 	%ˆAÝ˜1˜q™5 *Ñ-Ô-ð %ð %�Ø˜˜aœ�=�=Ø&'�E˜!˜U˜(‘OØ&'�E˜!˜U˜(‘OØ˜Q‘J�EØ ’~�~Ø$˜˜˜˜˜øð%ð%r   c                 ó   — d}t          j        d|ft          ¬¦  «        }	 t          d| dz
  d¦  «        D ]"}||d|f<   |dz   |d|f<   |dz  }||k    r|c S Œ#t          d| dz
  d¦  «        D ]"}||d|f<   |dz   |d|f<   |dz  }||k    r|c S Œ#Œo)zû
    Generates a spin-like network.

    Args:
        num_qubits: number of qubits.
        depth: depth of the network (number of layers of building blocks).

    Returns:
        A matrix of size ``2 x L`` that defines layers in qubit network.
    r   r   r;   Tr   r=   )r   r   rA   r,   r4   s        r   r%   r%   ¸   sç   € ð €EÝŒH�a˜�Z¥sÐ+Ñ+Ô+€EðÝ�q˜* q™.¨!Ñ,Ô,ð 	ð 	ˆAØˆE�!�U�(‰OØ !™eˆE�!�U�(‰OØ�Q‰JˆEØ˜Š~ˆ~Ø���ð õ �q˜* q™.¨!Ñ,Ô,ð 	ð 	ˆAØˆE�!�U�(‰OØ !™eˆE�!�U�(‰OØ�Q‰JˆEØ˜Š~ˆ~Ø���ð ðr   c           	      ó  — | }|dk    rÈt          j        g d¢g d¢g¦  «        }t          j        |dz
  |dz
  |dz
  |dz
  g|dz
  |dz
  |dz
  |dz
  gg¦  «        }t          |dz
  ¦  «        D ]d}t          j        t          j        t          j        ||f¦  «        d¦  «        |f¦  «        }|dxx         dz  cc<   t          j        |d¦  «        }Œen4|dk    rt          j        g d¢g d¢g¦  «        }nt          d	|› d
�¦  «        ‚|S )a?  
    Cartan decomposition in a recursive way, starting from n = 3.

    Args:
        num_qubits: number of qubits.

    Returns:
        2xN matrix that defines layers in qubit network, where N is the
             depth of Cartan decomposition.

    Raises:
        ValueError: if number of qubits is less than 3.
    r   )r   r   r   )r   r   r   r   r   )r   éÿÿÿÿ)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   z'The number of qubits must be >= 3, got ú.)r>   Úasarrayr2   ÚhstackÚtiler    )r   Únr,   ÚmultÚ_s        r   r&   r&   Õ   s@  € ð 	€AØˆ1‚u€uÝ”
˜I˜I˜I y y yÐ1Ñ2Ô2ˆÝŒz˜A ™E 1 q¡5¨!¨a©%°°Q±Ð7¸!¸a¹%ÀÀQÁÈÈAÉÈqÐSTÉuÐ9UÐVÑWÔWˆÝ�q˜1‘u‘”ð 	$ð 	$ˆAÝ”I�rœw¥r¤y°%¸°Ñ'?Ô'?ÀÑCÔCÀUÐKÑLÔLˆEØ�ˆKˆKŒK˜1ÑˆKˆK‰KÝ”7˜4 Ñ#Ô#ˆDˆDð	$ð 
ˆaŠˆÝ”
àRÐRÐRØRÐRÐRðñ
ô 
ˆˆõ ÐGÀ1ÐGÐGÐGÑHÔHÐHà€Lr   c                 ó~  — t          j        d|ft          ¬¦  «        }d}	 t          d| d¦  «        D ].}|dz   | dz
  k    r||d|f<   |dz   |d|f<   |dz  }||k    r|c S Œ/t          d| d¦  «        D ]K}|dz   | dz
  k    r||d|f<   |dz   |d|f<   |dz  }n|| dz
  k    r||d|f<   d|d|f<   |dz  }||k    r|c S ŒLŒž)a4  
    Same as in the spin-like network, but the first and the last qubits are also connected.

    Args:
        num_qubits: number of qubits.
        depth: depth of the network (number of layers of building blocks).

    Returns:
        A matrix of size ``2 x L`` that defines layers in qubit network.
    r   r;   r   Tr   r=   )r   r   r,   Úzr4   s        r   r(   r(   ø   s9  € õ ŒH�a˜�Z¥sÐ+Ñ+Ô+€EØ	€AðÝ�q˜* aÑ(Ô(ð 	ð 	ˆAØ�1‰u˜
 Q™Ò&Ð&Ø��a˜�d‘Ø !™e��a˜�d‘Ø�Q‘�Ø�EŠzˆzØ���ð õ �q˜* aÑ(Ô(ð 
	ð 
	ˆAØ�1‰u˜
 Q™Ò&Ð&Ø��a˜�d‘Ø !™e��a˜�d‘Ø�Q‘��Ø�j 1‘nÒ$Ð$Ø��a˜�d‘Ø��a˜�d‘Ø�Q‘�Ø�EŠzˆzØ���ð ð%r   c                 ó˜   — t          j        d|ft          ¬¦  «        }t          |¦  «        D ]}|dz   | z  |d|f<   |dz   | z  |d|f<   Œ|S )a  
    Generates a line based CNOT structure.

    Args:
        num_qubits: number of qubits.
        depth: depth of the network (number of layers of building blocks).

    Returns:
        A matrix of size ``2 x L`` that defines layers in qubit network.
    r   r;   r   r   r=   )r   r   r,   r4   s       r   r)   r)     sd   € õ ŒH�a˜�Z¥sÐ+Ñ+Ô+€EÝ�5‰\Œ\ð +ð +ˆØ˜1‘u 
Ñ*ˆˆa�ˆd‰Ø˜1‘u 
Ñ*ˆˆa�ˆd‰ˆØ€Lr   )r   r   r   )Ú__doc__Úloggingr   Únumpyr>   r*   r9   Ú	getLoggerÚ__name__r!   r@   r   ÚstrÚndarrayr-   Údictr#   r$   r%   r&   r(   r)   r0   r   r   ú<module>rX      sé  ððð ð €€€Ø €€€à Ð Ð Ð àIÐIÐIÐ Ø.Ð.Ð.Ð ð 
ˆÔ	˜8Ñ	$Ô	$€ð˜Sð  Sð ð ð ð ð" !Ø#Øð	E
ð E
ØðE
àðE
ð ðE
ð ð	E
ð
 „ZðE
ð E
ð E
ð E
ðP* #ð *°Sð *¸Tð *ð *ð *ð *ðZ% Cð %°ð %¸Sð %ÀRÄZð %ð %ð %ð %ð2˜cð ¨#ð °"´*ð ð ð ð ð:  ð  ¨¬
ð  ð  ð  ð  ðF! Sð !°ð !¸¼ð !ð !ð !ð !ðH Sð °ð ¸¼ð ð ð ð ð ð r   