§
    ¹³Ùg¶"  ã                  ó²   — d Z ddlmZ ddlZddlZddlmZ ddlm	Z	 ddl
mZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ dZ G d„ de¦  «        ZdS )z;Uniformly controlled gates (also called multiplexed gates).é    )ÚannotationsN)ÚGate)ÚHGate)Úis_unitary_matrix)ÚQuantumRegister)ÚQuantumCircuit)ÚCircuitError)ÚQiskitError)Úuc_gateé   )ÚDiagonalg»½×Ùß|Û=c                  óh   ‡ — e Zd ZdZddˆ fd„Zddˆ fd„Zd„ Zd„ Zd„ Zd„ Z	e
d„ ¦   «         Zd„ Zˆ xZS )ÚUCGatea�  Uniformly controlled gate (also called multiplexed gate).

    These gates can have several control qubits and a single target qubit.
    If the k control qubits are in the state :math:`|i\rangle` (in the computational basis),
    a single-qubit unitary :math:`U_i` is applied to the target qubit.

    This gate is represented by a block-diagonal matrix, where each block is a
    :math:`2\times 2` unitary, that is

    .. math::

        \begin{pmatrix}
            U_0 & 0 & \cdots & 0 \\
            0 & U_1 & \cdots & 0 \\
            \vdots  &     & \ddots & \vdots \\
            0 & 0   &  \cdots & U_{2^{k-1}}
        \end{pmatrix}.

    The decomposition is based on Ref. [1].

    **References:**

    [1] Bergholm et al., Quantum circuits with uniformly controlled one-qubit gates (2005).
        `Phys. Rev. A 71, 052330 <https://journals.aps.org/pra/abstract/10.1103/PhysRevA.71.052330>`__.

    FÚ	gate_listúlist[np.ndarray]Úup_to_diagonalÚboolc                ó
  •— t          |t          ¦  «        st          d¦  «        ‚|D ]}|j        dk    st          d¦  «        ‚Œ|st          d¦  «        ‚t	          j        t          |¦  «        ¦  «        }|dk     s|                     ¦   «         st          d¦  «        ‚|D ]&}t          |t          ¦  «        st          d¦  «        ‚Œ't          ¦   «                              dt          |¦  «        d	z   |¦  «         || _        d
S )a}  
        Args:
            gate_list: List of two qubit unitaries :math:`[U_0, ..., U_{2^{k-1}}]`, where each
                single-qubit unitary :math:`U_i` is given as a :math:`2 \times 2` numpy array.
            up_to_diagonal: Determines if the gate is implemented up to a diagonal.
                or if it is decomposed completely (default: False).
                If the ``UCGate`` :math:`U` is decomposed up to a diagonal :math:`D`, this means
                that the circuit implements a unitary :math:`U'` such that :math:`D U' = U`.

        Raises:
            QiskitError: in case of bad input to the constructor
        z6The single-qubit unitaries are not provided in a list.)é   r   z9The dimension of a controlled gate is not equal to (2,2).zThe gate list cannot be empty.r   zMThe number of controlled single-qubit gates is not a non-negative power of 2.z!A controlled gate is not unitary.Úmultiplexerr   N)Ú
isinstanceÚlistr
   ÚshapeÚmathÚlog2ÚlenÚ
is_integerr   Ú_EPSÚsuperÚ__init__Úintr   )Úselfr   r   ÚgateÚ	num_contrÚ	__class__s        €úa/granary/edev/quantum/lib/python3.11/site-packages/qiskit/circuit/library/generalized_gates/uc.pyr    zUCGate.__init__F   s(  ø€ õ ˜)¥TÑ*Ô*ð 	XÝÐVÑWÔWÐWØð 	_ð 	_ˆDØ”: Ò'Ð'Ý!Ð"]Ñ^Ô^Ð^ð (àð 	@ÝÐ>Ñ?Ô?Ð?õ ”I�c )™nœnÑ-Ô-ˆ	Ø�qŠ=ˆ= 	× 4Ò 4Ñ 6Ô 6ˆ=ÝØ_ñô ð ð
 ð 	Gð 	GˆDÝ$ T­4Ñ0Ô0ð GÝ!Ð"EÑFÔFÐFðGõ 	‰Œ×Ò˜­¨I©¬¸Ñ(:¸IÑFÔFÐFØ,ˆÔÐÐó    Ú	annotatedÚreturnr   c                óš  •— |s¥t          | j        dz   | j        g ¬¦  «        }t          | j        j        Ž }t          | j        ¦  «        D ]D}|                     | 	                    |j
                             |¬¦  «        ¬¦  «        ¦  «         ŒE| j        j         |_        ||_        n"t          ¦   «                              |¬¦  «        }|S )z¹Return the inverse.

        This does not re-compute the decomposition for the multiplexer with the inverse of the
        gates but simply inverts the existing decomposition.
        Ú_dg)ÚnameÚ
