§
    º³Ùgì  ã                  óÈ   — d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	 ddl
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mZ ej        rddlmZ  G d„ de¦  «        ZdS )zQDrift Classé    )ÚannotationsN)Úchain)ÚCallable)ÚQuantumCircuit)ÚSparsePauliOpÚPauli)Údeprecate_arg)ÚQiskitErroré   )ÚProductFormulaÚreorder_paulis)ÚPauliEvolutionGatec                  ój   ‡ — e Zd ZdZ eddd„ dd¬¦  «        	 	 	 	 	 	 	 dd ˆ fd„¦   «         Zd!d„Zˆ xZS )"ÚQDriftay  The QDrift Trotterization method, which selects each each term in the
    Trotterization randomly, with a probability proportional to its weight. Based on the work
    of Earl Campbell in Ref. [1].

    References:
        [1]: E. Campbell, "A random compiler for fast Hamiltonian simulation" (2018).
        `arXiv:quant-ph/1811.08017 <https://arxiv.org/abs/1811.08017>`_
    Úatomic_evolutionz1.4c                ó^   — | d uo)t          t          j        | ¦  «        j        ¦  «        dk    S )Né   )ÚlenÚinspectÚ	signatureÚ
parameters)Úcallables    úW/granary/edev/quantum/lib/python3.11/site-packages/qiskit/synthesis/evolution/qdrift.pyú<lambda>zQDrift.<lambda>/   s1   €  8°4Ð#7ð $=Ý•Ô! (Ñ+Ô+Ô6Ñ7Ô7¸1Ò<ð ó    zkThe 'Callable[[Pauli | SparsePauliOp, float], QuantumCircuit]' signature of the 'atomic_evolution' argumentz™Instead you should update your 'atomic_evolution' function to be of the following type: 'Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None]'.)ÚnameÚsinceÚ	predicateÚdeprecation_descriptionÚadditional_msgr   Fr   NTÚrepsÚintÚinsert_barriersÚboolÚcx_structureÚstrú€Callable[[Pauli | SparsePauliOp, float], QuantumCircuit] | Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None] | NoneÚseedú
int | NoneÚwrapÚpreserve_orderÚreturnÚNonec           	     ó¬   •— t          ¦   «                              d||||||¦  «         d| _        t          j                             |¦  «        | _        dS )ak  
        Args:
            reps: The number of times to repeat the Trotterization circuit.
            insert_barriers: Whether to insert barriers between the atomic evolutions.
            cx_structure: How to arrange the CX gates for the Pauli evolutions, can be
                ``"chain"``, where next neighbor connections are used, or ``"fountain"``, where all
                qubits are connected to one. This only takes effect when
                ``atomic_evolution is None``.
            atomic_evolution: A function to apply the evolution of a single :class:`.Pauli`, or
                :class:`.SparsePauliOp` of only commuting terms, to a circuit. The function takes in
                three arguments: the circuit to append the evolution to, the Pauli operator to
                evolve, and the evolution time. By default, a single Pauli evolution is decomposed
                into a chain of ``CX`` gates and a single ``RZ`` gate.
                Alternatively, the function can also take Pauli operator and evolution time as
                inputs and returns the circuit that will be appended to the overall circuit being
                built.
            seed: An optional seed for reproducibility of the random sampling process.
            wrap: Whether to wrap the atomic evolutions into custom gate objects. This only takes
                effect when ``atomic_evolution is None``.
            preserve_order: If ``False``, allows reordering the terms of the operator to
                potentially yield a shallower evolution circuit. Not relevant
                when synthesizing operator with a single term.
        r   N)ÚsuperÚ__init__Úsampled_opsÚnpÚrandomÚdefault_rngÚrng)	Úselfr!   r#   r%   r   r(   r*   r+   Ú	__class__s	           €r   r0   zQDrift.__init__,   sW   ø€ õf 	‰Œ×ÒØˆt�_ lÐ4DÀdÈNñ	
ô 	
ð 	
ð  ˆÔÝ”9×(Ò(¨Ñ.Ô.ˆŒˆˆr   Ú	evolutionr   ú#list[tuple[str, tuple[int], float]]c                ó   ‡— |j         }|j        }t          |t          ¦  «        r,t          t	          j        d„ |D ¦   «         ¦  «        ¦  «        }n|                     ¦   «         }	 d„ |D ¦   «         }n"# t          $ r}t          d¦  «        |‚d }~ww xY wt          j
        |¦  «        }t          j        |¦  «        }t          j        d|dz  z  |dz  z  | j        z  ¦  «        }	| j                             t          j        |t$          ¬¦  «        |	f||z  ¬¦  «        }
