
    z	iX%                        S r SSKrSSKrSSKr/ SQr/ SQr\R                  " \5      r	S\
S\
4S jr   SS\
S\S	\S
\
S\R                  4
S jjrS\
S\S\4S jrS\
S\S
\
S\R                  4S jrS\
S
\
S\R                  4S jrS\
S\R                  4S jrS\
S
\
S\R                  4S jrS\
S
\
S\R                  4S jrg)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                 P    [         R                  " SU -  SU -  -
  S-
  S-  5      nU$ )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     f/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/synthesis/unitary/aqc/cnot_structures.py_lower_limitr      s/     		1j=1z>9A=DEI    network_layoutconnectivity_typedepthc                    U S:  a  [        S5      eUS::  a$  [        U 5      n[        R                  SUU5        UnUS:X  a  [	        XS9n[        XUS9$ US:X  a	  [        XS	9$ US
:X  a8  [        U S9n[        R                  S[        U 5      UR                  S   5        U$ US:X  a   US:w  a  [        SU S35      e[        X5      $ US:X  a   US:w  a  [        SU S35      e[        X5      $ [        S[         SU 35      e)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z ,	^	

 !ZX"jUSS	6	!
@@	6	!:67j9QSXS^S^_`Sa	
 	=	(&q 00TUVV#J66	=	(&q 00TUVV#J66BCSBT U!"$
 	
r   r   c           	         U S:X  a  SS/0nU$ US:X  a/  [        U 5       Vs0 s H  o3[        [        U 5      5      _M     nnU$ US:X  a?  [        SU S-
  5       Vs0 s H  o3US-
  X3S-   /_M     nnSS/US'   U S-
  U S-
  /X S-
  '   U$ US:X  a7  [        SU 5       Vs0 s H  o3SU/_M	     nn[        [        U 5      5      US'   U$ [        S[         SU 35      es  snf s  snf s  snf )	a5  
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   r	   r   r
   z*Unknown connectivity type, expects one of r   )rangelistr    _CONNECTIVITY_TYPES)r   r   r   is       r   r#   r#   r   s?    QQC6 L3 
	5::5FG5FDz*++5FG. L+ 
	/4Q
Q/GH/G!QUA1u%%/GH q6a ",aa @1n L 
	$)!Z$89$8qQF$89 j)*a L 89L8MVT`Sab
 	
) H I :s   CCC$r   c                     Sn[         R                  " SU4[        S9n [        SU S-
  5       H?  n[        US-   U 5       H)  nXaU   ;   d  M  XTSU4'   XdSU4'   US-  nX2:  d  M%  Us  s  $    MA     MT  )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   dtyper   npzerosintr/   )r   r   r   layerr,   r2   js          r   r$   r$      s     EHHaZs+E
q*q.)A1q5*-a=&'!U(O&'!U(OQJE~$ . * r   c                    Sn[         R                  " SU4[        S9n [        SU S-
  S5       H!  nXCSU4'   US-   USU4'   US-  nX!:  d  M  Us  $    [        SU S-
  S5       H!  nXCSU4'   US-   USU4'   US-  nX!:  d  M  Us  $    Ml  )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   r4   r   r6   )r   r   r:   r,   r2   s        r   r%   r%      s     EHHaZs+E
q*q.!,A!U(O!eE!U(OQJE~ - q*q.!,A!U(O!eE!U(OQJE~ - r   c           	         U nUS:  a  [         R                  " / SQ/ SQ/5      n[         R                  " US-
  US-
  US-
  US-
  /US-
  US-
  US-
  US-
  //5      n[        US-
  5       Hi  n[         R                  " [         R                  " [         R                  " X#45      S5      U45      nUS==   S-  ss'   [         R                  " US5      nMk     U$ US:X  a  [         R                  " / SQ/ SQ/5      nU$ [        S	U S
35      e)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 .)r7   asarrayr/   hstacktiler    )r   nr,   mult_s        r   r&   r&      s	    	A1u

Iy12zzAE1q5!a%Q7!a%QAqSTu9UVWq1uAIIrwwryy%'?CUKLEK1K774#D  L 
a

RR
 L B1#QGHHr   c                 p   [         R                  " SU4[        S9nSn [        SU S5       H-  nUS-   U S-
  ::  a  XBSU4'   US-   USU4'   US-  nX1:  d  M+  Us  $    [        SU S5       HH  nUS-   U S-
  ::  a  XBSU4'   US-   USU4'   US-  nOX@S-
  :X  a  XBSU4'   SUSU4'   US-  nX1:  d  MF  Us  $    M  )a  
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   r4   r   r   r6   )r   r   r,   zr2   s        r   r(   r(      s     HHaZs+E	A
q*a(A1u
Q&ad!eadQz ) q*a(A1u
Q&ad!eadQ1n$adadQz ) r   c                     [         R                  " SU4[        S9n[        U5       H  nUS-   U -  USU4'   US-   U -  USU4'   M     U$ )z
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   r4   r   r   r6   )r   r   r,   r2   s       r   r)   r)     sY     HHaZs+E5\1u
*ad1u
*ad  Lr   )r   r   r   )__doc__loggingr   numpyr7   r*   r1   	getLogger__name__r!   r9   r   strndarrayr-   dictr#   r$   r%   r&   r(   r)    r   r   <module>rR      sB     I .  
		8	$S S " !#	E
E
E
 E
 	E

 ZZE
P*# *S *T *Z%C % %S %RZZ %2c # "** :   

  F!S ! ! !HS   r   