§
    º³Ùg²*  ã                  óä   — d Z ddlmZ ddlZddlmZ ddlZddlZddl	m
Z
mZ ddlmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZ ddlmZ ddlmZ 	 	 	 	 dddœdd„Zdddœd„Zd„ Z d„ Z!dS ) zP
Quantum Shannon Decomposition.

Method is described in arXiv:quant-ph/0406176.
é    )ÚannotationsN)ÚCallable)ÚQuantumCircuitÚQuantumRegister)ÚTwoQubitBasisDecomposerÚtwo_qubit_decompose)Úone_qubit_decompose)Úis_hermitian_matrix)ÚCXGate)ÚUCPauliRotGateÚ_EPS)ÚUCRYGate)ÚUCRZGate)Ú"two_qubit_decompose_up_to_diagonalT)Ú_depthÚmatú
np.ndarrayÚopt_a1ÚboolÚopt_a2Údecomposer_1qú-Callable[[np.ndarray], QuantumCircuit] | NoneÚdecomposer_2qc               óB  ‡— | j         d         }t          t          j        |¦  «        ¦  «        }t	          j        t	          j        |¦  «        | ¦  «        rt          |¦  «        S |dk    r"|€t          j	        ¦   «         } || ¦  «        }�nô|dk    r@|€1|r|dk    rddl
mŠ ˆfd„}	|	}nt          t          ¦   «         ¦  «        } || ¦  «        }�n®t          |¦  «        }
t          |
¦  «        }|dz  }t          j                             | d||¬¦  «        \  \  }}}\  }}t%          |||||¬	¦  «        }|                     |                     ¦   «         |
¦  «         |r˜t+          |¦  «        }|dz  }t-          |d|z                       ¦   «         ¦  «        }|                     |                     ¦   «         t1          |¦  «        ¦  «         t	          j        |dd…|d…f         ¦  «        |dd…|d…f<   nLt5          d|z                       ¦   «         ¦  «        }|                     ||
d
         g|
dd
…         z   ¦  «         t%          |||||¬	¦  «        }|                     |                     ¦   «         |
¦  «         |r|dk    r|dk    rt7          |¦  «        S |S )u’  
    Decomposes a unitary matrix into one and two qubit gates using Quantum Shannon Decomposition,

    This decomposition is described in Shende et al. [1].

    .. code-block:: text

          â”Œâ”€â”€â”€â”�               â”Œâ”€â”€â”€â”�     â”Œâ”€â”€â”€â”�     â”Œâ”€â”€â”€â”�
         â”€â”¤   â”œâ”€       â”€â”€â”€â”€â”€â”€â”€â”¤ Rzâ”œâ”€â”€â”€â”€â”€â”¤ Ryâ”œâ”€â”€â”€â”€â”€â”¤ Rzâ”œâ”€â”€â”€â”€â”€
          â”‚   â”‚    â‰ƒ     â”Œâ”€â”€â”€â”�â””â”€â”¬â”€â”˜â”Œâ”€â”€â”€â”�â””â”€â”¬â”€â”˜â”Œâ”€â”€â”€â”�â””â”€â”¬â”€â”˜â”Œâ”€â”€â”€â”�
        /â”€â”¤   â”œâ”€       /â”€â”¤   â”œâ”€â”€â–¡â”€â”€â”¤   â”œâ”€â”€â–¡â”€â”€â”¤   â”œâ”€â”€â–¡â”€â”€â”¤   â”œ
          â””â”€â”€â”€â”˜          â””â”€â”€â”€â”˜     â””â”€â”€â”€â”˜     â””â”€â”€â”€â”˜     â””â”€â”€â”€â”˜

    The number of :class:`.CXGate`\ s generated with the decomposition without optimizations is:

    .. math::

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

    If ``opt_a1 = True``, the default, the CX count is reduced by:

    .. math::

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

    If ``opt_a2 = True``, the default, the CX count is reduced by:

    .. math::

        4^{n-2} - 1.

    Args:
        mat: unitary matrix to decompose
        opt_a1: whether to try optimization A.1 from Shende et al. [1].
            This should eliminate 1 ``cx`` per call.
            If ``True``, :class:`.CZGate`\s are left in the output.
            If desired these can be further decomposed to :class:`.CXGate`\s.
        opt_a2: whether to try optimization A.2 from Shende et al. [1].
            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`.
        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>`_
    r   é   Né   ©ÚUnitaryGatec                óp   •—  ‰| ¦  «        }t          dd¬¦  «        }|                     |ddg¦  «         |S )Nr   Úqsd2q)Únamer   é   )r   Úappend)r   ÚugateÚqcr   s      €úR/granary/edev/quantum/lib/python3.11/site-packages/qiskit/synthesis/unitary/qsd.pyÚ	decomp_2qz#qs_decomposition.<locals>.decomp_2qq   sA   ø€ Ø'˜K¨Ñ,Ô,�EÝ'¨°Ð8Ñ8Ô8�BØ—I’I˜e a¨ VÑ,Ô,Ð,Ø�Ió    T)ÚseparateÚpÚq©r   r   r   éÿÿÿÿ)ÚshapeÚintÚmathÚlog2ÚnpÚallcloseÚidentityr   r	   ÚOneQubitEulerDecomposerÚ0qiskit.circuit.library.generalized_gates.unitaryr   r   r   r   ÚscipyÚlinalgÚcossinÚ_demultiplexr#   Úto_instructionÚlenÚ_get_ucry_czÚtolistÚrangeÚnegativer   Ú	_apply_a2)r   r   r   r   r   r   ÚdimÚnqubitsÚcircr'   ÚqrÚdim_o2Úu1Úu2ÚvthetaÚv1hÚv2hÚ	left_circÚnanglesÚ	half_sizeÚcirc_czÚucryÚ
