
    z	ii>                       S r SSKJr  SSKJr  SSKrSSK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	KJr  SS
KJrJr  SSKJr      SSS.         SS jjjrS rS r SSSSS.S jjrSS jrS rS rSS jr g)zP
Quantum Shannon Decomposition.

Method is described in arXiv:quant-ph/0406176.
    )annotations)CallableN)QuantumCircuitQuantumRegister)TwoQubitBasisDecomposertwo_qubit_decompose)one_qubit_decompose)is_hermitian_matrix)CXGate)UCPauliRotGate_EPS)"two_qubit_decompose_up_to_diagonal)_depthc                 ^! U R                   S   nUR                  5       S-
  nUc  Sn[        R                  " [        R                  " U5      U 5      (       a  [        U5      $ US:X  a"  Uc  [        R                  " 5       nU" U 5      nU$ US:X  aG  Uc/  U(       a  US:  a  SSKJ	m!  U!4S jn	U	nO[        [        5       5      n[        U 5      n U" U 5      nU$ Uc6  Sn[        U5       H%  n
[        X
5      u  pp[        X5      (       d  M#  SnM'     USL aM  [        U5       H>  n
[        X
5      u  pp[        X5      (       d  M#  [!        UUUUS	UUS-
  U
-
  S
9u  n  nUs  $    [#        U5      n[%        [        R&                  " U [(        S95      u  nnnn[        R*                  " SUS-
  -  5      n[!        UUXSUS9u  nnn[!        UUXSUS9u  nnn[        R,                  " S/US-  -  S/US-  -  -   5      nUU-  nU(       a  UU-  U-  U-  U-  nOUU-  U-  n[!        UUXS	US9u  n   n[        U5      nUR/                  UR1                  5       U5        UR3                  US-
  5        UR/                  U R1                  5       U5        UR3                  US-
  5        UR/                  UR1                  5       U5        U(       a  US:X  a  US:  a  [5        U5      $ U$ )u	  
Decomposes a unitary matrix into one and two qubit gates using Quantum Shannon Decomposition,
based on the Block ZXZ-Decomposition.

This decomposition is described in Krol and Al-Ars [2] and improves the method of
Shende et al. [1].

.. code-block:: text

      ┌───┐              ┌───┐     ┌───┐
     ─┤   ├─      ────□──┤ H ├──□──┤ H ├──□──
      │   │    ≃    ┌─┴─┐└───┘┌─┴─┐└───┘┌─┴─┐
    /─┤   ├─      ──┤ C ├─────┤ B ├─────┤ A ├
      └───┘         └───┘     └───┘     └───┘

The number of :class:`.CXGate`\ s generated with the decomposition without optimizations is
the same as the unoptimized method in [1]:

.. math::

    \frac{9}{16} 4^n - \frac{3}{2} 2^n

If ``opt_a1 = True``, the CX count is reduced, improving [1], by:

.. math::

    \frac{2}{3} (4^{n - 2} - 1).

Saving two :class:`.CXGate`\ s instead of one in each step of the recursion.

If ``opt_a2 = True``, the CX count is reduced, as in [1], by:

.. math::

    4^{n-2} - 1.

Hence, the number of :class:`.CXGate`\ s generated with the decomposition with optimizations is

.. math::

    \frac{22}{48} 4^n - \frac{3}{2} 2^n + \frac{5}{3}.

Args:
    mat: unitary matrix to decompose
    opt_a1: whether to try optimization A.1 from [1, 2].
        This should eliminate 2 ``cx`` per call.
    opt_a2: whether to try optimization A.2 from [1, 2].
        This decomposes two qubit unitaries into a diagonal gate and
        a two ``cx`` unitary and reduces overall ``cx`` count by :math:`4^{n-2} - 1`.
        This optimization should not be done if the original unitary is controlled.
    decomposer_1q: optional 1Q decomposer. If None, uses
        :class:`~qiskit.synthesis.OneQubitEulerDecomposer`.
    decomposer_2q: optional 2Q decomposer. If None, uses
        :class:`~qiskit.synthesis.TwoQubitBasisDecomposer`.

Returns:
    QuantumCircuit: Decomposed quantum circuit.

References:
    1. Shende, Bullock, Markov, *Synthesis of Quantum Logic Circuits*,
       `arXiv:0406176 [quant-ph] <https://arxiv.org/abs/quant-ph/0406176>`_
    2. Krol, Al-Ars, *Beyond Quantum Shannon: Circuit Construction for General
       n-Qubit Gates Based on Block ZXZ-Decomposition*,
       `arXiv:2403.13692 <https://arxiv.org/abs/2403.13692>`_
r      T      UnitaryGatec                T   > T" U 5      n[        SSS9nUR                  USS/5        U$ )Nr   qsd2q)namer   r   )r   append)matugateqcr   s      V/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/synthesis/unitary/qsd.py	decomp_2q#qs_decomposition.<locals>.decomp_2q   s0    ',E'8BIIeaV,I    Fall)opt_a1opt_a2_vw_typer   _ctrl_index)dtypeonly_w)r"   r#   r$   r   only_v)shape
bit_lengthnpallcloseidentityr   r	   OneQubitEulerDecomposer0qiskit.circuit.library.generalized_gates.unitaryr   r   r   _closest_unitaryrange_extract_multiplex_blocks_off_diagonals_are_zero_demultiplexr   _block_zxz_decompasarraycomplexeyediagr   to_instructionh	_apply_a2)"r   r"   r#   decomposer_1qdecomposer_2qr   dimnqubitscircr   
ctrl_indexum00um11um01um10decirc_qrA1A2BCiden	left_circvmatC_wmatC
right_circ_vmatAwmatAzmatB1B2middle_circr   s"                                    @r   qs_decompositionrZ   #   s   V ))A,Cnn"G~	{{2;;s#S))g&&
ax /GGIMS!
ax &1* !* 7 As#S!~.J%>s%O"D&t22 ) .J%>s%O"D&t22+!!"! '!j 8 1  ) 
	!B %RZZ7%CDLBAq66!!$%D+a Iuf !-
Bvx!J 77A3#(#rdcQh&778D	BE\A%,QY$
BvuVKA
 "DKK	((*B/FF7Q;KK**,b1FF7Q;KK
))+R0&A+#'Kr    c                   U R                   S   nUS-  nU SU2SU24   nU SU2US24   nXS2SU24   nXS2US24   n[        R                  R                  U5      u  pxn	[        R
                  " U5      n
UR                  5       R                  nXz-  U-  nXy-  n[        R                  R                  U5      u  pn[        R
                  " U5      n
UR                  5       R                  nX-  U-  nX-  nUR                  5       R                  nSU-  U-  nUR                  5       R                  nUSU-  -   U-  nUR                  5       R                  nXVSUU-  -  -  -   nSUU-  -  [        R                  " U5      -
  nUUUU4$ )z7Block ZXZ decomposition method, by Krol and Al-Ars [2].r   r   Ny              ?)	r*   scipylinalgsvdr,   r:   conjTr9   )Umatr@   nXYU21U22VXSWXdgSigmaVXdgSXUXVYWYdgVYdgSYUYUYdgCdgrN   rK   A1dgrL   rM   s                             r   r6   r6      sx   
**Q-CqARaR!VARaRVA
r2A2v,C
r12v,C,,""1%KB4GGAJE779;;D	d	B	B,,""1%KB4GGAJE779;;D	d	B	B779;;D
t)b.C
A
rBw,"	B779;;D	bD2I&'	'B	TAX"Ar1a<r    c                R    [         R                  R                  U 5      u  pnX-  n U $ )z0Find the closest unitary matrix to a matrix mat.)r\   r]   r^   )r   V_SWdgs       r   r1   r1      s(     !!#&JA3
'CJr    r!   )r$   r   r%   c                  U R                   S   UR                   S   -   nUR                  5       S-
  nUc  US-
  n[        [        SU5      5      [        [        US-   U5      5      -   U/-   n	XR                  R                  5       -  n
[        U
5      (       a"  [        R                  R                  U
5      u  pO0[        R                  R                  U
SS9u  pUR                  5       n[        R                  R                  U5      n[        R                  " U5      nXR                  R                  5       -  U-  n[!        U5      nUS;   a4  [#        UX#US-   S9R%                  5       nUR'                  UU	SUS-
   5        S[        R(                  " [        R*                  " U5      5      -  nUS	:X  a  U(       a  [-        UU5      nO3US
:X  a"  U(       a  [-        UU5      R/                  5       nO[-        UUSS9nUR'                  UU	S   /U	SUS-
   -   5        US;   a3  [#        XX5S-   S9R%                  5       nUR'                  UU	SUS-
   5        UUU4$ )u  Decompose a generic multiplexer.

      ────□────
       ┌──┴──┐
     /─┤     ├─
       └─────┘

represented by the block diagonal matrix

        ┏         ┓
        ┃ um0     ┃
        ┃     um1 ┃
        ┗         ┛

to
           ┌───┐
    ───────┤ Rz├──────
      ┌───┐└─┬─┘┌───┐
    /─┤ w ├──□──┤ v ├─
      └───┘     └───┘

where v and w are general unitaries determined from decomposition.

Args:
   um0 (ndarray): applied if MSB is 0
   um1 (ndarray): applied if MSB is 1
   opt_a1 (bool): whether to try optimization A.1 from [1, 2]. This should eliminate
      two ``cx`` gates per call.
   opt_a2 (bool): whether to try  optimization A.2 from [1, 2]. This decomposes two qubit
      unitaries into a diagonal gate and a two cx unitary and reduces overall ``cx`` count by
      4^(n-2) - 1. This optimization should not be done if the original unitary is controlled.
   _vw_type (string): "only_v", "only_w" or "all" for reductions.
      This is needed in order to combine the vmat or wmat into the B matrix in [2],
      instead of decomposing them.
   _depth (int): This is an internal variable to track the recursion depth.
   _ctrl_index (int): The index wrt which um0 and um1 are controlled.

Returns:
    QuantumCircuit: decomposed circuit
r   r   Nr8   )output)r'   r!   )r"   r#   r   r   r'   r(   r!   )r$   r)   )r(   r!   )r*   r+   listr2   r`   	conjugater
   r\   r]   eighschurdiagonalr,   emathsqrtr:   r   rZ   r;   r   angler_   	_get_ucrzreverse_ops)um0um1r"   r#   r$   r   r%   r@   rA   layoutum0um1eigvalsvmatevalsdvalsdmatwmatrB   	left_gateanglesucrz
right_gates                         r   r5   r5      s)   V ))A,1
%Cnn"Gk%;'(4kAow0O+PPT_S``F55??$$F6""))&1ll((	(B.."HHMM'"E775>D&&""$$s*D'"D $$$vz

.
 	 	Ivm!45 "''%.))F8&)	X	&&)557&59KKvbzlVMgk%::; $$%z

.
 	 	J}1 56tr    c                D   [        U 5      nUR                  SS nUR                  S   n[        R                  " US[	        U5      S5        [        U5       H  u  pg[        R                  " U5      [        :  a  UR                  Xu5        U[	        U5      S-
  :X  dU  [        R                  " US-   5      n[	        U5      [	        UR                  S5      5      -
  n	UR                  XI   U5        M  US:X  d  M  [	        U5      S-
  n	UR                  XI   U5        M     U$ )zTThis function synthesizes UCRZ without the final CX gate,
unless _vw_type = ``all``.r   Nr   F0r!   )r   qubitsr   _dec_uc_rotationslen	enumerater,   absr   rzbinary_reprrstripcx)
rA   r   r$   circuit
q_controlsq_targetir   
binary_repq_contr_indexs
             r   r   r   O  s     W%G#J~~a H$$VQFUCf%66%=4JJu'CK!O#A.J
Oc*2C2CC2H.IIMJJz0(;
Oa/MJJz0(; & Nr    c                   SSK Jn  SSKJn  SSKJn  [        nU" / SQSS9nU" U 5      n/ n[        UR                  5       H2  u  pU	R                  R                  S:X  d  M!  UR                  U5        M4     [        U5      S:X  a  U$ [        U5      S	:X  a#  S
UR                  US      R                  l
        U$ Sn
[        USS US	S 5       H  u  pUR                  U   nU" UR                  5      R                  nUR                  U
   nU" UR                  5      R                  nU" U5      u  nn[        R                  " U5      nUR!                  UR#                  5       S9UR                  U'   UU-  nUR!                  U" U5      5      UR                  U
'   M     [$        R&                  " W5      nUR                  U
   R!                  UR#                  5       S9UR                  U
'   U$ )zThe optimization A.2 from [1, 2]. This decomposes two qubit unitaries into a
diagonal gate and a two cx unitary and reduces overall ``cx`` count by
4^(n-2) - 1. This optimization should not be done if the original unitary is controlled.
r   )Operatorr   )HighLevelSynthesis)ur   r   F)basis_gatesqubits_initially_zeror   r   UnitaryNr)   )	operation)qiskit.quantum_infor   r0   r   "qiskit.transpiler.passes.synthesisr   r   r   datar   r   r   r   zipr   _from_circuit_datareplaceto_gater   two_qubit_cnot_decompose)rB   r   r   r   
decomposerhlsccircind2qr   instructionind2ind1instr1mat1instr2mat2r   
qc2cx_dataqc2cxqc3s                       r   r=   r=   e  s   
 -LE3J
)=UZ
[CIEE#EJJ/  %%0LLO 0 5zQ	Uq.7

58&&+D%",ac
3
D!(()..D!(()..%d+j11*=!>>EMMO>D

4d{!>>+d*;<

4 4 
6
6t
<Czz$'//#++-/HEJJtLr    c                   U R                   S   nUR                  5       S-
  nUS-  nU R                  SSU-  -  5      nUS:w  a1  [        R                  " XQS5      n[        R                  " XQU-   U5      nUR                  SUSU5      nUSSS2SSS24   nUSSS2SSS24   nUSSS2SSS24   n	USSS2SSS24   n
XxX4$ )aT  
A block diagonal gate is represented as:
[ um00 | um01 ]
[ ---- | ---- ]
[ um10 | um11 ]

Args:
   umat (ndarray): unitary matrix
   k (integer): qubit which indicates the ctrl index

Returns:
   um00 (ndarray): upper left block
   um01 (ndarray): upper right block
   um10 (ndarray): lower left block
   um11 (ndarray): lower right block
r   r   r   )r   N)r*   r+   reshaper,   moveaxis)umatkr@   rA   halfdimutensorud4rD   rE   rF   rG   s              r   r3   r3     s    " **Q-Cnn"GQhGll41w;/0G 	Av++g!,++g7{G< //!Wa
1Cq!Qz?Dq!Qz?Dq!Qz?Dq!Qz?Dt!!r    c                h    [         R                  " U SUS9=(       a    [         R                  " USUS9$ )z
Checks whether off-diagonal blocks are zero.

Args:
   um01 (ndarray): upper right block
   um10 (ndarray): lower left block
   atol (float): absolute tolerance

Returns:
   bool: whether both blocks are zero within tolerance
r   )atol)r,   r-   )rF   rG   r   s      r   r4   r4     s)     ;;tQT*Nr{{4/NNr    )NNNN)
r   z
np.ndarrayr"   bool | Noner#   r   r>   -Callable[[np.ndarray], QuantumCircuit] | Noner?   r   )FF)N)g-q=)!__doc__
__future__r   typingr   r\   numpyr,   qiskit.circuit.quantumcircuitr   r   qiskit.synthesis.two_qubitr   r   qiskit.synthesis.one_qubitr	   (qiskit.quantum_info.operators.predicatesr
   %qiskit.circuit.library.standard_gatesr   5qiskit.circuit.library.generalized_gates.uc_pauli_rotr   r   &qiskit._accelerate.two_qubit_decomposer   rZ   r6   r1   r5   r   r=   r3   r4    r    r   <module>r      s   
 #    I ; H 8 V U CGCGh h	hh h A	h
 AhV< $)X6;ASWXv,'T%"POr    