
    z	ic2                        S r SSKJr  SSKJrJr  SSKJr  SSKr	SSK
JrJrJrJrJrJr   " S S	\5      r " S
 S\5      r " S S\5      rSS jrSS jrSS jrSS jrg)z5
Layer classes for the fast gradient implementation.
    )annotations)abstractmethodABC)OptionalN   )bit_permutation_1qreverse_bitsinverse_permutationbit_permutation_2qmake_rzmake_ryc                  @    \ rS rSrSr\SS j5       r\SS j5       rSrg)		LayerBase   z
Base class for any layer implementation. Each layer here is represented
by a 2x2 or 4x4 gate matrix ``G`` (applied to 1 or 2 qubits respectively)
interleaved with the identity ones:
``Layer = I kron I kron ... kron G kron ... kron I kron I``
c                    [        5       e)zz
Updates this layer from an external gate matrix.

Args:
    mat: external gate matrix that initializes this layer's one.
NotImplementedErrorselfmats     j/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/synthesis/unitary/aqc/fast_gradient/layer.pyset_from_matrixLayerBase.set_from_matrix&        "##    c                    [        5       e)z
Returns gate matrix, direct and inverse permutations.

Returns:
    (1) gate matrix; (2) direct permutation; (3) inverse permutations.
r   r   s    r   get_attrLayerBase.get_attr0   r   r    Nr   
np.ndarrayreturnz)tuple[np.ndarray, np.ndarray, np.ndarray])	__name__
__module____qualname____firstlineno____doc__r   r   r   __static_attributes__r    r   r   r   r      s/     $ $ $ $r   r   c                  H   ^  \ rS rSrSrSSU 4S jjjrS	S jrS
S jrSrU =r	$ )Layer1Q;   zo
Layer represents a simple circuit where 1-qubit gate matrix (of size 2x2)
interleaves with the identity ones.
c                  > [         TU ]  5         [        R                  " SS[        R                  S9U l        [        U[        R                  5      (       a!  [        R                  " U R
                  U5        SnSU-  n[        [        XS9XS9n[        [        R                  " U[        R                  S9XS9n[        R                  " U4S[        R                  S9U l        XpR                  U'   [        U R                  5      U l        g	)
z
Args:
    num_qubits: number of qubits.
    k: index of the bit where gate is applied.
    g2x2: 2x2 matrix that makes up this layer along with identity ones,
          or None (should be set up later).
)   r/   r   
fill_valuedtypeTr/   )nknbitsenabler2   N)super__init__npfull
complex128_gmat
isinstancendarraycopytor	   r   arangeint64_permr
   	_inv_perm)	r   
num_qubitsr4   g2x2bit_flipdimrow_permcol_perm	__class__s	           r   r:   Layer1Q.__init__A   s     	 WWVG
dBJJ''IIdjj$'m1
  		#RXX >jbWWcVB
'

8,TZZ8r   c                F    [         R                  " U R                  U5        gSee base class description.Nr;   rA   r>   r   s     r   r   Layer1Q.set_from_matrixZ       
		$**c"r   c                H    U R                   U R                  U R                  4$ rP   r>   rD   rE   r   s    r   r   Layer1Q.get_attr^       zz4::t~~55r   r>   rE   rD   N)rF   intr4   r[   rG   Optional[np.ndarray]r!   r#   
r%   r&   r'   r(   r)   r:   r   r   r*   __classcell__rL   s   @r   r,   r,   ;   s!    
9 92#6 6r   r,   c                  H   ^  \ rS rSrSrSSU 4S jjjrS	S jrS
S jrSrU =r	$ )Layer2Qc   zo
Layer represents a simple circuit where 2-qubit gate matrix (of size 4x4)
interleaves with the identity ones.
c                   > [         T	U ]  5         [        R                  " SS[        R                  S9U l        [        U[        R                  5      (       a!  [        R                  " U R
                  U5        SnSU-  n[        [        XUS9XS9n[        [        R                  " U[        R                  S9XS9n[        R                  " U4S[        R                  S9U l        XR                  U'   [        U R                  5      U l        g	)
z
Args:
    num_qubits: number of qubits.
    j: index of the first (control) bit.
    k: index of the second (target) bit.
    g4x4: 4x4 matrix that makes up this layer along with identity ones,
          or None (should be set up later).
)   rd   r   r0   Tr/   )r3   jr4   r5   r8   N)r9   r:   r;   r<   r=   r>   r?   r@   rA   r	   r   rB   rC   rD   r
   rE   )
r   rF   re   r4   g4x4rH   rI   rJ   rK   rL   s
            r   r:   Layer2Q.__init__i   s     	 WWVG
dBJJ''IIdjj$'mA6j
  		#RXX >jbWWcVB
'

8,TZZ8r   c                F    [         R                  " U R                  U5        grO   rQ   r   s     r   r   Layer2Q.set_from_matrix   rS   r   c                H    U R                   U R                  U R                  4$ rU   rV   r   s    r   r   Layer2Q.get_attr   rX   r   rY   rZ   )rF   r[   re   r[   r4   r[   rf   r\   r!   r#   r]   r_   s   @r   ra   ra   c   s!    
9 94#6 6r   ra   c           	     T   U R                   S   n[        R                  " SS[        R                  S9n[	        U5       He  nX   n[        US   US   S9n[        US   US   S9n[        US   US   S9n[        R                  " [        R                  " XgUS   S9XU   S9  Mg     U$ )L  
Initializes 4x4 matrices of 2-qubit gates defined in the paper.

Args:
    thetas: depth x 4 matrix of gate parameters for every layer, where
            "depth" is the number of layers.
    dst: destination array of size depth x 4 x 4 that will receive gate
         matrices of each layer.

Returns:
    Returns the "dst" array.
r   )rd   r/   r/   r0   outr   r/      )shaper;   r<   r=   ranger   r   dot)	thetasdstr3   tmpr4   thabcs	            r   init_layer1q_matricesr{      s     	QA
'')
?C1XYBqEs1v&BqEs1v&BqEs1v&
rvvaA'A7  Jr   c           
     P   U R                   S   n[        R                  " SS/SS//[        R                  S9n[        R                  " SS/SS//[        R                  S9n[        R                  " SS[        R                  S9n[        U5       GH  nX   n[        US   US   S	9n[        US
   US
   S	9n	[        US   US   S	9n
[        R                  " XHUS   S	9n[        R                  " [        R                  " XUS   S	9XUS4   S	9  [        R                  " X9US   S	9n[        R                  " U[        R                  " XUS   S	9XS
4   S	9  [        R                  " XJUS   S	9n[        R                  " U[        R                  " XUS   S	9XS4   S	9  GM     U$ )a  
Initializes 4x4 derivative matrices of 2-qubit gates defined in the paper.

Args:
    thetas: depth x 4 matrix of gate parameters for every layer, where
            "depth" is the number of layers.
    dst: destination array of size depth x 4 x 4 x 4 that will receive gate
         derivative matrices of each layer; there are 4 parameters per gate,
         hence, 4 derivative matrices per layer.

Returns:
    Returns the "dst" array.
r   g            ?r8                              ?)   r/   r/   r0   rn   r   r/   rp   rd   )	rq   r;   asarrayr=   r<   rr   r   r   rs   )rt   ru   r3   yzrv   r4   rw   rx   ry   rz   zaybzcs                 r   init_layer1q_deriv_matricesr      sl    	QA


QIQx(>A


UAJD	*"--@A
'')
?C1XYBqEs1v&BqEs1v&BqEs1v&VVAc!f%
rvvbQ(!QT;VVAc!f%
q"&&CF+T;VVAc!f%
q"&&CF+T;  Jr   c                d   U R                   S   n[        U5       GH  nX   n[        R                  " SUS   -  5      R	                  5       n[        R
                  " SUS   -  5      R	                  5       n[        R                  " SUS   -  5      R	                  5       n[        R                  " SUS   -  5      R	                  5       n[        R                  " SUS   -  5      R	                  5       n	[        R
                  " SUS   -  5      R	                  5       n
[        R                  " SUS   -  5      R	                  5       n[        R
                  " SUS   -  5      R	                  5       nXu-  nXv-  nX-  nX-  nX-  nX-  nX-  nSU-  U	-  nSU-  nX   R                  5       nUU-
  * U-  UU-   * U-  UU-   U-  UU-
  U-  UU-
  U-  UU-   U-  UU-   * U-  U* U-   U-  U* U-   U-  UU-   * U-  UU-   * U-  U* U-   U-  UU-
  U-  UU-   U-  UU-   U-  UU-
  U-  /US	S	& GM     U$ )
rm   r   r}   r   r   r~   r/   rp                 ?Nrq   rr   r;   cositemsinexpravel)rt   ru   depthr4   rw   cs0sn0ep1en1cs2sn2cs3sn3ep1cs0ep1sn0en1cs0en1sn0sn2cs3sn2sn3cs2cs3sn3cs2jsn2sn3jflat_dsts                          r   init_layer2q_matricesr      sj    LLOE5\YffS2a5[!&&(ffS2a5[!&&(ffTBqE\"'')ffURU]#((*ffS2a5[!&&(ffS2a5[!&&(ffS2a5[!&&(ffS2a5[!&&(s(S.v+6<<>&(w&(g'v'g'v'&(Ww&(X&(w&(w&(X&(g'v'v'g'!
+ N Jr   c                   U R                   S   n[        U5       GH  nX   n[        R                  " SUS   -  5      R	                  5       n[        R
                  " SUS   -  5      R	                  5       n[        R                  " SUS   -  5      R	                  5       S-  n[        R                  " SUS   -  5      R	                  5       S-  n[        R                  " SUS   -  5      R	                  5       n	[        R
                  " SUS   -  5      R	                  5       n
[        R                  " SUS   -  5      R	                  5       n[        R
                  " SUS   -  5      R	                  5       nXu-  nXv-  nX-  nX-  nX-  nX-  nX-  nX-  nSU-  nSU-  nSU-  nSU-  nXS4   R                  5       nUU-
  U-  UU-   U-  UU-   U-  UU-
  U-  U* U-   U-  UU-   * U-  UU-   * U-  U* U-   U-  U* U-   U-  UU-   * U-  UU-   U-  UU-
  U-  UU-
  U-  UU-   U-  UU-   * U-  U* U-   U-  /US	S	& XS4   R                  5       nUU-   * U-  UU-
  U-  UU-
  * U-  UU-   U-  UU-   * U-  UU-
  U-  U* U-   U-  UU-   U-  UU-   U-  U* U-   U-  U* U-   U-  UU-   U-  UU-   U-  U* U-   U-  U* U-   U-  UU-   U-  /US	S	& XS4   R                  5       nUU-   * U-  UU-
  U-  UU-
  * U-  UU-   U-  UU-   U-  U* U-   U-  UU-
  U-  UU-   * U-  UU-   * U-  UU-
  U-  UU-
  U-  UU-   * U-  UU-   U-  U* U-   U-  U* U-   U-  UU-   U-  /US	S	& XS4   R                  5       nUU-   * U-  UU-
  U-  U* U-   U-  UU-   U-  UU-   * U-  UU-
  U-  UU-
  * U-  UU-   U-  UU-   * U-  UU-
  U-  UU-
  U-  UU-   * U-  UU-   * U-  UU-
  U-  UU-
  U-  UU-   * U-  /US	S	& GM     U$ )
a  
Initializes 4 x 4 derivative matrices of 2-qubit gates defined in the paper.

Args:
    thetas: depth x 4 matrix of gate parameters for every layer, where
            "depth" is the number of layers.
    dst: destination array of size depth x 4 x 4 x 4 that will receive gate
         derivative matrices of each layer; there are 4 parameters per gate,
         hence, 4 derivative matrices per layer.

Returns:
    Returns the "dst" array.
r   r}   r   r   r~   r/   rp   r   Nr   )rt   ru   r   r4   rw   r   r   r   r   r   r   r   r   r   r   r   r   r   r   sn3cs2r   sn2cs3jr   r   cs2cs3jr   s                             r   init_layer2q_deriv_matricesr      s    LLOE5\YffS2a5[!&&(ffS2a5[!&&(ffTBqE\"'')C/ffURU]#((*S0ffS2a5[!&&(ffS2a5[!&&(ffS2a5[!&&(ffS2a5[!&&(v+v+v+v+!t9??$v'g'g'v'Ww&(&(&(Ww&(X&(w&(g'v'g'v'&(Ww&(!
& !t9??$w&(v'&(g'&(g'Ww&(v'g'X&(X&(g'v'Ww&(Ww&(v'!
& !t9??$w&(v'&(g'v'Ww&(g'&(w&(v'v'w&(v'Ww&(Ww&(v'!
& !t9??$&(g'Ww&(v'w&(v'&(g'&(g'g'&(w&(v'v'w&(!
i L Jr   )rt   r"   ru   r"   r$   r"   )r)   
__future__r   abcr   r   typingr   numpyr;   fast_grad_utilsr   r	   r
   r   r   r   r   r,   ra   r{   r   r   r   r    r   r   <module>r      s_    # #   $ $:%6i %6P&6i &6R0B5pur   