right_circr   s                          @r&   Úqs_decompositionrR   $   sÇ  ø€ ð| Œ)�AŒ,€CÝ•$”)˜C‘.”.Ñ!Ô!€GÝ	„{•2”;˜sÑ#Ô# SÑ)Ô)ð 'Ý˜gÑ&Ô&Ð&Ø
ˆa‚x€xØÐ Ý/ÔGÑIÔIˆMØˆ}˜SÑ!Ô!ˆ‰Ø	�ŠˆØÐ Øð B˜& 1š*˜*ðð ð ð ð ð ðð ð ð ð ð !*��å 7½¹¼Ñ AÔ A�Øˆ}˜SÑ!Ô!ˆ‰å˜WÑ%Ô%ˆÝ˜bÑ!Ô!ˆØ˜‘ˆå',¤|×':Ò':¸3ÈÐQWÐ[aÐ':Ñ'bÔ'bÑ$‰ˆˆR�&™*˜3 å   c°&ÀÐPVÐWÑWÔWˆ	Ø�Š�I×,Ò,Ñ.Ô.°Ñ3Ô3Ð3àð 
	2Ý˜&‘k”kˆGØ 1™ˆIå" 7¨Q°©Z×,?Ò,?Ñ,AÔ,AÑBÔBˆGØ�KŠK˜×.Ò.Ñ0Ô0µ%¸±.´.ÑAÔAÐAå "¤¨B¨q¨q¨q°)°*°*¨}Ô,=Ñ >Ô >ˆBˆqˆqˆq�)�*�*ˆ}ÑÐå˜Q ™Z×/Ò/Ñ1Ô1Ñ2Ô2ˆDØ�KŠK˜˜r "œv˜h¨¨C¨R¨C¬Ñ0Ñ1Ô1Ð1å! " b°ÀÈvÐVÑVÔVˆ
Ø�Š�J×-Ò-Ñ/Ô/°Ñ4Ô4Ð4àð �&˜A’+�+ #¨¢' 'Ý˜‰ŒÐØ€Kr(   Fc          
     óŒ  — | j         d         |j         d         z   }t          t          j        |¦  «        ¦  «        }| |j                             ¦   «         z  }t          |¦  «        r#t          j         	                    |¦  «        \  }}	n8t          j         
                    |d¬¦  «        \  }
}	|
                     ¦   «         }t          j                             |¦  «        }t          j        |¦  «        }||	j                             ¦   «         z  |z  }t!          |¦  «        }t#          ||||dz   ¬¦  «                             ¦   «         }|                     |t)          |dz
  ¦  «        ¦  «         dt          j        t          j        |¦  «        ¦  «        z  }t/          |                     ¦   «         ¦  «        }|                     ||dz
  gt3          t)          |dz
  ¦  «        ¦  «        z   ¦  «         t#          |	|||dz   ¬¦  «                             ¦   «         }|                     |t)          |dz
  ¦  «        ¦  «         |S )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 Shende. This should eliminate 1 cnot
          per call. If True CZ gates are left in the output. If desired these can be further decomposed
       opt_a2 (bool): whether to try  optimization A.2 from Shende. This decomposes two qubit
          unitaries into a diagonal gate and a two cx unitary and reduces overall cx count by
          4^(n-2) - 1.
       _depth (int): This is an internal variable to track the recursion depth.

    Returns:
        QuantumCircuit: decomposed circuit
    r   Úcomplex)Úoutputr"   r,   r   )r.   r/   r0   r1   ÚTÚ	conjugater
   r7   r8   ÚeighÚschurÚdiagonalr2   ÚemathÚsqrtÚdiagr   rR   r;   r#   r?   ÚangleÚconjr   r>   Úlist)Úum0Úum1r   r   r   rB   rC   Úum0um1ÚeigvalsÚvmatÚevalsÚdvalsÚdmatÚwmatrD   Ú	left_gateÚanglesÚucrzÚ
