
    z	in$                       S r SSKJr  SSKrSSKrSSKrSSKJr  SSKJ	r	  SSK
J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KJr  SSKJr  SSKJr  SSKJr  \R<                  (       a  SSKJ r    " S S\	5      r!g)z&Arbitrary unitary circuit instruction.    )annotationsN)_numpy_compat)Gate)ControlledGate)AnnotatedOperationControlModifier)QuantumCircuit)QuantumRegister)CircuitError)_compute_control_matrix)UGate)matrix_equal)is_unitary_matrix   )Isometry)BaseOperatorc                     ^  \ rS rSrSr  SSS.         SU 4S jjjjrS rS\R                  4S jr	SSS jjr
S	 rS
 rS rS r    S         SS jjrS rS rSrU =r$ )UnitaryGate'   aW  Class quantum gates specified by a unitary matrix.

Example:

We can create a unitary gate from a unitary matrix then add it to a
quantum circuit. The matrix can also be directly applied to the quantum
circuit, see :meth:`.QuantumCircuit.unitary`.

.. plot::
    :include-source:
    :nofigs:

    from qiskit import QuantumCircuit
    from qiskit.circuit.library import UnitaryGate

    matrix = [[0, 0, 0, 1],
                [0, 0, 1, 0],
                [1, 0, 0, 0],
                [0, 1, 0, 0]]
    gate = UnitaryGate(matrix)

    circuit = QuantumCircuit(2)
    circuit.append(gate, [0, 1])