d|z  |	z  |z  Šˆfd„|
D ¦   «         }| j        st)          |¦  «        }|S )Nc                ó6   — g | ]}|                      ¦   «         ‘ŒS © )Úto_sparse_list)Ú.0Úops     r   ú
<listcomp>z!QDrift.expand.<locals>.<listcomp>l   s$   € Ð.WÐ.WÐ.WÀr¨r×/@Ò/@Ñ/BÔ/BÐ.WÐ.WÐ.Wr   c                óX   — g | ]'\  }}}t          t          j        |¦  «        ¦  «        ‘Œ(S r<   )Úfloatr2   Úreal_if_close)r>   Ú_Úcoeffs      r   r@   z!QDrift.expand.<locals>.<listcomp>q   s1   € ÐOÐOÐO¹¸¸A¸u•e�BÔ,¨UÑ3Ô3Ñ4Ô4ÐOÐOÐOr   z)QDrift requires bound, real coefficients.r   )Údtype)ÚsizeÚpc           
     óŒ   •— g | ]@}|d          |d         t          j        t          j        |d         ¦  «        ¦  «        ‰z  f‘ŒAS )r   r   r   )r2   ÚrealÚsign)r>   ÚpauliÚrescaled_times     €r   r@   z!QDrift.expand.<locals>.<listcomp>‚   sR   ø€ ð 
ð 
ð 
ØQVˆU�1ŒX�u˜Q”x¥¤­¬°°q´Ñ):Ô):Ñ!;Ô!;¸mÑ!KÐLð
ð 
ð 
r   )ÚoperatorÚtimeÚ
isinstanceÚlistr   Úfrom_iterabler=   Ú	TypeErrorr
   r2   ÚabsÚsumÚmathÚceilr!   r5   ÚchoiceÚarrayÚobjectr+   r   )r6   r8   Ú	operatorsrO   ÚpaulisÚcoeffsÚexcÚweightsÚlambdÚ	num_gatesÚsampledÚsampled_paulisrM   s               @r   ÚexpandzQDrift.expande   sˆ  ø€ ØÔ&ˆ	ØŒ~ˆõ �i¥Ñ&Ô&ð 	0Ý�%Ô-Ð.WÐ.WÈYÐ.WÑ.WÔ.WÑXÔXÑYÔYˆFˆFà×-Ò-Ñ/Ô/ˆFð	TØOÐOÈÐOÑOÔOˆFˆFøÝð 	Tð 	Tð 	TÝÐIÑJÔJÐPSÐSøøøøð	Tøøøõ ”&˜‘.”.ˆÝ”�w‘”ˆå”I˜a 5¨!¡8™n°°a±Ñ8¸4¼9ÑDÑEÔEˆ	ð ”(—/’/ÝŒH�V¥6Ð*Ñ*Ô*°)°ÀÈ5Áð "ñ 
ô 
ˆð ˜E™	 IÑ-°Ñ4ˆð
ð 
ð 
ð 
ØZað
ñ 
ô 
ˆð Ô"ð 	<Ý+¨NÑ;Ô;ˆNàÐs   Á&A3 Á3
BÁ=BÂB)r   Fr   NNFT)r!   r"   r#   r$   r%   r&   r   r'   r(   r)   r*   r$   r+   r$   r,   r-   )r8   r   r,   r9   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   r0   rd   Ú__classcell__)r7   s   @r   r   r   "   sµ   ø€ € € € € ðð ð €]ØØð=ð =ð*ðVðñ ô ð  Ø %Ø#ð
 ØØØ#ð)/ð )/ð )/ð )/ð )/ð )/ñô ð)/ðV$ð $ð $ð $ð $ð $ð $ð $r   r   )rh   Ú
__future__r   r   rV   ÚtypingÚ	itertoolsr   Úcollections.abcr   Únumpyr2   Úqiskit.circuit.quantumcircuitr   Úqiskit.quantum_info.operatorsr   r   Úqiskit.utils.deprecationr	   Úqiskit.exceptionsr
   Úproduct_formular   r   ÚTYPE_CHECKINGÚqiskit.circuit.libraryr   r   r<   r   r   ú<module>rv      s+  ðð Ð à "Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø $Ð $Ð $Ð $Ð $Ð $Ø Ð Ð Ð Ø 8Ð 8Ð 8Ð 8Ð 8Ð 8Ø >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ø 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø )Ð )Ð )Ð )Ð )Ð )à ;Ð ;Ð ;Ð ;Ð ;Ð ;Ð ;Ð ;à	Ôð :Ø9Ð9Ð9Ð9Ð9Ð9ðgð gð gð gð gˆ^ñ gô gð gð gð gr   