right_gates                      r&   r:   r:   ™   sù  € ðJ Œ)�AŒ,˜œ 1œÑ
%€CÝ•$”)˜C‘.”.Ñ!Ô!€GØ�3”5—?’?Ñ$Ô$Ñ$€FÝ˜6Ñ"Ô"ð #Ýœ×)Ò)¨&Ñ1Ô1‰ˆ��å”l×(Ò(¨¸	Ð(ÑBÔB‰ˆˆtØ—.’.Ñ"Ô"ˆÝŒH�MŠM˜'Ñ"Ô"€EÝŒ7�5‰>Œ>€DØ�$”&×"Ò"Ñ$Ô$Ñ$ sÑ*€Då˜'Ñ"Ô"€Dõ !Ø�V F°6¸A±:ðñ ô ç‚nÑÔð ð 	‡K‚K�	�5 ¨1¡Ñ-Ô-Ñ.Ô.Ð.ð •”�"œ' %™.œ.Ñ)Ô)Ñ)€FÝ�F—M’M‘O”OÑ$Ô$€DØ‡K‚K��w ‘{�m¥d­5°¸1±Ñ+=Ô+=Ñ&>Ô&>Ñ>Ñ?Ô?Ð?õ "Ø�V F°6¸A±:ðñ ô ç‚nÑÔð ð 	‡K‚K�
�E '¨A¡+Ñ.Ô.Ñ/Ô/Ð/à€Kr(   c                ó.  — t          |¦  «        }t          | ¦  «        }|j        dd…         }|j        d         }|sAt          j        |d         ¦  «        t
          k    r|                     |d         |¦  «         �n|                     ¦   «         }t          j	        |dt          |¦  «        d¦  «         t          |¦  «        D ]Ï\  }}t          j        |¦  «        t
          k    r|                     ||¦  «         |t          |¦  «        dz
  k    sJt          j        |dz   ¦  «        }t          |¦  «        t          |                     d¦  «        ¦  «        z
  }	nt          |¦  «        dz
  }	||dz
  k     r|                     ||	         |¦  «         ŒÐ|S )zI
    Get uniformly controlled Ry gate in CZ-Ry as in UCPauliRotGate.
    Nr-   r   Fr"   Ú0)r<   r   Úqubitsr2   Úabsr   ÚryÚcopyr   Ú_dec_uc_rotationsÚ	enumerateÚbinary_reprÚrstripÚcz)
rC   rk   rM   r%   Ú
q_controlsÚq_targetÚir^   Ú
binary_repÚq_contr_indexs
             r&   r=   r=   à   sj  € õ �&‰kŒk€GÝ	˜Ñ	 Ô	 €BØ”˜3˜B˜3”€JØŒy˜Œ}€HØð ;ÝŒ6�&˜”)ÑÔ�tÒ#Ð#Ø�EŠE�&˜”)˜XÑ&Ô&Ð&ùà—’‘”ˆÝÔ(¨°µC¸±K´KÀÑGÔGÐGÝ! &Ñ)Ô)ð 	;ð 	;‰HˆAˆuÝŒv�e‰}Œ}�tÒ#Ð#Ø—’�e˜XÑ&Ô&Ð&Ø�˜F™œ a™Ò'Ð'Ýœ^¨A°©EÑ2Ô2�
Ý # J¡¤µ#°j×6GÒ6GÈÑ6LÔ6LÑ2MÔ2MÑ M��õ !$ J¡¤°!Ñ 3�à�7˜Q‘;ŠˆØ—’�j Ô/°Ñ:Ô:Ð:øØ€Ir(   c                óì  — ddl m} ddlm} ddlm} t          } |g d¢d¬¦  «        } || ¦  «        }g }t          |j        ¦  «        D ]*\  }}	|	j	        j
        dk    r|                     |¦  «         Œ+t          |¦  «        dk    r|S t          |¦  «        d	k    rd