num_qubitsÚparams)r(   )Ú	operation)r   r,   r-   r   Ú
definitionÚqregsÚreversedÚ_definitionÚ_appendÚreplacer/   ÚinverseÚglobal_phaser   )r"   r(   Úinverse_gater0   Úinstr%   s        €r&   r6   zUCGate.inversel   sØ   ø€ ð ð 	@ÝØ”Y Ñ&°4´?È2ðñ ô ˆLõ (¨¬Ô)>Ð?ˆJÝ  Ô!1Ñ2Ô2ð ð �Ø×"Ò"Ø—L’L¨4¬>×+AÒ+AÈIÐ+AÑ+VÔ+V�LÑWÔWñô ð ð ð (,¤Ô'CÐ&CˆJÔ#à&0ˆLÔ#Ð#å ™7œ7Ÿ?š?°Y˜?Ñ?Ô?ˆLØÐr'   c                ó4   — |                       ¦   «         \  }}|S ©N)Ú_dec_ucg)r"   Ú_Údiags      r&   Ú_get_diagonalzUCGate._get_diagonal„   s   € ð
 —-’-‘/”/‰ˆˆ4Øˆr'   c                óB   — |                       ¦   «         \  }}|| _        d S r;   )r<   r0   )r"   Úucg_circuitr=   s      r&   Ú_definezUCGate._defineŒ   s   € ØŸš™œ‰ˆ�QØ%ˆŒˆˆr'   c           	     óî  — t          j        d| j        z  ¦  «                             ¦   «         }t	          | j        d¦  «        }|dd…         }|d         }t          |d¬¦  «        }|s&|                     | j        d         |g¦  «         ||fS |                      ¦   «         \  }}t          |¦  «        D �]\  }}|dk    r5t          ¦   «                              ¦   «                              |¦  «        }	�n|t          |¦  «        dz
  k    rl|                     t                               t           j        dz  ¦  «        ¦  «                             t          ¦   «                              ¦   «         ¦  «        }	nœt          ¦   «                              ¦   «                              |                     t                               t           j        dz  ¦  «        ¦  «        ¦  «                             t          ¦   «                              ¦   «         ¦  «        }	|                     |	|g¦  «         t          j        |dz   ¦  «        }
t          |
¦  «        t          |
                     d¦  «        ¦  «        z
  }|}|t          |¦  «        dz
  k    s9|                     ||         |¦  «         |xj        d	t           j        z  z  c_        �Œ| j        s%t-          |¦  «        }|                     ||¦  «         ||fS )
zß
        Call to create a circuit that implements the uniformly controlled gate. If
        up_to_diagonal=True, the circuit implements the gate up to a diagonal gate and
        the diagonal gate is also returned.
        r   Úqr   Nr   Úuc)r,   Ú0g      Ð?)ÚnpÚonesr-   Útolistr   r   Úunitaryr.   Ú_dec_ucg_helpÚ	enumerater   Ú	to_matrixÚdotr   r   Ú_rzÚpiÚbinary_reprÚrstripÚcxr7   r   r   Úappend)r"   r>   rD   Ú
q_controlsÚq_targetÚcircuitÚsingle_qubit_gatesÚir#   ÚsquÚ
binary_repÚnum_trailing_zerosÚq_contr_indexÚdiagonals                 r&   r<   zUCGate._dec_ucg�   s‰  € õ Œw�q˜$œ/Ñ)Ñ*Ô*×1Ò1Ñ3Ô3ˆÝ˜DœO¨SÑ1Ô1ˆØ�q�r�r”Uˆ
Ø�Q”4ˆÝ  ¨Ð.Ñ.Ô.ˆàð 	!Ø�OŠO˜DœK¨œN¨Q¨CÑ0Ô0Ð0Ø˜D�=Ð ð &*×%7Ò%7Ñ%9Ô%9Ñ"Ð	˜Tõ !Ð!3Ñ4Ô4ð 	5ñ 	5‰GˆAˆtà�AŠvˆvÝ‘g”g×'Ò'Ñ)Ô)×-Ò-¨dÑ3Ô3�‘Ø•cÐ,Ñ-Ô-°Ñ1Ò1Ð1Ø—h’h�vŸzšz­"¬%°!©)Ñ4Ô4Ñ5Ô5×9Ò9½%¹'¼'×:KÒ:KÑ:MÔ:MÑNÔN��õ ‘G”Gß’Y‘[”[ß’S˜Ÿš¥&§*¢*­R¬U°Q©YÑ"7Ô"7Ñ8Ô8Ñ9Ô9ß’S�™œ×*Ò*Ñ,Ô,Ñ-Ô-ð	 ð �OŠO˜C ( Ñ,Ô,Ð,õ œ¨¨A©Ñ.Ô.ˆJÝ!$ Z¡¤µ3°z×7HÒ7HÈÑ7MÔ7MÑ3NÔ3NÑ!NÐØ.ˆMà�Ð.Ñ/Ô/°!Ñ3Ò3Ð3Ø—
’
˜: mÔ4°hÑ?Ô?Ð?ØÐ$Ô$¨­r¬u©Ñ4Ð$Ô$ùØÔ"ð 	(õ   ‘~”~ˆHØ�NŠN˜8 QÑ'Ô'Ð'Ø˜ˆ}Ðr'   c                óX   — d„ | j         D ¦   «         }t          j        || j        ¦  «        S )zž
        This method finds the single qubit gate arising in the decomposition of UCGates given in
        https://arxiv.org/pdf/quant-ph/0410066.pdf.
        c                óB   — g | ]}|                      t          ¦  «        ‘ŒS © )ÚastypeÚcomplex)Ú.0r#   s     r&   ú
