§
    ¹³Ùgè  ã                   ó”   — d 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
  G d„ de¦  «        Zd	„ Z	 	 	 ddedededededefd„ZdS )zUnitary overlap circuit.é    )ÚQuantumCircuitÚGate)ÚParameterVector)ÚCircuitError)ÚBarrier)Údeprecate_funcc                   óh   ‡ — e Zd ZdZ eddd¬¦  «        	 	 	 dd	ed
edededef
ˆ fd„¦   «         Zˆ xZ	S )ÚUnitaryOverlapa¼  Circuit that returns the overlap between two unitaries :math:`U_2^{\dag} U_1`.

    The input quantum circuits must represent unitary operations, since they must be invertible.
    If the inputs will have parameters, they are replaced by :class:`.ParameterVector`\s with
    names `"p1"` (for circuit ``unitary1``) and `"p2"` (for circuit ``unitary_2``) in the output
    circuit.

    This circuit is usually employed in computing the fidelity:

    .. math::

        \left|\langle 0| U_2^{\dag} U_1|0\rangle\right|^{2}

    by computing the probability of being in the all-zeros bit-string, or equivalently,
    the expectation value of projector :math:`|0\rangle\langle 0|`.

    Example::

        import numpy as np
        from qiskit.circuit.library import EfficientSU2, UnitaryOverlap
        from qiskit.primitives import Sampler

        # get two circuit to prepare states of which we compute the overlap
        circuit = EfficientSU2(2, reps=1)
        unitary1 = circuit.assign_parameters(np.random.random(circuit.num_parameters))
        unitary2 = circuit.assign_parameters(np.random.random(circuit.num_parameters))

        # create the overlap circuit
        overlap = UnitaryOverlap(unitary1, unitary2)

        # sample from the overlap
        sampler = Sampler(options={"shots": 100})
        result = sampler.run(overlap).result()

        # the fidelity is the probability to measure 0
        fidelity = result.quasi_dists[0].get(0, 0)

    z1.3z3Use qiskit.circuit.library.unitary_overlap instead.T)ÚsinceÚadditional_msgÚpendingÚp1Úp2FÚunitary1Úunitary2Úprefix1Úprefix2Úinsert_barrierc                 ó®   •— t          |||||¦  «        } t          ¦   «         j        |j        d|j        iŽ |                      || j        d¬¦  «         dS )a¼  
        Args:
            unitary1: Unitary acting on the ket vector.
            unitary2: Unitary whose inverse operates on the bra vector.
            prefix1: The name of the parameter vector associated to ``unitary1``,
                if it is parameterized. Defaults to ``"p1"``.
            prefix2: The name of the parameter vector associated to ``unitary2``,
                if it is parameterized. Defaults to ``"p2"``.
            insert_barrier: Whether to insert a barrier between the two unitaries.

        Raises:
            CircuitError: Number of qubits in ``unitary1`` and ``unitary2`` does not match.
            CircuitError: Inputs contain measurements and/or resets.
        ÚnameT)ÚqubitsÚinplaceN)Úunitary_overlapÚsuperÚ__init__Úqregsr   Úcomposer   )Úselfr   r   r   r   r   ÚcircuitÚ	__class__s          €úT/granary/edev/quantum/lib/python3.11/site-packages/qiskit/circuit/library/overlap.pyr   zUnitaryOverlap.__init__>   sZ   ø€ õ6 " (¨H°g¸wÈÑWÔWˆØ�‰ŒÔ˜'œ-Ð;¨g¬lÐ;Ð;Ð;Ø�Š�W T¤[¸$ˆÑ?Ô?Ð?Ð?Ð?ó    ©r   r   F)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   ÚstrÚboolr   Ú__classcell__)r    s   @r!   r
   r
      sÁ   ø€ € € € € ð%ð %ðN €^ØØLØðñ ô ð ØØ$ð@ð @à ð@ð !ð@ð ð	@ð
 ð@ð ð@ð @ð @ð @ð @ñô ð
@ð @ð @ð @ð @r"   r
   c                 ó–   — | j         D ]@}t          |j        t          t          f¦  «        st          d|j        j        › d�¦  «        ‚ŒAdS )zNCheck a circuit is unitary by checking if all operations are of type ``Gate``.z9One or more instructions cannot be converted to a gate. "z" is not a gate instructionN)ÚdataÚ
