
    z	i                         S 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
   " S S\5      rS	 r   SS
\S\S\S\S\S\4S jjrg)zUnitary overlap circuit.    )QuantumCircuitGate)ParameterVector)CircuitError)Barrier)deprecate_funcc                   d   ^  \ rS rSrSr\" SSSS9   SS\S\S	\S
\S\4
U 4S jjj5       r	Sr
U =r$ )UnitaryOverlap   aX  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2.1z3Use qiskit.circuit.library.unitary_overlap instead.zin Qiskit 3.0)sinceadditional_msgremoval_timelineunitary1unitary2prefix1prefix2insert_barrierc                    > [        XX4U5      n[        TU ]  " UR                  SUR                  06  U R                  X`R                  SS9  g)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          X/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/circuit/library/overlap.pyr   UnitaryOverlap.__init__>   sA    6 "(gW'--;gll;W[[$?     p1p2F)__name__
__module____qualname____firstlineno____doc__r   r   strboolr   __static_attributes____classcell__)r   s   @r    r
   r
      sm    %N L( $@ @ !@ 	@
 @ @
@r"   r
   c                     U R                    HK  n[        UR                  [        [        45      (       a  M*  [        SUR                  R                   S35      e   g)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_unitaryr5   ^   sV     ||+//$AA(227788SU  $r"   r   r   r   r   r   returnc                 $   U R                   UR                   :w  a&  [        SU R                    SUR                    S35      eX/nU H  n[        U5        M     [        X#/5       HF  u  pxXW   R                  S:  d  M  [        XU   R                  5      n	XW   R                  U	5      XW'   MH     [        US   R                   SS9n
U
R                  US   SS9  U(       a  U
R                  5         U
R                  US	   R                  5       SS9  U
$ )
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 efficient_su2, unitary_overlap

    # get two circuit to prepare states of which we compute the overlap
    circuit = efficient_su2(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   r5   	enumeratenum_parametersr   assign_parametersr   r   barrierinverse)r   r   r   r   r   	unitariesunitaryiprefix
new_paramsr   s              r    r   r   i   s   n h111"--.d83F3F2GqJ
 	

 $Iw 
 12	<&&*(11L1LMJ$<99*EIL 3 Yq\44;KLGOOIaL$O/OOIaL((*DO9Nr"   Nr$   )r+   qiskit.circuitr   r   qiskit.circuit.parametervectorr   qiskit.circuit.exceptionsr   r   qiskit.utils.deprecationr   r
   r5   r,   r-   r   r#   r"   r    <module>rI      s~     / : 2 " 3E@^ E@P  NNN N 	N
 N Nr"   