N)
num_qubitsc                 > [        US5      (       a  UR                  5       nO+[        US5      (       a  UR                  5       R                  n[        R
                  " U[        S9nUR                  u  pVUb  UO[        [        R                  " U5      5      nU(       a4  [        U5      (       d  [        S5      eXV:w  d	  SU-  U:w  a  [        S5      e[        TU ]9  SXA/US	9  g)
aT  
Args:
    data: Unitary operator.
    label: Unitary name for backend [Default: ``None``].
    check_input: If set to ``False`` this asserts the input
        is known to be unitary and the checking to validate this will
        be skipped. This should only ever be used if you know the
        input is unitary, setting this to ``False`` and passing in
        a non-unitary matrix will result unexpected behavior and errors.
    num_qubits: If given, the number of qubits in the matrix.  If not given, it is inferred.

Raises:
    ValueError: If input data is not an N-qubit unitary operator.
	to_matrixto_operator)dtypeNzInput matrix is not unitary.   z(Input matrix is not an N-qubit operator.unitary)label)hasattrr   r   datanumpyasarraycomplexshapeintmathlog2r   
ValueErrorsuper__init__)selfr   r   check_inputr   	input_dim
output_dim	__class__s          j/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/circuit/library/generalized_gates/unitary.pyr)   UnitaryGate.__init__A   s    , 4%% >>#DT=)) ##%**D}}T1 $

	#-#9Zs499YCW?X
$T** !?@@&!Z-9*D !KLLJeD    c                    [        U[        5      (       d  gU R                  UR                  :w  a  g[        U R                  S   UR                  S   5      $ )NFr   )
isinstancer   r   r   params)r*   others     r/   __eq__UnitaryGate.__eq__n   sB    %--::$DKKNELLO<<r1   c                    Uc  U R                   S   R                  OUn[        R                  " U R                   S   XS9$ )zReturn matrix for the unitary.r   )r   copy)r4   r   r    array)r*   r   r9   s      r/   	__array__UnitaryGate.__array__u   s4    (-A$$5{{4;;q>BBr1   c                "    U R                  5       $ z"Return the adjoint of the unitary.)adjoint)r*   	annotateds     r/   inverseUnitaryGate.inversez   s    ||~r1   c                \    [        [        R                  " U R                  5       5      5      $ )z$Return the conjugate of the unitary.)r   r    conjr   r*   s    r/   	conjugateUnitaryGate.conjugate~   s    5::dnn&6788r1   c                >    U R                  5       R                  5       $ r>   )	transposerF   rE   s    r/   r?   UnitaryGate.adjoint   s    ~~))++r1   c                \    [        [        R                  " U R                  5       5      5      $ )z$Return the transpose of the unitary.)r   r    rI   r   rE   s    r/   rI   UnitaryGate.transpose   s    5??4>>+;<==r1   c                   U R                   S:X  a{  SSKJn  [        SS5      n[	        X R
                  S9nU" S5      R                  U R                  5       5      u  pEpgUR                  [        XEU5      US   // 5        Xsl
        X0l        gU R                   S:X  a"  SSKJn  U" U R                  5       5      U l        gSS	KJn	  U	" U R                  5       5      U l        SS
KJn
  [%        U
" U R                  5      R                  5       U R                  5       SS9(       d'  ['        U R(                  SS5      R                  U l        gg)z4Calculate a subcircuit that implements this unitary.r   r   )OneQubitEulerDecomposerq)nameUr   )two_qubit_cnot_decomposeqs_decompositionOperatorHz>atolN)r   .qiskit.synthesis.one_qubit.one_qubit_decomposerN   r
   r	   rP   angles_and_phaser   _appendr   global_phase
definition.qiskit.synthesis.two_qubit.two_qubit_decomposerR   qiskit.synthesis.unitary.qsdrT   qiskit.quantum_info.operatorsrV   r   r   matrix)r*   rN   rO   qcthetaphilamr]   rR   rT   rV   s              r/   _defineUnitaryGate._define   s   ??a^3'A		2B,CC,H,Y,Y -)E JJuU-!vr:*O O__! 7t~~7GHDO /t~~/?@DO ? Xdoo6@@BDNNDT[_`"*4;;1"="H"H ar1   c                r   U(       d  U R                  5       n[        XQSS9nSSKJn  U" USSS9nSSKJn	  [        U	" U5      R                  5       US	S
9(       d  [        USS5      R                  U l        [        SU R                  U-   U/UUUUU R                  5       S9n
U
$ [        U [        XS95      n
U
$ )a  Return controlled version of gate.

Args:
    num_ctrl_qubits: Number of controls to add to gate (default is 1).
    label: Optional gate label.
    ctrl_state: The control state in decimal or as a bit string (e.g. ``"1011"``).
        If ``None``, use ``2**num_ctrl_qubits - 1``.
    annotated: indicates whether the controlled gate should be implemented
        as an annotated gate. If ``None``, this is handled as ``False``.

Returns:
    Controlled version of gate.
N)
ctrl_stater   rS   TF)opt_a1opt_a2rU   rW   rX   z	c-unitary)r   r4   r   num_ctrl_qubitsr^   rj   	base_gate)rm   rj   )r   r   r`   rT   ra   rV   r   r   r^   r   r   r9   r   r   )r*   rm   r   rj   r@   matcmatrT   cmat_defrV   gates              r/   controlUnitaryGate.control   s    ( .."C*3DQDE'T%HH ? 2 < < >4P"*4A"6"A"A!??_<u /#%))+	D  &oo]D r1   c                \    U R                   R                  5       nU R                  Ul        U$ )zReturn an unparameterized version of ourselves, so the OQ2 exporter doesn't choke on the
non-standard things in our `params` field.)r^   to_gaterP   )r*   outs     r/   _qasm_decompositionUnitaryGate._qasm_decomposition   s&     oo%%'99
r1   c                    [        U[        R                  5      (       a  U$ [        S[	        U5       SU R
                   35      e)z,Unitary gate parameter has to be an ndarray.zinvalid param type z	 in gate )r3   r    ndarrayr   typerP   )r*   	parameters     r/   validate_parameterUnitaryGate.validate_parameter   s;    i//!4T)_4EYtyykZ[[r1   )r^   )NT)
r   z#numpy.ndarray | Gate | BaseOperatorr   
str | Noner+   boolr   z
int | NonereturnNone)F)r@   r   )r   NNN)
rm   r$   r   r   rj   zint | str | Noner@   zbool | Noner   z#ControlledGate | AnnotatedOperation)__name__
__module____qualname____firstlineno____doc__r)   r6   r   COPY_ONLY_IF_NEEDEDr;   rA   rF   r?   rI   rg   rs   rx   r~   __static_attributes____classcell__)r.   s   @r/   r   r   '   s    8 ! 	+E "&+E1+E +E 	+E +E 
+E +EZ= #)J)J C
9,>!IJ  ! '+!%00 0 %	0
 0 
-0d\ \r1   r   )"r   
__future__r   r%   typingr    qiskitr   qiskit.circuit.gater   qiskit.circuit.controlledgater   "qiskit.circuit.annotated_operationr   r   qiskit.circuit.quantumcircuitr	   qiskit.circuitr
   qiskit.circuit.exceptionsr   qiskit.circuit._utilsr   'qiskit.circuit.library.standard_gates.ur   (qiskit.quantum_info.operators.predicatesr   r   isometryr   TYPE_CHECKING+qiskit.quantum_info.operators.base_operatorr   r    r1   r/   <module>r      sV    - "      $ 8 R 8 * 2 9 9 A F 	HD\$ D\r1   