isinstanceÚ	operationr   r   r   r   )r   Úinstructions     r!   Ú_check_unitaryr0   ^   sp   € ð ”|ð ð ˆÝ˜+Ô/µ$½°ÑAÔAð 	ÝðUØ(Ô2Ô7ðUð Uð Uñô ð ð	ðð r"   r   r   Fr   r   r   r   r   Úreturnc                 óT  — | j         |j         k    r t          d| j         › d|j         › d�¦  «        ‚| |g}|D ]}t          |¦  «         Œt          ||g¦  «        D ]O\  }}||         j        dk    r9t          |||         j        ¦  «        }	||                              |	¦  «        ||<   ŒPt          |d         j         d¬¦  «        }
|
                     |d         d¬¦  «         |r|
 	                    ¦   «          |
                     |d	          
                    ¦   «         d¬¦  «         |
S )
a´  Circuit that returns the overlap between two unitaries :math:`U_2^{\dag} U_1`.

    The input quantum circuits must represent unitary operations, since they must be invertible.
    If the inputs will have parameters, they are replaced by :class:`.ParameterVector`\s with
    names `"p1"` (for circuit ``unitary1``) and `"p2"` (for circuit ``unitary_2``) in the output
    circuit.

    This circuit is usually employed in computing the fidelity:

    .. math::

        \left|\langle 0| U_2^{\dag} U_1|0\rangle\right|^{2}

    by computing the probability of being in the all-zeros bit-string, or equivalently,
    the expectation value of projector :math:`|0\rangle\langle 0|`.

    **Reference Circuit:**

    .. plot::
        :alt: Circuit diagram output by the previous code.
        :include-source:

        import numpy as np
        from qiskit.circuit.library import EfficientSU2, unitary_overlap

        # get two circuit to prepare states of which we compute the overlap
        circuit = EfficientSU2(2, reps=1)
        unitary1 = circuit.assign_parameters(np.random.random(circuit.num_parameters))
        unitary2 = circuit.assign_parameters(np.random.random(circuit.num_parameters))

        # create the overlap circuit
        overlap = unitary_overlap(unitary1, unitary2)
        overlap.draw('mpl')

    Args:
        unitary1: Unitary acting on the ket vector.
        unitary2: Unitary whose inverse operates on the bra vector.
        prefix1: The name of the parameter vector associated to ``unitary1``,
            if it is parameterized. Defaults to ``"p1"``.
        prefix2: The name of the parameter vector associated to ``unitary2``,
            if it is parameterized. Defaults to ``"p2"``.
        insert_barrier: Whether to insert a barrier between the two unitaries.

    Raises:
        CircuitError: Number of qubits in ``unitary1`` and ``unitary2`` does not match.
        CircuitError: Inputs contain measurements and/or resets.
    z.Number of qubits in unitaries does not match: z != ú.r   r
   )r   T)r   é   )Ú
num_qubitsr   r0   Ú	enumerateÚnum_parametersr   Úassign_parametersr   r   ÚbarrierÚinverse)r   r   r   r   r   Ú	unitariesÚunitaryÚiÚprefixÚ
new_paramsr   s              r!   r   r   i   se  € ðn Ô˜hÔ1Ò1Ð1ÝðJØ"Ô-ðJð JØ3;Ô3FðJð Jð Jñ
ô 
ð 	
ð
 ˜8Ð$€IØð  ð  ˆÝ�wÑÔÐÐõ  ¨Ð1Ñ2Ô2ð Fð F‰	ˆˆ6Ø�QŒ<Ô&¨Ò*Ð*Ý(¨°¸1´Ô1LÑMÔMˆJØ$ Qœ<×9Ò9¸*ÑEÔEˆI�a‰Løõ ˜Y qœ\Ô4Ð;KÐLÑLÔL€GØ‡O‚O�I˜a”L¨$€OÑ/Ô/Ð/Øð Ø�ŠÑÔÐØ‡O‚O�I˜a”L×(Ò(Ñ*Ô*°D€OÑ9Ô9Ð9Ø€Nr"   Nr#   )r'   Úqiskit.circuitr   r   Úqiskit.circuit.parametervectorr   Úqiskit.circuit.exceptionsr   r   Úqiskit.utils.deprecationr   r
   r0   r(   r)   r   © r"   r!   ú<module>rE      s*  ðð Ð à /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ø :Ð :Ð :Ð :Ð :Ð :Ø 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø "Ð "Ð "Ð "Ð "Ð "Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3ðE@ð E@ð E@ð E@ð E@�^ñ E@ô E@ð E@ðPð ð ð ØØ ðNð NØðNàðNð ðNð ð	Nð
 ðNð ðNð Nð Nð Nð Nð Nr"   