<listcomp>z(UCGate._dec_ucg_help.<locals>.<listcomp>É   s$   € ÐKÐKÐK°t˜dŸkšk­'Ñ2Ô2ÐKÐKÐKr'   )r.   r   Údec_ucg_helpr-   )r"   rX   s     r&   rK   zUCGate._dec_ucg_helpÄ   s1   € ð
 LÐK¸t¼{ÐKÑKÔKÐÝÔ#Ð$6¸¼ÑHÔHÐHr'   c                ó–   — t          j        t          j        d| z  dz  ¦  «        dgdt          j        d| z  dz  ¦  «        gg¦  «        S )Ny              ð?r   r   y       €      ð¿)rG   ÚarrayÚexp)Úalphas    r&   rO   z
UCGate._rzÌ   sE   € åŒx�"œ&  e¡¨a¡Ñ0Ô0°!Ð4°q½"¼&ÀÀuÁÈqÁÑ:QÔ:QÐ6RÐSÑTÔTÐTr'   c                óˆ   — t          |t          j        ¦  «        r|S t          dt	          |¦  «        › d| j        › �¦  «        ‚)z9Uniformly controlled gate parameter has to be an ndarray.zinvalid param type z	 in gate )r   rG   Úndarrayr	   Útyper,   )r"   Ú	parameters     r&   Úvalidate_parameterzUCGate.validate_parameterÐ   sD   € å�i¥¤Ñ,Ô,ð 	\ØÐåÐZµT¸)±_´_ÐZÐZÈtÌyÐZÐZÑ[Ô[Ð[r'   )F)r   r   r   r   )r(   r   r)   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r    r6   r?   rB   r<   rK   ÚstaticmethodrO   ro   Ú__classcell__)r%   s   @r&   r   r   *   sä   ø€ € € € € ðð ð6$-ð $-ð $-ð $-ð $-ð $-ð $-ðLð ð ð ð ð ð ð0ð ð ð&ð &ð &ð2ð 2ð 2ðhIð Ið Ið ðUð Uñ „\ðUð\ð \ð \ð \ð \ð \ð \r'   r   )rs   Ú
__future__r   r   ÚnumpyrG   Úqiskit.circuit.gater   Ú'qiskit.circuit.library.standard_gates.hr   Ú(qiskit.quantum_info.operators.predicatesr   Úqiskit.circuit.quantumregisterr   Úqiskit.circuit.quantumcircuitr   Úqiskit.circuit.exceptionsr	   Úqiskit.exceptionsr
   Úqiskit._accelerater   r^   r   r   r   ra   r'   r&   ú<module>r€      s$  ðð( BÐ Aà "Ð "Ð "Ð "Ð "Ð "à €€€à Ð Ð Ð à $Ð $Ð $Ð $Ð $Ð $Ø 9Ð 9Ð 9Ð 9Ð 9Ð 9Ø FÐ FÐ FÐ FÐ FÐ FØ :Ð :Ð :Ð :Ð :Ð :Ø 8Ð 8Ð 8Ð 8Ð 8Ð 8Ø 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø )Ð )Ð )Ð )Ð )Ð )Ø &Ð &Ð &Ð &Ð &Ð &à Ð Ð Ð Ð Ð à€ðk\ð k\ð k\ð k\ð k\ˆTñ k\ô k\ð k\ð k\ð k\r'   