|j        |d                  j	        _
        |S d }
t          |dd…         |d	d …         ¦  «        D ]Æ\  }}
|j        |         } ||j	        ¦  «        j        }|j        |
         } ||j	        ¦  «        j        } ||¦  «        \  }}t          j        |¦  «        }|                     |                     ¦   «         ¬¦  «        |j        |<   ||z  }|                      ||¦  «        ¦  «        |j        |
<   ŒÇt%          j        |¦  «        }|j        |
                              |                     ¦   «         ¬¦  «        |j        |
<   |S )Nr   )ÚOperatorr   )ÚHighLevelSynthesis)ÚuÚcxr    F)Úbasis_gatesÚqubits_initially_zeror    r"   ÚUnitaryr-   )Ú	operation)Úqiskit.quantum_infor   r6   r   Ú"qiskit.transpiler.passes.synthesisr€   r   ru   Údatar†   r!   r#   r<   Úzipr   Ú_from_circuit_dataÚreplaceÚto_gater   Útwo_qubit_cnot_decompose)rD   r   r   r€   Ú
decomposerÚhlsÚccircÚind2qr{   ÚinstructionÚind2Úind1Úinstr1Úmat1Úinstr2Úmat2rh   Ú
qc2cx_dataÚqc2cxÚqc3s                       r&   rA   rA   ý   s  € Ø,Ð,Ð,Ð,Ð,Ð,ØLÐLÐLÐLÐLÐLØEÐEÐEÐEÐEÐEå3€JØ
Ð
Ð)=Ð)=Ð)=ÐUZÐ
[Ñ
[Ô
[€CØˆC�‰IŒI€EØ€Eå# E¤JÑ/Ô/ð ð ‰ˆˆ;ØÔ Ô%¨Ò0Ð0Ø�LŠL˜‰OŒOˆOøÝ
ˆ5�z„z�Q‚€ØˆÝ	ˆU‰Œ�qŠˆà.7ˆŒ
�5˜”8ÔÔ&Ô+Øˆà€DÝ˜%  " œ,¨¨a¨c¨c¬
Ñ3Ô3ð =ð =‰
ˆˆdà”˜DÔ!ˆØˆx˜Ô(Ñ)Ô)Ô.ˆØ”˜DÔ!ˆØˆx˜Ô(Ñ)Ô)Ô.ˆà%˜: dÑ+Ô+ÑˆˆjÝÔ1°*Ñ=Ô=ˆØ!Ÿ>š>°E·M²M±O´O˜>ÑDÔDˆŒ
�4ÑØ�d‰{ˆØ!Ÿ>š>¨+¨+°dÑ*;Ô*;Ñ<Ô<ˆŒ
�4ÑÐÝ
Ô
6°tÑ
<Ô
<€CØ”z $Ô'×/Ò/¸#¿+º+¹-¼-Ð/ÑHÔH€E„JˆtÑØ€Lr(   )TTNN)
r   r   r   r   r   r   r   r   r   r   )FF)"Ú__doc__Ú
__future__r   r0   Útypingr   r7   Únumpyr2   Ú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.circuit.library.generalized_gates.ucryr   Ú-qiskit.circuit.library.generalized_gates.ucrzr   Ú&qiskit._accelerate.two_qubit_decomposer   rR   r:   r=   rA   © r(   r&   ú<module>r«      s¦  ððð ð
 #Ð "Ð "Ð "Ð "Ð "Ø €€€Ø Ð Ð Ð Ð Ð Ø €€€Ø Ð Ð Ð Ø IÐ IÐ IÐ IÐ IÐ IÐ IÐ Iðð ð ð ð ð ð ð ð ;Ð :Ð :Ð :Ð :Ð :Ø HÐ HÐ HÐ HÐ HÐ HØ 8Ð 8Ð 8Ð 8Ð 8Ð 8Ø VÐ VÐ VÐ VÐ VÐ VÐ VÐ VØ BÐ BÐ BÐ BÐ BÐ BØ BÐ BÐ BÐ BÐ BÐ BØ UÐ UÐ UÐ UÐ UÐ Uð
 ØØCGØCGðrð ðrð rð rð rð rð rðjDÀð Dð Dð Dð Dð DðNð ð ð:#ð #ð #ð #ð #r(   